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