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