]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Library/TpmCommLib/TisPc.c
162e883d2170e89d9a82993df12159fae96be9e1
[mirror_edk2.git] / SecurityPkg / Library / TpmCommLib / TisPc.c
1 /** @file
2 Basic TIS (TPM Interface Specification) functions.
3
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "CommonHeader.h"
10
11 /**
12 Check whether TPM chip exist.
13
14 @param[in] TisReg Pointer to TIS register.
15
16 @retval TRUE TPM chip exists.
17 @retval FALSE TPM chip is not found.
18 **/
19 BOOLEAN
20 TisPcPresenceCheck (
21 IN TIS_PC_REGISTERS_PTR TisReg
22 )
23 {
24 UINT8 RegRead;
25
26 RegRead = MmioRead8 ((UINTN)&TisReg->Access);
27 return (BOOLEAN)(RegRead != (UINT8)-1);
28 }
29
30 /**
31 Check whether the value of a TPM chip register satisfies the input BIT setting.
32
33 @param[in] Register Address port of register to be checked.
34 @param[in] BitSet Check these data bits are set.
35 @param[in] BitClear Check these data bits are clear.
36 @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
37
38 @retval EFI_SUCCESS The register satisfies the check bit.
39 @retval EFI_TIMEOUT The register can't run into the expected status in time.
40 **/
41 EFI_STATUS
42 EFIAPI
43 TisPcWaitRegisterBits (
44 IN UINT8 *Register,
45 IN UINT8 BitSet,
46 IN UINT8 BitClear,
47 IN UINT32 TimeOut
48 )
49 {
50 UINT8 RegRead;
51 UINT32 WaitTime;
52
53 for (WaitTime = 0; WaitTime < TimeOut; WaitTime += 30){
54 RegRead = MmioRead8 ((UINTN)Register);
55 if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0)
56 return EFI_SUCCESS;
57 MicroSecondDelay (30);
58 }
59 return EFI_TIMEOUT;
60 }
61
62 /**
63 Get BurstCount by reading the burstCount field of a TIS regiger
64 in the time of default TIS_TIMEOUT_D.
65
66 @param[in] TisReg Pointer to TIS register.
67 @param[out] BurstCount Pointer to a buffer to store the got BurstConut.
68
69 @retval EFI_SUCCESS Get BurstCount.
70 @retval EFI_INVALID_PARAMETER TisReg is NULL or BurstCount is NULL.
71 @retval EFI_TIMEOUT BurstCount can't be got in time.
72 **/
73 EFI_STATUS
74 EFIAPI
75 TisPcReadBurstCount (
76 IN TIS_PC_REGISTERS_PTR TisReg,
77 OUT UINT16 *BurstCount
78 )
79 {
80 UINT32 WaitTime;
81 UINT8 DataByte0;
82 UINT8 DataByte1;
83
84 if (BurstCount == NULL || TisReg == NULL) {
85 return EFI_INVALID_PARAMETER;
86 }
87
88 WaitTime = 0;
89 do {
90 //
91 // TIS_PC_REGISTERS_PTR->burstCount is UINT16, but it is not 2bytes aligned,
92 // so it needs to use MmioRead8 to read two times
93 //
94 DataByte0 = MmioRead8 ((UINTN)&TisReg->BurstCount);
95 DataByte1 = MmioRead8 ((UINTN)&TisReg->BurstCount + 1);
96 *BurstCount = (UINT16)((DataByte1 << 8) + DataByte0);
97 if (*BurstCount != 0) {
98 return EFI_SUCCESS;
99 }
100 MicroSecondDelay (30);
101 WaitTime += 30;
102 } while (WaitTime < TIS_TIMEOUT_D);
103
104 return EFI_TIMEOUT;
105 }
106
107 /**
108 Set TPM chip to ready state by sending ready command TIS_PC_STS_READY
109 to Status Register in time.
110
111 @param[in] TisReg Pointer to TIS register.
112
113 @retval EFI_SUCCESS TPM chip enters into ready state.
114 @retval EFI_INVALID_PARAMETER TisReg is NULL.
115 @retval EFI_TIMEOUT TPM chip can't be set to ready state in time.
116 **/
117 EFI_STATUS
118 EFIAPI
119 TisPcPrepareCommand (
120 IN TIS_PC_REGISTERS_PTR TisReg
121 )
122 {
123 EFI_STATUS Status;
124
125 if (TisReg == NULL) {
126 return EFI_INVALID_PARAMETER;
127 }
128
129 MmioWrite8((UINTN)&TisReg->Status, TIS_PC_STS_READY);
130 Status = TisPcWaitRegisterBits (
131 &TisReg->Status,
132 TIS_PC_STS_READY,
133 0,
134 TIS_TIMEOUT_B
135 );
136 return Status;
137 }
138
139 /**
140 Get the control of TPM chip by sending requestUse command TIS_PC_ACC_RQUUSE
141 to ACCESS Register in the time of default TIS_TIMEOUT_A.
142
143 @param[in] TisReg Pointer to TIS register.
144
145 @retval EFI_SUCCESS Get the control of TPM chip.
146 @retval EFI_INVALID_PARAMETER TisReg is NULL.
147 @retval EFI_NOT_FOUND TPM chip doesn't exit.
148 @retval EFI_TIMEOUT Can't get the TPM control in time.
149 **/
150 EFI_STATUS
151 EFIAPI
152 TisPcRequestUseTpm (
153 IN TIS_PC_REGISTERS_PTR TisReg
154 )
155 {
156 EFI_STATUS Status;
157
158 if (TisReg == NULL) {
159 return EFI_INVALID_PARAMETER;
160 }
161
162 if (!TisPcPresenceCheck (TisReg)) {
163 return EFI_NOT_FOUND;
164 }
165
166 MmioWrite8((UINTN)&TisReg->Access, TIS_PC_ACC_RQUUSE);
167 //
168 // No locality set before, ACCESS_X.activeLocality MUST be valid within TIMEOUT_A
169 //
170 Status = TisPcWaitRegisterBits (
171 &TisReg->Access,
172 (UINT8)(TIS_PC_ACC_ACTIVE |TIS_PC_VALID),
173 0,
174 TIS_TIMEOUT_A
175 );
176 return Status;
177 }