Commit 4cd7b7834c19903504d76542fb0240cde34853f5

Authored by Simon Glass
1 parent 07470d6f5b

tpm: Move the I2C TPM code into one file

The current Infineon I2C TPM driver is written in two parts, intended to
support use with other I2C devices. However we don't have any users and the
Atmel I2C TPM device does not use this file.

We should simplify this and remove the unused abstration. As a first step,
move the code into one file.

Also the name tpm_private.h suggests that the header file is generic to all
TPMs but it is not. Rename it indicate that it relates only to this driver

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heiko Schocher <hs@denx.de>

Showing 5 changed files with 667 additions and 735 deletions Side-by-side Diff

drivers/tpm/Makefile
... ... @@ -3,9 +3,7 @@
3 3 # SPDX-License-Identifier: GPL-2.0+
4 4 #
5 5  
6   -# TODO: Merge tpm_tis_lpc.c with tpm.c
7 6 obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o
8   -obj-$(CONFIG_TPM_TIS_I2C) += tpm.o
9 7 obj-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
10 8 obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
11 9 obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o
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   -}
drivers/tpm/tpm_private.h
1   -/*
2   - * Copyright (C) 2011 Infineon Technologies
3   - *
4   - * Authors:
5   - * Peter Huewe <huewe.external@infineon.com>
6   - *
7   - * Version: 2.1.1
8   - *
9   - * Description:
10   - * Device driver for TCG/TCPA TPM (trusted platform module).
11   - * Specifications at www.trustedcomputinggroup.org
12   - *
13   - * It is based on the Linux kernel driver tpm.c from Leendert van
14   - * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
15   - *
16   - *
17   - * See file CREDITS for list of people who contributed to this
18   - * project.
19   - *
20   - * This program is free software; you can redistribute it and/or
21   - * modify it under the terms of the GNU General Public License as
22   - * published by the Free Software Foundation, version 2 of the
23   - * License.
24   - *
25   - * This program is distributed in the hope that it will be useful,
26   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
27   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28   - * GNU General Public License for more details.
29   - *
30   - * You should have received a copy of the GNU General Public License
31   - * along with this program; if not, write to the Free Software
32   - * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33   - * MA 02111-1307 USA
34   - */
35   -
36   -#ifndef _TPM_PRIVATE_H_
37   -#define _TPM_PRIVATE_H_
38   -
39   -#include <linux/compiler.h>
40   -#include <linux/types.h>
41   -
42   -enum tpm_timeout {
43   - TPM_TIMEOUT = 5, /* msecs */
44   -};
45   -
46   -/* Size of external transmit buffer (used in tpm_transmit)*/
47   -#define TPM_BUFSIZE 4096
48   -
49   -/* Index of Count field in TPM response buffer */
50   -#define TPM_RSP_SIZE_BYTE 2
51   -#define TPM_RSP_RC_BYTE 6
52   -
53   -struct tpm_chip;
54   -
55   -struct tpm_vendor_specific {
56   - const u8 req_complete_mask;
57   - const u8 req_complete_val;
58   - const u8 req_canceled;
59   - int irq;
60   - int (*recv) (struct tpm_chip *, u8 *, size_t);
61   - int (*send) (struct tpm_chip *, u8 *, size_t);
62   - void (*cancel) (struct tpm_chip *);
63   - u8(*status) (struct tpm_chip *);
64   - int locality;
65   - unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
66   - unsigned long duration[3]; /* msec */
67   -};
68   -
69   -struct tpm_chip {
70   - int is_open;
71   - struct tpm_vendor_specific vendor;
72   -};
73   -
74   -struct tpm_input_header {
75   - __be16 tag;
76   - __be32 length;
77   - __be32 ordinal;
78   -} __packed;
79   -
80   -struct tpm_output_header {
81   - __be16 tag;
82   - __be32 length;
83   - __be32 return_code;
84   -} __packed;
85   -
86   -struct timeout_t {
87   - __be32 a;
88   - __be32 b;
89   - __be32 c;
90   - __be32 d;
91   -} __packed;
92   -
93   -struct duration_t {
94   - __be32 tpm_short;
95   - __be32 tpm_medium;
96   - __be32 tpm_long;
97   -} __packed;
98   -
99   -union cap_t {
100   - struct timeout_t timeout;
101   - struct duration_t duration;
102   -};
103   -
104   -struct tpm_getcap_params_in {
105   - __be32 cap;
106   - __be32 subcap_size;
107   - __be32 subcap;
108   -} __packed;
109   -
110   -struct tpm_getcap_params_out {
111   - __be32 cap_size;
112   - union cap_t cap;
113   -} __packed;
114   -
115   -union tpm_cmd_header {
116   - struct tpm_input_header in;
117   - struct tpm_output_header out;
118   -};
119   -
120   -union tpm_cmd_params {
121   - struct tpm_getcap_params_out getcap_out;
122   - struct tpm_getcap_params_in getcap_in;
123   -};
124   -
125   -struct tpm_cmd_t {
126   - union tpm_cmd_header header;
127   - union tpm_cmd_params params;
128   -} __packed;
129   -
130   -struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
131   -
132   -struct udevice;
133   -int tpm_vendor_init(struct udevice *dev);
134   -
135   -void tpm_vendor_cleanup(struct tpm_chip *chip);
136   -
137   -
138   -#endif
drivers/tpm/tpm_tis_i2c.c
... ... @@ -30,7 +30,7 @@
30 30 #include <linux/types.h>
31 31 #include <linux/unaligned/be_byteshift.h>
32 32  
33   -#include "tpm_private.h"
  33 +#include "tpm_tis_i2c.h"
