+/** @file\r
+ PTP (Platform TPM Profile) CRB (Command Response Buffer) interface used by dTPM2.0 library.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <IndustryStandard/Tpm20.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/Tpm2DeviceLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <IndustryStandard/TpmPtp.h>\r
+#include <IndustryStandard/TpmTis.h>\r
+\r
+typedef enum {\r
+ PtpInterfaceTis,\r
+ PtpInterfaceFifo,\r
+ PtpInterfaceCrb,\r
+ PtpInterfaceMax,\r
+} PTP_INTERFACE_TYPE;\r
+\r
+//\r
+// Execution of the command may take from several seconds to minutes for certain\r
+// commands, such as key generation.\r
+//\r
+#define PTP_TIMEOUT_MAX (90000 * 1000) // 90s\r
+\r
+//\r
+// Max TPM command/reponse length\r
+//\r
+#define TPMCMDBUFLENGTH 0x500\r
+\r
+/**\r
+ Check whether TPM PTP register exist.\r
+\r
+ @param[in] Reg Pointer to PTP register.\r
+\r
+ @retval TRUE TPM PTP exists.\r
+ @retval FALSE TPM PTP is not found.\r
+**/\r
+BOOLEAN\r
+IsPtpPresence (\r
+ IN VOID *Reg\r
+ )\r
+{\r
+ UINT8 RegRead;\r
+\r
+ RegRead = MmioRead8 ((UINTN)Reg);\r
+ if (RegRead == 0xFF) {\r
+ //\r
+ // No TPM chip\r
+ //\r
+ return FALSE;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Check whether the value of a TPM chip register satisfies the input BIT setting.\r
+\r
+ @param[in] Register Address port of register to be checked.\r
+ @param[in] BitSet Check these data bits are set.\r
+ @param[in] BitClear Check these data bits are clear.\r
+ @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.\r
+\r
+ @retval EFI_SUCCESS The register satisfies the check bit.\r
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.\r
+**/\r
+EFI_STATUS\r
+PtpCrbWaitRegisterBits (\r
+ IN UINT32 *Register,\r
+ IN UINT32 BitSet,\r
+ IN UINT32 BitClear,\r
+ IN UINT32 TimeOut\r
+ )\r
+{\r
+ UINT32 RegRead;\r
+ UINT32 WaitTime;\r
+\r
+ for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){\r
+ RegRead = MmioRead32 ((UINTN)Register);\r
+ if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ MicroSecondDelay (30);\r
+ }\r
+ return EFI_TIMEOUT;\r
+}\r
+\r
+/**\r
+ Get the control of TPM chip.\r
+\r
+ @param[in] CrbReg Pointer to CRB register.\r
+\r
+ @retval EFI_SUCCESS Get the control of TPM chip.\r
+ @retval EFI_INVALID_PARAMETER CrbReg is NULL.\r
+ @retval EFI_NOT_FOUND TPM chip doesn't exit.\r
+ @retval EFI_TIMEOUT Can't get the TPM control in time.\r
+**/\r
+EFI_STATUS\r
+PtpCrbRequestUseTpm (\r
+ IN PTP_CRB_REGISTERS_PTR CrbReg\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (!IsPtpPresence (CrbReg)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ MmioWrite32((UINTN)&CrbReg->LocalityControl, PTP_CRB_LOCALITY_CONTROL_REQUEST_ACCESS);\r
+ Status = PtpCrbWaitRegisterBits (\r
+ &CrbReg->LocalityStatus,\r
+ PTP_CRB_LOCALITY_STATUS_GRANTED,\r
+ 0,\r
+ PTP_TIMEOUT_A\r
+ );\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Send a command to TPM for execution and return response data.\r
+\r
+ @param[in] CrbReg TPM register space base address.\r
+ @param[in] BufferIn Buffer for command data.\r
+ @param[in] SizeIn Size of command data.\r
+ @param[in, out] BufferOut Buffer for response data.\r
+ @param[in, out] SizeOut Size of response data.\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.\r
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+ @retval EFI_UNSUPPORTED Unsupported TPM version\r
+\r
+**/\r
+EFI_STATUS\r
+PtpCrbTpmCommand (\r
+ IN PTP_CRB_REGISTERS_PTR CrbReg,\r
+ IN UINT8 *BufferIn,\r
+ IN UINT32 SizeIn,\r
+ IN OUT UINT8 *BufferOut,\r
+ IN OUT UINT32 *SizeOut\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 Index;\r
+ UINT32 TpmOutSize;\r
+ UINT16 Data16;\r
+ UINT32 Data32;\r
+\r
+ DEBUG_CODE (\r
+ UINTN DebugSize;\r
+\r
+ DEBUG ((EFI_D_VERBOSE, "PtpCrbTpmCommand Send - "));\r
+ if (SizeIn > 0x100) {\r
+ DebugSize = 0x40;\r
+ } else {\r
+ DebugSize = SizeIn;\r
+ }\r
+ for (Index = 0; Index < DebugSize; Index++) {\r
+ DEBUG ((EFI_D_VERBOSE, "%02x ", BufferIn[Index]));\r
+ }\r
+ if (DebugSize != SizeIn) {\r
+ DEBUG ((EFI_D_VERBOSE, "...... "));\r
+ for (Index = SizeIn - 0x20; Index < SizeIn; Index++) {\r
+ DEBUG ((EFI_D_VERBOSE, "%02x ", BufferIn[Index]));\r
+ }\r
+ }\r
+ DEBUG ((EFI_D_VERBOSE, "\n"));\r
+ );\r
+ TpmOutSize = 0;\r
+\r
+ //\r
+ // STEP 0:\r
+ // Ready is any time the TPM is ready to receive a command, following a write\r
+ // of 1 by software to Request.cmdReady, as indicated by the Status field\r
+ // being cleared to 0.\r
+ //\r
+ MmioWrite32((UINTN)&CrbReg->CrbControlRequest, PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY);\r
+ Status = PtpCrbWaitRegisterBits (\r
+ &CrbReg->CrbControlRequest,\r
+ 0,\r
+ PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY,\r
+ PTP_TIMEOUT_C\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+ Status = PtpCrbWaitRegisterBits (\r
+ &CrbReg->CrbControlStatus,\r
+ 0,\r
+ PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE,\r
+ PTP_TIMEOUT_C\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
+ //\r
+ // STEP 1:\r
+ // Command Reception occurs following a Ready state between the write of the\r
+ // first byte of a command to the Command Buffer and the receipt of a write\r
+ // of 1 to Start.\r
+ //\r
+ for (Index = 0; Index < SizeIn; Index++) {\r
+ MmioWrite8 ((UINTN)&CrbReg->CrbDataBuffer[Index], BufferIn[Index]);\r
+ }\r
+ MmioWrite32 ((UINTN)&CrbReg->CrbControlCommandAddressHigh, (UINT32)RShiftU64 ((UINTN)CrbReg->CrbDataBuffer, 32));\r
+ MmioWrite32 ((UINTN)&CrbReg->CrbControlCommandAddressLow, (UINT32)(UINTN)CrbReg->CrbDataBuffer);\r
+ MmioWrite32 ((UINTN)&CrbReg->CrbControlCommandSize, sizeof(CrbReg->CrbDataBuffer));\r
+\r
+ MmioWrite64 ((UINTN)&CrbReg->CrbControlResponseAddrss, (UINT32)(UINTN)CrbReg->CrbDataBuffer);\r
+ MmioWrite32 ((UINTN)&CrbReg->CrbControlResponseSize, sizeof(CrbReg->CrbDataBuffer));\r
+\r
+ //\r
+ // STEP 2:\r
+ // Command Execution occurs after receipt of a 1 to Start and the TPM\r
+ // clearing Start to 0.\r
+ //\r
+ MmioWrite32((UINTN)&CrbReg->CrbControlStart, PTP_CRB_CONTROL_START);\r
+ Status = PtpCrbWaitRegisterBits (\r
+ &CrbReg->CrbControlStart,\r
+ 0,\r
+ PTP_CRB_CONTROL_START,\r
+ PTP_TIMEOUT_MAX\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ }\r
+\r
+ //\r
+ // STEP 3:\r
+ // Command Completion occurs after completion of a command (indicated by the\r
+ // TPM clearing TPM_CRB_CTRL_Start_x to 0) and before a write of a 1 by the\r
+ // software to Request.goIdle.\r
+ //\r
+\r
+ //\r
+ // Get response data header\r
+ //\r
+ for (Index = 0; Index < sizeof (TPM2_RESPONSE_HEADER); Index++) {\r
+ BufferOut[Index] = MmioRead8 ((UINTN)&CrbReg->CrbDataBuffer[Index]);\r
+ }\r
+ DEBUG_CODE (\r
+ DEBUG ((EFI_D_VERBOSE, "PtpCrbTpmCommand ReceiveHeader - "));\r
+ for (Index = 0; Index < sizeof (TPM2_RESPONSE_HEADER); Index++) {\r
+ DEBUG ((EFI_D_VERBOSE, "%02x ", BufferOut[Index]));\r
+ }\r
+ DEBUG ((EFI_D_VERBOSE, "\n"));\r
+ );\r
+ //\r
+ // Check the reponse data header (tag, parasize and returncode)\r
+ //\r
+ CopyMem (&Data16, BufferOut, sizeof (UINT16));\r
+ // TPM2 should not use this RSP_COMMAND\r
+ if (SwapBytes16 (Data16) == TPM_ST_RSP_COMMAND) {\r
+ DEBUG ((EFI_D_ERROR, "TPM2: TPM_ST_RSP error - %x\n", TPM_ST_RSP_COMMAND));\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Exit;\r
+ }\r
+\r
+ CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));\r
+ TpmOutSize = SwapBytes32 (Data32);\r
+ if (*SizeOut < TpmOutSize) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ goto Exit;\r
+ }\r
+ *SizeOut = TpmOutSize;\r
+ //\r
+ // Continue reading the remaining data\r
+ //\r
+ for (Index = sizeof (TPM2_RESPONSE_HEADER); Index < TpmOutSize; Index++) {\r
+ BufferOut[Index] = MmioRead8 ((UINTN)&CrbReg->CrbDataBuffer[Index]);\r
+ }\r
+Exit:\r
+ DEBUG_CODE (\r
+ DEBUG ((EFI_D_VERBOSE, "PtpCrbTpmCommand Receive - "));\r
+ for (Index = 0; Index < TpmOutSize; Index++) {\r
+ DEBUG ((EFI_D_VERBOSE, "%02x ", BufferOut[Index]));\r
+ }\r
+ DEBUG ((EFI_D_VERBOSE, "\n"));\r
+ );\r
+\r
+ //\r
+ // STEP 4:\r
+ // Idle is any time TPM_CRB_CTRL_STS_x.Status.goIdle is 1.\r
+ //\r
+ MmioWrite32((UINTN)&CrbReg->CrbControlRequest, PTP_CRB_CONTROL_AREA_REQUEST_GO_IDLE);\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Send a command to TPM for execution and return response data.\r
+\r
+ @param[in] TisReg TPM register space base address.\r
+ @param[in] BufferIn Buffer for command data.\r
+ @param[in] SizeIn Size of command data.\r
+ @param[in, out] BufferOut Buffer for response data.\r
+ @param[in, out] SizeOut Size of response data.\r
+\r
+ @retval EFI_SUCCESS Operation completed successfully.\r
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.\r
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+ @retval EFI_UNSUPPORTED Unsupported TPM version\r
+\r
+**/\r
+EFI_STATUS\r
+Tpm2TisTpmCommand (\r
+ IN TIS_PC_REGISTERS_PTR TisReg,\r
+ IN UINT8 *BufferIn,\r
+ IN UINT32 SizeIn,\r
+ IN OUT UINT8 *BufferOut,\r
+ IN OUT UINT32 *SizeOut\r
+ );\r
+\r
+/**\r
+ Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE\r
+ to ACCESS Register in the time of default TIS_TIMEOUT_A.\r
+\r
+ @param[in] TisReg Pointer to TIS register.\r
+\r
+ @retval EFI_SUCCESS Get the control of TPM chip.\r
+ @retval EFI_INVALID_PARAMETER TisReg is NULL.\r
+ @retval EFI_NOT_FOUND TPM chip doesn't exit.\r
+ @retval EFI_TIMEOUT Can't get the TPM control in time.\r
+**/\r
+EFI_STATUS\r
+TisPcRequestUseTpm (\r
+ IN TIS_PC_REGISTERS_PTR TisReg\r
+ );\r
+\r
+/**\r
+ Return PTP interface type.\r
+\r
+ @param[in] Register Pointer to PTP register.\r
+\r
+ @return PTP interface type.\r
+**/\r
+PTP_INTERFACE_TYPE\r
+GetPtpInterface (\r
+ IN VOID *Register\r
+ )\r
+{\r
+ PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;\r
+ PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;\r
+\r
+ if (!IsPtpPresence (Register)) {\r
+ return PtpInterfaceMax;\r
+ }\r
+ //\r
+ // Check interface id\r
+ //\r
+ InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);\r
+ InterfaceCapability.Uint32 = MmioRead32 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->InterfaceCapability);\r
+\r
+ if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) &&\r
+ (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_CRB) &&\r
+ (InterfaceId.Bits.CapCRB != 0)) {\r
+ return PtpInterfaceCrb;\r
+ }\r
+ if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO) &&\r
+ (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_FIFO) &&\r
+ (InterfaceId.Bits.CapFIFO != 0) &&\r
+ (InterfaceCapability.Bits.InterfaceVersion == INTERFACE_CAPABILITY_INTERFACE_VERSION_PTP)) {\r
+ return PtpInterfaceFifo;\r
+ }\r
+ return PtpInterfaceTis;\r
+}\r
+\r
+/**\r
+ Dump PTP register information.\r
+\r
+ @param[in] Register Pointer to PTP register.\r
+**/\r
+VOID\r
+DumpPtpInfo (\r
+ IN VOID *Register\r
+ )\r
+{\r
+ PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;\r
+ PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;\r
+ UINT8 StatusEx;\r
+ UINT16 Vid;\r
+ UINT16 Did;\r
+ UINT8 Rid;\r
+ PTP_INTERFACE_TYPE PtpInterface;\r
+\r
+ if (!IsPtpPresence (Register)) {\r
+ return ;\r
+ }\r
+\r
+ InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);\r
+ InterfaceCapability.Uint32 = MmioRead32 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->InterfaceCapability);\r
+ StatusEx = MmioRead8 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->StatusEx);\r
+\r
+ //\r
+ // Dump InterfaceId Register for PTP\r
+ //\r
+ DEBUG ((EFI_D_INFO, "InterfaceId - 0x%08x\n", InterfaceId.Uint32));\r
+ DEBUG ((EFI_D_INFO, " InterfaceType - 0x%02x\n", InterfaceId.Bits.InterfaceType));\r
+ if (InterfaceId.Bits.InterfaceType != PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_TIS) {\r
+ DEBUG ((EFI_D_INFO, " InterfaceVersion - 0x%02x\n", InterfaceId.Bits.InterfaceVersion));\r
+ DEBUG ((EFI_D_INFO, " CapFIFO - 0x%x\n", InterfaceId.Bits.CapFIFO));\r
+ DEBUG ((EFI_D_INFO, " CapCRB - 0x%x\n", InterfaceId.Bits.CapCRB));\r
+ }\r
+\r
+ //\r
+ // Dump Capability Register for TIS and FIFO\r
+ //\r
+ DEBUG ((EFI_D_INFO, "InterfaceCapability - 0x%08x\n", InterfaceCapability.Uint32));\r
+ if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_TIS) ||\r
+ (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO)) {\r
+ DEBUG ((EFI_D_INFO, " InterfaceVersion - 0x%x\n", InterfaceCapability.Bits.InterfaceVersion));\r
+ }\r
+\r
+ //\r
+ // Dump StatusEx Register for PTP FIFO\r
+ //\r
+ DEBUG ((EFI_D_INFO, "StatusEx - 0x%02x\n", StatusEx));\r
+ if (InterfaceCapability.Bits.InterfaceVersion == INTERFACE_CAPABILITY_INTERFACE_VERSION_PTP) {\r
+ DEBUG ((EFI_D_INFO, " TpmFamily - 0x%x\n", (StatusEx & PTP_FIFO_STS_EX_TPM_FAMILY) >> PTP_FIFO_STS_EX_TPM_FAMILY_OFFSET));\r
+ }\r
+\r
+ Vid = 0xFFFF;\r
+ Did = 0xFFFF;\r
+ Rid = 0xFF;\r
+ PtpInterface = GetPtpInterface (Register);\r
+ DEBUG ((EFI_D_INFO, "PtpInterface - %x\n", PtpInterface));\r
+ switch (PtpInterface) {\r
+ case PtpInterfaceCrb:\r
+ Vid = MmioRead16 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->Vid);\r
+ Did = MmioRead16 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->Did);\r
+ Rid = (UINT8)InterfaceId.Bits.Rid;\r
+ break;\r
+ case PtpInterfaceFifo:\r
+ case PtpInterfaceTis:\r
+ Vid = MmioRead16 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->Vid);\r
+ Did = MmioRead16 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->Did);\r
+ Rid = MmioRead8 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->Rid);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ DEBUG ((EFI_D_INFO, "VID - 0x%04x\n", Vid));\r
+ DEBUG ((EFI_D_INFO, "DID - 0x%04x\n", Did));\r
+ DEBUG ((EFI_D_INFO, "RID - 0x%02x\n", Rid));\r
+}\r
+\r
+/**\r
+ This service enables the sending of commands to the TPM2.\r
+\r
+ @param[in] InputParameterBlockSize Size of the TPM2 input parameter block.\r
+ @param[in] InputParameterBlock Pointer to the TPM2 input parameter block.\r
+ @param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.\r
+ @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.\r
+\r
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.\r
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.\r
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DTpm2SubmitCommand (\r
+ IN UINT32 InputParameterBlockSize,\r
+ IN UINT8 *InputParameterBlock,\r
+ IN OUT UINT32 *OutputParameterBlockSize,\r
+ IN UINT8 *OutputParameterBlock\r
+ )\r
+{\r
+ PTP_INTERFACE_TYPE PtpInterface;\r
+\r
+ PtpInterface = GetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
+ switch (PtpInterface) {\r
+ case PtpInterfaceCrb:\r
+ return PtpCrbTpmCommand (\r
+ (PTP_CRB_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress),\r
+ InputParameterBlock,\r
+ InputParameterBlockSize,\r
+ OutputParameterBlock,\r
+ OutputParameterBlockSize\r
+ );\r
+ case PtpInterfaceFifo:\r
+ case PtpInterfaceTis:\r
+ return Tpm2TisTpmCommand (\r
+ (TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress),\r
+ InputParameterBlock,\r
+ InputParameterBlockSize,\r
+ OutputParameterBlock,\r
+ OutputParameterBlockSize\r
+ );\r
+ default:\r
+ return EFI_NOT_FOUND;\r
+ }\r
+}\r
+\r
+/**\r
+ This service requests use TPM2.\r
+\r
+ @retval EFI_SUCCESS Get the control of TPM2 chip.\r
+ @retval EFI_NOT_FOUND TPM2 not found.\r
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DTpm2RequestUseTpm (\r
+ VOID\r
+ )\r
+{\r
+ PTP_INTERFACE_TYPE PtpInterface;\r
+\r
+ PtpInterface = GetPtpInterface ((VOID *) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
+ switch (PtpInterface) {\r
+ case PtpInterfaceCrb:\r
+ return PtpCrbRequestUseTpm ((PTP_CRB_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
+ case PtpInterfaceFifo:\r
+ case PtpInterfaceTis:\r
+ return TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress));\r
+ default:\r
+ return EFI_NOT_FOUND;\r
+ }\r
+}\r