@@ -33,6 +33,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
33
33
//
34
34
#define TPMCMDBUFLENGTH 0x500
35
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
+
36
42
/**
37
43
Check whether TPM PTP register exist.
38
44
@@ -153,6 +159,7 @@ PtpCrbTpmCommand (
153
159
UINT32 TpmOutSize ;
154
160
UINT16 Data16 ;
155
161
UINT32 Data32 ;
162
+ UINT8 RetryCnt ;
156
163
157
164
DEBUG_CODE_BEGIN ();
158
165
UINTN DebugSize ;
@@ -179,53 +186,76 @@ PtpCrbTpmCommand (
179
186
DEBUG_CODE_END ();
180
187
TpmOutSize = 0 ;
181
188
182
- //
183
- // STEP 0:
184
- // if CapCRbIdelByPass == 0, enforce Idle state before sending command
185
- //
186
- if ((GetCachedIdleByPass () == 0 ) && ((MmioRead32 ((UINTN )& CrbReg -> CrbControlStatus ) & PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE ) == 0 )) {
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 );
187
224
Status = PtpCrbWaitRegisterBits (
188
- & CrbReg -> CrbControlStatus ,
189
- PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE ,
225
+ & CrbReg -> CrbControlRequest ,
190
226
0 ,
227
+ PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY ,
191
228
PTP_TIMEOUT_C
192
229
);
193
230
if (EFI_ERROR (Status )) {
194
- //
195
- // Try to goIdle to recover TPM
196
- //
197
- Status = EFI_DEVICE_ERROR ;
198
- goto GoIdle_Exit ;
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
+ }
199
239
}
200
- }
201
240
202
- //
203
- // STEP 1:
204
- // Ready is any time the TPM is ready to receive a command, following a write
205
- // of 1 by software to Request.cmdReady, as indicated by the Status field
206
- // being cleared to 0.
207
- //
208
- MmioWrite32 ((UINTN )& CrbReg -> CrbControlRequest , PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY );
209
- Status = PtpCrbWaitRegisterBits (
210
- & CrbReg -> CrbControlRequest ,
211
- 0 ,
212
- PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY ,
213
- PTP_TIMEOUT_C
214
- );
215
- if (EFI_ERROR (Status )) {
216
- Status = EFI_DEVICE_ERROR ;
217
- goto GoIdle_Exit ;
218
- }
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
+ }
219
257
220
- Status = PtpCrbWaitRegisterBits (
221
- & CrbReg -> CrbControlStatus ,
222
- 0 ,
223
- PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE ,
224
- PTP_TIMEOUT_C
225
- );
226
- if (EFI_ERROR (Status )) {
227
- Status = EFI_DEVICE_ERROR ;
228
- goto GoIdle_Exit ;
258
+ break ;
229
259
}
230
260
231
261
//
0 commit comments