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