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