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