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