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