TisPc.c revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
2N/A/** @file
2N/A Basic TIS (TPM Interface Specification) functions.
2N/A
2N/ACopyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
2N/AThis program and the accompanying materials
2N/Aare licensed and made available under the terms and conditions of the BSD License
2N/Awhich accompanies this distribution. The full text of the license may be found at
2N/Ahttp://opensource.org/licenses/bsd-license.php
2N/A
2N/ATHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
2N/AWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
2N/A
2N/A**/
2N/A
2N/A#include "CommonHeader.h"
2N/A
2N/A/**
2N/A Check whether TPM chip exist.
2N/A
2N/A @param[in] TisReg Pointer to TIS register.
2N/A
2N/A @retval TRUE TPM chip exists.
2N/A @retval FALSE TPM chip is not found.
2N/A**/
2N/ABOOLEAN
2N/ATisPcPresenceCheck (
2N/A IN TIS_PC_REGISTERS_PTR TisReg
2N/A )
2N/A{
2N/A UINT8 RegRead;
2N/A
2N/A RegRead = MmioRead8 ((UINTN)&TisReg->Access);
2N/A return (BOOLEAN)(RegRead != (UINT8)-1);
2N/A}
2N/A
2N/A/**
2N/A Check whether the value of a TPM chip register satisfies the input BIT setting.
2N/A
2N/A @param[in] Register Address port of register to be checked.
2N/A @param[in] BitSet Check these data bits are set.
2N/A @param[in] BitClear Check these data bits are clear.
2N/A @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
2N/A
2N/A @retval EFI_SUCCESS The register satisfies the check bit.
2N/A @retval EFI_TIMEOUT The register can't run into the expected status in time.
2N/A**/
2N/AEFI_STATUS
2N/AEFIAPI
2N/ATisPcWaitRegisterBits (
2N/A IN UINT8 *Register,
2N/A IN UINT8 BitSet,
2N/A IN UINT8 BitClear,
2N/A IN UINT32 TimeOut
2N/A )
2N/A{
2N/A UINT8 RegRead;
2N/A UINT32 WaitTime;
2N/A
2N/A for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
2N/A RegRead = MmioRead8 ((UINTN)Register);
if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)
return EFI_SUCCESS;
MicroSecondDelay (30);
}
return EFI_TIMEOUT;
}
/**
Get BurstCount by reading the burstCount field of a TIS regiger
in the time of default TIS_TIMEOUT_D.
@param[in] TisReg Pointer to TIS register.
@param[out] BurstCount Pointer to a buffer to store the got BurstConut.
@retval EFI_SUCCESS Get BurstCount.
@retval EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.
@retval EFI_TIMEOUT BurstCount can't be got in time.
**/
EFI_STATUS
EFIAPI
TisPcReadBurstCount (
IN TIS_PC_REGISTERS_PTR TisReg,
OUT UINT16 *BurstCount
)
{
UINT32 WaitTime;
UINT8 DataByte0;
UINT8 DataByte1;
if (BurstCount == NULL || TisReg == NULL) {
return EFI_INVALID_PARAMETER;
}
WaitTime = 0;
do {
//
// TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,
// so it needs to use MmioRead8 to read two times
//
DataByte0 = MmioRead8 ((UINTN)&TisReg->BurstCount);
DataByte1 = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);
*BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
if (*BurstCount != 0) {
return EFI_SUCCESS;
}
MicroSecondDelay (30);
WaitTime += 30;
} while (WaitTime < TIS_TIMEOUT_D);
return EFI_TIMEOUT;
}
/**
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;
}
/**
Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
to ACCESS Register in the time of default TIS_TIMEOUT_D.
@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);
Status = TisPcWaitRegisterBits (
&TisReg->Access,
(UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
0,
TIS_TIMEOUT_D
);
return Status;
}