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