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