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