Exemple #1
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;

    //
    // Check to see if TPM exists
    //
    if (TpmReadByte (INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT) == 0xFF) {
        return EFI_NOT_FOUND;
    }

    TpmWriteByte (INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT, TIS_PC_ACC_RQUUSE);

    //
    // No locality set before, ACCESS_X.activeLocality MUST be valid within TIMEOUT_A
    //
    Status = TisPcWaitRegisterBits (
                 INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT,
                 (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
                 0,
                 TIS_TIMEOUT_A
             );
    return Status;
}
Exemple #2
0
/**
  Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE 
  to ACCESS Register in the time of default TIS_TIMEOUT_A.

  @param[in] TisReg                Pointer to TIS register.

  @retval    EFI_SUCCESS           Get the control of TPM chip.
  @retval    EFI_INVALID_PARAMETER TisReg is NULL.
  @retval    EFI_NOT_FOUND         TPM chip doesn't exit.
  @retval    EFI_TIMEOUT           Can't get the TPM control in time.
**/
EFI_STATUS
EFIAPI
TisPcRequestUseTpm (
  IN      TIS_PC_REGISTERS_PTR      TisReg
  )
{
  EFI_STATUS                        Status;
  
  if (TisReg == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  if (!TisPcPresenceCheck (TisReg)) {
    return EFI_NOT_FOUND;
  }

  MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);
  //
  // No locality set before, ACCESS_X.activeLocality MUST be valid within TIMEOUT_A
  //
  Status = TisPcWaitRegisterBits (
             &TisReg->Access,
             (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
             0,
             TIS_TIMEOUT_A
             );
  return Status;
}
Exemple #3
0
/**
  Send command to TPM for execution.

  @param[in] TpmBuffer   Buffer for TPM command data.
  @param[in] DataLength  TPM command data length.

  @retval EFI_SUCCESS  Operation completed successfully.
  @retval EFI_TIMEOUT  The register can't run into the expected status in time.

**/
EFI_STATUS
TisPcSend (
    IN UINT8   *TpmBuffer,
    IN UINT32  DataLength
)
{
    UINT16      BurstCount;
    UINT32      Index;
    EFI_STATUS  Status;

    Status = TisPcPrepareCommand ();
    if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "The TPM is not ready!\n"));
        goto Done;
    }
    Index = 0;
    while (Index < DataLength) {
        Status = TisPcReadBurstCount (&BurstCount);
        if (EFI_ERROR (Status)) {
            Status = EFI_TIMEOUT;
            goto Done;
        }
        for (; BurstCount > 0 && Index < DataLength; BurstCount--) {
            TpmWriteByte (INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT, *(TpmBuffer + Index));
            Index++;
        }
    }
    //
    // Ensure the TPM status STS_EXPECT change from 1 to 0
    //
    Status = TisPcWaitRegisterBits (
                 INFINEON_TPM_STS_0_ADDRESS_DEFAULT,
                 (UINT8) TIS_PC_VALID,
                 TIS_PC_STS_EXPECT,
                 TIS_TIMEOUT_C
             );
    if (EFI_ERROR (Status)) {
        goto Done;
    }

    //
    // Start the command
    //
    TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_GO);

