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