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