Done:
    if (EFI_ERROR (Status))  {
        //
        // Ensure the TPM state change from "Reception" to "Idle/Ready"
        //
        TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_READY);
    }

    return Status;
}
Exemple #4
0
/**
  Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
  to Status Register in time.

  @retval EFI_SUCCESS  TPM chip enters into ready state.
  @retval EFI_TIMEOUT  TPM chip can't be set to ready state in time.
**/
EFI_STATUS
TisPcPrepareCommand (
    VOID
)
{
    EFI_STATUS  Status;

    TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_READY);
    Status = TisPcWaitRegisterBits (
                 INFINEON_TPM_STS_0_ADDRESS_DEFAULT,
                 TIS_PC_STS_READY,
                 0,
                 TIS_TIMEOUT_B
             );
    return Status;
}
Exemple #5
0
/**
  Set TPM chip to ready state by sending ready command TIS_PC_STS_READY 
  to Status Register in time.

  @param[in] TisReg                Pointer to TIS register.

  @retval    EFI_SUCCESS           TPM chip enters into ready state.
  @retval    EFI_INVALID_PARAMETER TisReg is NULL.
  @retval    EFI_TIMEOUT           TPM chip can't be set to ready state in time.
**/
EFI_STATUS
EFIAPI
TisPcPrepareCommand (
  IN      TIS_PC_REGISTERS_PTR      TisReg
  )
{
  EFI_STATUS                        Status;

  if (TisReg == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
  Status = TisPcWaitRegisterBits (
             &TisReg->Status,
             TIS_PC_STS_READY,
             0,
             TIS_TIMEOUT_B
             );
  return Status;
}
Exemple #6
0
/**
  Receive response data of last command from TPM.

  @param[out] TpmBuffer  Buffer for response data.
  @param[out] RespSize   Response data length.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
  @retval EFI_DEVICE_ERROR      Unexpected device status.
  @retval EFI_BUFFER_TOO_SMALL  Response data is too long.

**/
EFI_STATUS
TisPcReceive (
    OUT UINT8   *TpmBuffer,
    OUT UINT32  *RespSize
)
{
    EFI_STATUS           Status;
    UINT16               BurstCount;
    UINT32               Index;
    UINT32               ResponseSize;
    TPM_RSP_COMMAND_HDR  *ResponseHeader;

    //
    // Wait for the command completion
    //
    Status = TisPcWaitRegisterBits (
                 INFINEON_TPM_STS_0_ADDRESS_DEFAULT,
                 (UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
                 0,
                 TIS_TIMEOUT_B
             );
    if (EFI_ERROR (Status)) {
        Status = EFI_TIMEOUT;
        goto Done;
    }
    //
    // Read the response data header and check it
    //
    Index = 0;
    BurstCount = 0;
    while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
        Status = TisPcReadBurstCount (&BurstCount);
        if (EFI_ERROR (Status)) {
            Status = EFI_TIMEOUT;
            goto Done;
        }
        for (; BurstCount > 0 ; BurstCount--) {
            *(TpmBuffer + Index) = TpmReadByte (INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT);
            Index++;
            if (Index == sizeof (TPM_RSP_COMMAND_HDR))
                break;
        }
    }

    //
    // Check the response data header (tag, parasize and returncode)
    //
    ResponseHeader = (TPM_RSP_COMMAND_HDR *)TpmBuffer;
    if (SwapBytes16 (ReadUnaligned16 (&ResponseHeader->tag)) != TPM_TAG_RSP_COMMAND) {
        Status = EFI_DEVICE_ERROR;
        goto Done;
    }

    ResponseSize = SwapBytes32 (ReadUnaligned32 (&ResponseHeader->paramSize));
    if (ResponseSize == sizeof (TPM_RSP_COMMAND_HDR)) {
        Status = EFI_SUCCESS;
        goto Done;
    }
    if (ResponseSize < sizeof (TPM_RSP_COMMAND_HDR)) {
        Status = EFI_DEVICE_ERROR;
        goto Done;
    }
    if (*RespSize < ResponseSize) {
        Status = EFI_BUFFER_TOO_SMALL;
        goto Done;
    }
    *RespSize = ResponseSize;

    //
    // Continue reading the remaining data
    //
    while (Index < ResponseSize) {
        for (; BurstCount > 0 ; BurstCount--) {
            *(TpmBuffer + Index) = TpmReadByte (INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT);
            Index++;
            if (Index == ResponseSize) {
                Status = EFI_SUCCESS;
                goto Done;
            }
        }
        Status = TisPcReadBurstCount (&BurstCount);
        if (EFI_ERROR (Status) && (Index < ResponseSize)) {
            Status = EFI_DEVICE_ERROR;
            goto Done;
        }
    }

Done:
    //
    // Ensure the TPM state change from "Execution" or "Completion" to "Idle/Ready"
    //
    TpmWriteByte (INFINEON_TPM_STS_0_ADDRESS_DEFAULT, TIS_PC_STS_READY);

    return Status;
}
Exemple #7
0
/**
  Send a command to TPM for execution and return response data.

  @param[in]      PeiServices   Describes the list of possible PEI Services.
  @param[in]      TisReg        TPM register space base address.  
  @param[in]      BufferIn      Buffer for command data.  
  @param[in]      SizeIn        Size of command data.  
  @param[in, out] BufferOut     Buffer for response data.  
  @param[in, out] SizeOut       Size of response data.  
 
  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_TIMEOUT           The register can't run into the expected status in time.
  @retval EFI_BUFFER_TOO_SMALL  Response data buffer is too small.
  @retval EFI_DEVICE_ERROR      Unexpected device behavior.

**/
EFI_STATUS
TisTpmCommand (
  IN     EFI_PEI_SERVICES           **PeiServices,
  IN     TIS_PC_REGISTERS_PTR       TisReg,
  IN     UINT8                      *BufferIn,
  IN     UINT32                     SizeIn,
  IN OUT UINT8                      *BufferOut,
  IN OUT UINT32                     *SizeOut
  )
{
  EFI_STATUS                        Status;
  UINT16                            BurstCount;
  UINT32                            Index;
  UINT32                            TpmOutSize;
  UINT16                            Data16;
  UINT32                            Data32;

  Status = TisPcPrepareCommand (TisReg);
  if (EFI_ERROR (Status)){
    DEBUG ((DEBUG_ERROR, "Tpm is not ready for command!\n"));
    return Status;
  }
  //
  // Send the command data to Tpm
  //
  Index = 0;
  while (Index < SizeIn) {
    Status = TisPcReadBurstCount (TisReg, &BurstCount);
    if (EFI_ERROR (Status)) {
      Status = EFI_TIMEOUT;
      goto Exit;
    }
    for (; BurstCount > 0 && Index < SizeIn; BurstCount--) {
      MmioWrite8((UINTN)&TisReg->DataFifo, *(BufferIn + Index));
      Index++;
    }
  }
  //
  // Check the Tpm status STS_EXPECT change from 1 to 0
  //
  Status = TisPcWaitRegisterBits (
             &TisReg->Status,
             (UINT8) TIS_PC_VALID,
             TIS_PC_STS_EXPECT,
             TIS_TIMEOUT_C
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "The send buffer too small!\n"));
    Status = EFI_BUFFER_TOO_SMALL;
    goto Exit;
  }
  //
  // Executed the TPM command and waiting for the response data ready
  //
  MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_GO);
  Status = TisPcWaitRegisterBits (
             &TisReg->Status,
             (UINT8) (TIS_PC_VALID | TIS_PC_STS_DATA),
             0,
             TIS_TIMEOUT_B
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Wait for Tpm response data time out!!\n"));
    Status = EFI_TIMEOUT;
    goto Exit;
  }
  //
  // Get response data header
  //
  Index = 0;
  BurstCount = 0;
  while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
    Status = TisPcReadBurstCount (TisReg, &BurstCount);
    if (EFI_ERROR (Status)) {
      Status = EFI_TIMEOUT;
      goto Exit;
    }
    for (; BurstCount > 0; BurstCount--) {
      *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
      Index++;
      if (Index == sizeof (TPM_RSP_COMMAND_HDR)) break;
    }
  }
  //
  // Check the reponse data header (tag,parasize and returncode )
  //
  CopyMem (&Data16, BufferOut, sizeof (UINT16));
  if (SwapBytes16 (Data16) != TPM_TAG_RSP_COMMAND ) {
    Status = EFI_DEVICE_ERROR;
    goto Exit;
  }
  
  CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));
  TpmOutSize  = SwapBytes32 (Data32);
  if (*SizeOut < TpmOutSize) {
    Status = EFI_BUFFER_TOO_SMALL;
    goto Exit;
  }
  *SizeOut = TpmOutSize;
  //
  // Continue reading the remaining data
  //
  while ( Index < TpmOutSize ) {
    for (; BurstCount > 0; BurstCount--) {
      *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
      Index++;
      if (Index == TpmOutSize) {
        Status = EFI_SUCCESS;
        goto Exit;
      }
    }
    Status = TisPcReadBurstCount (TisReg, &BurstCount);
    if (EFI_ERROR (Status)) {
      Status = EFI_TIMEOUT;
      goto Exit;
    }
  }
Exit:
  MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
  return Status;
}