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