tpm.c revision 1.9 1 /* $NetBSD: tpm.c,v 1.9 2013/10/17 21:24:24 christos Exp $ */
2 /*
3 * Copyright (c) 2008, 2009 Michael Shalayeff
4 * Copyright (c) 2009, 2010 Hans-Jrg Hxer
5 * All rights reserved.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
16 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include <sys/cdefs.h>
21 __KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.9 2013/10/17 21:24:24 christos Exp $");
22
23 #if 0
24 #define TPM_DEBUG
25 #define aprint_debug_dev aprint_error_dev
26 #endif
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/kernel.h>
31 #include <sys/malloc.h>
32 #include <sys/proc.h>
33 #include <sys/device.h>
34 #include <sys/conf.h>
35 #include <sys/bus.h>
36 #include <sys/pmf.h>
37
38 #include <dev/ic/tpmreg.h>
39 #include <dev/ic/tpmvar.h>
40
41 /* Set when enabling legacy interface in host bridge. */
42 int tpm_enabled;
43
44 const struct {
45 uint32_t devid;
46 char name[32];
47 int flags;
48 #define TPM_DEV_NOINTS 0x0001
49 } tpm_devs[] = {
50 { 0x000615d1, "IFX SLD 9630 TT 1.1", 0 },
51 { 0x000b15d1, "IFX SLB 9635 TT 1.2", 0 },
52 { 0x100214e4, "Broadcom BCM0102", TPM_DEV_NOINTS },
53 { 0x00fe1050, "WEC WPCT200", 0 },
54 { 0x687119fa, "SNS SSX35", 0 },
55 { 0x2e4d5453, "STM ST19WP18", 0 },
56 { 0x32021114, "ATML 97SC3203", TPM_DEV_NOINTS },
57 { 0x10408086, "INTEL INTC0102", 0 },
58 { 0, "", TPM_DEV_NOINTS },
59 };
60
61 int tpm_tis12_irqinit(struct tpm_softc *, int, int);
62
63 int tpm_waitfor_poll(struct tpm_softc *, uint8_t, int, void *);
64 int tpm_waitfor_int(struct tpm_softc *, uint8_t, int, void *, int);
65 int tpm_waitfor(struct tpm_softc *, uint8_t, int, void *);
66 int tpm_request_locality(struct tpm_softc *, int);
67 int tpm_getburst(struct tpm_softc *);
68 uint8_t tpm_status(struct tpm_softc *);
69 int tpm_tmotohz(int);
70
71 static dev_type_open(tpmopen);
72 static dev_type_close(tpmclose);
73 static dev_type_read(tpmread);
74 static dev_type_read(tpmwrite);
75 static dev_type_ioctl(tpmioctl);
76
77 extern struct cfdriver tpm_cd;
78 #define TPMUNIT(a) minor(a)
79
80 const struct cdevsw tpm_cdevsw = {
81 tpmopen, tpmclose, tpmread, tpmwrite, tpmioctl,
82 nostop, notty, nopoll, nommap, nokqfilter, D_OTHER,
83 };
84
85 /* Probe TPM using TIS 1.2 interface. */
86 int
87 tpm_tis12_probe(bus_space_tag_t bt, bus_space_handle_t bh)
88 {
89 uint32_t r;
90 uint8_t save, reg;
91
92 r = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITIES);
93 if (r == 0xffffffff)
94 return 0;
95
96 #ifdef TPM_DEBUG
97 char buf[128];
98 snprintb(buf, sizeof(buf), TPM_CAPBITS, r);
99 printf("%s: caps=%s\n", __func__, buf);
100 #endif
101 if ((r & TPM_CAPSREQ) != TPM_CAPSREQ ||
102 !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) {
103 #ifdef TPM_DEBUG
104 printf("%s: caps too low (caps=%s)\n", __func__, buf);
105 #endif
106 return 0;
107 }
108
109 save = bus_space_read_1(bt, bh, TPM_ACCESS);
110 bus_space_write_1(bt, bh, TPM_ACCESS, TPM_ACCESS_REQUEST_USE);
111 reg = bus_space_read_1(bt, bh, TPM_ACCESS);
112 if ((reg & TPM_ACCESS_VALID) && (reg & TPM_ACCESS_ACTIVE_LOCALITY) &&
113 bus_space_read_4(bt, bh, TPM_ID) != 0xffffffff)
114 return 1;
115
116 bus_space_write_1(bt, bh, TPM_ACCESS, save);
117 return 0;
118 }
119
120 /*
121 * Setup interrupt vector if one is provided and interrupts are know to
122 * work on that particular chip.
123 */
124 int
125 tpm_tis12_irqinit(struct tpm_softc *sc, int irq, int idx)
126 {
127 uint32_t r;
128
129 if ((irq == -1) || (tpm_devs[idx].flags & TPM_DEV_NOINTS)) {
130 sc->sc_vector = -1;
131 return 0;
132 }
133
134 /* Ack and disable all interrupts. */
135 r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE);
136 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
137 r & ~TPM_GLOBAL_INT_ENABLE);
138 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS,
139 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS));
140 #ifdef TPM_DEBUG
141 char buf[128];
142 snprintb(buf, sizeof(buf), TPM_INTERRUPT_ENABLE_BITS, r);
143 aprint_debug_dev(sc->sc_dev, "%s: before ien %s\n", __func__, buf);
144 #endif
145
146 /* Program interrupt vector. */
147 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_INT_VECTOR, irq);
148 sc->sc_vector = irq;
149
150 /* Program interrupt type. */
151 r &= ~(TPM_INT_EDGE_RISING|TPM_INT_EDGE_FALLING|TPM_INT_LEVEL_HIGH|
152 TPM_INT_LEVEL_LOW);
153 r |= TPM_GLOBAL_INT_ENABLE|TPM_CMD_READY_INT|TPM_LOCALITY_CHANGE_INT|
154 TPM_STS_VALID_INT|TPM_DATA_AVAIL_INT;
155 if (sc->sc_capabilities & TPM_INTF_INT_EDGE_RISING)
156 r |= TPM_INT_EDGE_RISING;
157 else if (sc->sc_capabilities & TPM_INTF_INT_EDGE_FALLING)
158 r |= TPM_INT_EDGE_FALLING;
159 else if (sc->sc_capabilities & TPM_INTF_INT_LEVEL_HIGH)
160 r |= TPM_INT_LEVEL_HIGH;
161 else
162 r |= TPM_INT_LEVEL_LOW;
163
164 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, r);
165 #ifdef TPM_DEBUG
166 snprintb(buf, sizeof(buf), TPM_INTERRUPT_ENABLE_BITS, r);
167 aprint_debug_dev(sc->sc_dev, "%s: after ien %s\n", __func__, buf);
168 #endif
169
170 return 0;
171 }
172
173 /* Setup TPM using TIS 1.2 interface. */
174 int
175 tpm_tis12_init(struct tpm_softc *sc, int irq, const char *name)
176 {
177 uint32_t r;
178 int i;
179
180 r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTF_CAPABILITIES);
181 #ifdef TPM_DEBUG
182 char cbuf[128];
183 snprintb(cbuf, sizeof(cbuf), TPM_CAPBITS, r);
184 aprint_debug_dev(sc->sc_dev, "%s: caps=%s ", __func__, cbuf);
185 #endif
186 if ((r & TPM_CAPSREQ) != TPM_CAPSREQ ||
187 !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) {
188 char buf[128];
189 snprintb(buf, sizeof(buf), TPM_CAPBITS, r);
190 aprint_error_dev(sc->sc_dev, "capabilities too low (caps=%s)\n",
191 buf);
192 return 1;
193 }
194 sc->sc_capabilities = r;
195
196 sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID);
197 sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV);
198
199 for (i = 0; tpm_devs[i].devid; i++)
200 if (tpm_devs[i].devid == sc->sc_devid)
201 break;
202
203 if (tpm_devs[i].devid)
204 aprint_normal(": %s rev 0x%x\n",
205 tpm_devs[i].name, sc->sc_rev);
206 else
207 aprint_normal(": device 0x%08x rev 0x%x\n",
208 sc->sc_devid, sc->sc_rev);
209
210 if (tpm_tis12_irqinit(sc, irq, i))
211 return 1;
212
213 if (tpm_request_locality(sc, 0))
214 return 1;
215
216 /* Abort whatever it thought it was doing. */
217 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
218
219 return 0;
220 }
221
222 int
223 tpm_request_locality(struct tpm_softc *sc, int l)
224 {
225 uint32_t r;
226 int to, rv;
227
228 if (l != 0)
229 return EINVAL;
230
231 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
232 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) ==
233 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
234 return 0;
235
236 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS,
237 TPM_ACCESS_REQUEST_USE);
238
239 to = tpm_tmotohz(TPM_ACCESS_TMO);
240
241 while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
242 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
243 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) {
244 rv = tsleep(sc->sc_init, PRIBIO | PCATCH, "tpm_locality", 1);
245 if (rv && rv != EWOULDBLOCK) {
246 #ifdef TPM_DEBUG
247 aprint_debug_dev(sc->sc_dev, "%s: interrupted %d\n",
248 __func__, rv);
249 #endif
250 return rv;
251 }
252 }
253
254 if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
255 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
256 #ifdef TPM_DEBUG
257 char buf[128];
258 snprintb(buf, sizeof(buf), TPM_ACCESS_BITS, r);
259 aprint_debug_dev(sc->sc_dev, "%s: access %s\n", __func__, buf);
260 #endif
261 return EBUSY;
262 }
263
264 return 0;
265 }
266
267 int
268 tpm_getburst(struct tpm_softc *sc)
269 {
270 int burst, to, rv;
271
272 to = tpm_tmotohz(TPM_BURST_TMO);
273
274 burst = 0;
275 while (burst == 0 && to--) {
276 /*
277 * Burst count has to be read from bits 8 to 23 without
278 * touching any other bits, eg. the actual status bits 0
279 * to 7.
280 */
281 burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1);
282 burst |= bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2)
283 << 8;
284 #ifdef TPM_DEBUG
285 aprint_debug_dev(sc->sc_dev, "%s: read %d\n", __func__, burst);
286 #endif
287 if (burst)
288 return burst;
289
290 rv = tsleep(sc, PRIBIO | PCATCH, "tpm_getburst", 1);
291 if (rv && rv != EWOULDBLOCK) {
292 return 0;
293 }
294 }
295
296 return 0;
297 }
298
299 uint8_t
300 tpm_status(struct tpm_softc *sc)
301 {
302 return bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) & TPM_STS_MASK;
303 }
304
305 int
306 tpm_tmotohz(int tmo)
307 {
308 struct timeval tv;
309
310 tv.tv_sec = tmo / 1000;
311 tv.tv_usec = 1000 * (tmo % 1000);
312
313 return tvtohz(&tv);
314 }
315
316 /* Save TPM state on suspend. */
317 bool
318 tpm_suspend(device_t dev, const pmf_qual_t *qual)
319 {
320 struct tpm_softc *sc = device_private(dev);
321 static const uint8_t command[] = {
322 0, 193, /* TPM_TAG_RQU_COMMAND */
323 0, 0, 0, 10, /* Length in bytes */
324 0, 0, 0, 156 /* TPM_ORD_SaveStates */
325 };
326 uint8_t scratch[sizeof(command)];
327
328 /*
329 * Power down: We have to issue the SaveStates command.
330 */
331 (*sc->sc_write)(sc, &command, sizeof(command));
332 (*sc->sc_read)(sc, &scratch, sizeof(scratch), NULL, TPM_HDRSIZE);
333 #ifdef TPM_DEBUG
334 aprint_debug_dev(sc->sc_dev, "%s: power down\n", __func__);
335 #endif
336 return true;
337 }
338
339 /*
340 * Handle resume event. Actually nothing to do as the BIOS is supposed
341 * to restore the previously saved state.
342 */
343 bool
344 tpm_resume(device_t dev, const pmf_qual_t *qual)
345 {
346 #ifdef TPM_DEBUG
347 struct tpm_softc *sc = device_private(dev);
348 aprint_debug_dev(sc->sc_dev, "%s: resume\n", __func__);
349 #endif
350 return true;
351 }
352
353 /* Wait for given status bits using polling. */
354 int
355 tpm_waitfor_poll(struct tpm_softc *sc, uint8_t mask, int tmo, void *c)
356 {
357 int rv;
358
359 /*
360 * Poll until either the requested condition or a time out is
361 * met.
362 */
363 while (((sc->sc_stat = tpm_status(sc)) & mask) != mask && tmo--) {
364 rv = tsleep(c, PRIBIO | PCATCH, "tpm_poll", 1);
365 if (rv && rv != EWOULDBLOCK) {
366 #ifdef TPM_DEBUG
367 aprint_debug_dev(sc->sc_dev,
368 "%s: interrupted %d\n", __func__, rv);
369 #endif
370 return rv;
371 }
372 }
373
374 return 0;
375 }
376
377 /* Wait for given status bits using interrupts. */
378 int
379 tpm_waitfor_int(struct tpm_softc *sc, uint8_t mask, int tmo, void *c,
380 int inttype)
381 {
382 int rv, to;
383
384 /* Poll and return when condition is already met. */
385 sc->sc_stat = tpm_status(sc);
386 if ((sc->sc_stat & mask) == mask)
387 return 0;
388
389 /*
390 * Enable interrupt on tpm chip. Note that interrupts on our
391 * level (SPL_TTY) are disabled (see tpm{read,write} et al) and
392 * will not be delivered to the cpu until we call tsleep(9) below.
393 */
394 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
395 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) |
396 inttype);
397 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
398 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) |
399 TPM_GLOBAL_INT_ENABLE);
400
401 /*
402 * Poll once more to remedy the race between previous polling
403 * and enabling interrupts on the tpm chip.
404 */
405 sc->sc_stat = tpm_status(sc);
406 if ((sc->sc_stat & mask) == mask) {
407 rv = 0;
408 goto out;
409 }
410
411 to = tpm_tmotohz(tmo);
412 #ifdef TPM_DEBUG
413 aprint_debug_dev(sc->sc_dev,
414 "%s: sleeping for %d ticks on %p\n", __func__, to, c);
415 #endif
416 /*
417 * tsleep(9) enables interrupts on the cpu and returns after
418 * wake up with interrupts disabled again. Note that interrupts
419 * generated by the tpm chip while being at SPL_TTY are not lost
420 * but held and delivered as soon as the cpu goes below SPL_TTY.
421 */
422 rv = tsleep(c, PRIBIO | PCATCH, "tpm_wait", to);
423
424 sc->sc_stat = tpm_status(sc);
425 #ifdef TPM_DEBUG
426 char buf[128];
427 snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
428 aprint_debug_dev(sc->sc_dev,
429 "%s: woke up with rv %d stat %s\n", __func__, rv, buf);
430 #endif
431 if ((sc->sc_stat & mask) == mask)
432 rv = 0;
433
434 /* Disable interrupts on tpm chip again. */
435 out: bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
436 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) &
437 ~TPM_GLOBAL_INT_ENABLE);
438 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
439 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) &
440 ~inttype);
441
442 return rv;
443 }
444
445 /*
446 * Wait on given status bits, uses interrupts where possible, otherwise polls.
447 */
448 int
449 tpm_waitfor(struct tpm_softc *sc, uint8_t b0, int tmo, void *c)
450 {
451 uint8_t b;
452 int re, to, rv;
453
454 #ifdef TPM_DEBUG
455 char buf[128];
456 snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
457 aprint_debug_dev(sc->sc_dev, "%s: b0 %s\n", __func__, buf);
458 #endif
459
460 /*
461 * If possible, use interrupts, otherwise poll.
462 *
463 * We use interrupts for TPM_STS_VALID and TPM_STS_DATA_AVAIL (if
464 * the tpm chips supports them) as waiting for those can take
465 * really long. The other TPM_STS* are not needed very often
466 * so we do not support them.
467 */
468 if (sc->sc_vector != -1) {
469 b = b0;
470
471 /*
472 * Wait for data ready. This interrupt only occures
473 * when both TPM_STS_VALID and TPM_STS_DATA_AVAIL are asserted.
474 * Thus we don't have to bother with TPM_STS_VALID
475 * separately and can just return.
476 *
477 * This only holds for interrupts! When using polling
478 * both flags have to be waited for, see below.
479 */
480 if ((b & TPM_STS_DATA_AVAIL) && (sc->sc_capabilities &
481 TPM_INTF_DATA_AVAIL_INT))
482 return tpm_waitfor_int(sc, b, tmo, c,
483 TPM_DATA_AVAIL_INT);
484
485 /* Wait for status valid bit. */
486 if ((b & TPM_STS_VALID) && (sc->sc_capabilities &
487 TPM_INTF_STS_VALID_INT)) {
488 rv = tpm_waitfor_int(sc, b, tmo, c, TPM_STS_VALID_INT);
489 if (rv != 0)
490 return rv;
491 else
492 b = b0 & ~TPM_STS_VALID;
493 }
494
495 /*
496 * When all flags are taken care of, return. Otherwise
497 * use polling for eg. TPM_STS_CMD_READY.
498 */
499 if (b == 0)
500 return 0;
501 }
502
503 re = 3;
504 restart:
505 /*
506 * If requested wait for TPM_STS_VALID before dealing with
507 * any other flag. Eg. when both TPM_STS_DATA_AVAIL and TPM_STS_VALID
508 * are requested, wait for the latter first.
509 */
510 b = b0;
511 if (b0 & TPM_STS_VALID)
512 b = TPM_STS_VALID;
513
514 to = tpm_tmotohz(tmo);
515 again:
516 if ((rv = tpm_waitfor_poll(sc, b, to, c)) != 0)
517 return rv;
518
519 if ((b & sc->sc_stat) == TPM_STS_VALID) {
520 /* Now wait for other flags. */
521 b = b0 & ~TPM_STS_VALID;
522 to++;
523 goto again;
524 }
525
526 if ((sc->sc_stat & b) != b) {
527 #ifdef TPM_DEBUG
528 char bbuf[128], cbuf[128];
529 snprintb(bbuf, sizeof(bbuf), TPM_STS_BITS, b);
530 snprintb(cbuf, sizeof(cbuf), TPM_STS_BITS, sc->sc_stat);
531 aprint_debug_dev(sc->sc_dev,
532 "%s: timeout: stat=%s b=%s\n", __func__, cbuf, bbuf);
533 #endif
534 if (re-- && (b0 & TPM_STS_VALID)) {
535 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
536 TPM_STS_RESP_RETRY);
537 goto restart;
538 }
539 return EIO;
540 }
541
542 return 0;
543 }
544
545 /* Start transaction. */
546 int
547 tpm_tis12_start(struct tpm_softc *sc, int flag)
548 {
549 int rv;
550
551 if (flag == UIO_READ) {
552 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
553 TPM_READ_TMO, sc->sc_read);
554 return rv;
555 }
556
557 /* Own our (0th) locality. */
558 if ((rv = tpm_request_locality(sc, 0)) != 0)
559 return rv;
560
561 sc->sc_stat = tpm_status(sc);
562 if (sc->sc_stat & TPM_STS_CMD_READY) {
563 #ifdef TPM_DEBUG
564 char buf[128];
565 snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
566 aprint_debug_dev(sc->sc_dev, "%s: UIO_WRITE status %s\n",
567 __func__, buf);
568 #endif
569 return 0;
570 }
571
572 #ifdef TPM_DEBUG
573 aprint_debug_dev(sc->sc_dev,
574 "%s: UIO_WRITE readying chip\n", __func__);
575 #endif
576
577 /* Abort previous and restart. */
578 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
579 if ((rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READY_TMO,
580 sc->sc_write))) {
581 #ifdef TPM_DEBUG
582 aprint_debug_dev(sc->sc_dev,
583 "%s: UIO_WRITE readying failed %d\n", __func__, rv);
584 #endif
585 return rv;
586 }
587
588 #ifdef TPM_DEBUG
589 aprint_debug_dev(sc->sc_dev,
590 "%s: UIO_WRITE readying done\n", __func__);
591 #endif
592
593 return 0;
594 }
595
596 int
597 tpm_tis12_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count,
598 int flags)
599 {
600 uint8_t *p = buf;
601 size_t cnt;
602 int rv, n, bcnt;
603
604 #ifdef TPM_DEBUG
605 aprint_debug_dev(sc->sc_dev, "%s: len %zu\n", __func__, len);
606 #endif
607 cnt = 0;
608 while (len > 0) {
609 if ((rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
610 TPM_READ_TMO, sc->sc_read)))
611 return rv;
612
613 bcnt = tpm_getburst(sc);
614 n = MIN(len, bcnt);
615 #ifdef TPM_DEBUG
616 aprint_debug_dev(sc->sc_dev,
617 "%s: fetching %d, burst is %d\n", __func__, n, bcnt);
618 #endif
619 for (; n--; len--) {
620 *p++ = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA);
621 cnt++;
622 }
623
624 if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6)
625 break;
626 }
627 #ifdef TPM_DEBUG
628 aprint_debug_dev(sc->sc_dev,
629 "%s: read %zu bytes, len %zu\n", __func__, cnt, len);
630 #endif
631
632 if (count)
633 *count = cnt;
634
635 return 0;
636 }
637
638 int
639 tpm_tis12_write(struct tpm_softc *sc, const void *buf, size_t len)
640 {
641 const uint8_t *p = buf;
642 size_t cnt;
643 int rv, r;
644
645 #ifdef TPM_DEBUG
646 aprint_debug_dev(sc->sc_dev,
647 "%s: sc %p buf %p len %zu\n", __func__, sc, buf, len);
648 #endif
649 if (len == 0)
650 return 0;
651
652 if ((rv = tpm_request_locality(sc, 0)) != 0)
653 return rv;
654
655 cnt = 0;
656 while (cnt < len - 1) {
657 for (r = tpm_getburst(sc); r > 0 && cnt < len - 1; r--) {
658 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
659 cnt++;
660 }
661 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
662 #ifdef TPM_DEBUG
663 aprint_debug_dev(sc->sc_dev,
664 "%s: failed burst rv %d\n", __func__, rv);
665 #endif
666 return rv;
667 }
668 sc->sc_stat = tpm_status(sc);
669 if (!(sc->sc_stat & TPM_STS_DATA_EXPECT)) {
670 #ifdef TPM_DEBUG
671 char sbuf[128];
672 snprintb(sbuf, sizeof(sbuf), TPM_STS_BITS, sc->sc_stat);
673 aprint_debug_dev(sc->sc_dev,
674 "%s: failed rv %d stat=%s\n", __func__, rv, sbuf);
675 #endif
676 return EIO;
677 }
678 }
679
680 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
681 cnt++;
682
683 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
684 #ifdef TPM_DEBUG
685 aprint_debug_dev(sc->sc_dev, "%s: failed last byte rv %d\n",
686 __func__, rv);
687 #endif
688 return rv;
689 }
690 if ((sc->sc_stat & TPM_STS_DATA_EXPECT) != 0) {
691 #ifdef TPM_DEBUG
692 char sbuf[128];
693 snprintb(sbuf, sizeof(sbuf), TPM_STS_BITS, sc->sc_stat);
694 aprint_debug_dev(sc->sc_dev,
695 "%s: failed rv %d stat=%s\n", __func__, rv, sbuf);
696 #endif
697 return EIO;
698 }
699
700 #ifdef TPM_DEBUG
701 aprint_debug_dev(sc->sc_dev, "%s: wrote %zu byte\n", __func__, cnt);
702 #endif
703
704 return 0;
705 }
706
707 /* Finish transaction. */
708 int
709 tpm_tis12_end(struct tpm_softc *sc, int flag, int err)
710 {
711 int rv = 0;
712
713 if (flag == UIO_READ) {
714 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO,
715 sc->sc_read)))
716 return rv;
717
718 /* Still more data? */
719 sc->sc_stat = tpm_status(sc);
720 if (!err && ((sc->sc_stat & TPM_STS_DATA_AVAIL)
721 == TPM_STS_DATA_AVAIL)) {
722 #ifdef TPM_DEBUG
723 char buf[128];
724 snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
725 aprint_debug_dev(sc->sc_dev,
726 "%s: read failed stat=%s\n", __func__, buf);
727 #endif
728 rv = EIO;
729 }
730
731 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
732 TPM_STS_CMD_READY);
733
734 /* Release our (0th) locality. */
735 bus_space_write_1(sc->sc_bt, sc->sc_bh,TPM_ACCESS,
736 TPM_ACCESS_ACTIVE_LOCALITY);
737 } else {
738 /* Hungry for more? */
739 sc->sc_stat = tpm_status(sc);
740 if (!err && (sc->sc_stat & TPM_STS_DATA_EXPECT)) {
741 #ifdef TPM_DEBUG
742 char buf[128];
743 snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
744 aprint_debug_dev(sc->sc_dev,
745 "%s: write failed stat=%s\n", __func__, buf);
746 #endif
747 rv = EIO;
748 }
749
750 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
751 err ? TPM_STS_CMD_READY : TPM_STS_GO);
752 }
753
754 return rv;
755 }
756
757 int
758 tpm_intr(void *v)
759 {
760 struct tpm_softc *sc = v;
761 uint32_t r;
762 #ifdef TPM_DEBUG
763 static int cnt = 0;
764 #endif
765
766 r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS);
767 #ifdef TPM_DEBUG
768 if (r != 0) {
769 char buf[128];
770 snprintb(buf, sizeof(buf), TPM_INTERRUPT_ENABLE_BITS, r);
771 aprint_debug_dev(sc->sc_dev, "%s: int=%s (%d)\n", __func__,
772 buf, cnt);
773 } else
774 cnt++;
775 #endif
776 if (!(r & (TPM_CMD_READY_INT | TPM_LOCALITY_CHANGE_INT |
777 TPM_STS_VALID_INT | TPM_DATA_AVAIL_INT)))
778 #ifdef __FreeBSD__
779 return;
780 #else
781 return 0;
782 #endif
783 if (r & TPM_STS_VALID_INT)
784 wakeup(sc);
785
786 if (r & TPM_CMD_READY_INT)
787 wakeup(sc->sc_write);
788
789 if (r & TPM_DATA_AVAIL_INT)
790 wakeup(sc->sc_read);
791
792 if (r & TPM_LOCALITY_CHANGE_INT)
793 wakeup(sc->sc_init);
794
795 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS, r);
796
797 return 1;
798 }
799
800 /* Read single byte using legacy interface. */
801 static inline uint8_t
802 tpm_legacy_in(bus_space_tag_t iot, bus_space_handle_t ioh, int reg)
803 {
804 bus_space_write_1(iot, ioh, 0, reg);
805 return bus_space_read_1(iot, ioh, 1);
806 }
807
808 /* Probe for TPM using legacy interface. */
809 int
810 tpm_legacy_probe(bus_space_tag_t iot, bus_addr_t iobase)
811 {
812 bus_space_handle_t ioh;
813 uint8_t r, v;
814 int i, rv = 0;
815 char id[8];
816
817 if (!tpm_enabled || iobase == -1)
818 return 0;
819
820 if (bus_space_map(iot, iobase, 2, 0, &ioh))
821 return 0;
822
823 v = bus_space_read_1(iot, ioh, 0);
824 if (v == 0xff) {
825 bus_space_unmap(iot, ioh, 2);
826 return 0;
827 }
828 r = bus_space_read_1(iot, ioh, 1);
829
830 for (i = sizeof(id); i--; )
831 id[i] = tpm_legacy_in(iot, ioh, TPM_ID + i);
832
833 #ifdef TPM_DEBUG
834 printf("tpm_legacy_probe %.4s %d.%d.%d.%d\n",
835 &id[4], id[0], id[1], id[2], id[3]);
836 #endif
837 /*
838 * The only chips using the legacy interface we are aware of are
839 * by Atmel. For other chips more signature would have to be added.
840 */
841 if (!bcmp(&id[4], "ATML", 4))
842 rv = 1;
843
844 if (!rv) {
845 bus_space_write_1(iot, ioh, r, 1);
846 bus_space_write_1(iot, ioh, v, 0);
847 }
848 bus_space_unmap(iot, ioh, 2);
849
850 return rv;
851 }
852
853 /* Setup TPM using legacy interface. */
854 int
855 tpm_legacy_init(struct tpm_softc *sc, int irq, const char *name)
856 {
857 char id[8];
858 int i;
859
860 if ((i = bus_space_map(sc->sc_batm, tpm_enabled, 2, 0, &sc->sc_bahm))) {
861 aprint_debug_dev(sc->sc_dev, "cannot map tpm registers (%d)\n",
862 i);
863 tpm_enabled = 0;
864 return 1;
865 }
866
867 for (i = sizeof(id); i--; )
868 id[i] = tpm_legacy_in(sc->sc_bt, sc->sc_bh, TPM_ID + i);
869
870 aprint_debug_dev(sc->sc_dev, "%.4s %d.%d @0x%x\n", &id[4], id[0],
871 id[1], tpm_enabled);
872 tpm_enabled = 0;
873
874 return 0;
875 }
876
877 /* Start transaction. */
878 int
879 tpm_legacy_start(struct tpm_softc *sc, int flag)
880 {
881 struct timeval tv;
882 uint8_t bits, r;
883 int to, rv;
884
885 bits = flag == UIO_READ ? TPM_LEGACY_DA : 0;
886 tv.tv_sec = TPM_LEGACY_TMO;
887 tv.tv_usec = 0;
888 to = tvtohz(&tv) / TPM_LEGACY_SLEEP;
889 while (((r = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1)) &
890 (TPM_LEGACY_BUSY|bits)) != bits && to--) {
891 rv = tsleep(sc, PRIBIO | PCATCH, "legacy_tpm_start",
892 TPM_LEGACY_SLEEP);
893 if (rv && rv != EWOULDBLOCK)
894 return rv;
895 }
896
897 #if defined(TPM_DEBUG) && !defined(__FreeBSD__)
898 char buf[128];
899 snprintb(buf, sizeof(buf), TPM_LEGACY_BITS, r);
900 aprint_debug_dev(sc->sc_dev, "%s: bits %s\n", device_xname(sc->sc_dev),
901 buf);
902 #endif
903 if ((r & (TPM_LEGACY_BUSY|bits)) != bits)
904 return EIO;
905
906 return 0;
907 }
908
909 int
910 tpm_legacy_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count,
911 int flags)
912 {
913 uint8_t *p;
914 size_t cnt;
915 int to, rv;
916
917 cnt = rv = 0;
918 for (p = buf; !rv && len > 0; len--) {
919 for (to = 1000;
920 !(bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1) &
921 TPM_LEGACY_DA); DELAY(1))
922 if (!to--)
923 return EIO;
924
925 DELAY(TPM_LEGACY_DELAY);
926 *p++ = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 0);
927 cnt++;
928 }
929
930 *count = cnt;
931 return 0;
932 }
933
934 int
935 tpm_legacy_write(struct tpm_softc *sc, const void *buf, size_t len)
936 {
937 const uint8_t *p;
938 size_t n;
939
940 for (p = buf, n = len; n--; DELAY(TPM_LEGACY_DELAY)) {
941 if (!n && len != TPM_BUFSIZ) {
942 bus_space_write_1(sc->sc_batm, sc->sc_bahm, 1,
943 TPM_LEGACY_LAST);
944 DELAY(TPM_LEGACY_DELAY);
945 }
946 bus_space_write_1(sc->sc_batm, sc->sc_bahm, 0, *p++);
947 }
948
949 return 0;
950 }
951
952 /* Finish transaction. */
953 int
954 tpm_legacy_end(struct tpm_softc *sc, int flag, int rv)
955 {
956 struct timeval tv;
957 uint8_t r;
958 int to;
959
960 if (rv || flag == UIO_READ)
961 bus_space_write_1(sc->sc_batm, sc->sc_bahm, 1, TPM_LEGACY_ABRT);
962 else {
963 tv.tv_sec = TPM_LEGACY_TMO;
964 tv.tv_usec = 0;
965 to = tvtohz(&tv) / TPM_LEGACY_SLEEP;
966 while(((r = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1)) &
967 TPM_LEGACY_BUSY) && to--) {
968 rv = tsleep(sc, PRIBIO | PCATCH, "legacy_tpm_end",
969 TPM_LEGACY_SLEEP);
970 if (rv && rv != EWOULDBLOCK)
971 return rv;
972 }
973
974 #if defined(TPM_DEBUG) && !defined(__FreeBSD__)
975 char buf[128];
976 snprintb(buf, sizeof(buf), TPM_LEGACY_BITS, r);
977 aprint_debug_dev(sc->sc_dev, "%s: bits %s\n",
978 device_xname(sc->sc_dev), buf);
979 #endif
980 if (r & TPM_LEGACY_BUSY)
981 return EIO;
982
983 if (r & TPM_LEGACY_RE)
984 return EIO; /* XXX Retry the loop? */
985 }
986
987 return rv;
988 }
989
990 int
991 tpmopen(dev_t dev, int flag, int mode, struct lwp *l)
992 {
993 struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
994
995 if (!sc)
996 return ENXIO;
997
998 if (sc->sc_flags & TPM_OPEN)
999 return EBUSY;
1000
1001 sc->sc_flags |= TPM_OPEN;
1002
1003 return 0;
1004 }
1005
1006 int
1007 tpmclose(dev_t dev, int flag, int mode, struct lwp *l)
1008 {
1009 struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
1010
1011 if (!sc)
1012 return ENXIO;
1013
1014 if (!(sc->sc_flags & TPM_OPEN))
1015 return EINVAL;
1016
1017 sc->sc_flags &= ~TPM_OPEN;
1018
1019 return 0;
1020 }
1021
1022 int
1023 tpmread(dev_t dev, struct uio *uio, int flags)
1024 {
1025 struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
1026 uint8_t buf[TPM_BUFSIZ], *p;
1027 size_t cnt, len, n;
1028 int rv, s;
1029
1030 if (!sc)
1031 return ENXIO;
1032
1033 s = spltty();
1034 if ((rv = (*sc->sc_start)(sc, UIO_READ)))
1035 goto out;
1036
1037 #ifdef TPM_DEBUG
1038 aprint_debug_dev(sc->sc_dev, "%s: getting header\n", __func__);
1039 #endif
1040 if ((rv = (*sc->sc_read)(sc, buf, TPM_HDRSIZE, &cnt, 0))) {
1041 (*sc->sc_end)(sc, UIO_READ, rv);
1042 goto out;
1043 }
1044
1045 len = (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | buf[5];
1046 #ifdef TPM_DEBUG
1047 aprint_debug_dev(sc->sc_dev, "%s: len %zu, io count %zu\n", __func__,
1048 len, uio->uio_resid);
1049 #endif
1050 if (len > uio->uio_resid) {
1051 rv = EIO;
1052 (*sc->sc_end)(sc, UIO_READ, rv);
1053 #ifdef TPM_DEBUG
1054 aprint_debug_dev(sc->sc_dev,
1055 "%s: bad residual io count 0x%zx\n", __func__,
1056 uio->uio_resid);
1057 #endif
1058 goto out;
1059 }
1060
1061 /* Copy out header. */
1062 if ((rv = uiomove(buf, cnt, uio))) {
1063 #ifdef TPM_DEBUG
1064 aprint_debug_dev(sc->sc_dev,
1065 "%s: uiomove failed %d\n", __func__, rv);
1066 #endif
1067 (*sc->sc_end)(sc, UIO_READ, rv);
1068 goto out;
1069 }
1070
1071 /* Get remaining part of the answer (if anything is left). */
1072 for (len -= cnt, p = buf, n = sizeof(buf); len > 0; p = buf, len -= n,
1073 n = sizeof(buf)) {
1074 n = MIN(n, len);
1075 #ifdef TPM_DEBUG
1076 aprint_debug_dev(sc->sc_dev, "%s: n %zu len %zu\n", __func__,
1077 n, len);
1078 #endif
1079 if ((rv = (*sc->sc_read)(sc, p, n, NULL, TPM_PARAM_SIZE))) {
1080 (*sc->sc_end)(sc, UIO_READ, rv);
1081 goto out;
1082 }
1083 p += n;
1084 if ((rv = uiomove(buf, p - buf, uio))) {
1085 #ifdef TPM_DEBUG
1086 aprint_debug_dev(sc->sc_dev,
1087 "%s: uiomove failed %d\n", __func__, rv);
1088 #endif
1089 (*sc->sc_end)(sc, UIO_READ, rv);
1090 goto out;
1091 }
1092 }
1093
1094 rv = (*sc->sc_end)(sc, UIO_READ, rv);
1095 out:
1096 splx(s);
1097 return rv;
1098 }
1099
1100 int
1101 tpmwrite(dev_t dev, struct uio *uio, int flags)
1102 {
1103 struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
1104 uint8_t buf[TPM_BUFSIZ];
1105 int n, rv, s;
1106
1107 if (!sc)
1108 return ENXIO;
1109
1110 s = spltty();
1111
1112 #ifdef TPM_DEBUG
1113 aprint_debug_dev(sc->sc_dev, "%s: io count %zu\n", __func__,
1114 uio->uio_resid);
1115 #endif
1116
1117 n = MIN(sizeof(buf), uio->uio_resid);
1118 if ((rv = uiomove(buf, n, uio))) {
1119 #ifdef TPM_DEBUG
1120 aprint_debug_dev(sc->sc_dev,
1121 "%s: uiomove failed %d\n", __func__, rv);
1122 #endif
1123 splx(s);
1124 return rv;
1125 }
1126
1127 if ((rv = (*sc->sc_start)(sc, UIO_WRITE))) {
1128 splx(s);
1129 return rv;
1130 }
1131
1132 if ((rv = (*sc->sc_write)(sc, buf, n))) {
1133 splx(s);
1134 return rv;
1135 }
1136
1137 rv = (*sc->sc_end)(sc, UIO_WRITE, rv);
1138 splx(s);
1139 return rv;
1140 }
1141
1142 int
1143 tpmioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
1144 {
1145 return ENOTTY;
1146 }
1147