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