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