TianoCore EDK2 master
Loading...
Searching...
No Matches
Tpm12Tis.c
Go to the documentation of this file.
1
10#include <Uefi.h>
12#include <Library/BaseLib.h>
14#include <Library/IoLib.h>
15#include <Library/TimerLib.h>
16#include <Library/DebugLib.h>
18#include <Library/PcdLib.h>
19
22
23typedef enum {
24 PtpInterfaceTis,
25 PtpInterfaceFifo,
26 PtpInterfaceCrb,
27 PtpInterfaceMax,
28} PTP_INTERFACE_TYPE;
29
30//
31// Max TPM command/response length
32//
33#define TPMCMDBUFLENGTH 1024
34
43BOOLEAN
46 )
47{
48 UINT8 RegRead;
49
50 RegRead = MmioRead8 ((UINTN)&TisReg->Access);
51 return (BOOLEAN)(RegRead != (UINT8)-1);
52}
53
61PTP_INTERFACE_TYPE
63 IN VOID *Register
64 )
65{
67 PTP_FIFO_INTERFACE_CAPABILITY InterfaceCapability;
68
70 return PtpInterfaceMax;
71 }
72
73 //
74 // Check interface id
75 //
76 InterfaceId.Uint32 = MmioRead32 ((UINTN)&((PTP_CRB_REGISTERS *)Register)->InterfaceId);
77 InterfaceCapability.Uint32 = MmioRead32 ((UINTN)&((PTP_FIFO_REGISTERS *)Register)->InterfaceCapability);
78
79 if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_CRB) &&
80 (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_CRB) &&
81 (InterfaceId.Bits.CapCRB != 0))
82 {
83 return PtpInterfaceCrb;
84 }
85
86 if ((InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO) &&
87 (InterfaceId.Bits.InterfaceVersion == PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_FIFO) &&
88 (InterfaceId.Bits.CapFIFO != 0) &&
89 (InterfaceCapability.Bits.InterfaceVersion == INTERFACE_CAPABILITY_INTERFACE_VERSION_PTP))
90 {
91 return PtpInterfaceFifo;
92 }
93
94 if (InterfaceId.Bits.InterfaceType == PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_TIS) {
95 return PtpInterfaceTis;
96 }
97
98 return PtpInterfaceMax;
99}
100
114 IN UINT8 *Register,
115 IN UINT8 BitSet,
116 IN UINT8 BitClear,
117 IN UINT32 TimeOut
118 )
119{
120 UINT8 RegRead;
121 UINT32 WaitTime;
122
123 for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30) {
124 RegRead = MmioRead8 ((UINTN)Register);
125 if (((RegRead & BitSet) == BitSet) && ((RegRead & BitClear) == 0)) {
126 return EFI_SUCCESS;
127 }
128
129 MicroSecondDelay (30);
130 }
131
132 return EFI_TIMEOUT;
133}
134
149 OUT UINT16 *BurstCount
150 )
151{
152 UINT32 WaitTime;
153 UINT8 DataByte0;
154 UINT8 DataByte1;
155
156 if ((BurstCount == NULL) || (TisReg == NULL)) {
157 return EFI_INVALID_PARAMETER;
158 }
159
160 WaitTime = 0;
161 do {
162 //
163 // TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,
164 // so it needs to use MmioRead8 to read two times
165 //
166 DataByte0 = MmioRead8 ((UINTN)&TisReg->BurstCount);
167 DataByte1 = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);
168 *BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
169 if (*BurstCount != 0) {
170 return EFI_SUCCESS;
171 }
172
173 MicroSecondDelay (30);
174 WaitTime += 30;
175 } while (WaitTime < TIS_TIMEOUT_D);
176
177 return EFI_TIMEOUT;
178}
179
193 )
194{
195 EFI_STATUS Status;
196
197 if (TisReg == NULL) {
198 return EFI_INVALID_PARAMETER;
199 }
200
201 MmioWrite8 ((UINTN)&TisReg->Status, TIS_PC_STS_READY);
203 &TisReg->Status,
205 0,
206 TIS_TIMEOUT_B
207 );
208 return Status;
209}
210
225 )
226{
227 EFI_STATUS Status;
228
229 if (TisReg == NULL) {
230 return EFI_INVALID_PARAMETER;
231 }
232
233 if (!Tpm12TisPcPresenceCheck (TisReg)) {
234 return EFI_NOT_FOUND;
235 }
236
237 MmioWrite8 ((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);
239 &TisReg->Access,
241 0,
242 TIS_TIMEOUT_A
243 );
244 return Status;
245}
246
265 IN UINT8 *BufferIn,
266 IN UINT32 SizeIn,
267 IN OUT UINT8 *BufferOut,
268 IN OUT UINT32 *SizeOut
269 )
270{
271 EFI_STATUS Status;
272 UINT16 BurstCount;
273 UINT32 Index;
274 UINT32 TpmOutSize;
275 UINT16 Data16;
276 UINT32 Data32;
277 UINT16 RspTag;
278
280 UINTN DebugSize;
281
282 DEBUG ((DEBUG_VERBOSE, "Tpm12TisTpmCommand Send - "));
283 if (SizeIn > 0x100) {
284 DebugSize = 0x40;
285 } else {
286 DebugSize = SizeIn;
287 }
288
289 for (Index = 0; Index < DebugSize; Index++) {
290 DEBUG ((DEBUG_VERBOSE, "%02x ", BufferIn[Index]));
291 }
292
293 if (DebugSize != SizeIn) {
294 DEBUG ((DEBUG_VERBOSE, "...... "));
295 for (Index = SizeIn - 0x20; Index < SizeIn; Index++) {
296 DEBUG ((DEBUG_VERBOSE, "%02x ", BufferIn[Index]));
297 }
298 }
299
300 DEBUG ((DEBUG_VERBOSE, "\n"));
302 TpmOutSize = 0;
303
304 Status = Tpm12TisPcPrepareCommand (TisReg);
305 if (EFI_ERROR (Status)) {
306 DEBUG ((DEBUG_ERROR, "Tpm12 is not ready for command!\n"));
307 return EFI_DEVICE_ERROR;
308 }
309
310 //
311 // Send the command data to Tpm
312 //
313 Index = 0;
314 while (Index < SizeIn) {
315 Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);
316 if (EFI_ERROR (Status)) {
317 Status = EFI_DEVICE_ERROR;
318 goto Exit;
319 }
320
321 for ( ; BurstCount > 0 && Index < SizeIn; BurstCount--) {
322 MmioWrite8 ((UINTN)&TisReg->DataFifo, *(BufferIn + Index));
323 Index++;
324 }
325 }
326
327 //
328 // Check the Tpm status STS_EXPECT change from 1 to 0
329 //
331 &TisReg->Status,
332 (UINT8)TIS_PC_VALID,
334 TIS_TIMEOUT_C
335 );
336 if (EFI_ERROR (Status)) {
337 DEBUG ((DEBUG_ERROR, "Tpm12 The send buffer too small!\n"));
338 Status = EFI_BUFFER_TOO_SMALL;
339 goto Exit;
340 }
341
342 //
343 // Executed the TPM command and waiting for the response data ready
344 //
345 MmioWrite8 ((UINTN)&TisReg->Status, TIS_PC_STS_GO);
347 &TisReg->Status,
348 (UINT8)(TIS_PC_VALID | TIS_PC_STS_DATA),
349 0,
350 TIS_TIMEOUT_B
351 );
352 if (EFI_ERROR (Status)) {
353 DEBUG ((DEBUG_ERROR, "Wait for Tpm12 response data time out!!\n"));
354 Status = EFI_DEVICE_ERROR;
355 goto Exit;
356 }
357
358 //
359 // Get response data header
360 //
361 Index = 0;
362 BurstCount = 0;
363 while (Index < sizeof (TPM_RSP_COMMAND_HDR)) {
364 Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);
365 if (EFI_ERROR (Status)) {
366 Status = EFI_DEVICE_ERROR;
367 goto Exit;
368 }
369
370 for ( ; BurstCount > 0; BurstCount--) {
371 *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
372 Index++;
373 if (Index == sizeof (TPM_RSP_COMMAND_HDR)) {
374 break;
375 }
376 }
377 }
378
380 DEBUG ((DEBUG_VERBOSE, "Tpm12TisTpmCommand ReceiveHeader - "));
381 for (Index = 0; Index < sizeof (TPM_RSP_COMMAND_HDR); Index++) {
382 DEBUG ((DEBUG_VERBOSE, "%02x ", BufferOut[Index]));
383 }
384
385 DEBUG ((DEBUG_VERBOSE, "\n"));
387 //
388 // Check the response data header (tag, parasize and returncode)
389 //
390 CopyMem (&Data16, BufferOut, sizeof (UINT16));
391 RspTag = SwapBytes16 (Data16);
392 if ((RspTag != TPM_TAG_RSP_COMMAND) && (RspTag != TPM_TAG_RSP_AUTH1_COMMAND) && (RspTag != TPM_TAG_RSP_AUTH2_COMMAND)) {
393 DEBUG ((DEBUG_ERROR, "TPM12: Response tag error - current tag value is %x\n", RspTag));
394 Status = EFI_UNSUPPORTED;
395 goto Exit;
396 }
397
398 CopyMem (&Data32, (BufferOut + 2), sizeof (UINT32));
399 TpmOutSize = SwapBytes32 (Data32);
400 if (*SizeOut < TpmOutSize) {
401 Status = EFI_BUFFER_TOO_SMALL;
402 goto Exit;
403 }
404
405 *SizeOut = TpmOutSize;
406 //
407 // Continue reading the remaining data
408 //
409 while ( Index < TpmOutSize ) {
410 for ( ; BurstCount > 0; BurstCount--) {
411 *(BufferOut + Index) = MmioRead8 ((UINTN)&TisReg->DataFifo);
412 Index++;
413 if (Index == TpmOutSize) {
414 Status = EFI_SUCCESS;
415 goto Exit;
416 }
417 }
418
419 Status = Tpm12TisPcReadBurstCount (TisReg, &BurstCount);
420 if (EFI_ERROR (Status)) {
421 Status = EFI_DEVICE_ERROR;
422 goto Exit;
423 }
424 }
425
426Exit:
428 DEBUG ((DEBUG_VERBOSE, "Tpm12TisTpmCommand Receive - "));
429 for (Index = 0; Index < TpmOutSize; Index++) {
430 DEBUG ((DEBUG_VERBOSE, "%02x ", BufferOut[Index]));
431 }
432
433 DEBUG ((DEBUG_VERBOSE, "\n"));
435 MmioWrite8 ((UINTN)&TisReg->Status, TIS_PC_STS_READY);
436 return Status;
437}
438
452EFIAPI
454 IN UINT32 InputParameterBlockSize,
455 IN UINT8 *InputParameterBlock,
456 IN OUT UINT32 *OutputParameterBlockSize,
457 IN UINT8 *OutputParameterBlock
458 )
459{
460 PTP_INTERFACE_TYPE PtpInterface;
461
462 //
463 // Special handle for TPM1.2 to check PTP too, because PTP/TIS share same register address.
464 //
465 PtpInterface = Tpm12GetPtpInterface ((VOID *)(UINTN)PcdGet64 (PcdTpmBaseAddress));
466 switch (PtpInterface) {
467 case PtpInterfaceFifo:
468 case PtpInterfaceTis:
469 return Tpm12TisTpmCommand (
470 (TIS_PC_REGISTERS_PTR)(UINTN)PcdGet64 (PcdTpmBaseAddress),
471 InputParameterBlock,
472 InputParameterBlockSize,
473 OutputParameterBlock,
474 OutputParameterBlockSize
475 );
476 case PtpInterfaceCrb:
477 //
478 // No need to support CRB because it is only accept TPM2 command.
479 //
480 default:
481 return EFI_DEVICE_ERROR;
482 }
483}
484
498 IN UINT32 *Register,
499 IN UINT32 BitSet,
500 IN UINT32 BitClear,
501 IN UINT32 TimeOut
502 )
503{
504 UINT32 RegRead;
505 UINT32 WaitTime;
506
507 for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30) {
508 RegRead = MmioRead32 ((UINTN)Register);
509 if (((RegRead & BitSet) == BitSet) && ((RegRead & BitClear) == 0)) {
510 return EFI_SUCCESS;
511 }
512
513 MicroSecondDelay (30);
514 }
515
516 return EFI_TIMEOUT;
517}
518
532 )
533{
534 EFI_STATUS Status;
535
536 MmioWrite32 ((UINTN)&CrbReg->LocalityControl, PTP_CRB_LOCALITY_CONTROL_REQUEST_ACCESS);
538 &CrbReg->LocalityStatus,
540 0,
541 PTP_TIMEOUT_A
542 );
543 return Status;
544}
545
554EFIAPI
556 VOID
557 )
558{
559 PTP_INTERFACE_TYPE PtpInterface;
560
561 //
562 // Special handle for TPM1.2 to check PTP too, because PTP/TIS share same register address.
563 // Some other program might leverage this function to check the existence of TPM chip.
564 //
565 PtpInterface = Tpm12GetPtpInterface ((VOID *)(UINTN)PcdGet64 (PcdTpmBaseAddress));
566 switch (PtpInterface) {
567 case PtpInterfaceCrb:
568 return Tpm12PtpCrbRequestUseTpm ((PTP_CRB_REGISTERS_PTR)(UINTN)PcdGet64 (PcdTpmBaseAddress));
569 case PtpInterfaceFifo:
570 case PtpInterfaceTis:
571 return Tpm12TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)(UINTN)PcdGet64 (PcdTpmBaseAddress));
572 default:
573 return EFI_NOT_FOUND;
574 }
575}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
UINT16 EFIAPI SwapBytes16(IN UINT16 Value)
Definition: SwapBytes16.c:25
UINT32 EFIAPI SwapBytes32(IN UINT32 Value)
Definition: SwapBytes32.c:25
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
UINT8 EFIAPI MmioRead8(IN UINTN Address)
Definition: IoLib.c:82
UINT8 EFIAPI MmioWrite8(IN UINTN Address, IN UINT8 Value)
Definition: IoLib.c:126
UINT32 EFIAPI MmioRead32(IN UINTN Address)
Definition: IoLib.c:262
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
Definition: IoLib.c:309
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
EFI_STATUS EFIAPI Register(IN EFI_PEI_RSC_HANDLER_CALLBACK Callback)
struct tdTPM_RSP_COMMAND_HDR TPM_RSP_COMMAND_HDR
EFI_STATUS Tpm12TisPcWaitRegisterBits(IN UINT8 *Register, IN UINT8 BitSet, IN UINT8 BitClear, IN UINT32 TimeOut)
Definition: Tpm12Tis.c:113
EFI_STATUS EFIAPI Tpm12RequestUseTpm(VOID)
Definition: Tpm12Tis.c:555
EFI_STATUS Tpm12TisTpmCommand(IN TIS_PC_REGISTERS_PTR TisReg, IN UINT8 *BufferIn, IN UINT32 SizeIn, IN OUT UINT8 *BufferOut, IN OUT UINT32 *SizeOut)
Definition: Tpm12Tis.c:263
EFI_STATUS EFIAPI Tpm12SubmitCommand(IN UINT32 InputParameterBlockSize, IN UINT8 *InputParameterBlock, IN OUT UINT32 *OutputParameterBlockSize, IN UINT8 *OutputParameterBlock)
Definition: Tpm12Tis.c:453
BOOLEAN Tpm12TisPcPresenceCheck(IN TIS_PC_REGISTERS_PTR TisReg)
Definition: Tpm12Tis.c:44
EFI_STATUS Tpm12TisPcPrepareCommand(IN TIS_PC_REGISTERS_PTR TisReg)
Definition: Tpm12Tis.c:191
PTP_INTERFACE_TYPE Tpm12GetPtpInterface(IN VOID *Register)
Definition: Tpm12Tis.c:62
EFI_STATUS Tpm12TisPcReadBurstCount(IN TIS_PC_REGISTERS_PTR TisReg, OUT UINT16 *BurstCount)
Definition: Tpm12Tis.c:147
EFI_STATUS Tpm12TisPcRequestUseTpm(IN TIS_PC_REGISTERS_PTR TisReg)
Definition: Tpm12Tis.c:223
EFI_STATUS Tpm12PtpCrbRequestUseTpm(IN PTP_CRB_REGISTERS_PTR CrbReg)
Definition: Tpm12Tis.c:530
EFI_STATUS Tpm12PtpCrbWaitRegisterBits(IN UINT32 *Register, IN UINT32 BitSet, IN UINT32 BitClear, IN UINT32 TimeOut)
Definition: Tpm12Tis.c:497
#define PTP_CRB_LOCALITY_STATUS_GRANTED
Definition: TpmPtp.h:439
#define PTP_INTERFACE_IDENTIFIER_INTERFACE_VERSION_FIFO
Definition: TpmPtp.h:357
#define PTP_INTERFACE_IDENTIFIER_INTERFACE_TYPE_FIFO
Definition: TpmPtp.h:350
#define PTP_CRB_LOCALITY_CONTROL_REQUEST_ACCESS
Definition: TpmPtp.h:423
#define TIS_PC_VALID
Definition: TpmTis.h:110
#define TIS_PC_ACC_ACTIVE
Definition: TpmTis.h:114
#define TIS_PC_ACC_RQUUSE
Definition: TpmTis.h:133
#define TIS_PC_STS_READY
Definition: TpmTis.h:151
#define TIS_PC_STS_GO
Definition: TpmTis.h:155
#define TIS_PC_STS_EXPECT
Definition: TpmTis.h:163
#define TIS_PC_STS_DATA
Definition: TpmTis.h:159
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112