]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/tpm/tpm.c
ARM: bcm2835: add simplefb DT node during bootz/m
[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 <compiler.h>
38 #include <fdtdec.h>
39 #include <i2c.h>
40 #include <tpm.h>
41 #include <asm-generic/errno.h>
42 #include <linux/types.h>
43 #include <linux/unaligned/be_byteshift.h>
44
45 #include "tpm_private.h"
46
47 DECLARE_GLOBAL_DATA_PTR;
48
49 /* TPM configuration */
50 struct tpm {
51         int i2c_bus;
52         int slave_addr;
53         char inited;
54         int old_bus;
55 } tpm;
56
57 /* Global structure for tpm chip data */
58 static struct tpm_chip g_chip;
59
60 enum tpm_duration {
61         TPM_SHORT = 0,
62         TPM_MEDIUM = 1,
63         TPM_LONG = 2,
64         TPM_UNDEFINED,
65 };
66
67 /* Extended error numbers from linux (see errno.h) */
68 #define ECANCELED       125     /* Operation Canceled */
69
70 /* Timer frequency. Corresponds to msec timer resolution*/
71 #define HZ              1000
72
73 #define TPM_MAX_ORDINAL                 243
74 #define TPM_MAX_PROTECTED_ORDINAL       12
75 #define TPM_PROTECTED_ORDINAL_MASK      0xFF
76
77 #define TPM_CMD_COUNT_BYTE      2
78 #define TPM_CMD_ORDINAL_BYTE    6
79
80 /*
81  * Array with one entry per ordinal defining the maximum amount
82  * of time the chip could take to return the result.  The ordinal
83  * designation of short, medium or long is defined in a table in
84  * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
85  * values of the SHORT, MEDIUM, and LONG durations are retrieved
86  * from the chip during initialization with a call to tpm_get_timeouts.
87  */
88 static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
89         TPM_UNDEFINED,          /* 0 */
90         TPM_UNDEFINED,
91         TPM_UNDEFINED,
92         TPM_UNDEFINED,
93         TPM_UNDEFINED,
94         TPM_UNDEFINED,          /* 5 */
95         TPM_UNDEFINED,
96         TPM_UNDEFINED,
97         TPM_UNDEFINED,
98         TPM_UNDEFINED,
99         TPM_SHORT,              /* 10 */
100         TPM_SHORT,
101 };
102
103 static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
104         TPM_UNDEFINED,          /* 0 */
105         TPM_UNDEFINED,
106         TPM_UNDEFINED,
107         TPM_UNDEFINED,
108         TPM_UNDEFINED,
109         TPM_UNDEFINED,          /* 5 */
110         TPM_UNDEFINED,
111         TPM_UNDEFINED,
112         TPM_UNDEFINED,
113         TPM_UNDEFINED,
114         TPM_SHORT,              /* 10 */
115         TPM_SHORT,
116         TPM_MEDIUM,
117         TPM_LONG,
118         TPM_LONG,
119         TPM_MEDIUM,             /* 15 */
120         TPM_SHORT,
121         TPM_SHORT,
122         TPM_MEDIUM,
123         TPM_LONG,
124         TPM_SHORT,              /* 20 */
125         TPM_SHORT,
126         TPM_MEDIUM,
127         TPM_MEDIUM,
128         TPM_MEDIUM,
129         TPM_SHORT,              /* 25 */
130         TPM_SHORT,
131         TPM_MEDIUM,
132         TPM_SHORT,
133         TPM_SHORT,
134         TPM_MEDIUM,             /* 30 */
135         TPM_LONG,
136         TPM_MEDIUM,
137         TPM_SHORT,
138         TPM_SHORT,
139         TPM_SHORT,              /* 35 */
140         TPM_MEDIUM,
141         TPM_MEDIUM,
142         TPM_UNDEFINED,
143         TPM_UNDEFINED,
144         TPM_MEDIUM,             /* 40 */
145         TPM_LONG,
146         TPM_MEDIUM,
147         TPM_SHORT,
148         TPM_SHORT,
149         TPM_SHORT,              /* 45 */
150         TPM_SHORT,
151         TPM_SHORT,
152         TPM_SHORT,
153         TPM_LONG,
154         TPM_MEDIUM,             /* 50 */
155         TPM_MEDIUM,
156         TPM_UNDEFINED,
157         TPM_UNDEFINED,
158         TPM_UNDEFINED,
159         TPM_UNDEFINED,          /* 55 */
160         TPM_UNDEFINED,
161         TPM_UNDEFINED,
162         TPM_UNDEFINED,
163         TPM_UNDEFINED,
164         TPM_MEDIUM,             /* 60 */
165         TPM_MEDIUM,
166         TPM_MEDIUM,
167         TPM_SHORT,
168         TPM_SHORT,
169         TPM_MEDIUM,             /* 65 */
170         TPM_UNDEFINED,
171         TPM_UNDEFINED,
172         TPM_UNDEFINED,
173         TPM_UNDEFINED,
174         TPM_SHORT,              /* 70 */
175         TPM_SHORT,
176         TPM_UNDEFINED,
177         TPM_UNDEFINED,
178         TPM_UNDEFINED,
179         TPM_UNDEFINED,          /* 75 */
180         TPM_UNDEFINED,
181         TPM_UNDEFINED,
182         TPM_UNDEFINED,
183         TPM_UNDEFINED,
184         TPM_LONG,               /* 80 */
185         TPM_UNDEFINED,
186         TPM_MEDIUM,
187         TPM_LONG,
188         TPM_SHORT,
189         TPM_UNDEFINED,          /* 85 */
190         TPM_UNDEFINED,
191         TPM_UNDEFINED,
192         TPM_UNDEFINED,
193         TPM_UNDEFINED,
194         TPM_SHORT,              /* 90 */
195         TPM_SHORT,
196         TPM_SHORT,
197         TPM_SHORT,
198         TPM_SHORT,
199         TPM_UNDEFINED,          /* 95 */
200         TPM_UNDEFINED,
201         TPM_UNDEFINED,
202         TPM_UNDEFINED,
203         TPM_UNDEFINED,
204         TPM_MEDIUM,             /* 100 */
205         TPM_SHORT,
206         TPM_SHORT,
207         TPM_UNDEFINED,
208         TPM_UNDEFINED,
209         TPM_UNDEFINED,          /* 105 */
210         TPM_UNDEFINED,
211         TPM_UNDEFINED,
212         TPM_UNDEFINED,
213         TPM_UNDEFINED,
214         TPM_SHORT,              /* 110 */
215         TPM_SHORT,
216         TPM_SHORT,
217         TPM_SHORT,
218         TPM_SHORT,
219         TPM_SHORT,              /* 115 */
220         TPM_SHORT,
221         TPM_SHORT,
222         TPM_UNDEFINED,
223         TPM_UNDEFINED,
224         TPM_LONG,               /* 120 */
225         TPM_LONG,
226         TPM_MEDIUM,
227         TPM_UNDEFINED,
228         TPM_SHORT,
229         TPM_SHORT,              /* 125 */
230         TPM_SHORT,
231         TPM_LONG,
232         TPM_SHORT,
233         TPM_SHORT,
234         TPM_SHORT,              /* 130 */
235         TPM_MEDIUM,
236         TPM_UNDEFINED,
237         TPM_SHORT,
238         TPM_MEDIUM,
239         TPM_UNDEFINED,          /* 135 */
240         TPM_UNDEFINED,
241         TPM_UNDEFINED,
242         TPM_UNDEFINED,
243         TPM_UNDEFINED,
244         TPM_SHORT,              /* 140 */
245         TPM_SHORT,
246         TPM_UNDEFINED,
247         TPM_UNDEFINED,
248         TPM_UNDEFINED,
249         TPM_UNDEFINED,          /* 145 */
250         TPM_UNDEFINED,
251         TPM_UNDEFINED,
252         TPM_UNDEFINED,
253         TPM_UNDEFINED,
254         TPM_SHORT,              /* 150 */
255         TPM_MEDIUM,
256         TPM_MEDIUM,
257         TPM_SHORT,
258         TPM_SHORT,
259         TPM_UNDEFINED,          /* 155 */
260         TPM_UNDEFINED,
261         TPM_UNDEFINED,
262         TPM_UNDEFINED,
263         TPM_UNDEFINED,
264         TPM_SHORT,              /* 160 */
265         TPM_SHORT,
266         TPM_SHORT,
267         TPM_SHORT,
268         TPM_UNDEFINED,
269         TPM_UNDEFINED,          /* 165 */
270         TPM_UNDEFINED,
271         TPM_UNDEFINED,
272         TPM_UNDEFINED,
273         TPM_UNDEFINED,
274         TPM_LONG,               /* 170 */
275         TPM_UNDEFINED,
276         TPM_UNDEFINED,
277         TPM_UNDEFINED,
278         TPM_UNDEFINED,
279         TPM_UNDEFINED,          /* 175 */
280         TPM_UNDEFINED,
281         TPM_UNDEFINED,
282         TPM_UNDEFINED,
283         TPM_UNDEFINED,
284         TPM_MEDIUM,             /* 180 */
285         TPM_SHORT,
286         TPM_MEDIUM,
287         TPM_MEDIUM,
288         TPM_MEDIUM,
289         TPM_MEDIUM,             /* 185 */
290         TPM_SHORT,
291         TPM_UNDEFINED,
292         TPM_UNDEFINED,
293         TPM_UNDEFINED,
294         TPM_UNDEFINED,          /* 190 */
295         TPM_UNDEFINED,
296         TPM_UNDEFINED,
297         TPM_UNDEFINED,
298         TPM_UNDEFINED,
299         TPM_UNDEFINED,          /* 195 */
300         TPM_UNDEFINED,
301         TPM_UNDEFINED,
302         TPM_UNDEFINED,
303         TPM_UNDEFINED,
304         TPM_SHORT,              /* 200 */
305         TPM_UNDEFINED,
306         TPM_UNDEFINED,
307         TPM_UNDEFINED,
308         TPM_SHORT,
309         TPM_SHORT,              /* 205 */
310         TPM_SHORT,
311         TPM_SHORT,
312         TPM_SHORT,
313         TPM_SHORT,
314         TPM_MEDIUM,             /* 210 */
315         TPM_UNDEFINED,
316         TPM_MEDIUM,
317         TPM_MEDIUM,
318         TPM_MEDIUM,
319         TPM_UNDEFINED,          /* 215 */
320         TPM_MEDIUM,
321         TPM_UNDEFINED,
322         TPM_UNDEFINED,
323         TPM_SHORT,
324         TPM_SHORT,              /* 220 */
325         TPM_SHORT,
326         TPM_SHORT,
327         TPM_SHORT,
328         TPM_SHORT,
329         TPM_UNDEFINED,          /* 225 */
330         TPM_UNDEFINED,
331         TPM_UNDEFINED,
332         TPM_UNDEFINED,
333         TPM_UNDEFINED,
334         TPM_SHORT,              /* 230 */
335         TPM_LONG,
336         TPM_MEDIUM,
337         TPM_UNDEFINED,
338         TPM_UNDEFINED,
339         TPM_UNDEFINED,          /* 235 */
340         TPM_UNDEFINED,
341         TPM_UNDEFINED,
342         TPM_UNDEFINED,
343         TPM_UNDEFINED,
344         TPM_SHORT,              /* 240 */
345         TPM_UNDEFINED,
346         TPM_MEDIUM,
347 };
348
349 /* Returns max number of milliseconds to wait */
350 static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
351                 u32 ordinal)
352 {
353         int duration_idx = TPM_UNDEFINED;
354         int duration = 0;
355
356         if (ordinal < TPM_MAX_ORDINAL) {
357                 duration_idx = tpm_ordinal_duration[ordinal];
358         } else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
359                         TPM_MAX_PROTECTED_ORDINAL) {
360                 duration_idx = tpm_protected_ordinal_duration[
361                                 ordinal & TPM_PROTECTED_ORDINAL_MASK];
362         }
363
364         if (duration_idx != TPM_UNDEFINED)
365                 duration = chip->vendor.duration[duration_idx];
366
367         if (duration <= 0)
368                 return 2 * 60 * HZ; /* Two minutes timeout */
369         else
370                 return duration;
371 }
372
373 static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
374 {
375         ssize_t rc;
376         u32 count, ordinal;
377         unsigned long start, stop;
378
379         struct tpm_chip *chip = &g_chip;
380
381         /* switch endianess: big->little */
382         count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
383         ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
384
385         if (count == 0) {
386                 error("no data\n");
387                 return -ENODATA;
388         }
389         if (count > bufsiz) {
390                 error("invalid count value %x %zx\n", count, bufsiz);
391                 return -E2BIG;
392         }
393
394         rc = chip->vendor.send(chip, (u8 *)buf, count);
395         if (rc < 0) {
396                 error("tpm_transmit: tpm_send: error %zd\n", rc);
397                 goto out;
398         }
399
400         if (chip->vendor.irq)
401                 goto out_recv;
402
403         start = get_timer(0);
404         stop = tpm_calc_ordinal_duration(chip, ordinal);
405         do {
406                 debug("waiting for status...\n");
407                 u8 status = chip->vendor.status(chip);
408                 if ((status & chip->vendor.req_complete_mask) ==
409                     chip->vendor.req_complete_val) {
410                         debug("...got it;\n");
411                         goto out_recv;
412                 }
413
414                 if ((status == chip->vendor.req_canceled)) {
415                         error("Operation Canceled\n");
416                         rc = -ECANCELED;
417                         goto out;
418                 }
419                 udelay(TPM_TIMEOUT * 1000);
420         } while (get_timer(start) < stop);
421
422         chip->vendor.cancel(chip);
423         error("Operation Timed out\n");
424         rc = -ETIME;
425         goto out;
426
427 out_recv:
428         debug("out_recv: reading response...\n");
429         rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
430         if (rc < 0)
431                 error("tpm_transmit: tpm_recv: error %zd\n", rc);
432
433 out:
434         return rc;
435 }
436
437 static int tpm_open(uint32_t dev_addr)
438 {
439         int rc;
440         if (g_chip.is_open)
441                 return -EBUSY;
442         rc = tpm_vendor_init(dev_addr);
443         if (rc < 0)
444                 g_chip.is_open = 0;
445         return rc;
446 }
447
448 static void tpm_close(void)
449 {
450         if (g_chip.is_open) {
451                 tpm_vendor_cleanup(&g_chip);
452                 g_chip.is_open = 0;
453         }
454 }
455
456 static int tpm_select(void)
457 {
458         int ret;
459
460         tpm.old_bus = i2c_get_bus_num();
461         if (tpm.old_bus != tpm.i2c_bus) {
462                 ret = i2c_set_bus_num(tpm.i2c_bus);
463                 if (ret) {
464                         debug("%s: Fail to set i2c bus %d\n", __func__,
465                               tpm.i2c_bus);
466                         return -1;
467                 }
468         }
469         return 0;
470 }
471
472 static int tpm_deselect(void)
473 {
474         int ret;
475
476         if (tpm.old_bus != i2c_get_bus_num()) {
477                 ret = i2c_set_bus_num(tpm.old_bus);
478                 if (ret) {
479                         debug("%s: Fail to restore i2c bus %d\n",
480                               __func__, tpm.old_bus);
481                         return -1;
482                 }
483         }
484         tpm.old_bus = -1;
485         return 0;
486 }
487
488 /**
489  * Decode TPM configuration.
490  *
491  * @param dev   Returns a configuration of TPM device
492  * @return 0 if ok, -1 on error
493  */
494 static int tpm_decode_config(struct tpm *dev)
495 {
496 #ifdef CONFIG_OF_CONTROL
497         const void *blob = gd->fdt_blob;
498         int node, parent;
499         int i2c_bus;
500
501         node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
502         if (node < 0) {
503                 node = fdtdec_next_compatible(blob, 0,
504                                 COMPAT_INFINEON_SLB9645_TPM);
505         }
506         if (node < 0) {
507                 debug("%s: Node not found\n", __func__);
508                 return -1;
509         }
510         parent = fdt_parent_offset(blob, node);
511         if (parent < 0) {
512                 debug("%s: Cannot find node parent\n", __func__);
513                 return -1;
514         }
515         i2c_bus = i2c_get_bus_num_fdt(parent);
516         if (i2c_bus < 0)
517                 return -1;
518         dev->i2c_bus = i2c_bus;
519         dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
520 #else
521         dev->i2c_bus = CONFIG_TPM_TIS_I2C_BUS_NUMBER;
522         dev->slave_addr = CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS;
523 #endif
524         return 0;
525 }
526
527 struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
528 {
529         struct tpm_chip *chip;
530
531         /* Driver specific per-device data */
532         chip = &g_chip;
533         memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
534         chip->is_open = 1;
535
536         return chip;
537 }
538
539 int tis_init(void)
540 {
541         if (tpm.inited)
542                 return 0;
543
544         if (tpm_decode_config(&tpm))
545                 return -1;
546
547         if (tpm_select())
548                 return -1;
549
550         /*
551          * Probe TPM twice; the first probing might fail because TPM is asleep,
552          * and the probing can wake up TPM.
553          */
554         if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
555                 debug("%s: fail to probe i2c addr 0x%x\n", __func__,
556                       tpm.slave_addr);
557                 return -1;
558         }
559
560         tpm_deselect();
561
562         tpm.inited = 1;
563
564         return 0;
565 }
566
567 int tis_open(void)
568 {
569         int rc;
570
571         if (!tpm.inited)
572                 return -1;
573
574         if (tpm_select())
575                 return -1;
576
577         rc = tpm_open(tpm.slave_addr);
578
579         tpm_deselect();
580
581         return rc;
582 }
583
584 int tis_close(void)
585 {
586         if (!tpm.inited)
587                 return -1;
588
589         if (tpm_select())
590                 return -1;
591
592         tpm_close();
593
594         tpm_deselect();
595
596         return 0;
597 }
598
599 int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
600                 uint8_t *recvbuf, size_t *rbuf_len)
601 {
602         int len;
603         uint8_t buf[4096];
604
605         if (!tpm.inited)
606                 return -1;
607
608         if (sizeof(buf) < sbuf_size)
609                 return -1;
610
611         memcpy(buf, sendbuf, sbuf_size);
612
613         if (tpm_select())
614                 return -1;
615
616         len = tpm_transmit(buf, sbuf_size);
617
618         tpm_deselect();
619
620         if (len < 10) {
621                 *rbuf_len = 0;
622                 return -1;
623         }
624
625         memcpy(recvbuf, buf, len);
626         *rbuf_len = len;
627
628         return 0;
629 }