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