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