/** Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs. And lock physical presence if needed. @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation @param[in] NotifyDescriptor Address of the notification descriptor data structure. @param[in] Ppi Address of the PPI that was installed. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_ABORTED physicalPresenceCMDEnable is locked. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI PhysicalPresencePpiNotifyCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; TPM_PERMANENT_FLAGS TpmPermanentFlags; PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi; TPM_PHYSICAL_PRESENCE PhysicalPresenceValue; Status = Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags); if (EFI_ERROR (Status)) { return Status; } // // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs. // if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !TpmPermanentFlags.physicalPresenceLifetimeLock) { // // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet. // PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK; TpmPermanentFlags.physicalPresenceLifetimeLock = TRUE; if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) { PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE; TpmPermanentFlags.physicalPresenceCMDEnable = TRUE; } else { PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE; TpmPermanentFlags.physicalPresenceCMDEnable = FALSE; } if (PcdGetBool (PcdPhysicalPresenceHwEnable)) { PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE; } else { PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE; } Status = Tpm12PhysicalPresence ( PhysicalPresenceValue ); if (EFI_ERROR (Status)) { return Status; } } // // 2. Lock physical presence if it is required. // LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi; if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) { return EFI_SUCCESS; } if (!TpmPermanentFlags.physicalPresenceCMDEnable) { if (TpmPermanentFlags.physicalPresenceLifetimeLock) { // // physicalPresenceCMDEnable is locked, can't change. // return EFI_ABORTED; } // // Enable physical presence command // It is necessary in order to lock physical presence // Status = Tpm12PhysicalPresence ( TPM_PHYSICAL_PRESENCE_CMD_ENABLE ); if (EFI_ERROR (Status)) { return Status; } } // // Lock physical presence // Status = Tpm12PhysicalPresence ( TPM_PHYSICAL_PRESENCE_LOCK ); return Status; }
/** This service requests use TPM12. @retval EFI_SUCCESS Get the control of TPM12 chip. @retval EFI_NOT_FOUND TPM12 not found. @retval EFI_DEVICE_ERROR Unexpected device behavior. **/ EFI_STATUS EFIAPI Tpm12RequestUseTpm ( VOID ) { EFI_STATUS Status; UINT8 Data; UINT64 Current; UINT64 Previous; UINT64 Total; UINT64 Start; UINT64 End; UINT64 Timeout; INT64 Cycle; INT64 Delta; // // Get the current timer value // Current = GetPerformanceCounter(); // // Initialize local variables // Start = 0; End = 0; Total = 0; // // Retrieve the performance counter properties and compute the number of // performance counter ticks required to reach the maximum TIS timeout of // TIS_TIMEOUT_A. TIS_TIMEOUT_A is in microseconds. // Timeout = DivU64x32 ( MultU64x32 ( GetPerformanceCounterProperties (&Start, &End), TIS_TIMEOUT_A ), 1000000 ); Cycle = End - Start; if (Cycle < 0) { Cycle = -Cycle; } Cycle++; // // Attempt to read a byte from the Atmel I2C TPM // do { Status = ReadTpmBufferMultiple (&Data, sizeof(Data)); Previous = Current; Current = GetPerformanceCounter(); Delta = (INT64) (Current - Previous); if (Start > End) { Delta = -Delta; } if (Delta < 0) { Delta += Cycle; } Total += Delta; if (Total >= Timeout) { Status = EFI_TIMEOUT; DEBUG ((EFI_D_ERROR, "Atmel I2C TPM failed to read: %r\n", Status)); return Status; } } while (EFI_ERROR (Status)); // // Send Physical Presence Command to Atmel I2C TPM // Status = Tpm12PhysicalPresence (TPM_PHYSICAL_PRESENCE_PRESENT); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Atmel I2C TPM failed to submit physical presence command: %r\n", Status)); return Status; } return EFI_SUCCESS; }