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