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