17
#include "qemu/osdep.h"
19
#include "qemu/module.h"
20
#include "qapi/error.h"
21
#include "exec/address-spaces.h"
22
#include "hw/qdev-properties.h"
23
#include "hw/pci/pci_ids.h"
24
#include "hw/acpi/tpm.h"
25
#include "migration/vmstate.h"
26
#include "sysemu/tpm_backend.h"
27
#include "sysemu/tpm_util.h"
28
#include "sysemu/reset.h"
29
#include "sysemu/xen.h"
33
#include "qom/object.h"
36
DeviceState parent_obj;
40
uint32_t regs[TPM_CRB_R_MAX];
44
size_t be_buffer_size;
49
typedef struct CRBState CRBState;
51
DECLARE_INSTANCE_CHECKER(CRBState, CRB,
54
#define CRB_INTF_TYPE_CRB_ACTIVE 0b1
55
#define CRB_INTF_VERSION_CRB 0b1
56
#define CRB_INTF_CAP_LOCALITY_0_ONLY 0b0
57
#define CRB_INTF_CAP_IDLE_FAST 0b0
58
#define CRB_INTF_CAP_XFER_SIZE_64 0b11
59
#define CRB_INTF_CAP_FIFO_NOT_SUPPORTED 0b0
60
#define CRB_INTF_CAP_CRB_SUPPORTED 0b1
61
#define CRB_INTF_IF_SELECTOR_CRB 0b1
63
#define CRB_CTRL_CMD_SIZE (TPM_CRB_ADDR_SIZE - A_CRB_DATA_BUFFER)
66
CRB_LOC_CTRL_REQUEST_ACCESS = BIT(0),
67
CRB_LOC_CTRL_RELINQUISH = BIT(1),
68
CRB_LOC_CTRL_SEIZE = BIT(2),
69
CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT = BIT(3),
73
CRB_CTRL_REQ_CMD_READY = BIT(0),
74
CRB_CTRL_REQ_GO_IDLE = BIT(1),
78
CRB_START_INVOKE = BIT(0),
82
CRB_CANCEL_INVOKE = BIT(0),
85
#define TPM_CRB_NO_LOCALITY 0xff
87
static uint64_t tpm_crb_mmio_read(void *opaque, hwaddr addr,
90
CRBState *s = CRB(opaque);
91
void *regs = (void *)&s->regs + (addr & ~3);
92
unsigned offset = addr & 3;
93
uint32_t val = *(uint32_t *)regs >> (8 * offset);
97
val |= !tpm_backend_get_tpm_established_flag(s->tpmbe);
101
trace_tpm_crb_mmio_read(addr, size, val);
106
static uint8_t tpm_crb_get_active_locty(CRBState *s)
108
if (!ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, locAssigned)) {
109
return TPM_CRB_NO_LOCALITY;
111
return ARRAY_FIELD_EX32(s->regs, CRB_LOC_STATE, activeLocality);
114
static void tpm_crb_mmio_write(void *opaque, hwaddr addr,
115
uint64_t val, unsigned size)
117
CRBState *s = CRB(opaque);
118
uint8_t locty = addr >> 12;
120
trace_tpm_crb_mmio_write(addr, size, val);
125
case CRB_CTRL_REQ_CMD_READY:
126
ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
129
case CRB_CTRL_REQ_GO_IDLE:
130
ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
135
case A_CRB_CTRL_CANCEL:
136
if (val == CRB_CANCEL_INVOKE &&
137
s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) {
138
tpm_backend_cancel_cmd(s->tpmbe);
141
case A_CRB_CTRL_START:
142
if (val == CRB_START_INVOKE &&
143
!(s->regs[R_CRB_CTRL_START] & CRB_START_INVOKE) &&
144
tpm_crb_get_active_locty(s) == locty) {
145
void *mem = memory_region_get_ram_ptr(&s->cmdmem);
147
s->regs[R_CRB_CTRL_START] |= CRB_START_INVOKE;
148
s->cmd = (TPMBackendCmd) {
150
.in_len = MIN(tpm_cmd_get_size(mem), s->be_buffer_size),
152
.out_len = s->be_buffer_size,
155
tpm_backend_deliver_request(s->tpmbe, &s->cmd);
160
case CRB_LOC_CTRL_RESET_ESTABLISHMENT_BIT:
163
case CRB_LOC_CTRL_RELINQUISH:
164
ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
166
ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
169
case CRB_LOC_CTRL_REQUEST_ACCESS:
170
ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
172
ARRAY_FIELD_DP32(s->regs, CRB_LOC_STS,
174
ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
182
static const MemoryRegionOps tpm_crb_memory_ops = {
183
.read = tpm_crb_mmio_read,
184
.write = tpm_crb_mmio_write,
185
.endianness = DEVICE_LITTLE_ENDIAN,
187
.min_access_size = 1,
188
.max_access_size = 4,
192
static void tpm_crb_request_completed(TPMIf *ti, int ret)
194
CRBState *s = CRB(ti);
196
s->regs[R_CRB_CTRL_START] &= ~CRB_START_INVOKE;
198
ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
201
memory_region_set_dirty(&s->cmdmem, 0, CRB_CTRL_CMD_SIZE);
204
static enum TPMVersion tpm_crb_get_version(TPMIf *ti)
206
CRBState *s = CRB(ti);
208
return tpm_backend_get_tpm_version(s->tpmbe);
211
static int tpm_crb_pre_save(void *opaque)
213
CRBState *s = opaque;
215
tpm_backend_finish_sync(s->tpmbe);
220
static const VMStateDescription vmstate_tpm_crb = {
222
.pre_save = tpm_crb_pre_save,
223
.fields = (const VMStateField[]) {
224
VMSTATE_UINT32_ARRAY(regs, CRBState, TPM_CRB_R_MAX),
225
VMSTATE_END_OF_LIST(),
229
static Property tpm_crb_properties[] = {
230
DEFINE_PROP_TPMBE("tpmdev", CRBState, tpmbe),
231
DEFINE_PROP_BOOL("ppi", CRBState, ppi_enabled, true),
232
DEFINE_PROP_END_OF_LIST(),
235
static void tpm_crb_reset(void *dev)
237
CRBState *s = CRB(dev);
239
if (s->ppi_enabled) {
240
tpm_ppi_reset(&s->ppi);
242
tpm_backend_reset(s->tpmbe);
244
memset(s->regs, 0, sizeof(s->regs));
246
ARRAY_FIELD_DP32(s->regs, CRB_LOC_STATE,
248
ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS,
250
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
251
InterfaceType, CRB_INTF_TYPE_CRB_ACTIVE);
252
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
253
InterfaceVersion, CRB_INTF_VERSION_CRB);
254
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
255
CapLocality, CRB_INTF_CAP_LOCALITY_0_ONLY);
256
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
257
CapCRBIdleBypass, CRB_INTF_CAP_IDLE_FAST);
258
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
259
CapDataXferSizeSupport, CRB_INTF_CAP_XFER_SIZE_64);
260
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
261
CapFIFO, CRB_INTF_CAP_FIFO_NOT_SUPPORTED);
262
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
263
CapCRB, CRB_INTF_CAP_CRB_SUPPORTED);
264
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
265
InterfaceSelector, CRB_INTF_IF_SELECTOR_CRB);
266
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID,
268
ARRAY_FIELD_DP32(s->regs, CRB_INTF_ID2,
269
VID, PCI_VENDOR_ID_IBM);
271
s->regs[R_CRB_CTRL_CMD_SIZE] = CRB_CTRL_CMD_SIZE;
272
s->regs[R_CRB_CTRL_CMD_LADDR] = TPM_CRB_ADDR_BASE + A_CRB_DATA_BUFFER;
273
s->regs[R_CRB_CTRL_RSP_SIZE] = CRB_CTRL_CMD_SIZE;
274
s->regs[R_CRB_CTRL_RSP_ADDR] = TPM_CRB_ADDR_BASE + A_CRB_DATA_BUFFER;
276
s->be_buffer_size = MIN(tpm_backend_get_buffer_size(s->tpmbe),
279
if (tpm_backend_startup_tpm(s->tpmbe, s->be_buffer_size) < 0) {
284
static void tpm_crb_realize(DeviceState *dev, Error **errp)
286
CRBState *s = CRB(dev);
289
error_setg(errp, "at most one TPM device is permitted");
293
error_setg(errp, "'tpmdev' property is required");
297
memory_region_init_io(&s->mmio, OBJECT(s), &tpm_crb_memory_ops, s,
298
"tpm-crb-mmio", sizeof(s->regs));
299
memory_region_init_ram(&s->cmdmem, OBJECT(s),
300
"tpm-crb-cmd", CRB_CTRL_CMD_SIZE, errp);
302
memory_region_add_subregion(get_system_memory(),
303
TPM_CRB_ADDR_BASE, &s->mmio);
304
memory_region_add_subregion(get_system_memory(),
305
TPM_CRB_ADDR_BASE + sizeof(s->regs), &s->cmdmem);
307
if (s->ppi_enabled) {
308
tpm_ppi_init(&s->ppi, get_system_memory(),
309
TPM_PPI_ADDR_BASE, OBJECT(s));
315
qemu_register_reset(tpm_crb_reset, dev);
319
static void tpm_crb_class_init(ObjectClass *klass, void *data)
321
DeviceClass *dc = DEVICE_CLASS(klass);
322
TPMIfClass *tc = TPM_IF_CLASS(klass);
324
dc->realize = tpm_crb_realize;
325
device_class_set_props(dc, tpm_crb_properties);
326
dc->vmsd = &vmstate_tpm_crb;
327
dc->user_creatable = true;
328
tc->model = TPM_MODEL_TPM_CRB;
329
tc->get_version = tpm_crb_get_version;
330
tc->request_completed = tpm_crb_request_completed;
332
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
335
static const TypeInfo tpm_crb_info = {
336
.name = TYPE_TPM_CRB,
338
.parent = TYPE_DEVICE,
339
.instance_size = sizeof(CRBState),
340
.class_init = tpm_crb_class_init,
341
.interfaces = (InterfaceInfo[]) {
347
static void tpm_crb_register(void)
349
type_register_static(&tpm_crb_info);
352
type_init(tpm_crb_register)