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