1/*- 2 * Copyright (c) 2018 Stormshield. 3 * Copyright (c) 2018 Semihalf. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD: stable/11/sys/dev/tpm/tpm_tis.c 346725 2019-04-26 01:58:36Z mw $"); 30 31#include "tpm20.h" 32 33/* 34 * TIS register space as defined in 35 * TCG_PC_Client_Platform_TPM_Profile_PTP_2.0_r1.03_v22 36 */ 37#define TPM_ACCESS 0x0 38#define TPM_INT_ENABLE 0x8 39#define TPM_INT_VECTOR 0xc 40#define TPM_INT_STS 0x10 41#define TPM_INTF_CAPS 0x14 42#define TPM_STS 0x18 43#define TPM_DATA_FIFO 0x24 44#define TPM_INTF_ID 0x30 45#define TPM_XDATA_FIFO 0x80 46#define TPM_DID_VID 0xF00 47#define TPM_RID 0xF04 48 49#define TPM_ACCESS_LOC_REQ BIT(1) 50#define TPM_ACCESS_LOC_Seize BIT(3) 51#define TPM_ACCESS_LOC_ACTIVE BIT(5) 52#define TPM_ACCESS_LOC_RELINQUISH BIT(5) 53#define TPM_ACCESS_VALID BIT(7) 54 55#define TPM_INT_ENABLE_GLOBAL_ENABLE BIT(31) 56#define TPM_INT_ENABLE_CMD_RDY BIT(7) 57#define TPM_INT_ENABLE_LOC_CHANGE BIT(2) 58#define TPM_INT_ENABLE_STS_VALID BIT(1) 59#define TPM_INT_ENABLE_DATA_AVAIL BIT(0) 60 61#define TPM_INT_STS_CMD_RDY BIT(7) 62#define TPM_INT_STS_LOC_CHANGE BIT(2) 63#define TPM_INT_STS_VALID BIT(1) 64#define TPM_INT_STS_DATA_AVAIL BIT(0) 65 66#define TPM_INTF_CAPS_VERSION 0x70000000 67#define TPM_INTF_CAPS_TPM20 0x30000000 68 69#define TPM_STS_VALID BIT(7) 70#define TPM_STS_CMD_RDY BIT(6) 71#define TPM_STS_CMD_START BIT(5) 72#define TPM_STS_DATA_AVAIL BIT(4) 73#define TPM_STS_DATA_EXPECTED BIT(3) 74#define TPM_STS_BURST_MASK 0xFFFF00 75#define TPM_STS_BURST_OFFSET 0x8 76 77static int tpmtis_transmit(struct tpm_sc *sc, size_t length); 78 79static int tpmtis_acpi_probe(device_t dev); 80static int tpmtis_attach(device_t dev); 81static int tpmtis_detach(device_t dev); 82 83static void tpmtis_intr_handler(void *arg); 84 85static ACPI_STATUS tpmtis_get_SIRQ_channel(ACPI_RESOURCE *res, void *arg); 86static bool tpmtis_setup_intr(struct tpm_sc *sc); 87 88static bool tpmtis_read_bytes(struct tpm_sc *sc, size_t count, uint8_t *buf); 89static bool tpmtis_write_bytes(struct tpm_sc *sc, size_t count, uint8_t *buf); 90static bool tpmtis_request_locality(struct tpm_sc *sc, int locality); 91static void tpmtis_relinquish_locality(struct tpm_sc *sc); 92static bool tpmtis_go_ready(struct tpm_sc *sc); 93 94static bool tpm_wait_for_u32(struct tpm_sc *sc, bus_size_t off, 95 uint32_t mask, uint32_t val, int32_t timeout); 96 97static uint16_t tpmtis_wait_for_burst(struct tpm_sc *sc); 98 99char *tpmtis_ids[] = {"MSFT0101", NULL}; 100 101static int 102tpmtis_acpi_probe(device_t dev) 103{ 104 int err = 0; 105 ACPI_TABLE_TPM2 *tbl; 106 ACPI_STATUS status; 107 108 if (ACPI_ID_PROBE(device_get_parent(dev), dev, tpmtis_ids) == NULL) 109 return (ENXIO); 110 111 /*Find TPM2 Header*/ 112 status = AcpiGetTable(ACPI_SIG_TPM2, 1, (ACPI_TABLE_HEADER **) &tbl); 113 if(ACPI_FAILURE(status) || 114 tbl->StartMethod != TPM2_START_METHOD_TIS) 115 err = ENXIO; 116 117 device_set_desc(dev, "Trusted Platform Module 2.0, FIFO mode"); 118 return (err); 119} 120 121static int 122tpmtis_attach(device_t dev) 123{ 124 struct tpm_sc *sc; 125 int result; 126 127 sc = device_get_softc(dev); 128 sc->dev = dev; 129 130 sc->mem_rid = 0; 131 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 132 RF_ACTIVE); 133 if (sc->mem_res == NULL) 134 return (ENXIO); 135 136 sc->irq_rid = 0; 137 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 138 RF_ACTIVE | RF_SHAREABLE); 139 if (sc->irq_res != NULL) { 140 if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 141 NULL, tpmtis_intr_handler, sc, &sc->intr_cookie)) 142 sc->interrupts = false; 143 else 144 sc->interrupts = tpmtis_setup_intr(sc); 145 } else { 146 sc->interrupts = false; 147 } 148 149 sc->intr_type = -1; 150 151 sc->transmit = tpmtis_transmit; 152 153 result = tpm20_init(sc); 154 if (result != 0) 155 tpmtis_detach(dev); 156 157 return (result); 158} 159 160static int 161tpmtis_detach(device_t dev) 162{ 163 struct tpm_sc *sc; 164 165 sc = device_get_softc(dev); 166 tpm20_release(sc); 167 168 if (sc->intr_cookie != NULL) 169 bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); 170 171 if (sc->irq_res != NULL) 172 bus_release_resource(dev, SYS_RES_IRQ, 173 sc->irq_rid, sc->irq_res); 174 175 if (sc->mem_res != NULL) 176 bus_release_resource(dev, SYS_RES_MEMORY, 177 sc->mem_rid, sc->mem_res); 178 179 return (0); 180} 181 182static ACPI_STATUS 183tpmtis_get_SIRQ_channel(ACPI_RESOURCE *res, void *arg) 184{ 185 struct tpm_sc *sc; 186 uint8_t channel; 187 188 sc = (struct tpm_sc *)arg; 189 190 switch (res->Type) { 191 case ACPI_RESOURCE_TYPE_IRQ: 192 channel = res->Data.Irq.Interrupts[0]; 193 break; 194 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 195 channel = res->Data.ExtendedIrq.Interrupts[0]; 196 break; 197 default: 198 return (AE_OK); 199 } 200 201 WR1(sc, TPM_INT_VECTOR, channel); 202 return (AE_OK); 203} 204 205static bool 206tpmtis_setup_intr(struct tpm_sc *sc) 207{ 208 ACPI_STATUS status; 209 ACPI_HANDLE handle; 210 uint32_t irq_mask; 211 212 handle = acpi_get_handle(sc->dev); 213 214 if(!tpmtis_request_locality(sc, 0)) 215 return (false); 216 217 irq_mask = RD4(sc, TPM_INT_ENABLE); 218 irq_mask |= TPM_INT_ENABLE_GLOBAL_ENABLE | 219 TPM_INT_ENABLE_DATA_AVAIL | 220 TPM_INT_ENABLE_LOC_CHANGE | 221 TPM_INT_ENABLE_CMD_RDY | 222 TPM_INT_ENABLE_STS_VALID; 223 WR4(sc, TPM_INT_ENABLE, irq_mask); 224 225 status = AcpiWalkResources(handle, "_CRS", 226 tpmtis_get_SIRQ_channel, (void *)sc); 227 228 tpmtis_relinquish_locality(sc); 229 230 return (ACPI_SUCCESS(status)); 231} 232 233static void 234tpmtis_intr_handler(void *arg) 235{ 236 struct tpm_sc *sc; 237 uint32_t status; 238 239 sc = (struct tpm_sc *)arg; 240 status = RD4(sc, TPM_INT_STS); 241 242 WR4(sc, TPM_INT_STS, status); 243 if (sc->intr_type != -1 && sc->intr_type & status) 244 wakeup(sc); 245} 246 247static bool 248tpm_wait_for_u32(struct tpm_sc *sc, bus_size_t off, uint32_t mask, uint32_t val, 249 int32_t timeout) 250{ 251 252 /* Check for condition */ 253 if ((RD4(sc, off) & mask) == val) 254 return (true); 255 256 /* If interrupts are enabled sleep for timeout duration */ 257 if(sc->interrupts && sc->intr_type != -1) { 258 tsleep(sc, PWAIT, "TPM WITH INTERRUPTS", timeout / tick); 259 260 sc->intr_type = -1; 261 return ((RD4(sc, off) & mask) == val); 262 } 263 264 /* If we don't have interrupts poll the device every tick */ 265 while (timeout > 0) { 266 if ((RD4(sc, off) & mask) == val) 267 return (true); 268 269 pause("TPM POLLING", 1); 270 timeout -= tick; 271 } 272 return (false); 273} 274 275static uint16_t 276tpmtis_wait_for_burst(struct tpm_sc *sc) 277{ 278 int timeout; 279 uint16_t burst_count; 280 281 timeout = TPM_TIMEOUT_A; 282 283 while (timeout-- > 0) { 284 burst_count = (RD4(sc, TPM_STS) & TPM_STS_BURST_MASK) >> 285 TPM_STS_BURST_OFFSET; 286 if (burst_count > 0) 287 break; 288 289 DELAY(1); 290 } 291 return (burst_count); 292} 293 294static bool 295tpmtis_read_bytes(struct tpm_sc *sc, size_t count, uint8_t *buf) 296{ 297 uint16_t burst_count; 298 299 while (count > 0) { 300 burst_count = tpmtis_wait_for_burst(sc); 301 if (burst_count == 0) 302 return (false); 303 304 burst_count = MIN(burst_count, count); 305 count -= burst_count; 306 307 while (burst_count-- > 0) 308 *buf++ = RD1(sc, TPM_DATA_FIFO); 309 } 310 311 return (true); 312} 313 314static bool 315tpmtis_write_bytes(struct tpm_sc *sc, size_t count, uint8_t *buf) 316{ 317 uint16_t burst_count; 318 319 while (count > 0) { 320 burst_count = tpmtis_wait_for_burst(sc); 321 if (burst_count == 0) 322 return (false); 323 324 burst_count = MIN(burst_count, count); 325 count -= burst_count; 326 327 while (burst_count-- > 0) 328 WR1(sc, TPM_DATA_FIFO, *buf++); 329 } 330 331 return (true); 332} 333 334 335static bool 336tpmtis_request_locality(struct tpm_sc *sc, int locality) 337{ 338 uint8_t mask; 339 int timeout; 340 341 /* Currently we only support Locality 0 */ 342 if (locality != 0) 343 return (false); 344 345 mask = TPM_ACCESS_LOC_ACTIVE | TPM_ACCESS_VALID; 346 timeout = TPM_TIMEOUT_A; 347 sc->intr_type = TPM_INT_STS_LOC_CHANGE; 348 349 WR1(sc, TPM_ACCESS, TPM_ACCESS_LOC_REQ); 350 bus_barrier(sc->mem_res, TPM_ACCESS, 1, BUS_SPACE_BARRIER_WRITE); 351 if(sc->interrupts) { 352 tsleep(sc, PWAIT, "TPMLOCREQUEST with INTR", timeout / tick); 353 return ((RD1(sc, TPM_ACCESS) & mask) == mask); 354 } else { 355 while(timeout > 0) { 356 if ((RD1(sc, TPM_ACCESS) & mask) == mask) 357 return (true); 358 359 pause("TPMLOCREQUEST POLLING", 1); 360 timeout -= tick; 361 } 362 } 363 364 return (false); 365} 366 367static void 368tpmtis_relinquish_locality(struct tpm_sc *sc) 369{ 370 371 /* 372 * Interrupts can only be cleared when a locality is active. 373 * Clear them now in case interrupt handler didn't make it in time. 374 */ 375 if(sc->interrupts) 376 AND4(sc, TPM_INT_STS, RD4(sc, TPM_INT_STS)); 377 378 OR1(sc, TPM_ACCESS, TPM_ACCESS_LOC_RELINQUISH); 379} 380 381static bool 382tpmtis_go_ready(struct tpm_sc *sc) 383{ 384 uint32_t mask; 385 386 mask = TPM_STS_CMD_RDY; 387 sc->intr_type = TPM_INT_STS_CMD_RDY; 388 389 OR4(sc, TPM_STS, TPM_STS_CMD_RDY); 390 bus_barrier(sc->mem_res, TPM_STS, 4, BUS_SPACE_BARRIER_WRITE); 391 if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, TPM_TIMEOUT_B)) 392 return (false); 393 394 AND4(sc, TPM_STS, ~TPM_STS_CMD_RDY); 395 return (true); 396} 397 398static int 399tpmtis_transmit(struct tpm_sc *sc, size_t length) 400{ 401 size_t bytes_available; 402 uint32_t mask, curr_cmd; 403 int timeout; 404 405 sx_assert(&sc->dev_lock, SA_XLOCKED); 406 407 if (!tpmtis_request_locality(sc, 0)) { 408 device_printf(sc->dev, 409 "Failed to obtain locality\n"); 410 return (EIO); 411 } 412 if (!tpmtis_go_ready(sc)) { 413 device_printf(sc->dev, 414 "Failed to switch to ready state\n"); 415 return (EIO); 416 } 417 if (!tpmtis_write_bytes(sc, length, sc->buf)) { 418 device_printf(sc->dev, 419 "Failed to write cmd to device\n"); 420 return (EIO); 421 } 422 423 mask = TPM_STS_VALID; 424 sc->intr_type = TPM_INT_STS_VALID; 425 if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, TPM_TIMEOUT_C)) { 426 device_printf(sc->dev, 427 "Timeout while waiting for valid bit\n"); 428 return (EIO); 429 } 430 if (RD4(sc, TPM_STS) & TPM_STS_DATA_EXPECTED) { 431 device_printf(sc->dev, 432 "Device expects more data even though we already" 433 " sent everything we had\n"); 434 return (EIO); 435 } 436 437 /* 438 * Calculate timeout for current command. 439 * Command code is passed in bytes 6-10. 440 */ 441 curr_cmd = be32toh(*(uint32_t *) (&sc->buf[6])); 442 timeout = tpm20_get_timeout(curr_cmd); 443 444 WR4(sc, TPM_STS, TPM_STS_CMD_START); 445 bus_barrier(sc->mem_res, TPM_STS, 4, BUS_SPACE_BARRIER_WRITE); 446 447 mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID; 448 sc->intr_type = TPM_INT_STS_DATA_AVAIL; 449 if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, timeout)) { 450 device_printf(sc->dev, 451 "Timeout while waiting for device to process cmd\n"); 452 /* 453 * Switching to ready state also cancels processing 454 * current command 455 */ 456 if (!tpmtis_go_ready(sc)) 457 return (EIO); 458 459 /* 460 * After canceling a command we should get a response, 461 * check if there is one. 462 */ 463 sc->intr_type = TPM_INT_STS_DATA_AVAIL; 464 if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, TPM_TIMEOUT_C)) 465 return (EIO); 466 } 467 /* Read response header. Length is passed in bytes 2 - 6. */ 468 if(!tpmtis_read_bytes(sc, TPM_HEADER_SIZE, sc->buf)) { 469 device_printf(sc->dev, 470 "Failed to read response header\n"); 471 return (EIO); 472 } 473 bytes_available = be32toh(*(uint32_t *) (&sc->buf[2])); 474 475 if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) { 476 device_printf(sc->dev, 477 "Incorrect response size: %zu\n", 478 bytes_available); 479 return (EIO); 480 } 481 if(!tpmtis_read_bytes(sc, bytes_available - TPM_HEADER_SIZE, 482 &sc->buf[TPM_HEADER_SIZE])) { 483 device_printf(sc->dev, 484 "Failed to read response\n"); 485 return (EIO); 486 } 487 tpmtis_relinquish_locality(sc); 488 sc->pending_data_length = bytes_available; 489 490 return (0); 491} 492 493/* ACPI Driver */ 494static device_method_t tpmtis_methods[] = { 495 DEVMETHOD(device_probe, tpmtis_acpi_probe), 496 DEVMETHOD(device_attach, tpmtis_attach), 497 DEVMETHOD(device_detach, tpmtis_detach), 498 DEVMETHOD(device_shutdown, tpm20_shutdown), 499 DEVMETHOD(device_suspend, tpm20_suspend), 500 {0, 0} 501}; 502static driver_t tpmtis_driver = { 503 "tpmtis", tpmtis_methods, sizeof(struct tpm_sc), 504}; 505 506devclass_t tpmtis_devclass; 507DRIVER_MODULE(tpmtis, acpi, tpmtis_driver, tpmtis_devclass, 0, 0); 508