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