1 /* $OpenBSD: tpm.c,v 1.2 2016/10/25 06:48:58 pirofti Exp $ */ 2 3 /* 4 * Minimal interface to Trusted Platform Module chips implementing the 5 * TPM Interface Spec 1.2, just enough to tell the TPM to save state before 6 * a system suspend. 7 * 8 * Copyright (c) 2008, 2009 Michael Shalayeff 9 * Copyright (c) 2009, 2010 Hans-Joerg Hoexer 10 * Copyright (c) 2016 joshua stein <jcs@openbsd.org> 11 * All rights reserved. 12 * 13 * Permission to use, copy, modify, and distribute this software for any 14 * purpose with or without fee is hereby granted, provided that the above 15 * copyright notice and this permission notice appear in all copies. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 18 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 20 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 22 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 23 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 */ 25 26 #include <sys/param.h> 27 #include <sys/systm.h> 28 #include <sys/device.h> 29 #include <sys/malloc.h> 30 31 #include <machine/bus.h> 32 #include <machine/apmvar.h> 33 34 #include <dev/acpi/acpireg.h> 35 #include <dev/acpi/acpivar.h> 36 #include <dev/acpi/acpidev.h> 37 #include <dev/acpi/amltypes.h> 38 #include <dev/acpi/dsdt.h> 39 40 /* #define TPM_DEBUG */ 41 42 #ifdef TPM_DEBUG 43 #define DPRINTF(x) printf x 44 #else 45 #define DPRINTF(x) 46 #endif 47 48 #define TPM_BUFSIZ 1024 49 #define TPM_HDRSIZE 10 50 #define TPM_PARAM_SIZE 0x0001 51 52 #define TPM_ACCESS 0x0000 /* access register */ 53 #define TPM_ACCESS_ESTABLISHMENT 0x01 /* establishment */ 54 #define TPM_ACCESS_REQUEST_USE 0x02 /* request using locality */ 55 #define TPM_ACCESS_REQUEST_PENDING 0x04 /* pending request */ 56 #define TPM_ACCESS_SEIZE 0x08 /* request locality seize */ 57 #define TPM_ACCESS_SEIZED 0x10 /* locality has been seized */ 58 #define TPM_ACCESS_ACTIVE_LOCALITY 0x20 /* locality is active */ 59 #define TPM_ACCESS_VALID 0x80 /* bits are valid */ 60 #define TPM_ACCESS_BITS \ 61 "\020\01EST\02REQ\03PEND\04SEIZE\05SEIZED\06ACT\010VALID" 62 63 #define TPM_INTERRUPT_ENABLE 0x0008 64 #define TPM_GLOBAL_INT_ENABLE 0x80000000 /* enable ints */ 65 #define TPM_CMD_READY_INT 0x00000080 /* cmd ready enable */ 66 #define TPM_INT_EDGE_FALLING 0x00000018 67 #define TPM_INT_EDGE_RISING 0x00000010 68 #define TPM_INT_LEVEL_LOW 0x00000008 69 #define TPM_INT_LEVEL_HIGH 0x00000000 70 #define TPM_LOCALITY_CHANGE_INT 0x00000004 /* locality change enable */ 71 #define TPM_STS_VALID_INT 0x00000002 /* int on TPM_STS_VALID is set */ 72 #define TPM_DATA_AVAIL_INT 0x00000001 /* int on TPM_STS_DATA_AVAIL is set */ 73 #define TPM_INTERRUPT_ENABLE_BITS \ 74 "\020\040ENA\010RDY\03LOCH\02STSV\01DRDY" 75 76 #define TPM_INT_VECTOR 0x000c /* 8 bit reg for 4 bit irq vector */ 77 #define TPM_INT_STATUS 0x0010 /* bits are & 0x87 from TPM_INTERRUPT_ENABLE */ 78 79 #define TPM_INTF_CAPABILITIES 0x0014 /* capability register */ 80 #define TPM_INTF_BURST_COUNT_STATIC 0x0100 /* TPM_STS_BMASK static */ 81 #define TPM_INTF_CMD_READY_INT 0x0080 /* int on ready supported */ 82 #define TPM_INTF_INT_EDGE_FALLING 0x0040 /* falling edge ints supported */ 83 #define TPM_INTF_INT_EDGE_RISING 0x0020 /* rising edge ints supported */ 84 #define TPM_INTF_INT_LEVEL_LOW 0x0010 /* level-low ints supported */ 85 #define TPM_INTF_INT_LEVEL_HIGH 0x0008 /* level-high ints supported */ 86 #define TPM_INTF_LOCALITY_CHANGE_INT 0x0004 /* locality-change int (mb 1) */ 87 #define TPM_INTF_STS_VALID_INT 0x0002 /* TPM_STS_VALID int supported */ 88 #define TPM_INTF_DATA_AVAIL_INT 0x0001 /* TPM_STS_DATA_AVAIL int supported (mb 1) */ 89 #define TPM_CAPSREQ \ 90 (TPM_INTF_DATA_AVAIL_INT|TPM_INTF_LOCALITY_CHANGE_INT|TPM_INTF_INT_LEVEL_LOW) 91 #define TPM_CAPBITS \ 92 "\020\01IDRDY\02ISTSV\03ILOCH\04IHIGH\05ILOW\06IEDGE\07IFALL\010IRDY\011BCST" 93 94 #define TPM_STS 0x0018 /* status register */ 95 #define TPM_STS_MASK 0x000000ff /* status bits */ 96 #define TPM_STS_BMASK 0x00ffff00 /* ro io burst size */ 97 #define TPM_STS_VALID 0x00000080 /* ro other bits are valid */ 98 #define TPM_STS_CMD_READY 0x00000040 /* rw chip/signal ready */ 99 #define TPM_STS_GO 0x00000020 /* wo start the command */ 100 #define TPM_STS_DATA_AVAIL 0x00000010 /* ro data available */ 101 #define TPM_STS_DATA_EXPECT 0x00000008 /* ro more data to be written */ 102 #define TPM_STS_RESP_RETRY 0x00000002 /* wo resend the response */ 103 #define TPM_STS_BITS "\020\010VALID\07RDY\06GO\05DRDY\04EXPECT\02RETRY" 104 105 #define TPM_DATA 0x0024 106 #define TPM_ID 0x0f00 107 #define TPM_REV 0x0f04 108 #define TPM_SIZE 0x5000 /* five pages of the above */ 109 110 #define TPM_ACCESS_TMO 2000 /* 2sec */ 111 #define TPM_READY_TMO 2000 /* 2sec */ 112 #define TPM_READ_TMO 120000 /* 2 minutes */ 113 #define TPM_BURST_TMO 2000 /* 2sec */ 114 115 struct tpm_softc { 116 struct device sc_dev; 117 118 bus_space_tag_t sc_bt; 119 bus_space_handle_t sc_bh; 120 121 struct acpi_softc *sc_acpi; 122 struct aml_node *sc_devnode; 123 124 uint32_t sc_devid; 125 uint32_t sc_rev; 126 127 int sc_enabled; 128 }; 129 130 struct tpm_crs { 131 int irq_int; 132 uint8_t irq_flags; 133 uint32_t addr_min; 134 uint32_t addr_bas; 135 uint32_t addr_len; 136 uint16_t i2c_addr; 137 struct aml_node *devnode; 138 struct aml_node *gpio_int_node; 139 uint16_t gpio_int_pin; 140 uint16_t gpio_int_flags; 141 }; 142 143 const struct { 144 uint32_t devid; 145 char name[32]; 146 } tpm_devs[] = { 147 { 0x000615d1, "Infineon SLD9630 1.1" }, 148 { 0x000b15d1, "Infineon SLB9635 1.2" }, 149 { 0x100214e4, "Broadcom BCM0102" }, 150 { 0x00fe1050, "WEC WPCT200" }, 151 { 0x687119fa, "SNS SSX35" }, 152 { 0x2e4d5453, "STM ST19WP18" }, 153 { 0x32021114, "Atmel 97SC3203" }, 154 { 0x10408086, "Intel INTC0102" }, 155 { 0, "" }, 156 }; 157 158 int tpm_match(struct device *, void *, void *); 159 void tpm_attach(struct device *, struct device *, void *); 160 int tpm_activate(struct device *, int); 161 int tpm_parse_crs(int, union acpi_resource *, void *); 162 163 int tpm_probe(bus_space_tag_t, bus_space_handle_t); 164 int tpm_init(struct tpm_softc *); 165 int tpm_read(struct tpm_softc *, void *, int, size_t *, int); 166 int tpm_write(struct tpm_softc *, void *, int); 167 int tpm_suspend(struct tpm_softc *); 168 int tpm_resume(struct tpm_softc *); 169 170 int tpm_waitfor(struct tpm_softc *, uint8_t, int); 171 int tpm_request_locality(struct tpm_softc *, int); 172 void tpm_release_locality(struct tpm_softc *); 173 int tpm_getburst(struct tpm_softc *); 174 uint8_t tpm_status(struct tpm_softc *); 175 int tpm_tmotohz(int); 176 177 struct cfattach tpm_ca = { 178 sizeof(struct tpm_softc), 179 tpm_match, 180 tpm_attach, 181 NULL, 182 tpm_activate 183 }; 184 185 struct cfdriver tpm_cd = { 186 NULL, "tpm", DV_DULL 187 }; 188 189 const char *tpm_hids[] = { 190 "PNP0C31", 191 "ATM1200", 192 "IFX0102", 193 "BCM0101", 194 "BCM0102", 195 "NSC1200", 196 "ICO0102", 197 0 198 }; 199 200 int 201 tpm_match(struct device *parent, void *match, void *aux) 202 { 203 struct acpi_attach_args *aa = aux; 204 struct cfdata *cf = match; 205 206 return (acpi_matchhids(aa, tpm_hids, cf->cf_driver->cd_name)); 207 } 208 209 void 210 tpm_attach(struct device *parent, struct device *self, void *aux) 211 { 212 struct tpm_softc *sc = (struct tpm_softc *)self; 213 struct acpi_attach_args *aa = aux; 214 struct tpm_crs crs; 215 struct aml_value res; 216 int64_t st; 217 218 sc->sc_acpi = (struct acpi_softc *)parent; 219 sc->sc_devnode = aa->aaa_node; 220 sc->sc_enabled = 0; 221 222 printf(": %s", sc->sc_devnode->name); 223 224 if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &st)) 225 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK; 226 if ((st & (STA_PRESENT | STA_ENABLED | STA_DEV_OK)) != 227 (STA_PRESENT | STA_ENABLED | STA_DEV_OK)) { 228 printf(", not enabled\n"); 229 return; 230 } 231 232 if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) { 233 printf(", no _CRS method\n"); 234 return; 235 } 236 if (res.type != AML_OBJTYPE_BUFFER || res.length < 5) { 237 printf(", invalid _CRS object (type %d len %d)\n", 238 res.type, res.length); 239 aml_freevalue(&res); 240 return; 241 } 242 memset(&crs, 0, sizeof(crs)); 243 crs.devnode = sc->sc_devnode; 244 aml_parse_resource(&res, tpm_parse_crs, &crs); 245 aml_freevalue(&res); 246 247 if (crs.addr_bas == 0) { 248 printf(", can't find address\n"); 249 return; 250 } 251 252 printf(" addr 0x%x/0x%x", crs.addr_bas, crs.addr_len); 253 254 sc->sc_bt = aa->aaa_memt; 255 if (bus_space_map(sc->sc_bt, crs.addr_bas, crs.addr_len, 0, 256 &sc->sc_bh)) { 257 printf(", failed mapping at 0x%x\n", crs.addr_bas); 258 return; 259 } 260 261 if (!tpm_probe(sc->sc_bt, sc->sc_bh)) { 262 printf(", probe failed\n"); 263 return; 264 } 265 266 if (tpm_init(sc) != 0) { 267 printf(", init failed\n"); 268 return; 269 } 270 271 sc->sc_enabled = 1; 272 } 273 274 int 275 tpm_parse_crs(int crsidx, union acpi_resource *crs, void *arg) 276 { 277 struct tpm_crs *sc_crs = arg; 278 279 switch (AML_CRSTYPE(crs)) { 280 case LR_MEM32: 281 sc_crs->addr_min = letoh32(crs->lr_m32._min); 282 sc_crs->addr_len = letoh32(crs->lr_m32._len); 283 break; 284 285 case LR_MEM32FIXED: 286 sc_crs->addr_bas = letoh32(crs->lr_m32fixed._bas); 287 sc_crs->addr_len = letoh32(crs->lr_m32fixed._len); 288 break; 289 290 case SR_IOPORT: 291 case SR_IRQ: 292 case LR_EXTIRQ: 293 case LR_GPIO: 294 break; 295 296 default: 297 DPRINTF(("%s: unknown resource type %d\n", __func__, 298 AML_CRSTYPE(crs))); 299 } 300 301 return 0; 302 } 303 304 int 305 tpm_activate(struct device *self, int act) 306 { 307 struct tpm_softc *sc = (struct tpm_softc *)self; 308 309 switch (act) { 310 case DVACT_SUSPEND: 311 if (!sc->sc_enabled) { 312 DPRINTF(("%s: suspend, but not enabled\n", 313 sc->sc_dev.dv_xname)); 314 return 0; 315 } 316 tpm_suspend(sc); 317 break; 318 319 case DVACT_WAKEUP: 320 if (!sc->sc_enabled) { 321 DPRINTF(("%s: wakeup, but not enabled\n", 322 sc->sc_dev.dv_xname)); 323 return 0; 324 } 325 tpm_resume(sc); 326 break; 327 } 328 329 return 0; 330 } 331 332 int 333 tpm_suspend(struct tpm_softc *sc) 334 { 335 uint8_t command[] = { 336 0, 0xc1, /* TPM_TAG_RQU_COMMAND */ 337 0, 0, 0, 10, /* Length in bytes */ 338 0, 0, 0, 0x98 /* TPM_ORD_SaveStates */ 339 }; 340 341 DPRINTF(("%s: saving state preparing for suspend\n", 342 sc->sc_dev.dv_xname)); 343 344 /* 345 * Tell the chip to save its state so the BIOS can then restore it upon 346 * resume. 347 */ 348 tpm_write(sc, &command, sizeof(command)); 349 tpm_read(sc, &command, sizeof(command), NULL, TPM_HDRSIZE); 350 351 return 0; 352 } 353 354 int 355 tpm_resume(struct tpm_softc *sc) 356 { 357 /* 358 * TODO: The BIOS should have restored the chip's state for us already, 359 * but we should tell the chip to do a self-test here (according to the 360 * Linux driver). 361 */ 362 363 DPRINTF(("%s: resume\n", sc->sc_dev.dv_xname)); 364 return 0; 365 } 366 367 int 368 tpm_probe(bus_space_tag_t bt, bus_space_handle_t bh) 369 { 370 uint32_t r; 371 int tries = 10000; 372 373 /* wait for chip to settle */ 374 while (tries--) { 375 if (bus_space_read_1(bt, bh, TPM_ACCESS) & TPM_ACCESS_VALID) 376 break; 377 else if (!tries) { 378 printf(": timed out waiting for validity\n"); 379 return 1; 380 } 381 382 DELAY(10); 383 } 384 385 r = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITIES); 386 if (r == 0xffffffff) 387 return 0; 388 389 return 1; 390 } 391 392 int 393 tpm_init(struct tpm_softc *sc) 394 { 395 uint32_t r, intmask; 396 int i; 397 398 r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTF_CAPABILITIES); 399 if ((r & TPM_CAPSREQ) != TPM_CAPSREQ || 400 !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) { 401 DPRINTF((": caps too low (caps=%b)\n", r, TPM_CAPBITS)); 402 return 0; 403 } 404 405 /* ack and disable all interrupts, we'll be using polling only */ 406 intmask = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE); 407 intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | 408 TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; 409 intmask &= ~TPM_GLOBAL_INT_ENABLE; 410 bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, intmask); 411 412 if (tpm_request_locality(sc, 0)) { 413 printf(", requesting locality failed\n"); 414 return 1; 415 } 416 417 sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID); 418 sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV); 419 420 for (i = 0; tpm_devs[i].devid; i++) 421 if (tpm_devs[i].devid == sc->sc_devid) 422 break; 423 424 if (tpm_devs[i].devid) 425 printf(": %s rev 0x%x\n", tpm_devs[i].name, sc->sc_rev); 426 else 427 printf(": device 0x%08x rev 0x%x\n", sc->sc_devid, sc->sc_rev); 428 429 return 0; 430 } 431 432 int 433 tpm_request_locality(struct tpm_softc *sc, int l) 434 { 435 uint32_t r; 436 int to; 437 438 if (l != 0) 439 return EINVAL; 440 441 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 442 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) == 443 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) 444 return 0; 445 446 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 447 TPM_ACCESS_REQUEST_USE); 448 449 to = tpm_tmotohz(TPM_ACCESS_TMO); 450 451 while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 452 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 453 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) { 454 DELAY(10); 455 } 456 457 if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 458 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) { 459 DPRINTF(("%s: %s: access %b\n", sc->sc_dev.dv_xname, __func__, 460 r, TPM_ACCESS_BITS)); 461 return EBUSY; 462 } 463 464 return 0; 465 } 466 467 void 468 tpm_release_locality(struct tpm_softc *sc) 469 { 470 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 471 (TPM_ACCESS_REQUEST_PENDING|TPM_ACCESS_VALID)) == 472 (TPM_ACCESS_REQUEST_PENDING|TPM_ACCESS_VALID)) { 473 DPRINTF(("%s: releasing locality\n", sc->sc_dev.dv_xname)); 474 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 475 TPM_ACCESS_ACTIVE_LOCALITY); 476 } 477 } 478 479 int 480 tpm_getburst(struct tpm_softc *sc) 481 { 482 int burst, burst2, to; 483 484 to = tpm_tmotohz(TPM_BURST_TMO); 485 486 burst = 0; 487 while (burst == 0 && to--) { 488 /* 489 * Burst count has to be read from bits 8 to 23 without 490 * touching any other bits, eg. the actual status bits 0 to 7. 491 */ 492 burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1); 493 DPRINTF(("%s: %s: read1(0x%x): 0x%x\n", sc->sc_dev.dv_xname, 494 __func__, TPM_STS + 1, burst)); 495 burst2 = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2); 496 DPRINTF(("%s: %s: read1(0x%x): 0x%x\n", sc->sc_dev.dv_xname, 497 __func__, TPM_STS + 2, burst2)); 498 burst |= burst2 << 8; 499 if (burst) 500 return burst; 501 502 DELAY(10); 503 } 504 505 DPRINTF(("%s: getburst timed out\n", sc->sc_dev.dv_xname)); 506 507 return 0; 508 } 509 510 uint8_t 511 tpm_status(struct tpm_softc *sc) 512 { 513 return bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) & TPM_STS_MASK; 514 } 515 516 int 517 tpm_tmotohz(int tmo) 518 { 519 struct timeval tv; 520 521 tv.tv_sec = tmo / 1000; 522 tv.tv_usec = 1000 * (tmo % 1000); 523 524 return tvtohz(&tv); 525 } 526 527 int 528 tpm_waitfor(struct tpm_softc *sc, uint8_t mask, int tries) 529 { 530 uint8_t status; 531 532 while (((status = tpm_status(sc)) & mask) != mask) { 533 if (tries == 0) { 534 DPRINTF(("%s: %s: timed out, status 0x%x != 0x%x\n", 535 sc->sc_dev.dv_xname, __func__, status, mask)); 536 return status; 537 } 538 539 tries--; 540 DELAY(1); 541 } 542 543 return 0; 544 } 545 546 int 547 tpm_read(struct tpm_softc *sc, void *buf, int len, size_t *count, 548 int flags) 549 { 550 uint8_t *p = buf; 551 uint8_t c; 552 size_t cnt; 553 int rv, n, bcnt; 554 555 DPRINTF(("%s: %s %d:", sc->sc_dev.dv_xname, __func__, len)); 556 557 cnt = 0; 558 while (len > 0) { 559 if ((rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 560 TPM_READ_TMO))) 561 return rv; 562 563 bcnt = tpm_getburst(sc); 564 n = MIN(len, bcnt); 565 566 for (; n--; len--) { 567 c = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA); 568 DPRINTF((" %02x", c)); 569 *p++ = c; 570 cnt++; 571 } 572 573 if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6) 574 break; 575 } 576 577 DPRINTF(("\n")); 578 579 if (count) 580 *count = cnt; 581 582 return 0; 583 } 584 585 int 586 tpm_write(struct tpm_softc *sc, void *buf, int len) 587 { 588 uint8_t *p = buf; 589 uint8_t status; 590 size_t count = 0; 591 int rv, r; 592 593 if ((rv = tpm_request_locality(sc, 0)) != 0) 594 return rv; 595 596 DPRINTF(("%s: %s %d:", sc->sc_dev.dv_xname, __func__, len)); 597 for (r = 0; r < len; r++) 598 DPRINTF((" %02x", (uint8_t)(*(p + r)))); 599 DPRINTF(("\n")); 600 601 /* read status */ 602 status = tpm_status(sc); 603 if ((status & TPM_STS_CMD_READY) == 0) { 604 /* abort! */ 605 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 606 TPM_STS_CMD_READY); 607 if ((rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READ_TMO))) { 608 DPRINTF(("%s: failed waiting for ready after abort " 609 "(0x%x)\n", sc->sc_dev.dv_xname, rv)); 610 return rv; 611 } 612 } 613 614 while (count < len - 1) { 615 for (r = tpm_getburst(sc); r > 0 && count < len - 1; r--) { 616 DPRINTF(("%s: %s: write1(0x%x, 0x%x)\n", 617 sc->sc_dev.dv_xname, __func__, TPM_DATA, *p)); 618 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 619 count++; 620 } 621 if ((rv = tpm_waitfor(sc, TPM_STS_VALID | TPM_STS_DATA_EXPECT, 622 TPM_READ_TMO))) { 623 DPRINTF(("%s: %s: failed waiting for next byte (%d)\n", 624 sc->sc_dev.dv_xname, __func__, rv)); 625 return rv; 626 } 627 } 628 629 DPRINTF(("%s: %s: write1(0x%x, 0x%x)\n", sc->sc_dev.dv_xname, __func__, 630 TPM_DATA, *p)); 631 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p); 632 count++; 633 634 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO))) { 635 DPRINTF(("%s: %s: failed after last byte (%d)\n", 636 sc->sc_dev.dv_xname, __func__, rv)); 637 return rv; 638 } 639 640 if ((status = tpm_status(sc)) & TPM_STS_DATA_EXPECT) { 641 DPRINTF(("%s: %s: final status still expecting data: %b\n", 642 sc->sc_dev.dv_xname, __func__, status, TPM_STS_BITS)); 643 return status; 644 } 645 646 DPRINTF(("%s: final status after write: %b\n", sc->sc_dev.dv_xname, 647 status, TPM_STS_BITS)); 648 649 /* XXX: are we ever sending non-command data? */ 650 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_GO); 651 652 return 0; 653 } 654