34 34  
35 35 DECLARE_GLOBAL_DATA_PTR;
36 36  
... ... @@ -95,6 +95,304 @@
95 95 #define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
96 96 #define TPM_DID_VID(l) (0x0006 | ((l) << 4))
97 97  
  98 +enum tpm_duration {
  99 + TPM_SHORT = 0,
  100 + TPM_MEDIUM = 1,
  101 + TPM_LONG = 2,
  102 + TPM_UNDEFINED,
  103 +};
  104 +
  105 +/* Extended error numbers from linux (see errno.h) */
  106 +#define ECANCELED 125 /* Operation Canceled */
  107 +
  108 +/* Timer frequency. Corresponds to msec timer resolution*/
  109 +#define HZ 1000
  110 +
  111 +#define TPM_MAX_ORDINAL 243
  112 +#define TPM_MAX_PROTECTED_ORDINAL 12
  113 +#define TPM_PROTECTED_ORDINAL_MASK 0xFF
  114 +
  115 +#define TPM_CMD_COUNT_BYTE 2
  116 +#define TPM_CMD_ORDINAL_BYTE 6
  117 +
  118 +/*
  119 + * Array with one entry per ordinal defining the maximum amount
  120 + * of time the chip could take to return the result. The ordinal
  121 + * designation of short, medium or long is defined in a table in
  122 + * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
  123 + * values of the SHORT, MEDIUM, and LONG durations are retrieved
  124 + * from the chip during initialization with a call to tpm_get_timeouts.
  125 + */
  126 +static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
  127 + TPM_UNDEFINED, /* 0 */
  128 + TPM_UNDEFINED,
  129 + TPM_UNDEFINED,
  130 + TPM_UNDEFINED,
  131 + TPM_UNDEFINED,
  132 + TPM_UNDEFINED, /* 5 */
  133 + TPM_UNDEFINED,
  134 + TPM_UNDEFINED,
  135 + TPM_UNDEFINED,
  136 + TPM_UNDEFINED,
  137 + TPM_SHORT, /* 10 */
  138 + TPM_SHORT,
  139 +};
  140 +
  141 +static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
  142 + TPM_UNDEFINED, /* 0 */
  143 + TPM_UNDEFINED,
  144 + TPM_UNDEFINED,
  145 + TPM_UNDEFINED,
  146 + TPM_UNDEFINED,
  147 + TPM_UNDEFINED, /* 5 */
  148 + TPM_UNDEFINED,
  149 + TPM_UNDEFINED,
  150 + TPM_UNDEFINED,
  151 + TPM_UNDEFINED,
  152 + TPM_SHORT, /* 10 */
  153 + TPM_SHORT,
  154 + TPM_MEDIUM,
  155 + TPM_LONG,
  156 + TPM_LONG,
  157 + TPM_MEDIUM, /* 15 */
  158 + TPM_SHORT,
  159 + TPM_SHORT,
  160 + TPM_MEDIUM,
  161 + TPM_LONG,
  162 + TPM_SHORT, /* 20 */
  163 + TPM_SHORT,
  164 + TPM_MEDIUM,
  165 + TPM_MEDIUM,
  166 + TPM_MEDIUM,
  167 + TPM_SHORT, /* 25 */
  168 + TPM_SHORT,
  169 + TPM_MEDIUM,
  170 + TPM_SHORT,
  171 + TPM_SHORT,
  172 + TPM_MEDIUM, /* 30 */
  173 + TPM_LONG,
  174 + TPM_MEDIUM,
  175 + TPM_SHORT,
  176 + TPM_SHORT,
  177 + TPM_SHORT, /* 35 */
  178 + TPM_MEDIUM,
  179 + TPM_MEDIUM,
  180 + TPM_UNDEFINED,
  181 + TPM_UNDEFINED,
  182 + TPM_MEDIUM, /* 40 */
  183 + TPM_LONG,
  184 + TPM_MEDIUM,
  185 + TPM_SHORT,
  186 + TPM_SHORT,
  187 + TPM_SHORT, /* 45 */
  188 + TPM_SHORT,
  189 + TPM_SHORT,
  190 + TPM_SHORT,
  191 + TPM_LONG,
  192 + TPM_MEDIUM, /* 50 */
  193 + TPM_MEDIUM,
  194 + TPM_UNDEFINED,
  195 + TPM_UNDEFINED,
  196 + TPM_UNDEFINED,
  197 + TPM_UNDEFINED, /* 55 */
  198 + TPM_UNDEFINED,
  199 + TPM_UNDEFINED,
  200 + TPM_UNDEFINED,
  201 + TPM_UNDEFINED,
  202 + TPM_MEDIUM, /* 60 */
  203 + TPM_MEDIUM,
  204 + TPM_MEDIUM,
  205 + TPM_SHORT,
  206 + TPM_SHORT,
  207 + TPM_MEDIUM, /* 65 */
  208 + TPM_UNDEFINED,
  209 + TPM_UNDEFINED,
  210 + TPM_UNDEFINED,
  211 + TPM_UNDEFINED,
  212 + TPM_SHORT, /* 70 */
  213 + TPM_SHORT,
  214 + TPM_UNDEFINED,
  215 + TPM_UNDEFINED,
  216 + TPM_UNDEFINED,
  217 + TPM_UNDEFINED, /* 75 */
  218 + TPM_UNDEFINED,
  219 + TPM_UNDEFINED,
  220 + TPM_UNDEFINED,
  221 + TPM_UNDEFINED,
  222 + TPM_LONG, /* 80 */
  223 + TPM_UNDEFINED,
  224 + TPM_MEDIUM,
  225 + TPM_LONG,
  226 + TPM_SHORT,
  227 + TPM_UNDEFINED, /* 85 */
  228 + TPM_UNDEFINED,
  229 + TPM_UNDEFINED,
  230 + TPM_UNDEFINED,
  231 + TPM_UNDEFINED,
  232 + TPM_SHORT, /* 90 */
  233 + TPM_SHORT,
  234 + TPM_SHORT,
  235 + TPM_SHORT,
  236 + TPM_SHORT,
  237 + TPM_UNDEFINED, /* 95 */
  238 + TPM_UNDEFINED,
  239 + TPM_UNDEFINED,
  240 + TPM_UNDEFINED,
  241 + TPM_UNDEFINED,
  242 + TPM_MEDIUM, /* 100 */
  243 + TPM_SHORT,
  244 + TPM_SHORT,
  245 + TPM_UNDEFINED,
  246 + TPM_UNDEFINED,
  247 + TPM_UNDEFINED, /* 105 */
  248 + TPM_UNDEFINED,
  249 + TPM_UNDEFINED,
  250 + TPM_UNDEFINED,
  251 + TPM_UNDEFINED,
  252 + TPM_SHORT, /* 110 */
  253 + TPM_SHORT,
  254 + TPM_SHORT,
  255 + TPM_SHORT,
  256 + TPM_SHORT,
  257 + TPM_SHORT, /* 115 */
  258 + TPM_SHORT,
  259 + TPM_SHORT,
  260 + TPM_UNDEFINED,
  261 + TPM_UNDEFINED,
  262 + TPM_LONG, /* 120 */
  263 + TPM_LONG,
  264 + TPM_MEDIUM,
  265 + TPM_UNDEFINED,
  266 + TPM_SHORT,
  267 + TPM_SHORT, /* 125 */
  268 + TPM_SHORT,
  269 + TPM_LONG,
  270 + TPM_SHORT,
  271 + TPM_SHORT,
  272 + TPM_SHORT, /* 130 */
  273 + TPM_MEDIUM,
  274 + TPM_UNDEFINED,
  275 + TPM_SHORT,
  276 + TPM_MEDIUM,
  277 + TPM_UNDEFINED, /* 135 */
  278 + TPM_UNDEFINED,
  279 + TPM_UNDEFINED,
  280 + TPM_UNDEFINED,
  281 + TPM_UNDEFINED,
  282 + TPM_SHORT, /* 140 */
  283 + TPM_SHORT,
  284 + TPM_UNDEFINED,
  285 + TPM_UNDEFINED,
  286 + TPM_UNDEFINED,
  287 + TPM_UNDEFINED, /* 145 */
  288 + TPM_UNDEFINED,
  289 + TPM_UNDEFINED,
  290 + TPM_UNDEFINED,
  291 + TPM_UNDEFINED,
  292 + TPM_SHORT, /* 150 */
  293 + TPM_MEDIUM,
  294 + TPM_MEDIUM,
  295 + TPM_SHORT,
  296 + TPM_SHORT,
  297 + TPM_UNDEFINED, /* 155 */
  298 + TPM_UNDEFINED,
  299 + TPM_UNDEFINED,
  300 + TPM_UNDEFINED,
  301 + TPM_UNDEFINED,
  302 + TPM_SHORT, /* 160 */
  303 + TPM_SHORT,
  304 + TPM_SHORT,
  305 + TPM_SHORT,
  306 + TPM_UNDEFINED,
  307 + TPM_UNDEFINED, /* 165 */
  308 + TPM_UNDEFINED,
  309 + TPM_UNDEFINED,
  310 + TPM_UNDEFINED,
  311 + TPM_UNDEFINED,
  312 + TPM_LONG, /* 170 */
  313 + TPM_UNDEFINED,
  314 + TPM_UNDEFINED,
  315 + TPM_UNDEFINED,
  316 + TPM_UNDEFINED,
  317 + TPM_UNDEFINED, /* 175 */
  318 + TPM_UNDEFINED,
  319 + TPM_UNDEFINED,
  320 + TPM_UNDEFINED,
  321 + TPM_UNDEFINED,
  322 + TPM_MEDIUM, /* 180 */
  323 + TPM_SHORT,
  324 + TPM_MEDIUM,
  325 + TPM_MEDIUM,
  326 + TPM_MEDIUM,
  327 + TPM_MEDIUM, /* 185 */
  328 + TPM_SHORT,
  329 + TPM_UNDEFINED,
  330 + TPM_UNDEFINED,
  331 + TPM_UNDEFINED,
  332 + TPM_UNDEFINED, /* 190 */
  333 + TPM_UNDEFINED,
  334 + TPM_UNDEFINED,
  335 + TPM_UNDEFINED,
  336 + TPM_UNDEFINED,
  337 + TPM_UNDEFINED, /* 195 */
  338 + TPM_UNDEFINED,
  339 + TPM_UNDEFINED,
  340 + TPM_UNDEFINED,
  341 + TPM_UNDEFINED,
  342 + TPM_SHORT, /* 200 */
  343 + TPM_UNDEFINED,
  344 + TPM_UNDEFINED,
  345 + TPM_UNDEFINED,
  346 + TPM_SHORT,
  347 + TPM_SHORT, /* 205 */
  348 + TPM_SHORT,
  349 + TPM_SHORT,
  350 + TPM_SHORT,
  351 + TPM_SHORT,
  352 + TPM_MEDIUM, /* 210 */
  353 + TPM_UNDEFINED,
  354 + TPM_MEDIUM,
  355 + TPM_MEDIUM,
  356 + TPM_MEDIUM,
  357 + TPM_UNDEFINED, /* 215 */
  358 + TPM_MEDIUM,
  359 + TPM_UNDEFINED,
  360 + TPM_UNDEFINED,
  361 + TPM_SHORT,
  362 + TPM_SHORT, /* 220 */
  363 + TPM_SHORT,
  364 + TPM_SHORT,
  365 + TPM_SHORT,
  366 + TPM_SHORT,
  367 + TPM_UNDEFINED, /* 225 */
  368 + TPM_UNDEFINED,
  369 + TPM_UNDEFINED,
  370 + TPM_UNDEFINED,
  371 + TPM_UNDEFINED,
  372 + TPM_SHORT, /* 230 */
  373 + TPM_LONG,
  374 + TPM_MEDIUM,
  375 + TPM_UNDEFINED,
  376 + TPM_UNDEFINED,
  377 + TPM_UNDEFINED, /* 235 */
  378 + TPM_UNDEFINED,
  379 + TPM_UNDEFINED,
  380 + TPM_UNDEFINED,
  381 + TPM_UNDEFINED,
  382 + TPM_SHORT, /* 240 */
  383 + TPM_UNDEFINED,
  384 + TPM_MEDIUM,
  385 +};
  386 +
  387 +/* TPM configuration */
  388 +struct tpm {
  389 + struct udevice *dev;
  390 + char inited;
  391 +} tpm;
  392 +
  393 +/* Global structure for tpm chip data */
  394 +static struct tpm_chip g_chip;
  395 +
