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