Exemple #1
0
/**
  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;
}
Exemple #2
0
/**
  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;
}