98 396 /* Structure to store I2C TPM specific stuff */
99 397 struct tpm_dev {
100 398 struct udevice *dev;
... ... @@ -594,5 +892,253 @@
594 892 void tpm_vendor_cleanup(struct tpm_chip *chip)
595 893 {
596 894 release_locality(chip, chip->vendor.locality, 1);
  895 +}
  896 +
  897 +/* Returns max number of milliseconds to wait */
  898 +static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  899 + u32 ordinal)
  900 +{
  901 + int duration_idx = TPM_UNDEFINED;
  902 + int duration = 0;
  903 +
  904 + if (ordinal < TPM_MAX_ORDINAL) {
  905 + duration_idx = tpm_ordinal_duration[ordinal];
  906 + } else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
  907 + TPM_MAX_PROTECTED_ORDINAL) {
  908 + duration_idx = tpm_protected_ordinal_duration[
  909 + ordinal & TPM_PROTECTED_ORDINAL_MASK];
  910 + }
  911 +
  912 + if (duration_idx != TPM_UNDEFINED)
  913 + duration = chip->vendor.duration[duration_idx];
  914 +
  915 + if (duration <= 0)
  916 + return 2 * 60 * HZ; /* Two minutes timeout */
  917 + else
  918 + return duration;
  919 +}
  920 +
  921 +static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  922 +{
  923 + int rc;
  924 + u32 count, ordinal;
  925 + unsigned long start, stop;
  926 +
  927 + struct tpm_chip *chip = &g_chip;
  928 +
  929 + /* switch endianess: big->little */
  930 + count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
  931 + ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
  932 +
  933 + if (count == 0) {
  934 + error("no data\n");
  935 + return -ENODATA;
  936 + }
  937 + if (count > bufsiz) {
  938 + error("invalid count value %x %zx\n", count, bufsiz);
  939 + return -E2BIG;
  940 + }
  941 +
  942 + debug("Calling send\n");
  943 + rc = chip->vendor.send(chip, (u8 *)buf, count);
  944 + debug(" ... done calling send\n");
  945 + if (rc < 0) {
  946 + error("tpm_transmit: tpm_send: error %d\n", rc);
  947 + goto out;
  948 + }
  949 +
  950 + if (chip->vendor.irq)
  951 + goto out_recv;
  952 +
  953 + start = get_timer(0);
  954 + stop = tpm_calc_ordinal_duration(chip, ordinal);
  955 + do {
  956 + debug("waiting for status... %ld %ld\n", start, stop);
  957 + u8 status = chip->vendor.status(chip);
  958 + if ((status & chip->vendor.req_complete_mask) ==
  959 + chip->vendor.req_complete_val) {
  960 + debug("...got it;\n");
  961 + goto out_recv;
  962 + }
  963 +
  964 + if (status == chip->vendor.req_canceled) {
  965 + error("Operation Canceled\n");
  966 + rc = -ECANCELED;
  967 + goto out;
  968 + }
  969 + udelay(TPM_TIMEOUT * 1000);
  970 + } while (get_timer(start) < stop);
  971 +
  972 + chip->vendor.cancel(chip);
  973 + error("Operation Timed out\n");
  974 + rc = -ETIME;
  975 + goto out;
  976 +
  977 +out_recv:
  978 + debug("out_recv: reading response...\n");
  979 + rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
  980 + if (rc < 0)
  981 + error("tpm_transmit: tpm_recv: error %d\n", rc);
  982 +
  983 +out:
  984 + return rc;
  985 +}
  986 +
  987 +static int tpm_open_dev(struct udevice *dev)
  988 +{
  989 + int rc;
  990 +
  991 + debug("%s: start\n", __func__);
  992 + if (g_chip.is_open)
  993 + return -EBUSY;
  994 + rc = tpm_vendor_init(dev);
  995 + if (rc < 0)
  996 + g_chip.is_open = 0;
  997 + return rc;
  998 +}
  999 +
  1000 +static void tpm_close(void)
  1001 +{
  1002 + if (g_chip.is_open) {
  1003 + tpm_vendor_cleanup(&g_chip);
  1004 + g_chip.is_open = 0;
  1005 + }
  1006 +}
  1007 +
  1008 +/**
  1009 + * Decode TPM configuration.
  1010 + *
  1011 + * @param dev Returns a configuration of TPM device
  1012 + * @return 0 if ok, -1 on error
  1013 + */
  1014 +static int tpm_decode_config(struct tpm *dev)
  1015 +{
  1016 + const void *blob = gd->fdt_blob;
  1017 + struct udevice *bus;
  1018 + int chip_addr;
  1019 + int parent;
  1020 + int node;
  1021 + int ret;
  1022 +
  1023 + node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
  1024 + if (node < 0) {
  1025 + node = fdtdec_next_compatible(blob, 0,
  1026 + COMPAT_INFINEON_SLB9645_TPM);
  1027 + }
  1028 + if (node < 0) {
  1029 + debug("%s: Node not found\n", __func__);
  1030 + return -1;
  1031 + }
  1032 + parent = fdt_parent_offset(blob, node);
  1033 + if (parent < 0) {
  1034 + debug("%s: Cannot find node parent\n", __func__);
  1035 + return -1;
  1036 + }
  1037 +
  1038 + /*
  1039 + * TODO(sjg@chromium.org): Remove this when driver model supports
  1040 + * TPMs
  1041 + */
  1042 + ret = uclass_get_device_by_of_offset(UCLASS_I2C, parent, &bus);
  1043 + if (ret) {
  1044 + debug("Cannot find bus for node '%s: ret=%d'\n",
  1045 + fdt_get_name(blob, parent, NULL), ret);
  1046 + return ret;
  1047 + }
  1048 +
  1049 + chip_addr = fdtdec_get_int(blob, node, "reg", -1);
  1050 + if (chip_addr == -1) {
  1051 + debug("Cannot find reg property for node '%s: ret=%d'\n",
  1052 + fdt_get_name(blob, node, NULL), ret);
  1053 + return ret;
  1054 + }
  1055 + /*
  1056 + * TODO(sjg@chromium.org): Older TPMs will need to use the older method
  1057 + * in iic_tpm_read() so the offset length needs to be 0 here.
  1058 + */
  1059 + ret = i2c_get_chip(bus, chip_addr, 1, &dev->dev);
  1060 + if (ret) {
  1061 + debug("Cannot find device for node '%s: ret=%d'\n",
  1062 + fdt_get_name(blob, node, NULL), ret);
  1063 + return ret;
  1064 + }
  1065 +
  1066 + return 0;
  1067 +}
  1068 +
  1069 +struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
  1070 +{
  1071 + struct tpm_chip *chip;
  1072 +
  1073 + /* Driver specific per-device data */
  1074 + chip = &g_chip;
  1075 + memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
  1076 + chip->is_open = 1;
  1077 +
  1078 + return chip;
  1079 +}
  1080 +
  1081 +int tis_init(void)
  1082 +{
  1083 + if (tpm.inited)
  1084 + return 0;
  1085 +
  1086 + if (tpm_decode_config(&tpm))
  1087 + return -1;
  1088 +
  1089 + debug("%s: done\n", __func__);
  1090 +
  1091 + tpm.inited = 1;
  1092 +
  1093 + return 0;
  1094 +}
  1095 +
  1096 +int tis_open(void)
  1097 +{
  1098 + int rc;
  1099 +
  1100 + if (!tpm.inited)
  1101 + return -1;
  1102 +
  1103 + rc = tpm_open_dev(tpm.dev);
  1104 +
  1105 + return rc;
  1106 +}
  1107 +
  1108 +int tis_close(void)
  1109 +{
  1110 + if (!tpm.inited)
  1111 + return -1;
  1112 +
  1113 + tpm_close();
  1114 +
  1115 + return 0;
  1116 +}
  1117 +
  1118 +int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
  1119 + uint8_t *recvbuf, size_t *rbuf_len)
  1120 +{
  1121 + int len;
  1122 + uint8_t buf[4096];
  1123 +
  1124 + if (!tpm.inited)
  1125 + return -1;
  1126 +
  1127 + if (sizeof(buf) < sbuf_size)
  1128 + return -1;
  1129 +
  1130 + memcpy(buf, sendbuf, sbuf_size);
  1131 +
  1132 + len = tpm_transmit(buf, sbuf_size);
  1133 +
  1134 + if (len < 10) {
  1135 + *rbuf_len = 0;
  1136 + return -1;
  1137 + }
  1138 +
  1139 + memcpy(recvbuf, buf, len);
  1140 + *rbuf_len = len;
  1141 +
  1142 + return 0;
597 1143 }
drivers/tpm/tpm_tis_i2c.h
  1 +/*
  2 + * Copyright (C) 2011 Infineon Technologies
  3 + *
  4 + * Authors:
  5 + * Peter Huewe <huewe.external@infineon.com>
  6 + *
  7 + * Version: 2.1.1
  8 + *
  9 + * Description:
  10 + * Device driver for TCG/TCPA TPM (trusted platform module).
  11 + * Specifications at www.trustedcomputinggroup.org
  12 + *
  13 + * It is based on the Linux kernel driver tpm.c from Leendert van
  14 + * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
  15 + *
  16 + * SPDX-License-Identifier: GPL-2.0
  17 + */
  18 +
  19 +#ifndef _TPM_TIS_I2C_H
  20 +#define _TPM_TIS_I2C_H
  21 +
  22 +#include <linux/compiler.h>
  23 +#include <linux/types.h>
  24 +
  25 +enum tpm_timeout {
  26 + TPM_TIMEOUT = 5, /* msecs */
  27 +};
  28 +
  29 +/* Size of external transmit buffer (used in tpm_transmit)*/
  30 +#define TPM_BUFSIZE 4096
  31 +
  32 +/* Index of Count field in TPM response buffer */
  33 +#define TPM_RSP_SIZE_BYTE 2
  34 +#define TPM_RSP_RC_BYTE 6
  35 +
  36 +struct tpm_chip;
  37 +
  38 +struct tpm_vendor_specific {
  39 + const u8 req_complete_mask;
  40 + const u8 req_complete_val;
  41 + const u8 req_canceled;
  42 + int irq;
  43 + int (*recv) (struct tpm_chip *, u8 *, size_t);
  44 + int (*send) (struct tpm_chip *, u8 *, size_t);
  45 + void (*cancel) (struct tpm_chip *);
  46 + u8(*status) (struct tpm_chip *);
  47 + int locality;
  48 + unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
  49 + unsigned long duration[3]; /* msec */
  50 +};
  51 +
  52 +struct tpm_chip {
  53 + int is_open;
  54 + struct tpm_vendor_specific vendor;
  55 +};
  56 +
  57 +struct tpm_input_header {
  58 + __be16 tag;
  59 + __be32 length;
  60 + __be32 ordinal;
  61 +} __packed;
  62 +
  63 +struct tpm_output_header {
  64 + __be16 tag;
  65 + __be32 length;
  66 + __be32 return_code;
  67 +} __packed;
  68 +
  69 +struct timeout_t {
  70 + __be32 a;
  71 + __be32 b;
  72 + __be32 c;
  73 + __be32 d;
  74 +} __packed;
  75 +
  76 +struct duration_t {
  77 + __be32 tpm_short;
  78 + __be32 tpm_medium;
  79 + __be32 tpm_long;
  80 +} __packed;
  81 +
  82 +union cap_t {
  83 + struct timeout_t timeout;
  84 + struct duration_t duration;
  85 +};
  86 +
  87 +struct tpm_getcap_params_in {
  88 + __be32 cap;
  89 + __be32 subcap_size;
  90 + __be32 subcap;
  91 +} __packed;
  92 +
  93 +struct tpm_getcap_params_out {
  94 + __be32 cap_size;
  95 + union cap_t cap;
  96 +} __packed;
  97 +
  98 +union tpm_cmd_header {
  99 + struct tpm_input_header in;
  100 + struct tpm_output_header out;
  101 +};
  102 +
  103 +union tpm_cmd_params {
  104 + struct tpm_getcap_params_out getcap_out;
  105 + struct tpm_getcap_params_in getcap_in;
  106 +};
  107 +
  108 +struct tpm_cmd_t {
  109 + union tpm_cmd_header header;
  110 + union tpm_cmd_params params;
  111 +} __packed;
  112 +
  113 +struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
  114 +
  115 +struct udevice;
  116 +int tpm_vendor_init(struct udevice *dev);
  117 +
  118 +void tpm_vendor_cleanup(struct tpm_chip *chip);
  119 +
  120 +#endif