Tpm2Ptp.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /** @file
  2. PTP (Platform TPM Profile) CRB (Command Response Buffer) interface used by dTPM2.0 library.
  3. Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <IndustryStandard/Tpm20.h>
  7. #include <Library/BaseLib.h>
  8. #include <Library/BaseMemoryLib.h>
  9. #include <Library/IoLib.h>
  10. #include <Library/TimerLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/Tpm2DeviceLib.h>
  13. #include <Library/PcdLib.h>
  14. #include <IndustryStandard/TpmPtp.h>
  15. #include <IndustryStandard/TpmTis.h>
  16. //
  17. // Execution of the command may take from several seconds to minutes for certain
  18. // commands, such as key generation.
  19. //
  20. #define PTP_TIMEOUT_MAX (90000 * 1000) // 90s
  21. //
  22. // Max TPM command/reponse length
  23. //
  24. #define TPMCMDBUFLENGTH 0x500
  25. /**
  26. Check whether TPM PTP register exist.
  27. @param[in] Reg Pointer to PTP register.
  28. @retval TRUE TPM PTP exists.
  29. @retval FALSE TPM PTP is not found.
  30. **/
  31. BOOLEAN
  32. Tpm2IsPtpPresence (
  33. IN VOID *Reg
  34. )
  35. {
  36. UINT8 RegRead;
  37. RegRead = MmioRead8 ((UINTN)Reg);
  38. if (RegRead == 0xFF) {
  39. //
  40. // No TPM chip
  41. //
  42. return FALSE;
  43. }
  44. return TRUE;
  45. }
  46. /**
  47. Check whether the value of a TPM chip register satisfies the input BIT setting.
  48. @param[in] Register Address port of register to be checked.
  49. @param[in] BitSet Check these data bits are set.
  50. @param[in] BitClear Check these data bits are clear.
  51. @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
  52. @retval EFI_SUCCESS The register satisfies the check bit.
  53. @retval EFI_TIMEOUT The register can't run into the expected status in time.
  54. **/
  55. EFI_STATUS
  56. PtpCrbWaitRegisterBits (
  57. IN UINT32 *Register,
  58. IN UINT32 BitSet,
  59. IN UINT32 BitClear,
  60. IN UINT32 TimeOut
  61. )
  62. {
  63. UINT32 RegRead;
  64. UINT32 WaitTime;
  65. for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
  66. RegRead = MmioRead32 ((UINTN)Register);
  67. if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0) {
  68. return EFI_SUCCESS;
  69. }
  70. MicroSecondDelay (30);
  71. }
  72. return EFI_TIMEOUT;
  73. }
  74. /**
  75. Get the control of TPM chip.
  76. @param[in] CrbReg Pointer to CRB register.
  77. @retval EFI_SUCCESS Get the control of TPM chip.
  78. @retval EFI_INVALID_PARAMETER CrbReg is NULL.
  79. @retval EFI_NOT_FOUND TPM chip doesn't exit.
  80. @retval EFI_TIMEOUT Can't get the TPM control in time.
  81. **/
  82. EFI_STATUS
  83. PtpCrbRequestUseTpm (
  84. IN PTP_CRB_REGISTERS_PTR CrbReg
  85. )
  86. {
  87. EFI_STATUS Status;
  88. if (!Tpm2IsPtpPresence (CrbReg)) {
  89. return EFI_NOT_FOUND;
  90. }
  91. MmioWrite32((UINTN)&CrbReg->LocalityControl, PTP_CRB_LOCALITY_CONTROL_REQUEST_ACCESS);
  92. Status = PtpCrbWaitRegisterBits (
  93. &CrbReg->LocalityStatus,
  94. PTP_CRB_LOCALITY_STATUS_GRANTED,
  95. 0,
  96. PTP_TIMEOUT_A
  97. );
  98. return Status;
  99. }
  100. /**
  101. Send a command to TPM for execution and return response data.
  102. @param[in] CrbReg TPM register space base address.
  103. @param[in] BufferIn Buffer for command data.
  104. @param[in] SizeIn Size of command data.
  105. @param[in, out] BufferOut Buffer for response data.
  106. @param[in, out] SizeOut Size of response data.
  107. @retval EFI_SUCCESS Operation completed successfully.
  108. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
  109. @retval EFI_DEVICE_ERROR Unexpected device behavior.
  110. @retval EFI_UNSUPPORTED Unsupported TPM version
  111. **/
  112. EFI_STATUS
  113. PtpCrbTpmCommand (
  114. IN PTP_CRB_REGISTERS_PTR CrbReg,
  115. IN UINT8 *BufferIn,
  116. IN UINT32 SizeIn,
  117. IN OUT UINT8 *BufferOut,
  118. IN OUT UINT32 *SizeOut
  119. )
  120. {
  121. EFI_STATUS Status;
  122. UINT32 Index;
  123. UINT32 TpmOutSize;
  124. UINT16 Data16;
  125. UINT32 Data32;
  126. DEBUG_CODE (
  127. UINTN DebugSize;
  128. DEBUG ((EFI_D_VERBOSE, "PtpCrbTpmCommand Send - "));
  129. if (SizeIn > 0x100) {
  130. DebugSize = 0x40;
  131. } else {
  132. DebugSize = SizeIn;
  133. }
  134. for (Index = 0; Index < DebugSize; Index++) {
  135. DEBUG ((EFI_D_VERBOSE, "%02x ", BufferIn[Index]));
  136. }
  137. if (DebugSize != SizeIn) {
  138. DEBUG ((EFI_D_VERBOSE, "...... "));
  139. for (Index = SizeIn - 0x20; Index < SizeIn; Index++) {
  140. DEBUG ((EFI_D_VERBOSE, "%02x ", BufferIn[Index]));
  141. }
  142. }
  143. DEBUG ((EFI_D_VERBOSE, "\n"));
  144. );
  145. TpmOutSize = 0;
  146. //
  147. // STEP 0:
  148. // if CapCRbIdelByPass == 0, enforce Idle state before sending command
  149. //
  150. if (PcdGet8(PcdCRBIdleByPass) == 0 && (MmioRead32((UINTN)&CrbReg->CrbControlStatus) & PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE) == 0){
  151. Status = PtpCrbWaitRegisterBits (
  152. &CrbReg->CrbControlStatus,
  153. PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE,
  154. 0,
  155. PTP_TIMEOUT_C
  156. );
  157. if (EFI_ERROR (Status)) {
  158. //
  159. // Try to goIdle to recover TPM
  160. //
  161. Status = EFI_DEVICE_ERROR;
  162. goto GoIdle_Exit;
  163. }
  164. }
  165. //
  166. // STEP 1:
  167. // Ready is any time the TPM is ready to receive a command, following a write
  168. // of 1 by software to Request.cmdReady, as indicated by the Status field
  169. // being cleared to 0.
  170. //
  171. MmioWrite32((UINTN)&CrbReg->CrbControlRequest, PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY);
  172. Status = PtpCrbWaitRegisterBits (
  173. &CrbReg->CrbControlRequest,
  174. 0,
  175. PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY,
  176. PTP_TIMEOUT_C
  177. );
  178. if (EFI_ERROR (Status)) {
  179. Status = EFI_DEVICE_ERROR;
  180. goto GoIdle_Exit;
  181. }
  182. Status = PtpCrbWaitRegisterBits (
  183. &CrbReg->CrbControlStatus,
  184. 0,
  185. PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE,
  186. PTP_TIMEOUT_C
  187. );
  188. if (EFI_ERROR (Status)) {
  189. Status = EFI_DEVICE_ERROR;
  190. goto GoIdle_Exit;
  191. }
  192. //
  193. // STEP 2:
  194. // Command Reception occurs following a Ready state between the write of the
  195. // first byte of a command to the Command Buffer and the receipt of a write
  196. // of 1 to Start.
  197. //
  198. for (Index = 0; Index < SizeIn; Index++) {
  199. MmioWrite8 ((UINTN)&CrbReg->CrbDataBuffer[Index], BufferIn[Index]);
  200. }
  201. MmioWrite32 ((UINTN)&CrbReg->CrbControlCommandAddressHigh, (UINT32)RShiftU64 ((UINTN)CrbReg->CrbDataBuffer, 32));
  202. MmioWrite32 ((UINTN)&CrbReg->CrbControlCommandAddressLow, (UINT32)(UINTN)CrbReg->CrbDataBuffer);
  203. MmioWrite32 ((UINTN)&CrbReg->CrbControlCommandSize, sizeof(CrbReg->CrbDataBuffer));
  204. MmioWrite64 ((UINTN)&CrbReg->CrbControlResponseAddrss, (UINT32)(UINTN)CrbReg->CrbDataBuffer);
  205. MmioWrite32 ((UINTN)&CrbReg->CrbControlResponseSize, sizeof(CrbReg->CrbDataBuffer));
  206. //
  207. // STEP 3:
  208. // Command Execution occurs after receipt of a 1 to Start and the TPM
  209. // clearing Start to 0.
  210. //
  211. MmioWrite32((UINTN)&CrbReg->CrbControlStart, PTP_CRB_CONTROL_START);
  212. Status = PtpCrbWaitRegisterBits (
  213. &CrbReg->CrbControlStart,
  214. 0,
  215. PTP_CRB_CONTROL_START,
  216. PTP_TIMEOUT_MAX
  217. );
  218. if (EFI_ERROR (Status)) {
  219. //
  220. // Command Completion check timeout. Cancel the currently executing command by writing TPM_CRB_CTRL_CANCEL,
  221. // Expect TPM_RC_CANCELLED or successfully completed response.
  222. //
  223. MmioWrite32((UINTN)&CrbReg->CrbControlCancel, PTP_CRB_CONTROL_CANCEL);
  224. Status = PtpCrbWaitRegisterBits (
  225. &CrbReg->CrbControlStart,
  226. 0,
  227. PTP_CRB_CONTROL_START,
  228. PTP_TIMEOUT_B
  229. );
  230. MmioWrite32((UINTN)&CrbReg->CrbControlCancel, 0);
  231. if (EFI_ERROR(Status)) {
  232. //
  233. // Still in Command Execution state. Try to goIdle, the behavior is agnostic.
  234. //
  235. Status = EFI_DEVICE_ERROR;
  236. goto GoIdle_Exit;
  237. }
  238. }
  239. //
  240. // STEP 4:
  241. // Command Completion occurs after completion of a command (indicated by the
  242. // TPM clearing TPM_CRB_CTRL_Start_x to 0) and before a write of a 1 by the
  243. // software to Request.goIdle.
  244. //
  245. //
  246. // Get response data header
  247. //
  248. for (Index = 0; Index < sizeof (TPM2_RESPONSE_HEADER); Index++) {
  249. BufferOut[Index] = MmioRead8 ((UINTN)&CrbReg->CrbDataBuffer[Index]);
  250. }
  251. DEBUG_CODE (
  252. DEBUG ((EFI_D_VERBOSE, "PtpCrbTpmCommand ReceiveHeader - "));
  253. for (Index = 0; Index < sizeof (TPM2_RESPONSE_HEADER); Index++) {
  254. DEBUG ((EFI_D_VERBOSE, "%02x ", BufferOut[Index]));
  255. }
  256. DEBUG ((EFI_D_VERBOSE, "\n"));
  257. );
  258. //
  259. // Check the reponse data header (tag, parasize and returncode)
  260. //
  261. CopyMem (&Data16, BufferOut, sizeof (UINT16));
  262. // TPM2 should not use this RSP_COMMAND
  263. if (SwapBytes16 (Data16) == TPM_ST_RSP_COMMAND) {
  264. DEBUG ((EFI_D_ERROR, "TPM2: TPM_ST_RSP error - %x\n", TPM_ST_RSP_COMMAND));
  265. Status = EFI_UNSUPPORTED;
  266. goto GoIdle_Exit;
  267. }
  268. CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));
  269. TpmOutSize = SwapBytes32 (Data32);
  270. if (*SizeOut < TpmOutSize) {
  271. //
  272. // Command completed, but buffer is not enough
  273. //
  274. Status = EFI_BUFFER_TOO_SMALL;
  275. goto GoReady_Exit;
  276. }
  277. *SizeOut = TpmOutSize;
  278. //
  279. // Continue reading the remaining data
  280. //
  281. for (Index = sizeof (TPM2_RESPONSE_HEADER); Index < TpmOutSize; Index++) {
  282. BufferOut[Index] = MmioRead8 ((UINTN)&CrbReg->CrbDataBuffer[Index]);
  283. }
  284. DEBUG_CODE (
  285. DEBUG ((EFI_D_VERBOSE, "PtpCrbTpmCommand Receive - "));
  286. for (Index = 0; Index < TpmOutSize; Index++) {
  287. DEBUG ((EFI_D_VERBOSE, "%02x ", BufferOut[Index]));
  288. }
  289. DEBUG ((EFI_D_VERBOSE, "\n"));
  290. );
  291. GoReady_Exit:
  292. //
  293. // Goto Ready State if command is completed successfully and TPM support IdleBypass
  294. // If not supported. flow down to GoIdle
  295. //
  296. if (PcdGet8(PcdCRBIdleByPass) == 1) {
  297. MmioWrite32((UINTN)&CrbReg->CrbControlRequest, PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY);
  298. return Status;
  299. }
  300. //
  301. // Do not wait for state transition for TIMEOUT_C
  302. // This function will try to wait 2 TIMEOUT_C at the beginning in next call.
  303. //
  304. GoIdle_Exit:
  305. //
  306. // Return to Idle state by setting TPM_CRB_CTRL_STS_x.Status.goIdle to 1.
  307. //
  308. MmioWrite32((UINTN)&CrbReg->CrbControlRequest, PTP_CRB_CONTROL_AREA_REQUEST_GO_IDLE);
  309. //
  310. // Only enforce Idle state transition if execution fails when CRBIdleBypass==1
  311. // Leave regular Idle delay at the beginning of next command execution
  312. //
  313. if (PcdGet8(PcdCRBIdleByPass) == 1){
  314. Status = PtpCrbWaitRegisterBits (
  315. &CrbReg->CrbControlStatus,
  316. PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE,
  317. 0,
  318. PTP_TIMEOUT_C
  319. );
  320. }
  321. return Status;
  322. }
  323. /**
  324. Send a command to TPM for execution and return response data.
  325. @param[in] TisReg TPM register space base address.
  326. @param[in] BufferIn Buffer for command data.
  327. @param[in] SizeIn Size of command data.
  328. @param[in, out] BufferOut Buffer for response data.
  329. @param[in, out] SizeOut Size of response data.
  330. @retval EFI_SUCCESS Operation completed successfully.
  331. @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
  332. @retval EFI_DEVICE_ERROR Unexpected device behavior.
  333. @retval EFI_UNSUPPORTED Unsupported TPM version
  334. **/
  335. EFI_STATUS
  336. Tpm2TisTpmCommand (
  337. IN TIS_PC_REGISTERS_PTR TisReg,
  338. IN UINT8 *BufferIn,
  339. IN UINT32 SizeIn,
  340. IN OUT UINT8 *BufferOut,
  341. IN OUT UINT32 *SizeOut
  342. );
  343. /**
  344. Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
  345. to ACCESS Register in the time of default TIS_TIMEOUT_A.
  346. @param[in] TisReg Pointer to TIS register.
  347. @retval EFI_SUCCESS Get the control of TPM chip.
  348. @retval EFI_INVALID_PARAMETER TisReg is NULL.
  349. @retval EFI_NOT_FOUND TPM chip doesn't exit.
  350. @retval EFI_TIMEOUT Can't get the TPM control in time.
  351. **/
  352. EFI_STATUS
  353. TisPcRequestUseTpm (
  354. IN TIS_PC_REGISTERS_PTR TisReg
  355. );
  356. /**
  357. Return PTP interface type.
  358. @param[in] Register Pointer to PTP register.
  359. @return PTP interface type.
  360. **/
  361. TPM2_PTP_INTERFACE_TYPE
  362. Tpm2GetPtpInterface (
  363. IN VOID *Register
  364. )
  365. {
  366. PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;
  367. PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;
  368. if (!Tpm2IsPtpPresence (Register)) {
  369. return Tpm2PtpInterfaceMax;
  370. }
  371. //
  372. // Check interface id
  373. //
  374. InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
  375. InterfaceCapability.Uint32 = MmioRead32 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->InterfaceCapability);
  376. if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) &&
  377. (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_CRB) &&
  378. (InterfaceId.Bits.CapCRB != 0)) {
  379. return Tpm2PtpInterfaceCrb;
  380. }
  381. if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO) &&
  382. (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_FIFO) &&
  383. (InterfaceId.Bits.CapFIFO != 0) &&
  384. (InterfaceCapability.Bits.InterfaceVersion == INTERFACE_CAPABILITY_INTERFACE_VERSION_PTP)) {
  385. return Tpm2PtpInterfaceFifo;
  386. }
  387. return Tpm2PtpInterfaceTis;
  388. }
  389. /**
  390. Return PTP CRB interface IdleByPass state.
  391. @param[in] Register Pointer to PTP register.
  392. @return PTP CRB interface IdleByPass state.
  393. **/
  394. UINT8
  395. Tpm2GetIdleByPass (
  396. IN VOID *Register
  397. )
  398. {
  399. PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;
  400. //
  401. // Check interface id
  402. //
  403. InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
  404. return (UINT8)(InterfaceId.Bits.CapCRBIdleBypass);
  405. }
  406. /**
  407. Dump PTP register information.
  408. @param[in] Register Pointer to PTP register.
  409. **/
  410. VOID
  411. DumpPtpInfo (
  412. IN VOID *Register
  413. )
  414. {
  415. PTP_CRB_INTERFACE_IDENTIFIER InterfaceId;
  416. PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;
  417. UINT8 StatusEx;
  418. UINT16 Vid;
  419. UINT16 Did;
  420. UINT8 Rid;
  421. TPM2_PTP_INTERFACE_TYPE PtpInterface;
  422. if (!Tpm2IsPtpPresence (Register)) {
  423. return ;
  424. }
  425. InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
  426. InterfaceCapability.Uint32 = MmioRead32 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->InterfaceCapability);
  427. StatusEx = MmioRead8 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->StatusEx);
  428. //
  429. // Dump InterfaceId Register for PTP
  430. //
  431. DEBUG ((EFI_D_INFO, "InterfaceId - 0x%08x\n", InterfaceId.Uint32));
  432. DEBUG ((EFI_D_INFO, " InterfaceType - 0x%02x\n", InterfaceId.Bits.InterfaceType));
  433. if (InterfaceId.Bits.InterfaceType != PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_TIS) {
  434. DEBUG ((EFI_D_INFO, " InterfaceVersion - 0x%02x\n", InterfaceId.Bits.InterfaceVersion));
  435. DEBUG ((EFI_D_INFO, " CapFIFO - 0x%x\n", InterfaceId.Bits.CapFIFO));
  436. DEBUG ((EFI_D_INFO, " CapCRB - 0x%x\n", InterfaceId.Bits.CapCRB));
  437. }
  438. //
  439. // Dump Capability Register for TIS and FIFO
  440. //
  441. DEBUG ((EFI_D_INFO, "InterfaceCapability - 0x%08x\n", InterfaceCapability.Uint32));
  442. if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_TIS) ||
  443. (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO)) {
  444. DEBUG ((EFI_D_INFO, " InterfaceVersion - 0x%x\n", InterfaceCapability.Bits.InterfaceVersion));
  445. }
  446. //
  447. // Dump StatusEx Register for PTP FIFO
  448. //
  449. DEBUG ((EFI_D_INFO, "StatusEx - 0x%02x\n", StatusEx));
  450. if (InterfaceCapability.Bits.InterfaceVersion == INTERFACE_CAPABILITY_INTERFACE_VERSION_PTP) {
  451. DEBUG ((EFI_D_INFO, " TpmFamily - 0x%x\n", (StatusEx & PTP_FIFO_STS_EX_TPM_FAMILY) >> PTP_FIFO_STS_EX_TPM_FAMILY_OFFSET));
  452. }
  453. Vid = 0xFFFF;
  454. Did = 0xFFFF;
  455. Rid = 0xFF;
  456. PtpInterface = PcdGet8(PcdActiveTpmInterfaceType);
  457. DEBUG ((EFI_D_INFO, "PtpInterface - %x\n", PtpInterface));
  458. switch (PtpInterface) {
  459. case Tpm2PtpInterfaceCrb:
  460. Vid = MmioRead16 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->Vid);
  461. Did = MmioRead16 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->Did);
  462. Rid = (UINT8)InterfaceId.Bits.Rid;
  463. break;
  464. case Tpm2PtpInterfaceFifo:
  465. case Tpm2PtpInterfaceTis:
  466. Vid = MmioRead16 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->Vid);
  467. Did = MmioRead16 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->Did);
  468. Rid = MmioRead8 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->Rid);
  469. break;
  470. default:
  471. break;
  472. }
  473. DEBUG ((EFI_D_INFO, "VID - 0x%04x\n", Vid));
  474. DEBUG ((EFI_D_INFO, "DID - 0x%04x\n", Did));
  475. DEBUG ((EFI_D_INFO, "RID - 0x%02x\n", Rid));
  476. }
  477. /**
  478. This service enables the sending of commands to the TPM2.
  479. @param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
  480. @param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
  481. @param[in,out] OutputParameterBlockSize Size of the TPM2 output parameter block.
  482. @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
  483. @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
  484. @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
  485. @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
  486. **/
  487. EFI_STATUS
  488. EFIAPI
  489. DTpm2SubmitCommand (
  490. IN UINT32 InputParameterBlockSize,
  491. IN UINT8 *InputParameterBlock,
  492. IN OUT UINT32 *OutputParameterBlockSize,
  493. IN UINT8 *OutputParameterBlock
  494. )
  495. {
  496. TPM2_PTP_INTERFACE_TYPE PtpInterface;
  497. PtpInterface = PcdGet8(PcdActiveTpmInterfaceType);
  498. switch (PtpInterface) {
  499. case Tpm2PtpInterfaceCrb:
  500. return PtpCrbTpmCommand (
  501. (PTP_CRB_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress),
  502. InputParameterBlock,
  503. InputParameterBlockSize,
  504. OutputParameterBlock,
  505. OutputParameterBlockSize
  506. );
  507. case Tpm2PtpInterfaceFifo:
  508. case Tpm2PtpInterfaceTis:
  509. return Tpm2TisTpmCommand (
  510. (TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress),
  511. InputParameterBlock,
  512. InputParameterBlockSize,
  513. OutputParameterBlock,
  514. OutputParameterBlockSize
  515. );
  516. default:
  517. return EFI_NOT_FOUND;
  518. }
  519. }
  520. /**
  521. This service requests use TPM2.
  522. @retval EFI_SUCCESS Get the control of TPM2 chip.
  523. @retval EFI_NOT_FOUND TPM2 not found.
  524. @retval EFI_DEVICE_ERROR Unexpected device behavior.
  525. **/
  526. EFI_STATUS
  527. EFIAPI
  528. DTpm2RequestUseTpm (
  529. VOID
  530. )
  531. {
  532. TPM2_PTP_INTERFACE_TYPE PtpInterface;
  533. PtpInterface = PcdGet8(PcdActiveTpmInterfaceType);
  534. switch (PtpInterface) {
  535. case Tpm2PtpInterfaceCrb:
  536. return PtpCrbRequestUseTpm ((PTP_CRB_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress));
  537. case Tpm2PtpInterfaceFifo:
  538. case Tpm2PtpInterfaceTis:
  539. return TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR) (UINTN) PcdGet64 (PcdTpmBaseAddress));
  540. default:
  541. return EFI_NOT_FOUND;
  542. }
  543. }