1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2022, Linaro Limited
4 *
5 * The driver in this file is based on
6 * - TCG PC Client Device Driver Design Principles for TPM 2.0
7 * Version 1.1 Revision 0.04 [DD Specification]
8 * - TCG PC Client Platform TPM Profile Specification for TPM 2.0
9 * Version 1.05 Revision 14 [PTP Specification]
10 */
11
12 #include <assert.h>
13 #include <drivers/tpm2_chip.h>
14 #include <drivers/tpm2_cmd.h>
15 #include <drivers/tpm2_ptp_fifo.h>
16 #include <kernel/delay.h>
17 #include <trace.h>
18
19 /* DD specification states that 3 is a good choice for retry count */
20 #define TPM2_DD_RETRY_CNT 3
21
tpm2_fifo_check_ops(const struct tpm2_ptp_phy_ops * ops)22 static bool tpm2_fifo_check_ops(const struct tpm2_ptp_phy_ops *ops)
23 {
24 return ops && ops->rx32 && ops->tx32 && ops->rx8 && ops->tx8;
25 }
26
27 /*
28 * Check if tpmRegValidSts bit is set in ACCESS Register. This is required
29 * during TPM initialization sequence. [Refer Figure 2 from PTP Specification]
30 */
tpm2_fifo_wait_valid(struct tpm2_chip * chip,uint32_t loc)31 static enum tpm2_result tpm2_fifo_wait_valid(struct tpm2_chip *chip,
32 uint32_t loc)
33 {
34 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
35 enum tpm2_result ret = TPM2_OK;
36 uint64_t timeout_ref = timeout_init_us(chip->timeout_a * 1000);
37 uint8_t access = 0;
38
39 do {
40 ret = ops->rx8(chip, TPM2_ACCESS(loc), sizeof(access), &access);
41 if (ret)
42 return ret;
43
44 if (access & TPM2_ACCESS_VALID)
45 return TPM2_OK;
46
47 mdelay(TPM2_TIMEOUT_RETRY_MS);
48 } while (!timeout_elapsed(timeout_ref));
49
50 return TPM2_ERR_TIMEOUT;
51 }
52
53 /* Check if activeLocality is 1 in TPM2 ACCESS Register for that locality */
tpm2_fifo_check_locality(struct tpm2_chip * chip,uint32_t loc)54 static bool tpm2_fifo_check_locality(struct tpm2_chip *chip, uint32_t loc)
55 {
56 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
57 uint8_t locality = 0;
58 enum tpm2_result ret = TPM2_OK;
59
60 ret = ops->rx8(chip, TPM2_ACCESS(loc), sizeof(locality), &locality);
61 if (ret)
62 return false;
63
64 /*
65 * Check if requested locality is active. If it has been requested for
66 * use, return false.
67 */
68 if ((locality & (TPM2_ACCESS_ACTIVE_LOCALITY | TPM2_ACCESS_VALID |
69 TPM2_ACCESS_REQUEST_USE)) ==
70 (TPM2_ACCESS_ACTIVE_LOCALITY | TPM2_ACCESS_VALID))
71 return true;
72
73 return false;
74 }
75
76 /* Based on Figure 2 - Locality Access protocol from DD Specification */
tpm2_fifo_request_locality(struct tpm2_chip * chip,uint32_t loc)77 static enum tpm2_result tpm2_fifo_request_locality(struct tpm2_chip *chip,
78 uint32_t loc)
79 {
80 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
81 uint64_t timeout_ref = 0;
82 uint8_t buf = 0;
83 enum tpm2_result ret = TPM2_OK;
84
85 if (chip->locality >= 0)
86 return TPM2_ERR_BUSY;
87
88 /* first check if locality is active FIFO.activeLocality == 1 */
89 if (tpm2_fifo_check_locality(chip, loc)) {
90 chip->locality = loc;
91 return TPM2_OK;
92 }
93
94 /* if not get one */
95 buf = TPM2_ACCESS_REQUEST_USE;
96 ret = ops->tx8(chip, TPM2_ACCESS(loc), sizeof(buf), &buf);
97 if (ret)
98 return ret;
99
100 timeout_ref = timeout_init_us(chip->timeout_a * 1000);
101 do {
102 /* keep trying to get one until timeout */
103 if (tpm2_fifo_check_locality(chip, loc)) {
104 chip->locality = loc;
105 return TPM2_OK;
106 }
107
108 mdelay(TPM2_TIMEOUT_RETRY_MS);
109 } while (!timeout_elapsed(timeout_ref));
110
111 return TPM2_ERR_NO_ACTIVE_LOCALITY;
112 }
113
tpm2_fifo_relinquish_locality(struct tpm2_chip * chip)114 static enum tpm2_result tpm2_fifo_relinquish_locality(struct tpm2_chip *chip)
115 {
116 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
117 uint8_t buf = 0;
118 enum tpm2_result ret = TPM2_OK;
119
120 if (chip->locality < 0)
121 return TPM2_OK;
122
123 /* Writing to TPM2_ACCESS_ACTIVE_LOCALITY relinquishes locality */
124 buf = TPM2_ACCESS_ACTIVE_LOCALITY;
125 ret = ops->tx8(chip, TPM2_ACCESS(chip->locality), sizeof(buf), &buf);
126 if (ret)
127 return ret;
128
129 chip->locality = -1;
130
131 return TPM2_OK;
132 }
133
tpm2_fifo_set_status(struct tpm2_chip * chip,uint8_t status)134 static enum tpm2_result tpm2_fifo_set_status(struct tpm2_chip *chip,
135 uint8_t status)
136 {
137 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
138 uint8_t buf = status;
139
140 return ops->tx8(chip, TPM2_STS(chip->locality), sizeof(buf), &buf);
141 }
142
tpm2_fifo_get_status(struct tpm2_chip * chip,uint8_t * status)143 static enum tpm2_result tpm2_fifo_get_status(struct tpm2_chip *chip,
144 uint8_t *status)
145 {
146 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
147 enum tpm2_result ret = TPM2_OK;
148
149 ret = ops->rx8(chip, TPM2_STS(chip->locality), sizeof(*status), status);
150 if (ret)
151 return ret;
152
153 /* Few bits in STS register are always expected to be 0. */
154 if ((*status & TPM2_STS_READ_ZERO)) {
155 EMSG("Invalid status");
156 return TPM2_ERR_INVALID_ARG;
157 }
158
159 return TPM2_OK;
160 }
161
162 /* Different status bit settings can require different timeouts */
tpm2_fifo_wait_for_status(struct tpm2_chip * chip,uint8_t mask,uint32_t timeout_ms,uint8_t * status)163 static enum tpm2_result tpm2_fifo_wait_for_status(struct tpm2_chip *chip,
164 uint8_t mask,
165 uint32_t timeout_ms,
166 uint8_t *status)
167 {
168 enum tpm2_result ret = TPM2_OK;
169 uint64_t timeout_ref = timeout_init_us(timeout_ms * 1000);
170
171 do {
172 ret = tpm2_fifo_get_status(chip, status);
173 if (ret)
174 return ret;
175
176 if ((*status & mask) == mask)
177 return TPM2_OK;
178
179 mdelay(TPM2_TIMEOUT_RETRY_MS);
180 } while (!timeout_elapsed(timeout_ref));
181
182 return TPM2_ERR_TIMEOUT;
183 }
184
tpm2_fifo_get_burstcount(struct tpm2_chip * chip,uint32_t * burstcount)185 static enum tpm2_result tpm2_fifo_get_burstcount(struct tpm2_chip *chip,
186 uint32_t *burstcount)
187 {
188 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
189 uint32_t burst = 0;
190 uint64_t timeout_ref = 0;
191 enum tpm2_result ret = TPM2_OK;
192
193 if (chip->locality < 0)
194 return TPM2_ERR_INVALID_ARG;
195
196 timeout_ref = timeout_init_us(chip->timeout_a * 1000);
197 /* wait for burstcount */
198 do {
199 ret = ops->rx32(chip, TPM2_STS(chip->locality), &burst);
200 if (ret)
201 return ret;
202 burst = burst & TPM2_STS_BURST_COUNT_MASK;
203 if (burst) {
204 *burstcount = (burst >> TPM2_STS_BURST_COUNT_SHIFT);
205 return TPM2_OK;
206 }
207
208 mdelay(TPM2_TIMEOUT_RETRY_MS);
209 } while (!timeout_elapsed(timeout_ref));
210
211 return TPM2_ERR_TIMEOUT;
212 }
213
tpm2_fifo_init(struct tpm2_chip * chip)214 enum tpm2_result tpm2_fifo_init(struct tpm2_chip *chip)
215 {
216 enum tpm2_result ret = TPM2_OK;
217 const struct tpm2_ptp_phy_ops *ops = chip->phy_ops;
218 uint32_t flags = 0;
219
220 assert(tpm2_fifo_check_ops(ops));
221
222 chip->timeout_a = TPM2_TIMEOUT_A;
223 chip->timeout_b = TPM2_TIMEOUT_B;
224 chip->timeout_c = TPM2_TIMEOUT_C;
225 chip->timeout_d = TPM2_TIMEOUT_D;
226 chip->locality = -1;
227
228 /* Wait for VALID bit to be set in TPM_ACCESS */
229 ret = tpm2_fifo_wait_valid(chip, 0);
230 if (ret)
231 return TPM2_ERR_NODEV;
232
233 ret = tpm2_fifo_request_locality(chip, 0);
234 if (ret)
235 return ret;
236
237 /* disable interrupts */
238 ret = chip->phy_ops->rx32(chip, TPM2_INT_ENABLE(chip->locality),
239 &flags);
240 if (ret)
241 return ret;
242
243 flags |= TPM2_INT_CMD_READY_INT | TPM2_INT_LOCALITY_CHANGE_INT |
244 TPM2_INT_DATA_AVAIL_INT | TPM2_INT_STS_VALID_INT;
245 flags &= ~TPM2_GLOBAL_INT_ENABLE;
246
247 ret = chip->phy_ops->tx32(chip, TPM2_INT_ENABLE(chip->locality), flags);
248 if (ret)
249 return ret;
250
251 return tpm2_fifo_relinquish_locality(chip);
252 }
253
tpm2_fifo_end(struct tpm2_chip * chip)254 enum tpm2_result tpm2_fifo_end(struct tpm2_chip *chip)
255 {
256 enum tpm2_result ret = TPM2_OK;
257
258 /* Cancel any command that may have been sent to TPM */
259 ret = tpm2_fifo_set_status(chip, TPM2_STS_COMMAND_READY);
260 if (ret)
261 return ret;
262
263 /* Relinquish locality if it was requested earlier */
264 return tpm2_fifo_relinquish_locality(chip);
265 }
266
267 /* Based on Figure 3 - Send Command using FIFO protocol in DD Specification */
tpm2_fifo_send(struct tpm2_chip * chip,uint8_t * buf,uint32_t len)268 enum tpm2_result tpm2_fifo_send(struct tpm2_chip *chip, uint8_t *buf,
269 uint32_t len)
270 {
271 enum tpm2_result ret = TPM2_OK;
272 const struct tpm2_ptp_phy_ops *ops = NULL;
273 uint32_t burstcnt = 0;
274 uint32_t sent = 0;
275 uint32_t wr_size = 0;
276 uint32_t buf_len = 0;
277 uint8_t retry_cnt = 0;
278 uint8_t status = 0;
279
280 if (!chip)
281 return TPM2_ERR_GENERIC;
282
283 ops = chip->phy_ops;
284
285 /* locality will be relinquishd in tpm2_fifo_recv() */
286 ret = tpm2_fifo_request_locality(chip, 0);
287 if (ret)
288 return ret;
289
290 while (retry_cnt < TPM2_DD_RETRY_CNT) {
291 /*
292 * If unable to get status, something fundamental is
293 * wrong. No retries needed.
294 */
295 ret = tpm2_fifo_get_status(chip, &status);
296 if (ret)
297 break;
298
299 if (!(status & TPM2_STS_COMMAND_READY)) {
300 /*
301 * If unable to set status, something fundamental is
302 * wrong. No retries needed.
303 */
304 ret = tpm2_fifo_set_status(chip,
305 TPM2_STS_COMMAND_READY);
306 if (ret) {
307 EMSG("Previous cmd cancel failed");
308 break;
309 }
310 ret = tpm2_fifo_wait_for_status(chip,
311 TPM2_STS_COMMAND_READY,
312 chip->timeout_b,
313 &status);
314 if (ret) {
315 retry_cnt++;
316 continue;
317 }
318 }
319
320 buf_len = len;
321 sent = 0;
322 while (buf_len > 0) {
323 ret = tpm2_fifo_get_burstcount(chip, &burstcnt);
324 if (ret)
325 break;
326
327 wr_size = MIN(buf_len, burstcnt);
328 ret = ops->tx8(chip, TPM2_DATA_FIFO(chip->locality),
329 wr_size, buf + sent);
330 if (ret)
331 break;
332
333 ret = tpm2_fifo_wait_for_status(chip, TPM2_STS_VALID,
334 chip->timeout_a,
335 &status);
336 if (ret)
337 break;
338
339 sent += wr_size;
340 buf_len -= wr_size;
341 /* TPM2 should expect more data */
342 if (buf_len && !(status & TPM2_STS_DATA_EXPECT)) {
343 ret = TPM2_ERR_IO;
344 break;
345 }
346 }
347
348 /* If any error has occurred in transmit loop above retry */
349 if (ret) {
350 retry_cnt++;
351 continue;
352 }
353
354 /* last check everything is ok and TPM2 expects no more data */
355 ret = tpm2_fifo_wait_for_status(chip, TPM2_STS_VALID,
356 chip->timeout_a, &status);
357 if (ret) {
358 retry_cnt++;
359 continue;
360 }
361
362 /* All data has been read, TPM2 should not expect more data */
363 if (status & TPM2_STS_DATA_EXPECT) {
364 ret = TPM2_ERR_GENERIC;
365 retry_cnt++;
366 continue;
367 }
368
369 ret = tpm2_fifo_set_status(chip, TPM2_STS_GO);
370 if (ret)
371 break;
372
373 return TPM2_OK;
374 }
375
376 /* Cancel command and relinquish locality */
377 if (tpm2_fifo_end(chip))
378 return TPM2_ERR_GENERIC;
379
380 return ret;
381 }
382
383 /* Based on Fig 4 - Receive response using FIFO protocol in DD Specification */
tpm2_fifo_recv(struct tpm2_chip * chip,uint8_t * buf,uint32_t * len,uint32_t cmd_duration)384 enum tpm2_result tpm2_fifo_recv(struct tpm2_chip *chip, uint8_t *buf,
385 uint32_t *len, uint32_t cmd_duration)
386 {
387 uint32_t burstcnt = 0;
388 uint32_t bytes2read = TPM2_HDR_LEN;
389 bool param_size_flag = false;
390 uint32_t sz = 0;
391 uint32_t rxsize = 0;
392 uint8_t retry_cnt = 0;
393 uint8_t status = 0;
394 uint8_t flags = 0;
395 enum tpm2_result ret = TPM2_OK;
396 const struct tpm2_ptp_phy_ops *ops = NULL;
397
398 if (!chip)
399 return TPM2_ERR_GENERIC;
400
401 ops = chip->phy_ops;
402
403 if (*len < TPM2_HDR_LEN) {
404 EMSG("Unable to read TPM2 header");
405 *len = TPM2_HDR_LEN;
406 return TPM2_ERR_INVALID_ARG;
407 }
408
409 while (retry_cnt < TPM2_DD_RETRY_CNT) {
410 /* If retry is happening, force TPM to resend response */
411 if (retry_cnt)
412 tpm2_fifo_set_status(chip, TPM2_STS_RESPONSE_RETRY);
413
414 flags = TPM2_STS_VALID | TPM2_STS_DATA_AVAIL;
415 ret = tpm2_fifo_wait_for_status(chip, flags, cmd_duration,
416 &status);
417 if (ret) {
418 EMSG("Data not available in response buffer");
419 goto out;
420 }
421
422 rxsize = 0;
423 /* First read the TPM header */
424 bytes2read = TPM2_HDR_LEN;
425 param_size_flag = 0;
426 ret = TPM2_OK;
427
428 while (bytes2read - rxsize) {
429 ret = tpm2_fifo_get_burstcount(chip, &burstcnt);
430 if (ret)
431 break;
432
433 sz = MIN(burstcnt, bytes2read - rxsize);
434 ret = ops->rx8(chip, TPM2_DATA_FIFO(chip->locality), sz,
435 buf + rxsize);
436 if (ret)
437 goto out;
438
439 rxsize += sz;
440
441 /*
442 * The first 6 bytes of the read header have the TPM
443 * command length.
444 */
445 if (rxsize >= 6 && !param_size_flag) {
446 bytes2read = tpm2_cmd_len((void *)buf);
447 param_size_flag = true;
448
449 if (bytes2read > *len) {
450 EMSG("Buffer too small: %" PRIx32 "> %"
451 PRIx32, bytes2read, *len);
452 /* Return required buffer length */
453 *len = bytes2read;
454 ret = TPM2_ERR_SHORT_BUFFER;
455 goto out;
456 }
457 }
458 }
459
460 /* If error in burstcnt, need to retry */
461 if (ret) {
462 retry_cnt++;
463 continue;
464 }
465
466 ret = tpm2_fifo_wait_for_status(chip, TPM2_STS_VALID,
467 chip->timeout_a, &status);
468 if (ret)
469 goto out;
470
471 /*
472 * Something went wrong if DATA_AVAIL is still set.
473 * Instruct TPM to RetryResponse.
474 */
475 if (!(status & TPM2_STS_DATA_AVAIL))
476 break;
477
478 retry_cnt++;
479 }
480 out:
481 /* Cancel command and relinquish locality */
482 if (tpm2_fifo_end(chip))
483 return TPM2_ERR_GENERIC;
484
485 return ret;
486 }
487