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