1 /* 2 * tpm_tis.c - QEMU's TPM TIS interface emulator 3 * 4 * Copyright (C) 2006,2010-2013 IBM Corporation 5 * 6 * Authors: 7 * Stefan Berger <stefanb@us.ibm.com> 8 * David Safford <safford@us.ibm.com> 9 * 10 * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at> 11 * 12 * This work is licensed under the terms of the GNU GPL, version 2 or later. 13 * See the COPYING file in the top-level directory. 14 * 15 * Implementation of the TIS interface according to specs found at 16 * http://www.trustedcomputinggroup.org. This implementation currently 17 * supports version 1.3, 21 March 2013 18 * In the developers menu choose the PC Client section then find the TIS 19 * specification. 20 * 21 * TPM TIS for TPM 2 implementation following TCG PC Client Platform 22 * TPM Profile (PTP) Specification, Familiy 2.0, Revision 00.43 23 */ 24 25 #include "qemu/osdep.h" 26 #include "hw/isa/isa.h" 27 #include "qapi/error.h" 28 29 #include "hw/acpi/tpm.h" 30 #include "hw/pci/pci_ids.h" 31 #include "sysemu/tpm_backend.h" 32 #include "tpm_int.h" 33 #include "tpm_util.h" 34 35 #define TPM_TIS_NUM_LOCALITIES 5 /* per spec */ 36 #define TPM_TIS_LOCALITY_SHIFT 12 37 #define TPM_TIS_NO_LOCALITY 0xff 38 39 #define TPM_TIS_IS_VALID_LOCTY(x) ((x) < TPM_TIS_NUM_LOCALITIES) 40 41 #define TPM_TIS_BUFFER_MAX 4096 42 43 typedef enum { 44 TPM_TIS_STATE_IDLE = 0, 45 TPM_TIS_STATE_READY, 46 TPM_TIS_STATE_COMPLETION, 47 TPM_TIS_STATE_EXECUTION, 48 TPM_TIS_STATE_RECEPTION, 49 } TPMTISState; 50 51 /* locality data -- all fields are persisted */ 52 typedef struct TPMLocality { 53 TPMTISState state; 54 uint8_t access; 55 uint32_t sts; 56 uint32_t iface_id; 57 uint32_t inte; 58 uint32_t ints; 59 } TPMLocality; 60 61 typedef struct TPMState { 62 ISADevice busdev; 63 MemoryRegion mmio; 64 65 unsigned char buffer[TPM_TIS_BUFFER_MAX]; 66 uint16_t rw_offset; 67 68 uint8_t active_locty; 69 uint8_t aborting_locty; 70 uint8_t next_locty; 71 72 TPMLocality loc[TPM_TIS_NUM_LOCALITIES]; 73 74 qemu_irq irq; 75 uint32_t irq_num; 76 77 TPMBackendCmd cmd; 78 79 TPMBackend *be_driver; 80 TPMVersion be_tpm_version; 81 82 size_t be_buffer_size; 83 } TPMState; 84 85 #define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS) 86 87 #define DEBUG_TIS 0 88 89 #define DPRINTF(fmt, ...) do { \ 90 if (DEBUG_TIS) { \ 91 printf(fmt, ## __VA_ARGS__); \ 92 } \ 93 } while (0) 94 95 /* tis registers */ 96 #define TPM_TIS_REG_ACCESS 0x00 97 #define TPM_TIS_REG_INT_ENABLE 0x08 98 #define TPM_TIS_REG_INT_VECTOR 0x0c 99 #define TPM_TIS_REG_INT_STATUS 0x10 100 #define TPM_TIS_REG_INTF_CAPABILITY 0x14 101 #define TPM_TIS_REG_STS 0x18 102 #define TPM_TIS_REG_DATA_FIFO 0x24 103 #define TPM_TIS_REG_INTERFACE_ID 0x30 104 #define TPM_TIS_REG_DATA_XFIFO 0x80 105 #define TPM_TIS_REG_DATA_XFIFO_END 0xbc 106 #define TPM_TIS_REG_DID_VID 0xf00 107 #define TPM_TIS_REG_RID 0xf04 108 109 /* vendor-specific registers */ 110 #define TPM_TIS_REG_DEBUG 0xf90 111 112 #define TPM_TIS_STS_TPM_FAMILY_MASK (0x3 << 26)/* TPM 2.0 */ 113 #define TPM_TIS_STS_TPM_FAMILY1_2 (0 << 26) /* TPM 2.0 */ 114 #define TPM_TIS_STS_TPM_FAMILY2_0 (1 << 26) /* TPM 2.0 */ 115 #define TPM_TIS_STS_RESET_ESTABLISHMENT_BIT (1 << 25) /* TPM 2.0 */ 116 #define TPM_TIS_STS_COMMAND_CANCEL (1 << 24) /* TPM 2.0 */ 117 118 #define TPM_TIS_STS_VALID (1 << 7) 119 #define TPM_TIS_STS_COMMAND_READY (1 << 6) 120 #define TPM_TIS_STS_TPM_GO (1 << 5) 121 #define TPM_TIS_STS_DATA_AVAILABLE (1 << 4) 122 #define TPM_TIS_STS_EXPECT (1 << 3) 123 #define TPM_TIS_STS_SELFTEST_DONE (1 << 2) 124 #define TPM_TIS_STS_RESPONSE_RETRY (1 << 1) 125 126 #define TPM_TIS_BURST_COUNT_SHIFT 8 127 #define TPM_TIS_BURST_COUNT(X) \ 128 ((X) << TPM_TIS_BURST_COUNT_SHIFT) 129 130 #define TPM_TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) 131 #define TPM_TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) 132 #define TPM_TIS_ACCESS_BEEN_SEIZED (1 << 4) 133 #define TPM_TIS_ACCESS_SEIZE (1 << 3) 134 #define TPM_TIS_ACCESS_PENDING_REQUEST (1 << 2) 135 #define TPM_TIS_ACCESS_REQUEST_USE (1 << 1) 136 #define TPM_TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) 137 138 #define TPM_TIS_INT_ENABLED (1 << 31) 139 #define TPM_TIS_INT_DATA_AVAILABLE (1 << 0) 140 #define TPM_TIS_INT_STS_VALID (1 << 1) 141 #define TPM_TIS_INT_LOCALITY_CHANGED (1 << 2) 142 #define TPM_TIS_INT_COMMAND_READY (1 << 7) 143 144 #define TPM_TIS_INT_POLARITY_MASK (3 << 3) 145 #define TPM_TIS_INT_POLARITY_LOW_LEVEL (1 << 3) 146 147 #define TPM_TIS_INTERRUPTS_SUPPORTED (TPM_TIS_INT_LOCALITY_CHANGED | \ 148 TPM_TIS_INT_DATA_AVAILABLE | \ 149 TPM_TIS_INT_STS_VALID | \ 150 TPM_TIS_INT_COMMAND_READY) 151 152 #define TPM_TIS_CAP_INTERFACE_VERSION1_3 (2 << 28) 153 #define TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 (3 << 28) 154 #define TPM_TIS_CAP_DATA_TRANSFER_64B (3 << 9) 155 #define TPM_TIS_CAP_DATA_TRANSFER_LEGACY (0 << 9) 156 #define TPM_TIS_CAP_BURST_COUNT_DYNAMIC (0 << 8) 157 #define TPM_TIS_CAP_INTERRUPT_LOW_LEVEL (1 << 4) /* support is mandatory */ 158 #define TPM_TIS_CAPABILITIES_SUPPORTED1_3 \ 159 (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \ 160 TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \ 161 TPM_TIS_CAP_DATA_TRANSFER_64B | \ 162 TPM_TIS_CAP_INTERFACE_VERSION1_3 | \ 163 TPM_TIS_INTERRUPTS_SUPPORTED) 164 165 #define TPM_TIS_CAPABILITIES_SUPPORTED2_0 \ 166 (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \ 167 TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \ 168 TPM_TIS_CAP_DATA_TRANSFER_64B | \ 169 TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 | \ 170 TPM_TIS_INTERRUPTS_SUPPORTED) 171 172 #define TPM_TIS_IFACE_ID_INTERFACE_TIS1_3 (0xf) /* TPM 2.0 */ 173 #define TPM_TIS_IFACE_ID_INTERFACE_FIFO (0x0) /* TPM 2.0 */ 174 #define TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO (0 << 4) /* TPM 2.0 */ 175 #define TPM_TIS_IFACE_ID_CAP_5_LOCALITIES (1 << 8) /* TPM 2.0 */ 176 #define TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED (1 << 13) /* TPM 2.0 */ 177 #define TPM_TIS_IFACE_ID_INT_SEL_LOCK (1 << 19) /* TPM 2.0 */ 178 179 #define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3 \ 180 (TPM_TIS_IFACE_ID_INTERFACE_TIS1_3 | \ 181 (~0u << 4)/* all of it is don't care */) 182 183 /* if backend was a TPM 2.0: */ 184 #define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0 \ 185 (TPM_TIS_IFACE_ID_INTERFACE_FIFO | \ 186 TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO | \ 187 TPM_TIS_IFACE_ID_CAP_5_LOCALITIES | \ 188 TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED) 189 190 #define TPM_TIS_TPM_DID 0x0001 191 #define TPM_TIS_TPM_VID PCI_VENDOR_ID_IBM 192 #define TPM_TIS_TPM_RID 0x0001 193 194 #define TPM_TIS_NO_DATA_BYTE 0xff 195 196 /* local prototypes */ 197 198 static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr, 199 unsigned size); 200 201 /* utility functions */ 202 203 static uint8_t tpm_tis_locality_from_addr(hwaddr addr) 204 { 205 return (uint8_t)((addr >> TPM_TIS_LOCALITY_SHIFT) & 0x7); 206 } 207 208 static void tpm_tis_show_buffer(const unsigned char *buffer, 209 size_t buffer_size, const char *string) 210 { 211 #ifdef DEBUG_TIS 212 uint32_t len, i; 213 214 len = MIN(tpm_cmd_get_size(buffer), buffer_size); 215 DPRINTF("tpm_tis: %s length = %d\n", string, len); 216 for (i = 0; i < len; i++) { 217 if (i && !(i % 16)) { 218 DPRINTF("\n"); 219 } 220 DPRINTF("%.2X ", buffer[i]); 221 } 222 DPRINTF("\n"); 223 #endif 224 } 225 226 /* 227 * Set the given flags in the STS register by clearing the register but 228 * preserving the SELFTEST_DONE and TPM_FAMILY_MASK flags and then setting 229 * the new flags. 230 * 231 * The SELFTEST_DONE flag is acquired from the backend that determines it by 232 * peeking into TPM commands. 233 * 234 * A VM suspend/resume will preserve the flag by storing it into the VM 235 * device state, but the backend will not remember it when QEMU is started 236 * again. Therefore, we cache the flag here. Once set, it will not be unset 237 * except by a reset. 238 */ 239 static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags) 240 { 241 l->sts &= TPM_TIS_STS_SELFTEST_DONE | TPM_TIS_STS_TPM_FAMILY_MASK; 242 l->sts |= flags; 243 } 244 245 /* 246 * Send a request to the TPM. 247 */ 248 static void tpm_tis_tpm_send(TPMState *s, uint8_t locty) 249 { 250 tpm_tis_show_buffer(s->buffer, s->be_buffer_size, 251 "tpm_tis: To TPM"); 252 253 /* 254 * rw_offset serves as length indicator for length of data; 255 * it's reset when the response comes back 256 */ 257 s->loc[locty].state = TPM_TIS_STATE_EXECUTION; 258 259 s->cmd = (TPMBackendCmd) { 260 .locty = locty, 261 .in = s->buffer, 262 .in_len = s->rw_offset, 263 .out = s->buffer, 264 .out_len = s->be_buffer_size, 265 }; 266 267 tpm_backend_deliver_request(s->be_driver, &s->cmd); 268 } 269 270 /* raise an interrupt if allowed */ 271 static void tpm_tis_raise_irq(TPMState *s, uint8_t locty, uint32_t irqmask) 272 { 273 if (!TPM_TIS_IS_VALID_LOCTY(locty)) { 274 return; 275 } 276 277 if ((s->loc[locty].inte & TPM_TIS_INT_ENABLED) && 278 (s->loc[locty].inte & irqmask)) { 279 DPRINTF("tpm_tis: Raising IRQ for flag %08x\n", irqmask); 280 qemu_irq_raise(s->irq); 281 s->loc[locty].ints |= irqmask; 282 } 283 } 284 285 static uint32_t tpm_tis_check_request_use_except(TPMState *s, uint8_t locty) 286 { 287 uint8_t l; 288 289 for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) { 290 if (l == locty) { 291 continue; 292 } 293 if ((s->loc[l].access & TPM_TIS_ACCESS_REQUEST_USE)) { 294 return 1; 295 } 296 } 297 298 return 0; 299 } 300 301 static void tpm_tis_new_active_locality(TPMState *s, uint8_t new_active_locty) 302 { 303 bool change = (s->active_locty != new_active_locty); 304 bool is_seize; 305 uint8_t mask; 306 307 if (change && TPM_TIS_IS_VALID_LOCTY(s->active_locty)) { 308 is_seize = TPM_TIS_IS_VALID_LOCTY(new_active_locty) && 309 s->loc[new_active_locty].access & TPM_TIS_ACCESS_SEIZE; 310 311 if (is_seize) { 312 mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY); 313 } else { 314 mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY| 315 TPM_TIS_ACCESS_REQUEST_USE); 316 } 317 /* reset flags on the old active locality */ 318 s->loc[s->active_locty].access &= mask; 319 320 if (is_seize) { 321 s->loc[s->active_locty].access |= TPM_TIS_ACCESS_BEEN_SEIZED; 322 } 323 } 324 325 s->active_locty = new_active_locty; 326 327 DPRINTF("tpm_tis: Active locality is now %d\n", s->active_locty); 328 329 if (TPM_TIS_IS_VALID_LOCTY(new_active_locty)) { 330 /* set flags on the new active locality */ 331 s->loc[new_active_locty].access |= TPM_TIS_ACCESS_ACTIVE_LOCALITY; 332 s->loc[new_active_locty].access &= ~(TPM_TIS_ACCESS_REQUEST_USE | 333 TPM_TIS_ACCESS_SEIZE); 334 } 335 336 if (change) { 337 tpm_tis_raise_irq(s, s->active_locty, TPM_TIS_INT_LOCALITY_CHANGED); 338 } 339 } 340 341 /* abort -- this function switches the locality */ 342 static void tpm_tis_abort(TPMState *s, uint8_t locty) 343 { 344 s->rw_offset = 0; 345 346 DPRINTF("tpm_tis: tis_abort: new active locality is %d\n", s->next_locty); 347 348 /* 349 * Need to react differently depending on who's aborting now and 350 * which locality will become active afterwards. 351 */ 352 if (s->aborting_locty == s->next_locty) { 353 s->loc[s->aborting_locty].state = TPM_TIS_STATE_READY; 354 tpm_tis_sts_set(&s->loc[s->aborting_locty], 355 TPM_TIS_STS_COMMAND_READY); 356 tpm_tis_raise_irq(s, s->aborting_locty, TPM_TIS_INT_COMMAND_READY); 357 } 358 359 /* locality after abort is another one than the current one */ 360 tpm_tis_new_active_locality(s, s->next_locty); 361 362 s->next_locty = TPM_TIS_NO_LOCALITY; 363 /* nobody's aborting a command anymore */ 364 s->aborting_locty = TPM_TIS_NO_LOCALITY; 365 } 366 367 /* prepare aborting current command */ 368 static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty) 369 { 370 uint8_t busy_locty; 371 372 s->aborting_locty = locty; 373 s->next_locty = newlocty; /* locality after successful abort */ 374 375 /* 376 * only abort a command using an interrupt if currently executing 377 * a command AND if there's a valid connection to the vTPM. 378 */ 379 for (busy_locty = 0; busy_locty < TPM_TIS_NUM_LOCALITIES; busy_locty++) { 380 if (s->loc[busy_locty].state == TPM_TIS_STATE_EXECUTION) { 381 /* 382 * request the backend to cancel. Some backends may not 383 * support it 384 */ 385 tpm_backend_cancel_cmd(s->be_driver); 386 return; 387 } 388 } 389 390 tpm_tis_abort(s, locty); 391 } 392 393 /* 394 * Callback from the TPM to indicate that the response was received. 395 */ 396 static void tpm_tis_request_completed(TPMIf *ti) 397 { 398 TPMState *s = TPM(ti); 399 uint8_t locty = s->cmd.locty; 400 uint8_t l; 401 402 if (s->cmd.selftest_done) { 403 for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) { 404 s->loc[locty].sts |= TPM_TIS_STS_SELFTEST_DONE; 405 } 406 } 407 408 tpm_tis_sts_set(&s->loc[locty], 409 TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE); 410 s->loc[locty].state = TPM_TIS_STATE_COMPLETION; 411 s->rw_offset = 0; 412 413 tpm_tis_show_buffer(s->buffer, s->be_buffer_size, 414 "tpm_tis: From TPM"); 415 416 if (TPM_TIS_IS_VALID_LOCTY(s->next_locty)) { 417 tpm_tis_abort(s, locty); 418 } 419 420 tpm_tis_raise_irq(s, locty, 421 TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID); 422 } 423 424 /* 425 * Read a byte of response data 426 */ 427 static uint32_t tpm_tis_data_read(TPMState *s, uint8_t locty) 428 { 429 uint32_t ret = TPM_TIS_NO_DATA_BYTE; 430 uint16_t len; 431 432 if ((s->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) { 433 len = MIN(tpm_cmd_get_size(&s->buffer), 434 s->be_buffer_size); 435 436 ret = s->buffer[s->rw_offset++]; 437 if (s->rw_offset >= len) { 438 /* got last byte */ 439 tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID); 440 tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID); 441 } 442 DPRINTF("tpm_tis: tpm_tis_data_read byte 0x%02x [%d]\n", 443 ret, s->rw_offset - 1); 444 } 445 446 return ret; 447 } 448 449 #ifdef DEBUG_TIS 450 static void tpm_tis_dump_state(void *opaque, hwaddr addr) 451 { 452 static const unsigned regs[] = { 453 TPM_TIS_REG_ACCESS, 454 TPM_TIS_REG_INT_ENABLE, 455 TPM_TIS_REG_INT_VECTOR, 456 TPM_TIS_REG_INT_STATUS, 457 TPM_TIS_REG_INTF_CAPABILITY, 458 TPM_TIS_REG_STS, 459 TPM_TIS_REG_DID_VID, 460 TPM_TIS_REG_RID, 461 0xfff}; 462 int idx; 463 uint8_t locty = tpm_tis_locality_from_addr(addr); 464 hwaddr base = addr & ~0xfff; 465 TPMState *s = opaque; 466 467 DPRINTF("tpm_tis: active locality : %d\n" 468 "tpm_tis: state of locality %d : %d\n" 469 "tpm_tis: register dump:\n", 470 s->active_locty, 471 locty, s->loc[locty].state); 472 473 for (idx = 0; regs[idx] != 0xfff; idx++) { 474 DPRINTF("tpm_tis: 0x%04x : 0x%08x\n", regs[idx], 475 (int)tpm_tis_mmio_read(opaque, base + regs[idx], 4)); 476 } 477 478 DPRINTF("tpm_tis: r/w offset : %d\n" 479 "tpm_tis: result buffer : ", 480 s->rw_offset); 481 for (idx = 0; 482 idx < MIN(tpm_cmd_get_size(&s->buffer), s->be_buffer_size); 483 idx++) { 484 DPRINTF("%c%02x%s", 485 s->rw_offset == idx ? '>' : ' ', 486 s->buffer[idx], 487 ((idx & 0xf) == 0xf) ? "\ntpm_tis: " : ""); 488 } 489 DPRINTF("\n"); 490 } 491 #endif 492 493 /* 494 * Read a register of the TIS interface 495 * See specs pages 33-63 for description of the registers 496 */ 497 static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr, 498 unsigned size) 499 { 500 TPMState *s = opaque; 501 uint16_t offset = addr & 0xffc; 502 uint8_t shift = (addr & 0x3) * 8; 503 uint32_t val = 0xffffffff; 504 uint8_t locty = tpm_tis_locality_from_addr(addr); 505 uint32_t avail; 506 uint8_t v; 507 508 if (tpm_backend_had_startup_error(s->be_driver)) { 509 return 0; 510 } 511 512 switch (offset) { 513 case TPM_TIS_REG_ACCESS: 514 /* never show the SEIZE flag even though we use it internally */ 515 val = s->loc[locty].access & ~TPM_TIS_ACCESS_SEIZE; 516 /* the pending flag is always calculated */ 517 if (tpm_tis_check_request_use_except(s, locty)) { 518 val |= TPM_TIS_ACCESS_PENDING_REQUEST; 519 } 520 val |= !tpm_backend_get_tpm_established_flag(s->be_driver); 521 break; 522 case TPM_TIS_REG_INT_ENABLE: 523 val = s->loc[locty].inte; 524 break; 525 case TPM_TIS_REG_INT_VECTOR: 526 val = s->irq_num; 527 break; 528 case TPM_TIS_REG_INT_STATUS: 529 val = s->loc[locty].ints; 530 break; 531 case TPM_TIS_REG_INTF_CAPABILITY: 532 switch (s->be_tpm_version) { 533 case TPM_VERSION_UNSPEC: 534 val = 0; 535 break; 536 case TPM_VERSION_1_2: 537 val = TPM_TIS_CAPABILITIES_SUPPORTED1_3; 538 break; 539 case TPM_VERSION_2_0: 540 val = TPM_TIS_CAPABILITIES_SUPPORTED2_0; 541 break; 542 } 543 break; 544 case TPM_TIS_REG_STS: 545 if (s->active_locty == locty) { 546 if ((s->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) { 547 val = TPM_TIS_BURST_COUNT( 548 MIN(tpm_cmd_get_size(&s->buffer), 549 s->be_buffer_size) 550 - s->rw_offset) | s->loc[locty].sts; 551 } else { 552 avail = s->be_buffer_size - s->rw_offset; 553 /* 554 * byte-sized reads should not return 0x00 for 0x100 555 * available bytes. 556 */ 557 if (size == 1 && avail > 0xff) { 558 avail = 0xff; 559 } 560 val = TPM_TIS_BURST_COUNT(avail) | s->loc[locty].sts; 561 } 562 } 563 break; 564 case TPM_TIS_REG_DATA_FIFO: 565 case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END: 566 if (s->active_locty == locty) { 567 if (size > 4 - (addr & 0x3)) { 568 /* prevent access beyond FIFO */ 569 size = 4 - (addr & 0x3); 570 } 571 val = 0; 572 shift = 0; 573 while (size > 0) { 574 switch (s->loc[locty].state) { 575 case TPM_TIS_STATE_COMPLETION: 576 v = tpm_tis_data_read(s, locty); 577 break; 578 default: 579 v = TPM_TIS_NO_DATA_BYTE; 580 break; 581 } 582 val |= (v << shift); 583 shift += 8; 584 size--; 585 } 586 shift = 0; /* no more adjustments */ 587 } 588 break; 589 case TPM_TIS_REG_INTERFACE_ID: 590 val = s->loc[locty].iface_id; 591 break; 592 case TPM_TIS_REG_DID_VID: 593 val = (TPM_TIS_TPM_DID << 16) | TPM_TIS_TPM_VID; 594 break; 595 case TPM_TIS_REG_RID: 596 val = TPM_TIS_TPM_RID; 597 break; 598 #ifdef DEBUG_TIS 599 case TPM_TIS_REG_DEBUG: 600 tpm_tis_dump_state(opaque, addr); 601 break; 602 #endif 603 } 604 605 if (shift) { 606 val >>= shift; 607 } 608 609 DPRINTF("tpm_tis: read.%u(%08x) = %08x\n", size, (int)addr, (int)val); 610 611 return val; 612 } 613 614 /* 615 * Write a value to a register of the TIS interface 616 * See specs pages 33-63 for description of the registers 617 */ 618 static void tpm_tis_mmio_write(void *opaque, hwaddr addr, 619 uint64_t val, unsigned size) 620 { 621 TPMState *s = opaque; 622 uint16_t off = addr & 0xffc; 623 uint8_t shift = (addr & 0x3) * 8; 624 uint8_t locty = tpm_tis_locality_from_addr(addr); 625 uint8_t active_locty, l; 626 int c, set_new_locty = 1; 627 uint16_t len; 628 uint32_t mask = (size == 1) ? 0xff : ((size == 2) ? 0xffff : ~0); 629 630 DPRINTF("tpm_tis: write.%u(%08x) = %08x\n", size, (int)addr, (int)val); 631 632 if (locty == 4) { 633 DPRINTF("tpm_tis: Access to locality 4 only allowed from hardware\n"); 634 return; 635 } 636 637 if (tpm_backend_had_startup_error(s->be_driver)) { 638 return; 639 } 640 641 val &= mask; 642 643 if (shift) { 644 val <<= shift; 645 mask <<= shift; 646 } 647 648 mask ^= 0xffffffff; 649 650 switch (off) { 651 case TPM_TIS_REG_ACCESS: 652 653 if ((val & TPM_TIS_ACCESS_SEIZE)) { 654 val &= ~(TPM_TIS_ACCESS_REQUEST_USE | 655 TPM_TIS_ACCESS_ACTIVE_LOCALITY); 656 } 657 658 active_locty = s->active_locty; 659 660 if ((val & TPM_TIS_ACCESS_ACTIVE_LOCALITY)) { 661 /* give up locality if currently owned */ 662 if (s->active_locty == locty) { 663 DPRINTF("tpm_tis: Releasing locality %d\n", locty); 664 665 uint8_t newlocty = TPM_TIS_NO_LOCALITY; 666 /* anybody wants the locality ? */ 667 for (c = TPM_TIS_NUM_LOCALITIES - 1; c >= 0; c--) { 668 if ((s->loc[c].access & TPM_TIS_ACCESS_REQUEST_USE)) { 669 DPRINTF("tpm_tis: Locality %d requests use.\n", c); 670 newlocty = c; 671 break; 672 } 673 } 674 DPRINTF("tpm_tis: TPM_TIS_ACCESS_ACTIVE_LOCALITY: " 675 "Next active locality: %d\n", 676 newlocty); 677 678 if (TPM_TIS_IS_VALID_LOCTY(newlocty)) { 679 set_new_locty = 0; 680 tpm_tis_prep_abort(s, locty, newlocty); 681 } else { 682 active_locty = TPM_TIS_NO_LOCALITY; 683 } 684 } else { 685 /* not currently the owner; clear a pending request */ 686 s->loc[locty].access &= ~TPM_TIS_ACCESS_REQUEST_USE; 687 } 688 } 689 690 if ((val & TPM_TIS_ACCESS_BEEN_SEIZED)) { 691 s->loc[locty].access &= ~TPM_TIS_ACCESS_BEEN_SEIZED; 692 } 693 694 if ((val & TPM_TIS_ACCESS_SEIZE)) { 695 /* 696 * allow seize if a locality is active and the requesting 697 * locality is higher than the one that's active 698 * OR 699 * allow seize for requesting locality if no locality is 700 * active 701 */ 702 while ((TPM_TIS_IS_VALID_LOCTY(s->active_locty) && 703 locty > s->active_locty) || 704 !TPM_TIS_IS_VALID_LOCTY(s->active_locty)) { 705 bool higher_seize = FALSE; 706 707 /* already a pending SEIZE ? */ 708 if ((s->loc[locty].access & TPM_TIS_ACCESS_SEIZE)) { 709 break; 710 } 711 712 /* check for ongoing seize by a higher locality */ 713 for (l = locty + 1; l < TPM_TIS_NUM_LOCALITIES; l++) { 714 if ((s->loc[l].access & TPM_TIS_ACCESS_SEIZE)) { 715 higher_seize = TRUE; 716 break; 717 } 718 } 719 720 if (higher_seize) { 721 break; 722 } 723 724 /* cancel any seize by a lower locality */ 725 for (l = 0; l < locty - 1; l++) { 726 s->loc[l].access &= ~TPM_TIS_ACCESS_SEIZE; 727 } 728 729 s->loc[locty].access |= TPM_TIS_ACCESS_SEIZE; 730 DPRINTF("tpm_tis: TPM_TIS_ACCESS_SEIZE: " 731 "Locality %d seized from locality %d\n", 732 locty, s->active_locty); 733 DPRINTF("tpm_tis: TPM_TIS_ACCESS_SEIZE: Initiating abort.\n"); 734 set_new_locty = 0; 735 tpm_tis_prep_abort(s, s->active_locty, locty); 736 break; 737 } 738 } 739 740 if ((val & TPM_TIS_ACCESS_REQUEST_USE)) { 741 if (s->active_locty != locty) { 742 if (TPM_TIS_IS_VALID_LOCTY(s->active_locty)) { 743 s->loc[locty].access |= TPM_TIS_ACCESS_REQUEST_USE; 744 } else { 745 /* no locality active -> make this one active now */ 746 active_locty = locty; 747 } 748 } 749 } 750 751 if (set_new_locty) { 752 tpm_tis_new_active_locality(s, active_locty); 753 } 754 755 break; 756 case TPM_TIS_REG_INT_ENABLE: 757 if (s->active_locty != locty) { 758 break; 759 } 760 761 s->loc[locty].inte &= mask; 762 s->loc[locty].inte |= (val & (TPM_TIS_INT_ENABLED | 763 TPM_TIS_INT_POLARITY_MASK | 764 TPM_TIS_INTERRUPTS_SUPPORTED)); 765 break; 766 case TPM_TIS_REG_INT_VECTOR: 767 /* hard wired -- ignore */ 768 break; 769 case TPM_TIS_REG_INT_STATUS: 770 if (s->active_locty != locty) { 771 break; 772 } 773 774 /* clearing of interrupt flags */ 775 if (((val & TPM_TIS_INTERRUPTS_SUPPORTED)) && 776 (s->loc[locty].ints & TPM_TIS_INTERRUPTS_SUPPORTED)) { 777 s->loc[locty].ints &= ~val; 778 if (s->loc[locty].ints == 0) { 779 qemu_irq_lower(s->irq); 780 DPRINTF("tpm_tis: Lowering IRQ\n"); 781 } 782 } 783 s->loc[locty].ints &= ~(val & TPM_TIS_INTERRUPTS_SUPPORTED); 784 break; 785 case TPM_TIS_REG_STS: 786 if (s->active_locty != locty) { 787 break; 788 } 789 790 if (s->be_tpm_version == TPM_VERSION_2_0) { 791 /* some flags that are only supported for TPM 2 */ 792 if (val & TPM_TIS_STS_COMMAND_CANCEL) { 793 if (s->loc[locty].state == TPM_TIS_STATE_EXECUTION) { 794 /* 795 * request the backend to cancel. Some backends may not 796 * support it 797 */ 798 tpm_backend_cancel_cmd(s->be_driver); 799 } 800 } 801 802 if (val & TPM_TIS_STS_RESET_ESTABLISHMENT_BIT) { 803 if (locty == 3 || locty == 4) { 804 tpm_backend_reset_tpm_established_flag(s->be_driver, locty); 805 } 806 } 807 } 808 809 val &= (TPM_TIS_STS_COMMAND_READY | TPM_TIS_STS_TPM_GO | 810 TPM_TIS_STS_RESPONSE_RETRY); 811 812 if (val == TPM_TIS_STS_COMMAND_READY) { 813 switch (s->loc[locty].state) { 814 815 case TPM_TIS_STATE_READY: 816 s->rw_offset = 0; 817 break; 818 819 case TPM_TIS_STATE_IDLE: 820 tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_COMMAND_READY); 821 s->loc[locty].state = TPM_TIS_STATE_READY; 822 tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY); 823 break; 824 825 case TPM_TIS_STATE_EXECUTION: 826 case TPM_TIS_STATE_RECEPTION: 827 /* abort currently running command */ 828 DPRINTF("tpm_tis: %s: Initiating abort.\n", 829 __func__); 830 tpm_tis_prep_abort(s, locty, locty); 831 break; 832 833 case TPM_TIS_STATE_COMPLETION: 834 s->rw_offset = 0; 835 /* shortcut to ready state with C/R set */ 836 s->loc[locty].state = TPM_TIS_STATE_READY; 837 if (!(s->loc[locty].sts & TPM_TIS_STS_COMMAND_READY)) { 838 tpm_tis_sts_set(&s->loc[locty], 839 TPM_TIS_STS_COMMAND_READY); 840 tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY); 841 } 842 s->loc[locty].sts &= ~(TPM_TIS_STS_DATA_AVAILABLE); 843 break; 844 845 } 846 } else if (val == TPM_TIS_STS_TPM_GO) { 847 switch (s->loc[locty].state) { 848 case TPM_TIS_STATE_RECEPTION: 849 if ((s->loc[locty].sts & TPM_TIS_STS_EXPECT) == 0) { 850 tpm_tis_tpm_send(s, locty); 851 } 852 break; 853 default: 854 /* ignore */ 855 break; 856 } 857 } else if (val == TPM_TIS_STS_RESPONSE_RETRY) { 858 switch (s->loc[locty].state) { 859 case TPM_TIS_STATE_COMPLETION: 860 s->rw_offset = 0; 861 tpm_tis_sts_set(&s->loc[locty], 862 TPM_TIS_STS_VALID| 863 TPM_TIS_STS_DATA_AVAILABLE); 864 break; 865 default: 866 /* ignore */ 867 break; 868 } 869 } 870 break; 871 case TPM_TIS_REG_DATA_FIFO: 872 case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END: 873 /* data fifo */ 874 if (s->active_locty != locty) { 875 break; 876 } 877 878 if (s->loc[locty].state == TPM_TIS_STATE_IDLE || 879 s->loc[locty].state == TPM_TIS_STATE_EXECUTION || 880 s->loc[locty].state == TPM_TIS_STATE_COMPLETION) { 881 /* drop the byte */ 882 } else { 883 DPRINTF("tpm_tis: Data to send to TPM: %08x (size=%d)\n", 884 (int)val, size); 885 if (s->loc[locty].state == TPM_TIS_STATE_READY) { 886 s->loc[locty].state = TPM_TIS_STATE_RECEPTION; 887 tpm_tis_sts_set(&s->loc[locty], 888 TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID); 889 } 890 891 val >>= shift; 892 if (size > 4 - (addr & 0x3)) { 893 /* prevent access beyond FIFO */ 894 size = 4 - (addr & 0x3); 895 } 896 897 while ((s->loc[locty].sts & TPM_TIS_STS_EXPECT) && size > 0) { 898 if (s->rw_offset < s->be_buffer_size) { 899 s->buffer[s->rw_offset++] = 900 (uint8_t)val; 901 val >>= 8; 902 size--; 903 } else { 904 tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID); 905 } 906 } 907 908 /* check for complete packet */ 909 if (s->rw_offset > 5 && 910 (s->loc[locty].sts & TPM_TIS_STS_EXPECT)) { 911 /* we have a packet length - see if we have all of it */ 912 bool need_irq = !(s->loc[locty].sts & TPM_TIS_STS_VALID); 913 914 len = tpm_cmd_get_size(&s->buffer); 915 if (len > s->rw_offset) { 916 tpm_tis_sts_set(&s->loc[locty], 917 TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID); 918 } else { 919 /* packet complete */ 920 tpm_tis_sts_set(&s->loc[locty], TPM_TIS_STS_VALID); 921 } 922 if (need_irq) { 923 tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID); 924 } 925 } 926 } 927 break; 928 case TPM_TIS_REG_INTERFACE_ID: 929 if (val & TPM_TIS_IFACE_ID_INT_SEL_LOCK) { 930 for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) { 931 s->loc[l].iface_id |= TPM_TIS_IFACE_ID_INT_SEL_LOCK; 932 } 933 } 934 break; 935 } 936 } 937 938 static const MemoryRegionOps tpm_tis_memory_ops = { 939 .read = tpm_tis_mmio_read, 940 .write = tpm_tis_mmio_write, 941 .endianness = DEVICE_LITTLE_ENDIAN, 942 .valid = { 943 .min_access_size = 1, 944 .max_access_size = 4, 945 }, 946 }; 947 948 static int tpm_tis_do_startup_tpm(TPMState *s, size_t buffersize) 949 { 950 return tpm_backend_startup_tpm(s->be_driver, buffersize); 951 } 952 953 /* 954 * Get the TPMVersion of the backend device being used 955 */ 956 static enum TPMVersion tpm_tis_get_tpm_version(TPMIf *ti) 957 { 958 TPMState *s = TPM(ti); 959 960 if (tpm_backend_had_startup_error(s->be_driver)) { 961 return TPM_VERSION_UNSPEC; 962 } 963 964 return tpm_backend_get_tpm_version(s->be_driver); 965 } 966 967 /* 968 * This function is called when the machine starts, resets or due to 969 * S3 resume. 970 */ 971 static void tpm_tis_reset(DeviceState *dev) 972 { 973 TPMState *s = TPM(dev); 974 int c; 975 976 s->be_tpm_version = tpm_backend_get_tpm_version(s->be_driver); 977 s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->be_driver), 978 TPM_TIS_BUFFER_MAX); 979 980 tpm_backend_reset(s->be_driver); 981 982 s->active_locty = TPM_TIS_NO_LOCALITY; 983 s->next_locty = TPM_TIS_NO_LOCALITY; 984 s->aborting_locty = TPM_TIS_NO_LOCALITY; 985 986 for (c = 0; c < TPM_TIS_NUM_LOCALITIES; c++) { 987 s->loc[c].access = TPM_TIS_ACCESS_TPM_REG_VALID_STS; 988 switch (s->be_tpm_version) { 989 case TPM_VERSION_UNSPEC: 990 break; 991 case TPM_VERSION_1_2: 992 s->loc[c].sts = TPM_TIS_STS_TPM_FAMILY1_2; 993 s->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3; 994 break; 995 case TPM_VERSION_2_0: 996 s->loc[c].sts = TPM_TIS_STS_TPM_FAMILY2_0; 997 s->loc[c].iface_id = TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0; 998 break; 999 } 1000 s->loc[c].inte = TPM_TIS_INT_POLARITY_LOW_LEVEL; 1001 s->loc[c].ints = 0; 1002 s->loc[c].state = TPM_TIS_STATE_IDLE; 1003 1004 s->rw_offset = 0; 1005 } 1006 1007 tpm_tis_do_startup_tpm(s, s->be_buffer_size); 1008 } 1009 1010 static const VMStateDescription vmstate_tpm_tis = { 1011 .name = "tpm", 1012 .unmigratable = 1, 1013 }; 1014 1015 static Property tpm_tis_properties[] = { 1016 DEFINE_PROP_UINT32("irq", TPMState, irq_num, TPM_TIS_IRQ), 1017 DEFINE_PROP_TPMBE("tpmdev", TPMState, be_driver), 1018 DEFINE_PROP_END_OF_LIST(), 1019 }; 1020 1021 static void tpm_tis_realizefn(DeviceState *dev, Error **errp) 1022 { 1023 TPMState *s = TPM(dev); 1024 1025 if (!tpm_find()) { 1026 error_setg(errp, "at most one TPM device is permitted"); 1027 return; 1028 } 1029 1030 if (!s->be_driver) { 1031 error_setg(errp, "'tpmdev' property is required"); 1032 return; 1033 } 1034 if (s->irq_num > 15) { 1035 error_setg(errp, "IRQ %d is outside valid range of 0 to 15", 1036 s->irq_num); 1037 return; 1038 } 1039 1040 isa_init_irq(&s->busdev, &s->irq, s->irq_num); 1041 1042 memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)), 1043 TPM_TIS_ADDR_BASE, &s->mmio); 1044 } 1045 1046 static void tpm_tis_initfn(Object *obj) 1047 { 1048 TPMState *s = TPM(obj); 1049 1050 memory_region_init_io(&s->mmio, OBJECT(s), &tpm_tis_memory_ops, 1051 s, "tpm-tis-mmio", 1052 TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT); 1053 } 1054 1055 static void tpm_tis_class_init(ObjectClass *klass, void *data) 1056 { 1057 DeviceClass *dc = DEVICE_CLASS(klass); 1058 TPMIfClass *tc = TPM_IF_CLASS(klass); 1059 1060 dc->realize = tpm_tis_realizefn; 1061 dc->props = tpm_tis_properties; 1062 dc->reset = tpm_tis_reset; 1063 dc->vmsd = &vmstate_tpm_tis; 1064 tc->model = TPM_MODEL_TPM_TIS; 1065 tc->get_version = tpm_tis_get_tpm_version; 1066 tc->request_completed = tpm_tis_request_completed; 1067 } 1068 1069 static const TypeInfo tpm_tis_info = { 1070 .name = TYPE_TPM_TIS, 1071 .parent = TYPE_ISA_DEVICE, 1072 .instance_size = sizeof(TPMState), 1073 .instance_init = tpm_tis_initfn, 1074 .class_init = tpm_tis_class_init, 1075 .interfaces = (InterfaceInfo[]) { 1076 { TYPE_TPM_IF }, 1077 { } 1078 } 1079 }; 1080 1081 static void tpm_tis_register(void) 1082 { 1083 type_register_static(&tpm_tis_info); 1084 } 1085 1086 type_init(tpm_tis_register) 1087