1 // Implementation of a TPM driver for the TPM TIS interface
2 //
3 // Copyright (C) 2006-2011 IBM Corporation
4 //
5 // Authors:
6 //     Stefan Berger <stefanb@linux.vnet.ibm.com>
7 //
8 // This file may be distributed under the terms of the GNU LGPLv3 license.
9 
10 #include "byteorder.h" // be32_to_cpu
11 #include "config.h" // CONFIG_TPM_TIS_SHA1THRESHOLD
12 #include "hw/tpm_drivers.h" // struct tpm_driver
13 #include "std/tcg.h" // TCG_RESPONSE_TIMEOUT
14 #include "output.h" // warn_timeout
15 #include "stacks.h" // yield
16 #include "string.h" // memcpy
17 #include "util.h" // timer_calc_usec
18 #include "x86.h" // readl
19 
20 /* low level driver implementation */
21 struct tpm_driver {
22     u32 *timeouts;
23     u32 *durations;
24     void (*set_timeouts)(u32 timeouts[4], u32 durations[3]);
25     u32 (*probe)(void);
26     TPMVersion (*get_tpm_version)(void);
27     u32 (*init)(void);
28     u32 (*activate)(u8 locty);
29     u32 (*ready)(void);
30     u32 (*senddata)(const u8 *const data, u32 len);
31     u32 (*readresp)(u8 *buffer, u32 *len);
32     u32 (*waitdatavalid)(void);
33     u32 (*waitrespready)(enum tpmDurationType to_t);
34 };
35 
36 extern struct tpm_driver tpm_drivers[];
37 
38 #define TIS_DRIVER_IDX       0
39 #define CRB_DRIVER_IDX       1
40 #define TPM_NUM_DRIVERS      2
41 
42 #define TPM_INVALID_DRIVER   0xf
43 
44 static const u32 tis_default_timeouts[4] = {
45     TIS_DEFAULT_TIMEOUT_A,
46     TIS_DEFAULT_TIMEOUT_B,
47     TIS_DEFAULT_TIMEOUT_C,
48     TIS_DEFAULT_TIMEOUT_D,
49 };
50 
51 static const u32 tpm_default_durations[3] = {
52     TPM_DEFAULT_DURATION_SHORT,
53     TPM_DEFAULT_DURATION_MEDIUM,
54     TPM_DEFAULT_DURATION_LONG,
55 };
56 
57 /* determined values */
58 static u32 tpm_default_dur[3];
59 static u32 tpm_default_to[4];
60 
61 static u32 crb_cmd_size;
62 static void *crb_cmd;
63 static u32 crb_resp_size;
64 static void *crb_resp;
65 
wait_reg8(u8 * reg,u32 time,u8 mask,u8 expect)66 static u32 wait_reg8(u8* reg, u32 time, u8 mask, u8 expect)
67 {
68     if (!CONFIG_TCGBIOS)
69         return 0;
70 
71     u32 rc = 1;
72     u32 end = timer_calc_usec(time);
73 
74     for (;;) {
75         u8 value = readl(reg);
76         if ((value & mask) == expect) {
77             rc = 0;
78             break;
79         }
80         if (timer_check(end)) {
81             warn_timeout();
82             break;
83         }
84         yield();
85     }
86     return rc;
87 }
88 
tis_wait_access(u8 locty,u32 time,u8 mask,u8 expect)89 static u32 tis_wait_access(u8 locty, u32 time, u8 mask, u8 expect)
90 {
91     return wait_reg8(TIS_REG(locty, TIS_REG_ACCESS), time, mask, expect);
92 }
93 
tis_wait_sts(u8 locty,u32 time,u8 mask,u8 expect)94 static u32 tis_wait_sts(u8 locty, u32 time, u8 mask, u8 expect)
95 {
96     return wait_reg8(TIS_REG(locty, TIS_REG_STS), time, mask, expect);
97 }
98 
crb_wait_reg(u8 locty,u16 reg,u32 time,u8 mask,u8 expect)99 static u32 crb_wait_reg(u8 locty, u16 reg, u32 time, u8 mask, u8 expect)
100 {
101     return wait_reg8(CRB_REG(locty, reg), time, mask, expect);
102 }
103 
104 /* if device is not there, return '0', '1' otherwise */
tis_probe(void)105 static u32 tis_probe(void)
106 {
107     if (!CONFIG_TCGBIOS)
108         return 0;
109 
110     /* Wait for the interface to report it's ready */
111     u32 rc = tis_wait_access(0, TIS_DEFAULT_TIMEOUT_A,
112                              TIS_ACCESS_TPM_REG_VALID_STS,
113                              TIS_ACCESS_TPM_REG_VALID_STS);
114     if (rc)
115         return 0;
116 
117     u32 didvid = readl(TIS_REG(0, TIS_REG_DID_VID));
118 
119     if ((didvid != 0) && (didvid != 0xffffffff))
120         rc = 1;
121 
122     /* TPM 2 has an interface register */
123     u32 ifaceid = readl(TIS_REG(0, TIS_REG_IFACE_ID));
124 
125     if ((ifaceid & 0xf) != 0xf) {
126         if ((ifaceid & 0xf) == 1) {
127             /* CRB is active; no TIS */
128             return 0;
129         }
130         if ((ifaceid & (1 << 13)) == 0) {
131             /* TIS cannot be selected */
132             return 0;
133         }
134         /* write of 0 to bits 17-18 selects TIS */
135         writel(TIS_REG(0, TIS_REG_IFACE_ID), 0);
136         /* since we only support TIS, we lock it */
137         writel(TIS_REG(0, TIS_REG_IFACE_ID), (1 << 19));
138     }
139 
140     return rc;
141 }
142 
tis_get_tpm_version(void)143 static TPMVersion tis_get_tpm_version(void)
144 {
145     u32 reg = readl(TIS_REG(0, TIS_REG_IFACE_ID));
146 
147     /*
148      * FIFO interface as defined in TIS1.3 is active
149      * Interface capabilities are defined in TIS_REG_INTF_CAPABILITY
150      */
151     if ((reg & 0xf) == 0xf) {
152         reg = readl(TIS_REG(0, TIS_REG_INTF_CAPABILITY));
153         /* Interface 1.3 for TPM 2.0 */
154         if (((reg >> 28) & 0x7) == 3)
155             return TPM_VERSION_2;
156     }
157     /* FIFO interface as defined in PTP for TPM 2.0 is active */
158     else if ((reg & 0xf) == 0) {
159         return TPM_VERSION_2;
160     }
161 
162     return TPM_VERSION_1_2;
163 }
164 
init_timeout(int driver)165 static void init_timeout(int driver)
166 {
167     if (tpm_drivers[driver].durations == NULL) {
168         u32 *durations = tpm_default_dur;
169         memcpy(durations, tpm_default_durations,
170                sizeof(tpm_default_durations));
171         tpm_drivers[driver].durations = durations;
172     }
173 
174     if (tpm_drivers[driver].timeouts == NULL) {
175         u32 *timeouts = tpm_default_to;
176         memcpy(timeouts, tis_default_timeouts,
177                sizeof(tis_default_timeouts));
178         tpm_drivers[driver].timeouts = timeouts;
179     }
180 }
181 
tis_init(void)182 static u32 tis_init(void)
183 {
184     if (!CONFIG_TCGBIOS)
185         return 1;
186 
187     writeb(TIS_REG(0, TIS_REG_INT_ENABLE), 0);
188 
189     init_timeout(TIS_DRIVER_IDX);
190 
191     return 1;
192 }
193 
194 
set_timeouts(u32 timeouts[4],u32 durations[3])195 static void set_timeouts(u32 timeouts[4], u32 durations[3])
196 {
197     if (!CONFIG_TCGBIOS)
198         return;
199 
200     u32 *tos = tpm_drivers[TIS_DRIVER_IDX].timeouts;
201     u32 *dus = tpm_drivers[TIS_DRIVER_IDX].durations;
202 
203     if (tos && tos != tis_default_timeouts && timeouts)
204         memcpy(tos, timeouts, 4 * sizeof(u32));
205     if (dus && dus != tpm_default_durations && durations)
206         memcpy(dus, durations, 3 * sizeof(u32));
207 }
208 
tis_activate(u8 locty)209 static u32 tis_activate(u8 locty)
210 {
211     if (!CONFIG_TCGBIOS)
212         return 0;
213 
214     u32 rc = 0;
215     u8 acc;
216     int l;
217     u32 timeout_a = tpm_drivers[TIS_DRIVER_IDX].timeouts[TIS_TIMEOUT_TYPE_A];
218 
219     if (!(readb(TIS_REG(locty, TIS_REG_ACCESS)) &
220           TIS_ACCESS_ACTIVE_LOCALITY)) {
221         /* release locality in use top-downwards */
222         for (l = 4; l >= 0; l--)
223             writeb(TIS_REG(l, TIS_REG_ACCESS),
224                    TIS_ACCESS_ACTIVE_LOCALITY);
225     }
226 
227     /* request access to locality */
228     writeb(TIS_REG(locty, TIS_REG_ACCESS), TIS_ACCESS_REQUEST_USE);
229 
230     acc = readb(TIS_REG(locty, TIS_REG_ACCESS));
231     if ((acc & TIS_ACCESS_ACTIVE_LOCALITY)) {
232         writeb(TIS_REG(locty, TIS_REG_STS), TIS_STS_COMMAND_READY);
233         rc = tis_wait_sts(locty, timeout_a,
234                           TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY);
235     }
236 
237     return rc;
238 }
239 
tis_find_active_locality(void)240 static u32 tis_find_active_locality(void)
241 {
242     if (!CONFIG_TCGBIOS)
243         return 0;
244 
245     u8 locty;
246 
247     for (locty = 0; locty <= 4; locty++) {
248         if ((readb(TIS_REG(locty, TIS_REG_ACCESS)) &
249              TIS_ACCESS_ACTIVE_LOCALITY))
250             return locty;
251     }
252 
253     tis_activate(0);
254 
255     return 0;
256 }
257 
tis_ready(void)258 static u32 tis_ready(void)
259 {
260     if (!CONFIG_TCGBIOS)
261         return 0;
262 
263     u32 rc = 0;
264     u8 locty = tis_find_active_locality();
265     u32 timeout_b = tpm_drivers[TIS_DRIVER_IDX].timeouts[TIS_TIMEOUT_TYPE_B];
266 
267     writeb(TIS_REG(locty, TIS_REG_STS), TIS_STS_COMMAND_READY);
268     rc = tis_wait_sts(locty, timeout_b,
269                       TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY);
270 
271     return rc;
272 }
273 
tis_senddata(const u8 * const data,u32 len)274 static u32 tis_senddata(const u8 *const data, u32 len)
275 {
276     if (!CONFIG_TCGBIOS)
277         return 0;
278 
279     u32 rc = 0;
280     u32 offset = 0;
281     u32 end_loop = 0;
282     u16 burst = 0;
283     u8 locty = tis_find_active_locality();
284     u32 timeout_d = tpm_drivers[TIS_DRIVER_IDX].timeouts[TIS_TIMEOUT_TYPE_D];
285     u32 end = timer_calc_usec(timeout_d);
286 
287     do {
288         while (burst == 0) {
289                burst = readl(TIS_REG(locty, TIS_REG_STS)) >> 8;
290             if (burst == 0) {
291                 if (timer_check(end)) {
292                     warn_timeout();
293                     break;
294                 }
295                 yield();
296             }
297         }
298 
299         if (burst == 0) {
300             rc = TCG_RESPONSE_TIMEOUT;
301             break;
302         }
303 
304         while (1) {
305             writeb(TIS_REG(locty, TIS_REG_DATA_FIFO), data[offset++]);
306             burst--;
307 
308             if (burst == 0 || offset == len)
309                 break;
310         }
311 
312         if (offset == len)
313             end_loop = 1;
314     } while (end_loop == 0);
315 
316     return rc;
317 }
318 
tis_readresp(u8 * buffer,u32 * len)319 static u32 tis_readresp(u8 *buffer, u32 *len)
320 {
321     if (!CONFIG_TCGBIOS)
322         return 0;
323 
324     u32 rc = 0;
325     u32 offset = 0;
326     u32 sts;
327     u8 locty = tis_find_active_locality();
328 
329     while (offset < *len) {
330         buffer[offset] = readb(TIS_REG(locty, TIS_REG_DATA_FIFO));
331         offset++;
332         sts = readb(TIS_REG(locty, TIS_REG_STS));
333         /* data left ? */
334         if ((sts & TIS_STS_DATA_AVAILABLE) == 0)
335             break;
336     }
337 
338     *len = offset;
339 
340     return rc;
341 }
342 
343 
tis_waitdatavalid(void)344 static u32 tis_waitdatavalid(void)
345 {
346     if (!CONFIG_TCGBIOS)
347         return 0;
348 
349     u32 rc = 0;
350     u8 locty = tis_find_active_locality();
351     u32 timeout_c = tpm_drivers[TIS_DRIVER_IDX].timeouts[TIS_TIMEOUT_TYPE_C];
352 
353     if (tis_wait_sts(locty, timeout_c, TIS_STS_VALID, TIS_STS_VALID) != 0)
354         rc = 1;
355 
356     return rc;
357 }
358 
tis_waitrespready(enum tpmDurationType to_t)359 static u32 tis_waitrespready(enum tpmDurationType to_t)
360 {
361     if (!CONFIG_TCGBIOS)
362         return 0;
363 
364     u32 rc = 0;
365     u8 locty = tis_find_active_locality();
366     u32 timeout = tpm_drivers[TIS_DRIVER_IDX].durations[to_t];
367 
368     writeb(TIS_REG(locty ,TIS_REG_STS), TIS_STS_TPM_GO);
369 
370     if (tis_wait_sts(locty, timeout,
371                      TIS_STS_DATA_AVAILABLE, TIS_STS_DATA_AVAILABLE) != 0)
372         rc = 1;
373 
374     return rc;
375 }
376 
377 #define CRB_STATE_VALID_STS 0b10000000
378 #define CRB_STATE_LOC_ASSIGNED 0x00000010
379 #define CRB_STATE_READY_MASK (CRB_STATE_VALID_STS | CRB_STATE_LOC_ASSIGNED)
380 
381 /* if device is not there, return '0', '1' otherwise */
crb_probe(void)382 static u32 crb_probe(void)
383 {
384     if (!CONFIG_TCGBIOS)
385         return 0;
386 
387     /* Wait for the interface to report it's ready */
388     u32 rc = crb_wait_reg(0, CRB_REG_LOC_STATE, TIS2_DEFAULT_TIMEOUT_D,
389                           CRB_STATE_READY_MASK, CRB_STATE_VALID_STS);
390     if (rc)
391         return 0;
392 
393     u32 ifaceid = readl(CRB_REG(0, CRB_REG_INTF_ID));
394 
395     if ((ifaceid & 0xf) != 0xf) {
396         if ((ifaceid & 0xf) == 1) {
397             /* CRB is active */
398         } else if ((ifaceid & (1 << 14)) == 0) {
399             /* CRB cannot be selected */
400             return 0;
401         }
402         /* write of 1 to bits 17-18 selects CRB */
403         writel(CRB_REG(0, CRB_REG_INTF_ID), (1 << 17));
404         /* lock it */
405         writel(CRB_REG(0, CRB_REG_INTF_ID), (1 << 19));
406     }
407 
408     /* no support for 64 bit addressing yet */
409     if (readl(CRB_REG(0, CRB_REG_CTRL_CMD_HADDR)))
410         return 0;
411 
412     u64 addr = readq(CRB_REG(0, CRB_REG_CTRL_RSP_ADDR));
413     if (addr > 0xffffffff)
414         return 0;
415 
416     return 1;
417 }
418 
crb_get_tpm_version(void)419 static TPMVersion crb_get_tpm_version(void)
420 {
421     /* CRB is supposed to be TPM 2.0 only */
422     return TPM_VERSION_2;
423 }
424 
crb_init(void)425 static u32 crb_init(void)
426 {
427     if (!CONFIG_TCGBIOS)
428         return 1;
429 
430     crb_cmd = (void*)readl(CRB_REG(0, CRB_REG_CTRL_CMD_LADDR));
431     crb_cmd_size = readl(CRB_REG(0, CRB_REG_CTRL_CMD_SIZE));
432     crb_resp = (void*)readl(CRB_REG(0, CRB_REG_CTRL_RSP_ADDR));
433     crb_resp_size = readl(CRB_REG(0, CRB_REG_CTRL_RSP_SIZE));
434 
435     init_timeout(CRB_DRIVER_IDX);
436 
437     return 0;
438 }
439 
crb_activate(u8 locty)440 static u32 crb_activate(u8 locty)
441 {
442     if (!CONFIG_TCGBIOS)
443         return 0;
444 
445     writeb(CRB_REG(locty, CRB_REG_LOC_CTRL), 1);
446 
447     return 0;
448 }
449 
crb_find_active_locality(void)450 static u32 crb_find_active_locality(void)
451 {
452     if (!CONFIG_TCGBIOS)
453         return 0;
454 
455     return 0;
456 }
457 
458 #define CRB_CTRL_REQ_CMD_READY 0b1
459 #define CRB_START_INVOKE 0b1
460 #define CRB_CTRL_STS_ERROR 0b1
461 
crb_ready(void)462 static u32 crb_ready(void)
463 {
464     if (!CONFIG_TCGBIOS)
465         return 0;
466 
467     u32 rc = 0;
468     u8 locty = crb_find_active_locality();
469     u32 timeout_c = tpm_drivers[CRB_DRIVER_IDX].timeouts[TIS_TIMEOUT_TYPE_C];
470 
471     writel(CRB_REG(locty, CRB_REG_CTRL_REQ), CRB_CTRL_REQ_CMD_READY);
472     rc = crb_wait_reg(locty, CRB_REG_CTRL_REQ, timeout_c,
473                       CRB_CTRL_REQ_CMD_READY, 0);
474 
475     return rc;
476 }
477 
crb_senddata(const u8 * const data,u32 len)478 static u32 crb_senddata(const u8 *const data, u32 len)
479 {
480     if (!CONFIG_TCGBIOS)
481         return 0;
482 
483     if (len > crb_cmd_size)
484         return 1;
485 
486     u8 locty = crb_find_active_locality();
487     memcpy(crb_cmd, data, len);
488     writel(CRB_REG(locty, CRB_REG_CTRL_START), CRB_START_INVOKE);
489 
490     return 0;
491 }
492 
crb_readresp(u8 * buffer,u32 * len)493 static u32 crb_readresp(u8 *buffer, u32 *len)
494 {
495     if (!CONFIG_TCGBIOS)
496         return 0;
497 
498     u8 locty = crb_find_active_locality();
499     if (readl(CRB_REG(locty, CRB_REG_CTRL_STS)) & CRB_CTRL_STS_ERROR)
500         return 1;
501 
502     if (*len < 6)
503         return 1;
504 
505     memcpy(buffer, crb_resp, 6);
506     u32 expected = be32_to_cpu(*(u32 *) &buffer[2]);
507     if (expected < 6)
508         return 1;
509 
510     *len = (*len < expected) ? *len : expected;
511 
512     memcpy(buffer + 6, crb_resp + 6, *len - 6);
513 
514     return 0;
515 }
516 
517 
crb_waitdatavalid(void)518 static u32 crb_waitdatavalid(void)
519 {
520     return 0;
521 }
522 
crb_waitrespready(enum tpmDurationType to_t)523 static u32 crb_waitrespready(enum tpmDurationType to_t)
524 {
525     if (!CONFIG_TCGBIOS)
526         return 0;
527 
528     u32 rc = 0;
529     u8 locty = crb_find_active_locality();
530     u32 timeout = tpm_drivers[CRB_DRIVER_IDX].durations[to_t];
531 
532     rc = crb_wait_reg(locty, CRB_REG_CTRL_START, timeout,
533                       CRB_START_INVOKE, 0);
534 
535     return rc;
536 }
537 
538 struct tpm_driver tpm_drivers[TPM_NUM_DRIVERS] = {
539     [TIS_DRIVER_IDX] =
540         {
541             .timeouts      = NULL,
542             .durations     = NULL,
543             .set_timeouts  = set_timeouts,
544             .probe         = tis_probe,
545             .get_tpm_version = tis_get_tpm_version,
546             .init          = tis_init,
547             .activate      = tis_activate,
548             .ready         = tis_ready,
549             .senddata      = tis_senddata,
550             .readresp      = tis_readresp,
551             .waitdatavalid = tis_waitdatavalid,
552             .waitrespready = tis_waitrespready,
553         },
554     [CRB_DRIVER_IDX] =
555         {
556             .timeouts      = NULL,
557             .durations     = NULL,
558             .set_timeouts  = set_timeouts,
559             .probe         = crb_probe,
560             .get_tpm_version = crb_get_tpm_version,
561             .init          = crb_init,
562             .activate      = crb_activate,
563             .ready         = crb_ready,
564             .senddata      = crb_senddata,
565             .readresp      = crb_readresp,
566             .waitdatavalid = crb_waitdatavalid,
567             .waitrespready = crb_waitrespready,
568         },
569 };
570 
571 static u8 TPMHW_driver_to_use = TPM_INVALID_DRIVER;
572 
573 TPMVersion
tpmhw_probe(void)574 tpmhw_probe(void)
575 {
576     unsigned int i;
577     for (i = 0; i < TPM_NUM_DRIVERS; i++) {
578         struct tpm_driver *td = &tpm_drivers[i];
579         if (td->probe() != 0) {
580             td->init();
581             TPMHW_driver_to_use = i;
582             return td->get_tpm_version();
583         }
584     }
585     return TPM_VERSION_NONE;
586 }
587 
588 int
tpmhw_is_present(void)589 tpmhw_is_present(void)
590 {
591     return TPMHW_driver_to_use != TPM_INVALID_DRIVER;
592 }
593 
594 int
tpmhw_transmit(u8 locty,struct tpm_req_header * req,void * respbuffer,u32 * respbufferlen,enum tpmDurationType to_t)595 tpmhw_transmit(u8 locty, struct tpm_req_header *req,
596                void *respbuffer, u32 *respbufferlen,
597                enum tpmDurationType to_t)
598 {
599     if (TPMHW_driver_to_use == TPM_INVALID_DRIVER)
600         return -1;
601 
602     struct tpm_driver *td = &tpm_drivers[TPMHW_driver_to_use];
603 
604     u32 irc = td->activate(locty);
605     if (irc != 0) {
606         /* tpm could not be activated */
607         return -1;
608     }
609 
610     irc = td->senddata((void*)req, be32_to_cpu(req->totlen));
611     if (irc != 0)
612         return -1;
613 
614     irc = td->waitdatavalid();
615     if (irc != 0)
616         return -1;
617 
618     irc = td->waitrespready(to_t);
619     if (irc != 0)
620         return -1;
621 
622     irc = td->readresp(respbuffer, respbufferlen);
623     if (irc != 0 ||
624         *respbufferlen < sizeof(struct tpm_rsp_header))
625         return -1;
626 
627     td->ready();
628 
629     return 0;
630 }
631 
632 void
tpmhw_set_timeouts(u32 timeouts[4],u32 durations[3])633 tpmhw_set_timeouts(u32 timeouts[4], u32 durations[3])
634 {
635     struct tpm_driver *td = &tpm_drivers[TPMHW_driver_to_use];
636     td->set_timeouts(timeouts, durations);
637 }
638