]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/tpm/tpm.c
a650892f09ab6d4760910dbefd4b8336d3a01aa9
[karo-tx-uboot.git] / drivers / tpm / tpm.c
1 /*
2  * Copyright (C) 2011 Infineon Technologies
3  *
4  * Authors:
5  * Peter Huewe <huewe.external@infineon.com>
6  *
7  * Description:
8  * Device driver for TCG/TCPA TPM (trusted platform module).
9  * Specifications at www.trustedcomputinggroup.org
10  *
11  * It is based on the Linux kernel driver tpm.c from Leendert van
12  * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
13  *
14  * Version: 2.1.1
15  *
16  * See file CREDITS for list of people who contributed to this
17  * project.
18  *
19  * This program is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU General Public License as
21  * published by the Free Software Foundation, version 2 of the
22  * License.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32  * MA 02111-1307 USA
33  */
34
35 #include <config.h>
36 #include <common.h>
37 #include <dm.h>
38 #include <linux/compiler.h>
39 #include <fdtdec.h>
40 #include <i2c.h>
41 #include <tpm.h>
42 #include <asm-generic/errno.h>
43 #include <linux/types.h>
44 #include <linux/unaligned/be_byteshift.h>
45
46 #include "tpm_private.h"
47
48 DECLARE_GLOBAL_DATA_PTR;
49
50 /* TPM configuration */
51 struct tpm {
52 #ifdef CONFIG_DM_I2C
53         struct udevice *dev;
54 #else
55         int i2c_bus;
56         int slave_addr;
57         int old_bus;
58 #endif
59         char inited;
60 } tpm;
61
62 /* Global structure for tpm chip data */
63 static struct tpm_chip g_chip;
64
65 enum tpm_duration {
66         TPM_SHORT = 0,
67         TPM_MEDIUM = 1,
68         TPM_LONG = 2,
69         TPM_UNDEFINED,
70 };
71
72 /* Extended error numbers from linux (see errno.h) */
73 #define ECANCELED       125     /* Operation Canceled */
74
75 /* Timer frequency. Corresponds to msec timer resolution*/
76 #define HZ              1000
77
78 #define TPM_MAX_ORDINAL                 243
79 #define TPM_MAX_PROTECTED_ORDINAL       12
80 #define TPM_PROTECTED_ORDINAL_MASK      0xFF
81
82 #define TPM_CMD_COUNT_BYTE      2
83 #define TPM_CMD_ORDINAL_BYTE    6
84
85 /*
86  * Array with one entry per ordinal defining the maximum amount
87  * of time the chip could take to return the result.  The ordinal
88  * designation of short, medium or long is defined in a table in
89  * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
90  * values of the SHORT, MEDIUM, and LONG durations are retrieved
91  * from the chip during initialization with a call to tpm_get_timeouts.
92  */
93 static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
94         TPM_UNDEFINED,          /* 0 */
95         TPM_UNDEFINED,
96         TPM_UNDEFINED,
97         TPM_UNDEFINED,
98         TPM_UNDEFINED,
99         TPM_UNDEFINED,          /* 5 */
100         TPM_UNDEFINED,
101         TPM_UNDEFINED,
102         TPM_UNDEFINED,
103         TPM_UNDEFINED,
104         TPM_SHORT,              /* 10 */
105         TPM_SHORT,
106 };
107
108 static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
109         TPM_UNDEFINED,          /* 0 */
110         TPM_UNDEFINED,
111         TPM_UNDEFINED,
112         TPM_UNDEFINED,
113         TPM_UNDEFINED,
114         TPM_UNDEFINED,          /* 5 */
115         TPM_UNDEFINED,
116         TPM_UNDEFINED,
117         TPM_UNDEFINED,
118         TPM_UNDEFINED,
119         TPM_SHORT,              /* 10 */
120         TPM_SHORT,
121         TPM_MEDIUM,
122         TPM_LONG,
123         TPM_LONG,
124         TPM_MEDIUM,             /* 15 */
125         TPM_SHORT,
126         TPM_SHORT,
127         TPM_MEDIUM,
128         TPM_LONG,
129         TPM_SHORT,              /* 20 */
130         TPM_SHORT,
131         TPM_MEDIUM,
132         TPM_MEDIUM,
133         TPM_MEDIUM,
134         TPM_SHORT,              /* 25 */
135         TPM_SHORT,
136         TPM_MEDIUM,
137         TPM_SHORT,
138         TPM_SHORT,
139         TPM_MEDIUM,             /* 30 */
140         TPM_LONG,
141         TPM_MEDIUM,
142         TPM_SHORT,
143         TPM_SHORT,
144         TPM_SHORT,              /* 35 */
145         TPM_MEDIUM,
146         TPM_MEDIUM,
147         TPM_UNDEFINED,
148         TPM_UNDEFINED,
149         TPM_MEDIUM,             /* 40 */
150         TPM_LONG,
151         TPM_MEDIUM,
152         TPM_SHORT,
153         TPM_SHORT,
154         TPM_SHORT,              /* 45 */
155         TPM_SHORT,
156         TPM_SHORT,
157         TPM_SHORT,
158         TPM_LONG,
159         TPM_MEDIUM,             /* 50 */
160         TPM_MEDIUM,
161         TPM_UNDEFINED,
162         TPM_UNDEFINED,
163         TPM_UNDEFINED,
164         TPM_UNDEFINED,          /* 55 */
165         TPM_UNDEFINED,
166         TPM_UNDEFINED,
167         TPM_UNDEFINED,
168         TPM_UNDEFINED,
169         TPM_MEDIUM,             /* 60 */
170         TPM_MEDIUM,
171         TPM_MEDIUM,
172         TPM_SHORT,
173         TPM_SHORT,
174         TPM_MEDIUM,             /* 65 */
175         TPM_UNDEFINED,
176         TPM_UNDEFINED,
177         TPM_UNDEFINED,
178         TPM_UNDEFINED,
179         TPM_SHORT,              /* 70 */
180         TPM_SHORT,
181         TPM_UNDEFINED,
182         TPM_UNDEFINED,
183         TPM_UNDEFINED,
184         TPM_UNDEFINED,          /* 75 */
185         TPM_UNDEFINED,
186         TPM_UNDEFINED,
187         TPM_UNDEFINED,
188         TPM_UNDEFINED,
189         TPM_LONG,               /* 80 */
190         TPM_UNDEFINED,
191         TPM_MEDIUM,
192         TPM_LONG,
193         TPM_SHORT,
194         TPM_UNDEFINED,          /* 85 */
195         TPM_UNDEFINED,
196         TPM_UNDEFINED,
197         TPM_UNDEFINED,
198         TPM_UNDEFINED,
199         TPM_SHORT,              /* 90 */
200         TPM_SHORT,
201         TPM_SHORT,
202         TPM_SHORT,
203         TPM_SHORT,
204         TPM_UNDEFINED,          /* 95 */
205         TPM_UNDEFINED,
206         TPM_UNDEFINED,
207         TPM_UNDEFINED,
208         TPM_UNDEFINED,
209         TPM_MEDIUM,             /* 100 */
210         TPM_SHORT,
211         TPM_SHORT,
212         TPM_UNDEFINED,
213         TPM_UNDEFINED,
214         TPM_UNDEFINED,          /* 105 */
215         TPM_UNDEFINED,
216         TPM_UNDEFINED,
217         TPM_UNDEFINED,
218         TPM_UNDEFINED,
219         TPM_SHORT,              /* 110 */
220         TPM_SHORT,
221         TPM_SHORT,
222         TPM_SHORT,
223         TPM_SHORT,
224         TPM_SHORT,              /* 115 */
225         TPM_SHORT,
226         TPM_SHORT,
227         TPM_UNDEFINED,
228         TPM_UNDEFINED,
229         TPM_LONG,               /* 120 */
230         TPM_LONG,
231         TPM_MEDIUM,
232         TPM_UNDEFINED,
233         TPM_SHORT,
234         TPM_SHORT,              /* 125 */
235         TPM_SHORT,
236         TPM_LONG,
237         TPM_SHORT,
238         TPM_SHORT,
239         TPM_SHORT,              /* 130 */
240         TPM_MEDIUM,
241         TPM_UNDEFINED,
242         TPM_SHORT,
243         TPM_MEDIUM,
244         TPM_UNDEFINED,          /* 135 */
245         TPM_UNDEFINED,
246         TPM_UNDEFINED,
247         TPM_UNDEFINED,
248         TPM_UNDEFINED,
249         TPM_SHORT,              /* 140 */
250         TPM_SHORT,
251         TPM_UNDEFINED,
252         TPM_UNDEFINED,
253         TPM_UNDEFINED,
254         TPM_UNDEFINED,          /* 145 */
255         TPM_UNDEFINED,
256         TPM_UNDEFINED,
257         TPM_UNDEFINED,
258         TPM_UNDEFINED,
259         TPM_SHORT,              /* 150 */
260         TPM_MEDIUM,
261         TPM_MEDIUM,
262         TPM_SHORT,
263         TPM_SHORT,
264         TPM_UNDEFINED,          /* 155 */
265         TPM_UNDEFINED,
266         TPM_UNDEFINED,
267         TPM_UNDEFINED,
268         TPM_UNDEFINED,
269         TPM_SHORT,              /* 160 */
270         TPM_SHORT,
271         TPM_SHORT,
272         TPM_SHORT,
273         TPM_UNDEFINED,
274         TPM_UNDEFINED,          /* 165 */
275         TPM_UNDEFINED,
276         TPM_UNDEFINED,
277         TPM_UNDEFINED,
278         TPM_UNDEFINED,
279         TPM_LONG,               /* 170 */
280         TPM_UNDEFINED,
281         TPM_UNDEFINED,
282         TPM_UNDEFINED,
283         TPM_UNDEFINED,
284         TPM_UNDEFINED,          /* 175 */
285         TPM_UNDEFINED,
286         TPM_UNDEFINED,
287         TPM_UNDEFINED,
288         TPM_UNDEFINED,
289         TPM_MEDIUM,             /* 180 */
290         TPM_SHORT,
291         TPM_MEDIUM,
292         TPM_MEDIUM,
293         TPM_MEDIUM,
294         TPM_MEDIUM,             /* 185 */
295         TPM_SHORT,
296         TPM_UNDEFINED,
297         TPM_UNDEFINED,
298         TPM_UNDEFINED,
299         TPM_UNDEFINED,          /* 190 */
300         TPM_UNDEFINED,
301         TPM_UNDEFINED,
302         TPM_UNDEFINED,
303         TPM_UNDEFINED,
304         TPM_UNDEFINED,          /* 195 */
305         TPM_UNDEFINED,
306         TPM_UNDEFINED,
307         TPM_UNDEFINED,
308         TPM_UNDEFINED,
309         TPM_SHORT,              /* 200 */
310         TPM_UNDEFINED,
311         TPM_UNDEFINED,
312         TPM_UNDEFINED,
313         TPM_SHORT,
314         TPM_SHORT,              /* 205 */
315         TPM_SHORT,
316         TPM_SHORT,
317         TPM_SHORT,
318         TPM_SHORT,
319         TPM_MEDIUM,             /* 210 */
320         TPM_UNDEFINED,
321         TPM_MEDIUM,
322         TPM_MEDIUM,
323         TPM_MEDIUM,
324         TPM_UNDEFINED,          /* 215 */
325         TPM_MEDIUM,
326         TPM_UNDEFINED,
327         TPM_UNDEFINED,
328         TPM_SHORT,
329         TPM_SHORT,              /* 220 */
330         TPM_SHORT,
331         TPM_SHORT,
332         TPM_SHORT,
333         TPM_SHORT,
334         TPM_UNDEFINED,          /* 225 */
335         TPM_UNDEFINED,
336         TPM_UNDEFINED,
337         TPM_UNDEFINED,
338         TPM_UNDEFINED,
339         TPM_SHORT,              /* 230 */
340         TPM_LONG,
341         TPM_MEDIUM,
342         TPM_UNDEFINED,
343         TPM_UNDEFINED,
344         TPM_UNDEFINED,          /* 235 */
345         TPM_UNDEFINED,
346         TPM_UNDEFINED,
347         TPM_UNDEFINED,
348         TPM_UNDEFINED,
349         TPM_SHORT,              /* 240 */
350         TPM_UNDEFINED,
351         TPM_MEDIUM,
352 };
353
354 /* Returns max number of milliseconds to wait */
355 static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
356                 u32 ordinal)
357 {
358         int duration_idx = TPM_UNDEFINED;
359         int duration = 0;
360
361         if (ordinal < TPM_MAX_ORDINAL) {
362                 duration_idx = tpm_ordinal_duration[ordinal];
363         } else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
364                         TPM_MAX_PROTECTED_ORDINAL) {
365                 duration_idx = tpm_protected_ordinal_duration[
366                                 ordinal & TPM_PROTECTED_ORDINAL_MASK];
367         }
368
369         if (duration_idx != TPM_UNDEFINED)
370                 duration = chip->vendor.duration[duration_idx];
371
372         if (duration <= 0)
373                 return 2 * 60 * HZ; /* Two minutes timeout */
374         else
375                 return duration;
376 }
377
378 static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
379 {
380         int rc;
381         u32 count, ordinal;
382         unsigned long start, stop;
383
384         struct tpm_chip *chip = &g_chip;
385
386         /* switch endianess: big->little */
387         count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
388         ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
389
390         if (count == 0) {
391                 error("no data\n");
392                 return -ENODATA;
393         }
394         if (count > bufsiz) {
395                 error("invalid count value %x %zx\n", count, bufsiz);
396                 return -E2BIG;
397         }
398
399         debug("Calling send\n");
400         rc = chip->vendor.send(chip, (u8 *)buf, count);
401         debug("   ... done calling send\n");
402         if (rc < 0) {
403                 error("tpm_transmit: tpm_send: error %d\n", rc);
404                 goto out;
405         }
406
407         if (chip->vendor.irq)
408                 goto out_recv;
409
410         start = get_timer(0);
411         stop = tpm_calc_ordinal_duration(chip, ordinal);
412         do {
413                 debug("waiting for status... %ld %ld\n", start, stop);
414                 u8 status = chip->vendor.status(chip);
415                 if ((status & chip->vendor.req_complete_mask) ==
416                     chip->vendor.req_complete_val) {
417                         debug("...got it;\n");
418                         goto out_recv;
419                 }
420
421                 if (status == chip->vendor.req_canceled) {
422                         error("Operation Canceled\n");
423                         rc = -ECANCELED;
424                         goto out;
425                 }
426                 udelay(TPM_TIMEOUT * 1000);
427         } while (get_timer(start) < stop);
428
429         chip->vendor.cancel(chip);
430         error("Operation Timed out\n");
431         rc = -ETIME;
432         goto out;
433
434 out_recv:
435         debug("out_recv: reading response...\n");
436         rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
437         if (rc < 0)
438                 error("tpm_transmit: tpm_recv: error %d\n", rc);
439
440 out:
441         return rc;
442 }
443
444 #ifdef CONFIG_DM_I2C
445 static int tpm_open_dev(struct udevice *dev)
446 {
447         int rc;
448
449         debug("%s: start\n", __func__);
450         if (g_chip.is_open)
451                 return -EBUSY;
452         rc = tpm_vendor_init_dev(dev);
453         if (rc < 0)
454                 g_chip.is_open = 0;
455         return rc;
456 }
457 #else
458 static int tpm_open(uint32_t dev_addr)
459 {
460         int rc;
461
462         if (g_chip.is_open)
463                 return -EBUSY;
464         rc = tpm_vendor_init(dev_addr);
465         if (rc < 0)
466                 g_chip.is_open = 0;
467         return rc;
468 }
469 #endif
470 static void tpm_close(void)
471 {
472         if (g_chip.is_open) {
473                 tpm_vendor_cleanup(&g_chip);
474                 g_chip.is_open = 0;
475         }
476 }
477
478 static int tpm_select(void)
479 {
480 #ifndef CONFIG_DM_I2C
481         int ret;
482
483         tpm.old_bus = i2c_get_bus_num();
484         if (tpm.old_bus != tpm.i2c_bus) {
485                 ret = i2c_set_bus_num(tpm.i2c_bus);
486                 if (ret) {
487                         debug("%s: Fail to set i2c bus %d\n", __func__,
488                               tpm.i2c_bus);
489                         return -1;
490                 }
491         }
492 #endif
493         return 0;
494 }
495
496 static int tpm_deselect(void)
497 {
498 #ifndef CONFIG_DM_I2C
499         int ret;
500
501         if (tpm.old_bus != i2c_get_bus_num()) {
502                 ret = i2c_set_bus_num(tpm.old_bus);
503                 if (ret) {
504                         debug("%s: Fail to restore i2c bus %d\n",
505                               __func__, tpm.old_bus);
506                         return -1;
507                 }
508         }
509         tpm.old_bus = -1;
510 #endif
511         return 0;
512 }
513
514 /**
515  * Decode TPM configuration.
516  *
517  * @param dev   Returns a configuration of TPM device
518  * @return 0 if ok, -1 on error
519  */
520 static int tpm_decode_config(struct tpm *dev)
521 {
522         const void *blob = gd->fdt_blob;
523         int parent;
524         int node;
525
526         node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
527         if (node < 0) {
528                 node = fdtdec_next_compatible(blob, 0,
529                                 COMPAT_INFINEON_SLB9645_TPM);
530         }
531         if (node < 0) {
532                 debug("%s: Node not found\n", __func__);
533                 return -1;
534         }
535         parent = fdt_parent_offset(blob, node);
536         if (parent < 0) {
537                 debug("%s: Cannot find node parent\n", __func__);
538                 return -1;
539         }
540 #ifdef CONFIG_DM_I2C
541         struct udevice *bus;
542         int chip_addr;
543         int ret;
544
545         /*
546          * TODO(sjg@chromium.org): Remove this when driver model supports
547          * TPMs
548          */
549         ret = uclass_get_device_by_of_offset(UCLASS_I2C, parent, &bus);
550         if (ret) {
551                 debug("Cannot find bus for node '%s: ret=%d'\n",
552                       fdt_get_name(blob, parent, NULL), ret);
553                 return ret;
554         }
555
556         chip_addr = fdtdec_get_int(blob, node, "reg", -1);
557         if (chip_addr == -1) {
558                 debug("Cannot find reg property for node '%s: ret=%d'\n",
559                       fdt_get_name(blob, node, NULL), ret);
560                 return ret;
561         }
562         /*
563          * TODO(sjg@chromium.org): Older TPMs will need to use the older method
564          * in iic_tpm_read() so the offset length needs to be 0 here.
565          */
566         ret = i2c_get_chip(bus, chip_addr, 1, &dev->dev);
567         if (ret) {
568                 debug("Cannot find device for node '%s: ret=%d'\n",
569                       fdt_get_name(blob, node, NULL), ret);
570                 return ret;
571         }
572 #else
573         int i2c_bus;
574
575         i2c_bus = i2c_get_bus_num_fdt(parent);
576         if (i2c_bus < 0)
577                 return -1;
578         dev->i2c_bus = i2c_bus;
579         dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
580 #endif
581
582         return 0;
583 }
584
585 struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
586 {
587         struct tpm_chip *chip;
588
589         /* Driver specific per-device data */
590         chip = &g_chip;
591         memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
592         chip->is_open = 1;
593
594         return chip;
595 }
596
597 int tis_init(void)
598 {
599         if (tpm.inited)
600                 return 0;
601
602         if (tpm_decode_config(&tpm))
603                 return -1;
604
605         if (tpm_select())
606                 return -1;
607
608 #ifndef CONFIG_DM_I2C
609         /*
610          * Probe TPM twice; the first probing might fail because TPM is asleep,
611          * and the probing can wake up TPM.
612          */
613         if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
614                 debug("%s: fail to probe i2c addr 0x%x\n", __func__,
615                       tpm.slave_addr);
616                 return -1;
617         }
618 #endif
619
620         tpm_deselect();
621         debug("%s: done\n", __func__);
622
623         tpm.inited = 1;
624
625         return 0;
626 }
627
628 int tis_open(void)
629 {
630         int rc;
631
632         if (!tpm.inited)
633                 return -1;
634
635         if (tpm_select())
636                 return -1;
637
638 #ifdef CONFIG_DM_I2C
639         rc = tpm_open_dev(tpm.dev);
640 #else
641         rc = tpm_open(tpm.slave_addr);
642 #endif
643
644         tpm_deselect();
645
646         return rc;
647 }
648
649 int tis_close(void)
650 {
651         if (!tpm.inited)
652                 return -1;
653
654         if (tpm_select())
655                 return -1;
656
657         tpm_close();
658
659         tpm_deselect();
660
661         return 0;
662 }
663
664 int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
665                 uint8_t *recvbuf, size_t *rbuf_len)
666 {
667         int len;
668         uint8_t buf[4096];
669
670         if (!tpm.inited)
671                 return -1;
672
673         if (sizeof(buf) < sbuf_size)
674                 return -1;
675
676         memcpy(buf, sendbuf, sbuf_size);
677
678         if (tpm_select())
679                 return -1;
680
681         len = tpm_transmit(buf, sbuf_size);
682
683         tpm_deselect();
684
685         if (len < 10) {
686                 *rbuf_len = 0;
687                 return -1;
688         }
689
690         memcpy(recvbuf, buf, len);
691         *rbuf_len = len;
692
693         return 0;
694 }