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