1 /* 2 * Copyright (c) 2008, 2009 Michael Shalayeff 3 * Copyright (c) 2009, 2010 Hans-Joerg Hoexer 4 * All rights reserved. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 15 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 16 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* #define TPM_DEBUG */ 20 21 #include <sys/cdefs.h> 22 __FBSDID("$FreeBSD$"); 23 24 #include <sys/param.h> 25 #include <sys/systm.h> 26 #include <sys/kernel.h> 27 #include <sys/malloc.h> 28 #include <sys/proc.h> 29 30 #ifdef __FreeBSD__ 31 #include <sys/module.h> 32 #include <sys/conf.h> 33 #include <sys/uio.h> 34 #include <sys/bus.h> 35 36 #include <machine/bus.h> 37 #include <sys/rman.h> 38 #include <machine/resource.h> 39 40 #include <machine/md_var.h> 41 42 #include <isa/isareg.h> 43 #include <isa/isavar.h> 44 #else 45 #include <sys/device.h> 46 47 #include <machine/cpu.h> 48 #include <machine/bus.h> 49 #include <machine/intr.h> 50 #include <machine/conf.h> 51 52 #include <dev/isa/isareg.h> 53 #include <dev/isa/isavar.h> 54 #endif 55 #include <dev/tpm/tpmvar.h> 56 57 #ifndef __FreeBSD__ 58 /* XXX horrible hack for tcsd (-lpthread) workaround on OpenBSD */ 59 #undef PCATCH 60 #define PCATCH 0 61 #endif 62 63 #define TPM_BUFSIZ 1024 64 65 #define TPM_HDRSIZE 10 66 67 #define TPM_PARAM_SIZE 0x0001 68 69 #ifdef __FreeBSD__ 70 #define IRQUNK -1 71 #endif 72 73 #define TPM_ACCESS 0x0000 /* access register */ 74 #define TPM_ACCESS_ESTABLISHMENT 0x01 /* establishment */ 75 #define TPM_ACCESS_REQUEST_USE 0x02 /* request using locality */ 76 #define TPM_ACCESS_REQUEST_PENDING 0x04 /* pending request */ 77 #define TPM_ACCESS_SEIZE 0x08 /* request locality seize */ 78 #define TPM_ACCESS_SEIZED 0x10 /* locality has been seized */ 79 #define TPM_ACCESS_ACTIVE_LOCALITY 0x20 /* locality is active */ 80 #define TPM_ACCESS_VALID 0x80 /* bits are valid */ 81 #define TPM_ACCESS_BITS \ 82 "\020\01EST\02REQ\03PEND\04SEIZE\05SEIZED\06ACT\010VALID" 83 84 #define TPM_INTERRUPT_ENABLE 0x0008 85 #define TPM_GLOBAL_INT_ENABLE 0x80000000 /* enable ints */ 86 #define TPM_CMD_READY_INT 0x00000080 /* cmd ready enable */ 87 #define TPM_INT_EDGE_FALLING 0x00000018 88 #define TPM_INT_EDGE_RISING 0x00000010 89 #define TPM_INT_LEVEL_LOW 0x00000008 90 #define TPM_INT_LEVEL_HIGH 0x00000000 91 #define TPM_LOCALITY_CHANGE_INT 0x00000004 /* locality change enable */ 92 #define TPM_STS_VALID_INT 0x00000002 /* int on TPM_STS_VALID is set */ 93 #define TPM_DATA_AVAIL_INT 0x00000001 /* int on TPM_STS_DATA_AVAIL is set */ 94 #define TPM_INTERRUPT_ENABLE_BITS \ 95 "\020\040ENA\010RDY\03LOCH\02STSV\01DRDY" 96 97 #define TPM_INT_VECTOR 0x000c /* 8 bit reg for 4 bit irq vector */ 98 #define TPM_INT_STATUS 0x0010 /* bits are & 0x87 from TPM_INTERRUPT_ENABLE */ 99 100 #define TPM_INTF_CAPABILITIES 0x0014 /* capability register */ 101 #define TPM_INTF_BURST_COUNT_STATIC 0x0100 /* TPM_STS_BMASK static */ 102 #define TPM_INTF_CMD_READY_INT 0x0080 /* int on ready supported */ 103 #define TPM_INTF_INT_EDGE_FALLING 0x0040 /* falling edge ints supported */ 104 #define TPM_INTF_INT_EDGE_RISING 0x0020 /* rising edge ints supported */ 105 #define TPM_INTF_INT_LEVEL_LOW 0x0010 /* level-low ints supported */ 106 #define TPM_INTF_INT_LEVEL_HIGH 0x0008 /* level-high ints supported */ 107 #define TPM_INTF_LOCALITY_CHANGE_INT 0x0004 /* locality-change int (mb 1) */ 108 #define TPM_INTF_STS_VALID_INT 0x0002 /* TPM_STS_VALID int supported */ 109 #define TPM_INTF_DATA_AVAIL_INT 0x0001 /* TPM_STS_DATA_AVAIL int supported (mb 1) */ 110 #define TPM_CAPSREQ \ 111 (TPM_INTF_DATA_AVAIL_INT|TPM_INTF_LOCALITY_CHANGE_INT|TPM_INTF_INT_LEVEL_LOW) 112 #define TPM_CAPBITS \ 113 "\020\01IDRDY\02ISTSV\03ILOCH\04IHIGH\05ILOW\06IEDGE\07IFALL\010IRDY\011BCST" 114 115 #define TPM_STS 0x0018 /* status register */ 116 #define TPM_STS_MASK 0x000000ff /* status bits */ 117 #define TPM_STS_BMASK 0x00ffff00 /* ro io burst size */ 118 #define TPM_STS_VALID 0x00000080 /* ro other bits are valid */ 119 #define TPM_STS_CMD_READY 0x00000040 /* rw chip/signal ready */ 120 #define TPM_STS_GO 0x00000020 /* wo start the command */ 121 #define TPM_STS_DATA_AVAIL 0x00000010 /* ro data available */ 122 #define TPM_STS_DATA_EXPECT 0x00000008 /* ro more data to be written */ 123 #define TPM_STS_RESP_RETRY 0x00000002 /* wo resend the response */ 124 #define TPM_STS_BITS "\020\010VALID\07RDY\06GO\05DRDY\04EXPECT\02RETRY" 125 126 #define TPM_DATA 0x0024 127 #define TPM_ID 0x0f00 128 #define TPM_REV 0x0f04 129 #define TPM_SIZE 0x5000 /* five pages of the above */ 130 131 #define TPM_ACCESS_TMO 2000 /* 2sec */ 132 #define TPM_READY_TMO 2000 /* 2sec */ 133 #define TPM_READ_TMO 120000 /* 2 minutes */ 134 #define TPM_BURST_TMO 2000 /* 2sec */ 135 136 #define TPM_LEGACY_BUSY 0x01 137 #define TPM_LEGACY_ABRT 0x01 138 #define TPM_LEGACY_DA 0x02 139 #define TPM_LEGACY_RE 0x04 140 #define TPM_LEGACY_LAST 0x04 141 #define TPM_LEGACY_BITS "\020\01BUSY\2DA\3RE\4LAST" 142 #define TPM_LEGACY_TMO (2*60) /* sec */ 143 #define TPM_LEGACY_SLEEP 5 /* ticks */ 144 #define TPM_LEGACY_DELAY 100 145 146 /* Set when enabling legacy interface in host bridge. */ 147 int tpm_enabled; 148 149 #ifdef __FreeBSD__ 150 #define TPMSOFTC(dev) \ 151 ((struct tpm_softc *)dev->si_drv1) 152 153 d_open_t tpmopen; 154 d_close_t tpmclose; 155 d_read_t tpmread; 156 d_write_t tpmwrite; 157 d_ioctl_t tpmioctl; 158 159 static struct cdevsw tpm_cdevsw = { 160 .d_version = D_VERSION, 161 .d_flags = D_NEEDGIANT, 162 .d_open = tpmopen, 163 .d_close = tpmclose, 164 .d_read = tpmread, 165 .d_write = tpmwrite, 166 .d_ioctl = tpmioctl, 167 .d_name = "tpm", 168 }; 169 #else 170 #define TPMSOFTC(dev) \ 171 (struct tpm_softc *)device_lookup(&tpm_cd, minor(dev)) 172 173 struct cfdriver tpm_cd = { 174 NULL, "tpm", DV_DULL 175 }; 176 177 int tpm_match(device_t , void *, void *); 178 void tpm_attach(device_t , device_t , void *); 179 180 struct cfattach tpm_ca = { 181 sizeof(struct tpm_softc), tpm_match, tpm_attach 182 }; 183 #endif 184 185 const struct { 186 u_int32_t devid; 187 char name[32]; 188 int flags; 189 #define TPM_DEV_NOINTS 0x0001 190 } tpm_devs[] = { 191 { 0x000615d1, "IFX SLD 9630 TT 1.1", 0 }, 192 { 0x000b15d1, "IFX SLB 9635 TT 1.2", 0 }, 193 { 0x100214e4, "Broadcom BCM0102", TPM_DEV_NOINTS }, 194 { 0x00fe1050, "WEC WPCT200", 0 }, 195 { 0x687119fa, "SNS SSX35", 0 }, 196 { 0x2e4d5453, "STM ST19WP18", 0 }, 197 { 0x32021114, "ATML 97SC3203", TPM_DEV_NOINTS }, 198 { 0x10408086, "INTEL INTC0102", 0 }, 199 { 0, "", TPM_DEV_NOINTS }, 200 }; 201 202 int tpm_tis12_irqinit(struct tpm_softc *, int, int); 203 int tpm_tis12_init(struct tpm_softc *, int, const char *); 204 int tpm_tis12_start(struct tpm_softc *, int); 205 int tpm_tis12_read(struct tpm_softc *, void *, int, size_t *, int); 206 int tpm_tis12_write(struct tpm_softc *, void *, int); 207 int tpm_tis12_end(struct tpm_softc *, int, int); 208 209 #ifdef __FreeBSD__ 210 void tpm_intr(void *); 211 #else 212 int tpm_intr(void *); 213 void tpm_powerhook(int, void *); 214 int tpm_suspend(struct tpm_softc *, int); 215 int tpm_resume(struct tpm_softc *, int); 216 #endif 217 218 int tpm_waitfor_poll(struct tpm_softc *, u_int8_t, int, void *); 219 int tpm_waitfor_int(struct tpm_softc *, u_int8_t, int, void *, int); 220 int tpm_waitfor(struct tpm_softc *, u_int8_t, int, void *); 221 int tpm_request_locality(struct tpm_softc *, int); 222 int tpm_getburst(struct tpm_softc *); 223 u_int8_t tpm_status(struct tpm_softc *); 224 int tpm_tmotohz(int); 225 226 int tpm_legacy_probe(bus_space_tag_t, bus_addr_t); 227 int tpm_legacy_init(struct tpm_softc *, int, const char *); 228 int tpm_legacy_start(struct tpm_softc *, int); 229 int tpm_legacy_read(struct tpm_softc *, void *, int, size_t *, int); 230 int tpm_legacy_write(struct tpm_softc *, void *, int); 231 int tpm_legacy_end(struct tpm_softc *, int, int); 232 233 #ifdef __FreeBSD__ 234 235 /* 236 * FreeBSD specific code for probing and attaching TPM to device tree. 237 */ 238 #if 0 239 static void 240 tpm_identify(driver_t *driver, device_t parent) 241 { 242 BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "tpm", 0); 243 } 244 #endif 245 246 int 247 tpm_attach(device_t dev) 248 { 249 struct tpm_softc *sc = device_get_softc(dev); 250 int irq; 251 252 sc->mem_rid = 0; 253 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 254 RF_ACTIVE); 255 if (sc->mem_res == NULL) 256 return ENXIO; 257 258 sc->sc_bt = rman_get_bustag(sc->mem_res); 259 sc->sc_bh = rman_get_bushandle(sc->mem_res); 260 261 sc->irq_rid = 0; 262 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 263 RF_ACTIVE | RF_SHAREABLE); 264 if (sc->irq_res != NULL) 265 irq = rman_get_start(sc->irq_res); 266 else 267 irq = IRQUNK; 268 269 /* In case PnP probe this may contain some initialization. */ 270 tpm_tis12_probe(sc->sc_bt, sc->sc_bh); 271 272 if (tpm_legacy_probe(sc->sc_bt, sc->sc_bh)) { 273 sc->sc_init = tpm_legacy_init; 274 sc->sc_start = tpm_legacy_start; 275 sc->sc_read = tpm_legacy_read; 276 sc->sc_write = tpm_legacy_write; 277 sc->sc_end = tpm_legacy_end; 278 } else { 279 sc->sc_init = tpm_tis12_init; 280 sc->sc_start = tpm_tis12_start; 281 sc->sc_read = tpm_tis12_read; 282 sc->sc_write = tpm_tis12_write; 283 sc->sc_end = tpm_tis12_end; 284 } 285 286 printf("%s", device_get_name(dev)); 287 if ((sc->sc_init)(sc, irq, "tpm")) { 288 tpm_detach(dev); 289 return ENXIO; 290 } 291 292 if (sc->sc_init == tpm_tis12_init && sc->irq_res != NULL && 293 bus_setup_intr(dev, sc->irq_res, INTR_TYPE_TTY, NULL, 294 tpm_intr, sc, &sc->intr_cookie) != 0) { 295 tpm_detach(dev); 296 printf(": cannot establish interrupt\n"); 297 return 1; 298 } 299 300 sc->sc_cdev = make_dev(&tpm_cdevsw, device_get_unit(dev), 301 UID_ROOT, GID_WHEEL, 0600, "tpm"); 302 sc->sc_cdev->si_drv1 = sc; 303 304 return 0; 305 } 306 307 int 308 tpm_detach(device_t dev) 309 { 310 struct tpm_softc * sc = device_get_softc(dev); 311 312 if(sc->intr_cookie){ 313 bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); 314 } 315 316 if(sc->mem_res){ 317 bus_release_resource(dev, SYS_RES_MEMORY, 318 sc->mem_rid, sc->mem_res); 319 } 320 321 if(sc->irq_res){ 322 bus_release_resource(dev, SYS_RES_IRQ, 323 sc->irq_rid, sc->irq_res); 324 } 325 if(sc->sc_cdev){ 326 destroy_dev(sc->sc_cdev); 327 } 328 329 return 0; 330 } 331 332 #else 333 /* 334 * OpenBSD specific code for probing and attaching TPM to device tree. 335 */ 336 int 337 tpm_match(device_t parent, void *match, void *aux) 338 { 339 struct isa_attach_args *ia = aux; 340 struct cfdata *cf = match; 341 bus_space_tag_t bt = ia->ia_memt; 342 bus_space_handle_t bh; 343 int rv; 344 345 /* There can be only one. */ 346 if (cf->cf_unit) 347 return 0; 348 349 if (tpm_legacy_probe(ia->ia_iot, ia->ia_iobase)) { 350 ia->ia_iosize = 2; 351 return 1; 352 } 353 354 if (ia->ia_maddr == -1) 355 return 0; 356 357 if (bus_space_map(bt, ia->ia_maddr, TPM_SIZE, 0, &bh)) 358 return 0; 359 360 if ((rv = tpm_tis12_probe(bt, bh))) { 361 ia->ia_iosize = 0; 362 ia->ia_msize = TPM_SIZE; 363 } 364 365 bus_space_unmap(bt, bh, TPM_SIZE); 366 return rv; 367 } 368 369 void 370 tpm_attach(device_t parent, device_t self, void *aux) 371 { 372 struct tpm_softc *sc = (struct tpm_softc *)self; 373 struct isa_attach_args *ia = aux; 374 bus_addr_t iobase; 375 bus_size_t size; 376 int rv; 377 378 if (tpm_legacy_probe(ia->ia_iot, ia->ia_iobase)) { 379 sc->sc_bt = ia->ia_iot; 380 iobase = ia->ia_iobase; 381 size = ia->ia_iosize; 382 sc->sc_batm = ia->ia_iot; 383 sc->sc_init = tpm_legacy_init; 384 sc->sc_start = tpm_legacy_start; 385 sc->sc_read = tpm_legacy_read; 386 sc->sc_write = tpm_legacy_write; 387 sc->sc_end = tpm_legacy_end; 388 } else { 389 sc->sc_bt = ia->ia_memt; 390 iobase = ia->ia_maddr; 391 size = TPM_SIZE; 392 sc->sc_init = tpm_tis12_init; 393 sc->sc_start = tpm_tis12_start; 394 sc->sc_read = tpm_tis12_read; 395 sc->sc_write = tpm_tis12_write; 396 sc->sc_end = tpm_tis12_end; 397 } 398 399 if (bus_space_map(sc->sc_bt, iobase, size, 0, &sc->sc_bh)) { 400 printf(": cannot map registers\n"); 401 return; 402 } 403 404 if ((rv = (sc->sc_init)(sc, ia->ia_irq, sc->sc_dev.dv_xname))) { 405 bus_space_unmap(sc->sc_bt, sc->sc_bh, size); 406 return; 407 } 408 409 /* 410 * Only setup interrupt handler when we have a vector and the 411 * chip is TIS 1.2 compliant. 412 */ 413 if (sc->sc_init == tpm_tis12_init && ia->ia_irq != IRQUNK && 414 (sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 415 IPL_TTY, tpm_intr, sc, sc->sc_dev.dv_xname)) == NULL) { 416 bus_space_unmap(sc->sc_bt, sc->sc_bh, TPM_SIZE); 417 printf("%s: cannot establish interrupt\n", 418 sc->sc_dev.dv_xname); 419 return; 420 } 421 422 sc->sc_suspend = PWR_RESUME; 423 sc->sc_powerhook = powerhook_establish(tpm_powerhook, sc); 424 } 425 #endif 426 427 /* Probe TPM using TIS 1.2 interface. */ 428 int 429 tpm_tis12_probe(bus_space_tag_t bt, bus_space_handle_t bh) 430 { 431 u_int32_t r; 432 u_int8_t save, reg; 433 434 r = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITIES); 435 if (r == 0xffffffff) 436 return 0; 437 438 #ifdef TPM_DEBUG 439 printf("tpm: caps=%b\n", r, TPM_CAPBITS); 440 #endif 441 if ((r & TPM_CAPSREQ) != TPM_CAPSREQ || 442 !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) { 443 #ifdef TPM_DEBUG 444 printf("tpm: caps too low (caps=%b)\n", r, TPM_CAPBITS); 445 #endif 446 return 0; 447 } 448 449 save = bus_space_read_1(bt, bh, TPM_ACCESS); 450 bus_space_write_1(bt, bh, TPM_ACCESS, TPM_ACCESS_REQUEST_USE); 451 reg = bus_space_read_1(bt, bh, TPM_ACCESS); 452 if ((reg & TPM_ACCESS_VALID) && (reg & TPM_ACCESS_ACTIVE_LOCALITY) && 453 bus_space_read_4(bt, bh, TPM_ID) != 0xffffffff) 454 return 1; 455 456 bus_space_write_1(bt, bh, TPM_ACCESS, save); 457 return 0; 458 } 459 460 /* 461 * Setup interrupt vector if one is provided and interrupts are know to 462 * work on that particular chip. 463 */ 464 int 465 tpm_tis12_irqinit(struct tpm_softc *sc, int irq, int idx) 466 { 467 u_int32_t r; 468 469 if ((irq == IRQUNK) || (tpm_devs[idx].flags & TPM_DEV_NOINTS)) { 470 sc->sc_vector = IRQUNK; 471 return 0; 472 } 473 474 /* Ack and disable all interrupts. */ 475 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, 476 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) & 477 ~TPM_GLOBAL_INT_ENABLE); 478 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS, 479 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS)); 480 481 /* Program interrupt vector. */ 482 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_INT_VECTOR, irq); 483 sc->sc_vector = irq; 484 485 /* Program interrupt type. */ 486 if (sc->sc_capabilities & TPM_INTF_INT_EDGE_RISING) 487 r = TPM_INT_EDGE_RISING; 488 else if (sc->sc_capabilities & TPM_INTF_INT_LEVEL_HIGH) 489 r = TPM_INT_LEVEL_HIGH; 490 else 491 r = TPM_INT_LEVEL_LOW; 492 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, r); 493 494 return 0; 495 } 496 497 /* Setup TPM using TIS 1.2 interface. */ 498 int 499 tpm_tis12_init(struct tpm_softc *sc, int irq, const char *name) 500 { 501 u_int32_t r; 502 int i; 503 504 r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTF_CAPABILITIES); 505 #ifdef TPM_DEBUG 506 printf(" caps=%b ", r, TPM_CAPBITS); 507 #endif 508 if ((r & TPM_CAPSREQ) != TPM_CAPSREQ || 509 !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) { 510 printf(": capabilities too low (caps=%b)\n", r, TPM_CAPBITS); 511 return 1; 512 } 513 sc->sc_capabilities = r; 514 515 sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID); 516 sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV); 517 518 for (i = 0; tpm_devs[i].devid; i++) 519 if (tpm_devs[i].devid == sc->sc_devid) 520 break; 521 522 if (tpm_devs[i].devid) 523 printf(": %s rev 0x%x\n", tpm_devs[i].name, sc->sc_rev); 524 else 525 printf(": device 0x%08x rev 0x%x\n", sc->sc_devid, sc->sc_rev); 526 527 if (tpm_tis12_irqinit(sc, irq, i)) 528 return 1; 529 530 if (tpm_request_locality(sc, 0)) 531 return 1; 532 533 /* Abort whatever it thought it was doing. */ 534 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY); 535 536 return 0; 537 } 538 539 int 540 tpm_request_locality(struct tpm_softc *sc, int l) 541 { 542 u_int32_t r; 543 int to, rv; 544 545 if (l != 0) 546 return EINVAL; 547 548 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 549 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) == 550 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) 551 return 0; 552 553 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 554 TPM_ACCESS_REQUEST_USE); 555 556 to = tpm_tmotohz(TPM_ACCESS_TMO); 557 558 while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 559 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 560 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) { 561 rv = tsleep(sc->sc_init, PRIBIO | PCATCH, "tpm_locality", 1); 562 if (rv && rv != EWOULDBLOCK) { 563 #ifdef TPM_DEBUG 564 printf("tpm_request_locality: interrupted %d\n", rv); 565 #endif 566 return rv; 567 } 568 } 569 570 if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 571 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) { 572 #ifdef TPM_DEBUG 573 printf("tpm_request_locality: access %b\n", r, TPM_ACCESS_BITS); 574 #endif 575 return EBUSY; 576 } 577 578 return 0; 579 } 580 581 int 582 tpm_getburst(struct tpm_softc *sc) 583 { 584 int burst, to, rv; 585 586 to = tpm_tmotohz(TPM_BURST_TMO); 587 588 burst = 0; 589 while (burst == 0 && to--) { 590 /* 591 * Burst count has to be read from bits 8 to 23 without 592 * touching any other bits, eg. the actual status bits 0 593 * to 7. 594 */ 595 burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1); 596 burst |= bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2) 597 << 8; 598 #ifdef TPM_DEBUG 599 printf("tpm_getburst: read %d\n", burst); 600 #endif 601 if (burst) 602 return burst; 603 604 rv = tsleep(sc, PRIBIO | PCATCH, "tpm_getburst", 1); 605 if (rv && rv != EWOULDBLOCK) { 606 return 0; 607 } 608 } 609 610 return 0; 611 } 612 613 u_int8_t 614 tpm_status(struct tpm_softc *sc) 615 { 616 u_int8_t status; 617 618 status = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) & 619 TPM_STS_MASK; 620 621 return status; 622 } 623 624 int 625 tpm_tmotohz(int tmo) 626 { 627 struct timeval tv; 628 629 tv.tv_sec = tmo / 1000; 630 tv.tv_usec = 1000 * (tmo % 1000); 631 632 return tvtohz(&tv); 633 } 634 635 /* Save TPM state on suspend. */ 636 int 637 #ifdef __FreeBSD__ 638 tpm_suspend(device_t dev) 639 #else 640 tpm_suspend(struct tpm_softc *sc, int why) 641 #endif 642 { 643 #ifdef __FreeBSD__ 644 struct tpm_softc *sc = device_get_softc(dev); 645 int why = 1; 646 #endif 647 u_int8_t command[] = { 648 0, 193, /* TPM_TAG_RQU_COMMAND */ 649 0, 0, 0, 10, /* Length in bytes */ 650 0, 0, 0, 156 /* TPM_ORD_SaveStates */ 651 }; 652 653 /* 654 * Power down: We have to issue the SaveStates command. 655 */ 656 sc->sc_write(sc, &command, sizeof(command)); 657 sc->sc_read(sc, &command, sizeof(command), NULL, TPM_HDRSIZE); 658 #ifdef TPM_DEBUG 659 printf("tpm_suspend: power down: %d -> %d\n", sc->sc_suspend, why); 660 #endif 661 sc->sc_suspend = why; 662 663 return 0; 664 } 665 666 /* 667 * Handle resume event. Actually nothing to do as the BIOS is supposed 668 * to restore the previously saved state. 669 */ 670 int 671 #ifdef __FreeBSD__ 672 tpm_resume(device_t dev) 673 #else 674 tpm_resume(struct tpm_softc *sc, int why) 675 #endif 676 { 677 #ifdef __FreeBSD__ 678 struct tpm_softc *sc = device_get_softc(dev); 679 int why = 0; 680 #endif 681 #ifdef TPM_DEBUG 682 printf("tpm_resume: resume: %d -> %d\n", sc->sc_suspend, why); 683 #endif 684 sc->sc_suspend = why; 685 686 return 0; 687 } 688 689 /* Dispatch suspend and resume events. */ 690 #ifndef __FreeBSD__ 691 void 692 tpm_powerhook(int why, void *self) 693 { 694 struct tpm_softc *sc = (struct tpm_softc *)self; 695 696 if (why != PWR_RESUME) 697 tpm_suspend(sc, why); 698 else 699 tpm_resume(sc, why); 700 } 701 #endif /* !__FreeBSD__ */ 702 703 /* Wait for given status bits using polling. */ 704 int 705 tpm_waitfor_poll(struct tpm_softc *sc, u_int8_t mask, int tmo, void *c) 706 { 707 int rv; 708 709 /* 710 * Poll until either the requested condition or a time out is 711 * met. 712 */ 713 while (((sc->sc_stat = tpm_status(sc)) & mask) != mask && tmo--) { 714 rv = tsleep(c, PRIBIO | PCATCH, "tpm_poll", 1); 715 if (rv && rv != EWOULDBLOCK) { 716 #ifdef TPM_DEBUG 717 printf("tpm_waitfor_poll: interrupted %d\n", rv); 718 #endif 719 return rv; 720 } 721 } 722 723 return 0; 724 } 725 726 /* Wait for given status bits using interrupts. */ 727 int 728 tpm_waitfor_int(struct tpm_softc *sc, u_int8_t mask, int tmo, void *c, 729 int inttype) 730 { 731 int rv, to; 732 733 /* Poll and return when condition is already met. */ 734 sc->sc_stat = tpm_status(sc); 735 if ((sc->sc_stat & mask) == mask) 736 return 0; 737 738 /* 739 * Enable interrupt on tpm chip. Note that interrupts on our 740 * level (SPL_TTY) are disabled (see tpm{read,write} et al) and 741 * will not be delivered to the cpu until we call tsleep(9) below. 742 */ 743 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, 744 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) | 745 inttype); 746 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, 747 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) | 748 TPM_GLOBAL_INT_ENABLE); 749 750 /* 751 * Poll once more to remedy the race between previous polling 752 * and enabling interrupts on the tpm chip. 753 */ 754 sc->sc_stat = tpm_status(sc); 755 if ((sc->sc_stat & mask) == mask) { 756 rv = 0; 757 goto out; 758 } 759 760 to = tpm_tmotohz(tmo); 761 #ifdef TPM_DEBUG 762 printf("tpm_waitfor_int: sleeping for %d ticks on %p\n", to, c); 763 #endif 764 /* 765 * tsleep(9) enables interrupts on the cpu and returns after 766 * wake up with interrupts disabled again. Note that interrupts 767 * generated by the tpm chip while being at SPL_TTY are not lost 768 * but held and delivered as soon as the cpu goes below SPL_TTY. 769 */ 770 rv = tsleep(c, PRIBIO | PCATCH, "tpm_intr", to); 771 772 sc->sc_stat = tpm_status(sc); 773 #ifdef TPM_DEBUG 774 printf("tpm_waitfor_int: woke up with rv %d stat %b\n", rv, 775 sc->sc_stat, TPM_STS_BITS); 776 #endif 777 if ((sc->sc_stat & mask) == mask) 778 rv = 0; 779 780 /* Disable interrupts on tpm chip again. */ 781 out: bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, 782 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) & 783 ~TPM_GLOBAL_INT_ENABLE); 784 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, 785 bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) & 786 ~inttype); 787 788 return rv; 789 } 790 791 /* 792 * Wait on given status bits, uses interrupts where possible, otherwise polls. 793 */ 794 int 795 tpm_waitfor(struct tpm_softc *sc, u_int8_t b0, int tmo, void *c) 796 { 797 u_int8_t b; 798 int re, to, rv; 799 800 #ifdef TPM_DEBUG 801 printf("tpm_waitfor: b0 %b\n", b0, TPM_STS_BITS); 802 #endif 803 804 /* 805 * If possible, use interrupts, otherwise poll. 806 * 807 * We use interrupts for TPM_STS_VALID and TPM_STS_DATA_AVAIL (if 808 * the tpm chips supports them) as waiting for those can take 809 * really long. The other TPM_STS* are not needed very often 810 * so we do not support them. 811 */ 812 if (sc->sc_vector != IRQUNK) { 813 b = b0; 814 815 /* 816 * Wait for data ready. This interrupt only occurs 817 * when both TPM_STS_VALID and TPM_STS_DATA_AVAIL are asserted. 818 * Thus we don't have to bother with TPM_STS_VALID 819 * separately and can just return. 820 * 821 * This only holds for interrupts! When using polling 822 * both flags have to be waited for, see below. 823 */ 824 if ((b & TPM_STS_DATA_AVAIL) && (sc->sc_capabilities & 825 TPM_INTF_DATA_AVAIL_INT)) 826 return tpm_waitfor_int(sc, b, tmo, c, 827 TPM_DATA_AVAIL_INT); 828 829 /* Wait for status valid bit. */ 830 if ((b & TPM_STS_VALID) && (sc->sc_capabilities & 831 TPM_INTF_STS_VALID_INT)) { 832 rv = tpm_waitfor_int(sc, b, tmo, c, TPM_STS_VALID_INT); 833 if (rv != 0) 834 return rv; 835 else 836 b = b0 & ~TPM_STS_VALID; 837 } 838 839 /* 840 * When all flags are taken care of, return. Otherwise 841 * use polling for eg. TPM_STS_CMD_READY. 842 */ 843 if (b == 0) 844 return 0; 845 } 846 847 re = 3; 848 restart: 849 /* 850 * If requested wait for TPM_STS_VALID before dealing with 851 * any other flag. Eg. when both TPM_STS_DATA_AVAIL and TPM_STS_VALID 852 * are requested, wait for the latter first. 853 */ 854 b = b0; 855 if (b0 & TPM_STS_VALID) 856 b = TPM_STS_VALID; 857 858 to = tpm_tmotohz(tmo); 859 again: 860 if ((rv = tpm_waitfor_poll(sc, b, to, c)) != 0) 861 return rv; 862 863 if ((b & sc->sc_stat) == TPM_STS_VALID) { 864 /* Now wait for other flags. */ 865 b = b0 & ~TPM_STS_VALID; 866 to++; 867 goto again; 868 } 869 870 if ((sc->sc_stat & b) != b) { 871 #ifdef TPM_DEBUG 872 printf("tpm_waitfor: timeout: stat=%b b=%b\n", 873 sc->sc_stat, TPM_STS_BITS, b, TPM_STS_BITS); 874 #endif 875 if (re-- && (b0 & TPM_STS_VALID)) { 876 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 877 TPM_STS_RESP_RETRY); 878 goto restart; 879 } 880 return EIO; 881 } 882 883 return 0; 884 } 885 886 /* Start transaction. */ 887 int 888 tpm_tis12_start(struct tpm_softc *sc, int flag) 889 { 890 int rv; 891 892 if (flag == UIO_READ) { 893 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 894 TPM_READ_TMO, sc->sc_read); 895 return rv; 896 } 897 898 /* Own our (0th) locality. */ 899 if ((rv = tpm_request_locality(sc, 0)) != 0) 900 return rv; 901 902 sc->sc_stat = tpm_status(sc); 903 if (sc->sc_stat & TPM_STS_CMD_READY) { 904 #ifdef TPM_DEBUG 905 printf("tpm_tis12_start: UIO_WRITE status %b\n", sc->sc_stat, 906 TPM_STS_BITS); 907 #endif 908 return 0; 909 } 910 911 #ifdef TPM_DEBUG 912 printf("tpm_tis12_start: UIO_WRITE readying chip\n"); 913 #endif 914 915 /* Abort previous and restart. */ 916 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY); 917 if ((rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READY_TMO, 918 sc->sc_write))) { 919 #ifdef TPM_DEBUG 920 printf("tpm_tis12_start: UIO_WRITE readying failed %d\n", rv); 921 #endif 922 return rv; 923 } 924 925 #ifdef TPM_DEBUG 926 printf("tpm_tis12_start: UIO_WRITE readying done\n"); 927 #endif 928 929 return 0; 930 } 931 932 int 933 tpm_tis12_read(struct tpm_softc *sc, void *buf, int len, size_t *count, 934 int flags) 935 { 936 u_int8_t *p = buf; 937 size_t cnt; 938 int rv, n, bcnt; 939 940 #ifdef TPM_DEBUG 941 printf("tpm_tis12_read: len %d\n", len); 942 #endif 943 cnt = 0; 944 while (len > 0) { 945 if ((rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 946 TPM_READ_TMO, sc->sc_read))) 947 return rv; 948 949 bcnt = tpm_getburst(sc); 950 n = MIN(len, bcnt); 951 #ifdef TPM_DEBUG 952 printf("tpm_tis12_read: fetching %d, burst is %d\n", n, bcnt); 953 #endif 954 for (; n--; len--) { 955 *p++ = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA); 956 cnt++; 957 } 958 959 if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6) 960 break; 961 } 962 #ifdef TPM_DEBUG 963 printf("tpm_tis12_read: read %zd bytes, len %d\n", cnt, len); 964 #endif 965 966 if (count) 967 *count = cnt; 968 969 return 0; 970 } 971 972 int 973 tpm_tis12_write(struct tpm_softc *sc, void *buf, int len) 974 { 975 u_int8_t *p = buf; 976 size_t cnt; 977 int rv, r; 978 979 #ifdef TPM_DEBUG 980 printf("tpm_tis12_write: sc %p buf %p len %d\n", sc, buf, len); 981 #endif 982 983 if ((rv = tpm_request_locality(sc, 0)) != 0) 984 return rv; 985 986 cnt = 0; 987 while (cnt < len - 1) { 988 for (r = tpm_getburst(sc); r > 0 && cnt < len - 1; r--) { 989 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 990 cnt++; 991 } 992 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) { 993 #ifdef TPM_DEBUG 994 printf("tpm_tis12_write: failed burst rv %d\n", rv); 995 #endif 996 return rv; 997 } 998 sc->sc_stat = tpm_status(sc); 999 if (!(sc->sc_stat & TPM_STS_DATA_EXPECT)) { 1000 #ifdef TPM_DEBUG 1001 printf("tpm_tis12_write: failed rv %d stat=%b\n", rv, 1002 sc->sc_stat, TPM_STS_BITS); 1003 #endif 1004 return EIO; 1005 } 1006 } 1007 1008 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 1009 cnt++; 1010 1011 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) { 1012 #ifdef TPM_DEBUG 1013 printf("tpm_tis12_write: failed last byte rv %d\n", rv); 1014 #endif 1015 return rv; 1016 } 1017 if ((sc->sc_stat & TPM_STS_DATA_EXPECT) != 0) { 1018 #ifdef TPM_DEBUG 1019 printf("tpm_tis12_write: failed rv %d stat=%b\n", rv, 1020 sc->sc_stat, TPM_STS_BITS); 1021 #endif 1022 return EIO; 1023 } 1024 1025 #ifdef TPM_DEBUG 1026 printf("tpm_tis12_write: wrote %d byte\n", cnt); 1027 #endif 1028 1029 return 0; 1030 } 1031 1032 /* Finish transaction. */ 1033 int 1034 tpm_tis12_end(struct tpm_softc *sc, int flag, int err) 1035 { 1036 int rv = 0; 1037 1038 if (flag == UIO_READ) { 1039 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, 1040 sc->sc_read))) 1041 return rv; 1042 1043 /* Still more data? */ 1044 sc->sc_stat = tpm_status(sc); 1045 if (!err && ((sc->sc_stat & TPM_STS_DATA_AVAIL) == TPM_STS_DATA_AVAIL)) { 1046 #ifdef TPM_DEBUG 1047 printf("tpm_tis12_end: read failed stat=%b\n", 1048 sc->sc_stat, TPM_STS_BITS); 1049 #endif 1050 rv = EIO; 1051 } 1052 1053 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 1054 TPM_STS_CMD_READY); 1055 1056 /* Release our (0th) locality. */ 1057 bus_space_write_1(sc->sc_bt, sc->sc_bh,TPM_ACCESS, 1058 TPM_ACCESS_ACTIVE_LOCALITY); 1059 } else { 1060 /* Hungry for more? */ 1061 sc->sc_stat = tpm_status(sc); 1062 if (!err && (sc->sc_stat & TPM_STS_DATA_EXPECT)) { 1063 #ifdef TPM_DEBUG 1064 printf("tpm_tis12_end: write failed stat=%b\n", 1065 sc->sc_stat, TPM_STS_BITS); 1066 #endif 1067 rv = EIO; 1068 } 1069 1070 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 1071 err ? TPM_STS_CMD_READY : TPM_STS_GO); 1072 } 1073 1074 return rv; 1075 } 1076 1077 #ifdef __FreeBSD__ 1078 void 1079 #else 1080 int 1081 #endif 1082 tpm_intr(void *v) 1083 { 1084 struct tpm_softc *sc = v; 1085 u_int32_t r; 1086 #ifdef TPM_DEBUG 1087 static int cnt = 0; 1088 #endif 1089 1090 r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS); 1091 #ifdef TPM_DEBUG 1092 if (r != 0) 1093 printf("tpm_intr: int=%b (%d)\n", r, TPM_INTERRUPT_ENABLE_BITS, 1094 cnt); 1095 else 1096 cnt++; 1097 #endif 1098 if (!(r & (TPM_CMD_READY_INT | TPM_LOCALITY_CHANGE_INT | 1099 TPM_STS_VALID_INT | TPM_DATA_AVAIL_INT))) 1100 #ifdef __FreeBSD__ 1101 return; 1102 #else 1103 return 0; 1104 #endif 1105 if (r & TPM_STS_VALID_INT) 1106 wakeup(sc); 1107 1108 if (r & TPM_CMD_READY_INT) 1109 wakeup(sc->sc_write); 1110 1111 if (r & TPM_DATA_AVAIL_INT) 1112 wakeup(sc->sc_read); 1113 1114 if (r & TPM_LOCALITY_CHANGE_INT) 1115 wakeup(sc->sc_init); 1116 1117 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS, r); 1118 1119 #ifdef __FreeBSD__ 1120 return; 1121 #else 1122 return 1; 1123 #endif 1124 } 1125 1126 /* Read single byte using legacy interface. */ 1127 static inline u_int8_t 1128 tpm_legacy_in(bus_space_tag_t iot, bus_space_handle_t ioh, int reg) 1129 { 1130 bus_space_write_1(iot, ioh, 0, reg); 1131 return bus_space_read_1(iot, ioh, 1); 1132 } 1133 1134 #if 0 1135 /* Write single byte using legacy interface. */ 1136 static inline void 1137 tpm_legacy_out(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, u_int8_t v) 1138 { 1139 bus_space_write_1(iot, ioh, 0, reg); 1140 bus_space_write_1(iot, ioh, 1, v); 1141 } 1142 #endif 1143 1144 /* Probe for TPM using legacy interface. */ 1145 int 1146 tpm_legacy_probe(bus_space_tag_t iot, bus_addr_t iobase) 1147 { 1148 bus_space_handle_t ioh; 1149 u_int8_t r, v; 1150 int i, rv = 0; 1151 char id[8]; 1152 1153 if (!tpm_enabled || iobase == -1) 1154 return 0; 1155 1156 if (bus_space_map(iot, iobase, 2, 0, &ioh)) 1157 return 0; 1158 1159 v = bus_space_read_1(iot, ioh, 0); 1160 if (v == 0xff) { 1161 bus_space_unmap(iot, ioh, 2); 1162 return 0; 1163 } 1164 r = bus_space_read_1(iot, ioh, 1); 1165 1166 for (i = sizeof(id); i--; ) 1167 id[i] = tpm_legacy_in(iot, ioh, TPM_ID + i); 1168 1169 #ifdef TPM_DEBUG 1170 printf("tpm_legacy_probe %.4s %d.%d.%d.%d\n", 1171 &id[4], id[0], id[1], id[2], id[3]); 1172 #endif 1173 /* 1174 * The only chips using the legacy interface we are aware of are 1175 * by Atmel. For other chips more signature would have to be added. 1176 */ 1177 if (!bcmp(&id[4], "ATML", 4)) 1178 rv = 1; 1179 1180 if (!rv) { 1181 bus_space_write_1(iot, ioh, r, 1); 1182 bus_space_write_1(iot, ioh, v, 0); 1183 } 1184 bus_space_unmap(iot, ioh, 2); 1185 1186 return rv; 1187 } 1188 1189 /* Setup TPM using legacy interface. */ 1190 int 1191 tpm_legacy_init(struct tpm_softc *sc, int irq, const char *name) 1192 { 1193 char id[8]; 1194 u_int8_t ioh, iol; 1195 int i; 1196 1197 if ((i = bus_space_map(sc->sc_batm, tpm_enabled, 2, 0, &sc->sc_bahm))) { 1198 printf(": cannot map tpm registers (%d)\n", i); 1199 tpm_enabled = 0; 1200 return 1; 1201 } 1202 1203 for (i = sizeof(id); i--; ) 1204 id[i] = tpm_legacy_in(sc->sc_bt, sc->sc_bh, TPM_ID + i); 1205 1206 printf(": %.4s %d.%d @0x%x\n", &id[4], id[0], id[1], tpm_enabled); 1207 iol = tpm_enabled & 0xff; 1208 ioh = tpm_enabled >> 16; 1209 tpm_enabled = 0; 1210 1211 return 0; 1212 } 1213 1214 /* Start transaction. */ 1215 int 1216 tpm_legacy_start(struct tpm_softc *sc, int flag) 1217 { 1218 struct timeval tv; 1219 u_int8_t bits, r; 1220 int to, rv; 1221 1222 bits = flag == UIO_READ ? TPM_LEGACY_DA : 0; 1223 tv.tv_sec = TPM_LEGACY_TMO; 1224 tv.tv_usec = 0; 1225 to = tvtohz(&tv) / TPM_LEGACY_SLEEP; 1226 while (((r = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1)) & 1227 (TPM_LEGACY_BUSY|bits)) != bits && to--) { 1228 rv = tsleep(sc, PRIBIO | PCATCH, "legacy_tpm_start", 1229 TPM_LEGACY_SLEEP); 1230 if (rv && rv != EWOULDBLOCK) 1231 return rv; 1232 } 1233 1234 #if defined(TPM_DEBUG) && !defined(__FreeBSD__) 1235 printf("%s: bits %b\n", sc->sc_dev.dv_xname, r, TPM_LEGACY_BITS); 1236 #endif 1237 if ((r & (TPM_LEGACY_BUSY|bits)) != bits) 1238 return EIO; 1239 1240 return 0; 1241 } 1242 1243 int 1244 tpm_legacy_read(struct tpm_softc *sc, void *buf, int len, size_t *count, 1245 int flags) 1246 { 1247 u_int8_t *p; 1248 size_t cnt; 1249 int to, rv; 1250 1251 cnt = rv = 0; 1252 for (p = buf; !rv && len > 0; len--) { 1253 for (to = 1000; 1254 !(bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1) & 1255 TPM_LEGACY_DA); DELAY(1)) 1256 if (!to--) 1257 return EIO; 1258 1259 DELAY(TPM_LEGACY_DELAY); 1260 *p++ = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 0); 1261 cnt++; 1262 } 1263 1264 *count = cnt; 1265 return 0; 1266 } 1267 1268 int 1269 tpm_legacy_write(struct tpm_softc *sc, void *buf, int len) 1270 { 1271 u_int8_t *p; 1272 int n; 1273 1274 for (p = buf, n = len; n--; DELAY(TPM_LEGACY_DELAY)) { 1275 if (!n && len != TPM_BUFSIZ) { 1276 bus_space_write_1(sc->sc_batm, sc->sc_bahm, 1, 1277 TPM_LEGACY_LAST); 1278 DELAY(TPM_LEGACY_DELAY); 1279 } 1280 bus_space_write_1(sc->sc_batm, sc->sc_bahm, 0, *p++); 1281 } 1282 1283 return 0; 1284 } 1285 1286 /* Finish transaction. */ 1287 int 1288 tpm_legacy_end(struct tpm_softc *sc, int flag, int rv) 1289 { 1290 struct timeval tv; 1291 u_int8_t r; 1292 int to; 1293 1294 if (rv || flag == UIO_READ) 1295 bus_space_write_1(sc->sc_batm, sc->sc_bahm, 1, TPM_LEGACY_ABRT); 1296 else { 1297 tv.tv_sec = TPM_LEGACY_TMO; 1298 tv.tv_usec = 0; 1299 to = tvtohz(&tv) / TPM_LEGACY_SLEEP; 1300 while(((r = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1)) & 1301 TPM_LEGACY_BUSY) && to--) { 1302 rv = tsleep(sc, PRIBIO | PCATCH, "legacy_tpm_end", 1303 TPM_LEGACY_SLEEP); 1304 if (rv && rv != EWOULDBLOCK) 1305 return rv; 1306 } 1307 1308 #if defined(TPM_DEBUG) && !defined(__FreeBSD__) 1309 printf("%s: bits %b\n", sc->sc_dev.dv_xname, r, TPM_LEGACY_BITS); 1310 #endif 1311 if (r & TPM_LEGACY_BUSY) 1312 return EIO; 1313 1314 if (r & TPM_LEGACY_RE) 1315 return EIO; /* XXX Retry the loop? */ 1316 } 1317 1318 return rv; 1319 } 1320 1321 int 1322 #ifdef __FreeBSD__ 1323 tpmopen(struct cdev *dev, int flag, int mode, struct thread *td) 1324 #else 1325 tpmopen(dev_t dev, int flag, int mode, struct proc *p) 1326 #endif 1327 { 1328 struct tpm_softc *sc = TPMSOFTC(dev); 1329 1330 if (!sc) 1331 return ENXIO; 1332 1333 if (sc->sc_flags & TPM_OPEN) 1334 return EBUSY; 1335 1336 sc->sc_flags |= TPM_OPEN; 1337 1338 return 0; 1339 } 1340 1341 int 1342 #ifdef __FreeBSD__ 1343 tpmclose(struct cdev *dev, int flag, int mode, struct thread *td) 1344 #else 1345 tpmclose(dev_t dev, int flag, int mode, struct proc *p) 1346 #endif 1347 { 1348 struct tpm_softc *sc = TPMSOFTC(dev); 1349 1350 if (!sc) 1351 return ENXIO; 1352 1353 if (!(sc->sc_flags & TPM_OPEN)) 1354 return EINVAL; 1355 1356 sc->sc_flags &= ~TPM_OPEN; 1357 1358 return 0; 1359 } 1360 1361 int 1362 #ifdef __FreeBSD__ 1363 tpmread(struct cdev *dev, struct uio *uio, int flags) 1364 #else 1365 tpmread(dev_t dev, struct uio *uio, int flags) 1366 #endif 1367 { 1368 struct tpm_softc *sc = TPMSOFTC(dev); 1369 u_int8_t buf[TPM_BUFSIZ], *p; 1370 size_t cnt; 1371 int n, len, rv, s; 1372 1373 if (!sc) 1374 return ENXIO; 1375 1376 s = spltty(); 1377 if ((rv = (sc->sc_start)(sc, UIO_READ))) { 1378 splx(s); 1379 return rv; 1380 } 1381 1382 #ifdef TPM_DEBUG 1383 printf("tpmread: getting header\n"); 1384 #endif 1385 if ((rv = (sc->sc_read)(sc, buf, TPM_HDRSIZE, &cnt, 0))) { 1386 (sc->sc_end)(sc, UIO_READ, rv); 1387 splx(s); 1388 return rv; 1389 } 1390 1391 len = (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | buf[5]; 1392 #ifdef TPM_DEBUG 1393 printf("tpmread: len %d, io count %d\n", len, uio->uio_resid); 1394 #endif 1395 if (len > uio->uio_resid) { 1396 rv = EIO; 1397 (sc->sc_end)(sc, UIO_READ, rv); 1398 #ifdef TPM_DEBUG 1399 printf("tpmread: bad residual io count 0x%x\n", uio->uio_resid); 1400 #endif 1401 splx(s); 1402 return rv; 1403 } 1404 1405 /* Copy out header. */ 1406 if ((rv = uiomove((caddr_t)buf, cnt, uio))) { 1407 (sc->sc_end)(sc, UIO_READ, rv); 1408 splx(s); 1409 return rv; 1410 } 1411 1412 /* Get remaining part of the answer (if anything is left). */ 1413 for (len -= cnt, p = buf, n = sizeof(buf); len > 0; p = buf, len -= n, 1414 n = sizeof(buf)) { 1415 n = MIN(n, len); 1416 #ifdef TPM_DEBUG 1417 printf("tpmread: n %d len %d\n", n, len); 1418 #endif 1419 if ((rv = (sc->sc_read)(sc, p, n, NULL, TPM_PARAM_SIZE))) { 1420 (sc->sc_end)(sc, UIO_READ, rv); 1421 splx(s); 1422 return rv; 1423 } 1424 p += n; 1425 if ((rv = uiomove((caddr_t)buf, p - buf, uio))) { 1426 (sc->sc_end)(sc, UIO_READ, rv); 1427 splx(s); 1428 return rv; 1429 } 1430 } 1431 1432 rv = (sc->sc_end)(sc, UIO_READ, rv); 1433 splx(s); 1434 return rv; 1435 } 1436 1437 int 1438 #ifdef __FreeBSD__ 1439 tpmwrite(struct cdev *dev, struct uio *uio, int flags) 1440 #else 1441 tpmwrite(dev_t dev, struct uio *uio, int flags) 1442 #endif 1443 { 1444 struct tpm_softc *sc = TPMSOFTC(dev); 1445 u_int8_t buf[TPM_BUFSIZ]; 1446 int n, rv, s; 1447 1448 if (!sc) 1449 return ENXIO; 1450 1451 s = spltty(); 1452 1453 #ifdef TPM_DEBUG 1454 printf("tpmwrite: io count %d\n", uio->uio_resid); 1455 #endif 1456 1457 n = MIN(sizeof(buf), uio->uio_resid); 1458 if ((rv = uiomove((caddr_t)buf, n, uio))) { 1459 splx(s); 1460 return rv; 1461 } 1462 1463 if ((rv = (sc->sc_start)(sc, UIO_WRITE))) { 1464 splx(s); 1465 return rv; 1466 } 1467 1468 if ((rv = (sc->sc_write(sc, buf, n)))) { 1469 splx(s); 1470 return rv; 1471 } 1472 1473 rv = (sc->sc_end)(sc, UIO_WRITE, rv); 1474 splx(s); 1475 return rv; 1476 } 1477 1478 int 1479 #ifdef __FreeBSD__ 1480 tpmioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, 1481 struct thread *td) 1482 #else 1483 tpmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 1484 #endif 1485 { 1486 return ENOTTY; 1487 } 1488