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