aboutsummaryrefslogtreecommitdiff
path: root/include/hw/acpi/tpm.h
blob: 579c45f5bafed9e271fc243943ac0cb2bf811b73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/*
 * tpm.h - TPM ACPI definitions
 *
 * Copyright (C) 2014 IBM Corporation
 *
 * Authors:
 *  Stefan Berger <stefanb@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 * Implementation of the TIS interface according to specs found at
 * http://www.trustedcomputinggroup.org
 *
 */
#ifndef HW_ACPI_TPM_H
#define HW_ACPI_TPM_H

#include "qemu/units.h"
#include "hw/registerfields.h"
#include "hw/acpi/aml-build.h"
#include "sysemu/tpm.h"

#ifdef CONFIG_TPM

#define TPM_TIS_ADDR_BASE           0xFED40000
#define TPM_TIS_ADDR_SIZE           0x5000

#define TPM_TIS_IRQ                 5

#define TPM_TIS_NUM_LOCALITIES      5     /* per spec */
#define TPM_TIS_LOCALITY_SHIFT      12

/* tis registers */
#define TPM_TIS_REG_ACCESS                0x00
#define TPM_TIS_REG_INT_ENABLE            0x08
#define TPM_TIS_REG_INT_VECTOR            0x0c
#define TPM_TIS_REG_INT_STATUS            0x10
#define TPM_TIS_REG_INTF_CAPABILITY       0x14
#define TPM_TIS_REG_STS                   0x18
#define TPM_TIS_REG_DATA_FIFO             0x24
#define TPM_TIS_REG_INTERFACE_ID          0x30
#define TPM_TIS_REG_DATA_XFIFO            0x80
#define TPM_TIS_REG_DATA_XFIFO_END        0xbc
#define TPM_TIS_REG_DID_VID               0xf00
#define TPM_TIS_REG_RID                   0xf04

/* vendor-specific registers */
#define TPM_TIS_REG_DEBUG                 0xf90

#define TPM_TIS_STS_TPM_FAMILY_MASK         (0x3 << 26)/* TPM 2.0 */
#define TPM_TIS_STS_TPM_FAMILY1_2           (0 << 26)  /* TPM 2.0 */
#define TPM_TIS_STS_TPM_FAMILY2_0           (1 << 26)  /* TPM 2.0 */
#define TPM_TIS_STS_RESET_ESTABLISHMENT_BIT (1 << 25)  /* TPM 2.0 */
#define TPM_TIS_STS_COMMAND_CANCEL          (1 << 24)  /* TPM 2.0 */

#define TPM_TIS_STS_VALID                 (1 << 7)
#define TPM_TIS_STS_COMMAND_READY         (1 << 6)
#define TPM_TIS_STS_TPM_GO                (1 << 5)
#define TPM_TIS_STS_DATA_AVAILABLE        (1 << 4)
#define TPM_TIS_STS_EXPECT                (1 << 3)
#define TPM_TIS_STS_SELFTEST_DONE         (1 << 2)
#define TPM_TIS_STS_RESPONSE_RETRY        (1 << 1)

#define TPM_TIS_BURST_COUNT_SHIFT         8
#define TPM_TIS_BURST_COUNT(X) \
    ((X) << TPM_TIS_BURST_COUNT_SHIFT)

#define TPM_TIS_ACCESS_TPM_REG_VALID_STS  (1 << 7)
#define TPM_TIS_ACCESS_ACTIVE_LOCALITY    (1 << 5)
#define TPM_TIS_ACCESS_BEEN_SEIZED        (1 << 4)
#define TPM_TIS_ACCESS_SEIZE              (1 << 3)
#define TPM_TIS_ACCESS_PENDING_REQUEST    (1 << 2)
#define TPM_TIS_ACCESS_REQUEST_USE        (1 << 1)
#define TPM_TIS_ACCESS_TPM_ESTABLISHMENT  (1 << 0)

#define TPM_TIS_INT_ENABLED               (1 << 31)
#define TPM_TIS_INT_DATA_AVAILABLE        (1 << 0)
#define TPM_TIS_INT_STS_VALID             (1 << 1)
#define TPM_TIS_INT_LOCALITY_CHANGED      (1 << 2)
#define TPM_TIS_INT_COMMAND_READY         (1 << 7)

#define TPM_TIS_INT_POLARITY_MASK         (3 << 3)
#define TPM_TIS_INT_POLARITY_LOW_LEVEL    (1 << 3)

#define TPM_TIS_INTERRUPTS_SUPPORTED (TPM_TIS_INT_LOCALITY_CHANGED | \
                                      TPM_TIS_INT_DATA_AVAILABLE   | \
                                      TPM_TIS_INT_STS_VALID | \
                                      TPM_TIS_INT_COMMAND_READY)

#define TPM_TIS_CAP_INTERFACE_VERSION1_3 (2 << 28)
#define TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 (3 << 28)
#define TPM_TIS_CAP_DATA_TRANSFER_64B    (3 << 9)
#define TPM_TIS_CAP_DATA_TRANSFER_LEGACY (0 << 9)
#define TPM_TIS_CAP_BURST_COUNT_DYNAMIC  (0 << 8)
#define TPM_TIS_CAP_BURST_COUNT_STATIC   (1 << 8)
#define TPM_TIS_CAP_INTERRUPT_LOW_LEVEL  (1 << 4) /* support is mandatory */
#define TPM_TIS_CAPABILITIES_SUPPORTED1_3 \
    (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \
     TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \
     TPM_TIS_CAP_DATA_TRANSFER_64B | \
     TPM_TIS_CAP_INTERFACE_VERSION1_3 | \
     TPM_TIS_INTERRUPTS_SUPPORTED)

#define TPM_TIS_CAPABILITIES_SUPPORTED2_0 \
    (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \
     TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \
     TPM_TIS_CAP_DATA_TRANSFER_64B | \
     TPM_TIS_CAP_INTERFACE_VERSION1_3_FOR_TPM2_0 | \
     TPM_TIS_INTERRUPTS_SUPPORTED)

#define TPM_TIS_IFACE_ID_INTERFACE_TIS1_3   (0xf)     /* TPM 2.0 */
#define TPM_TIS_IFACE_ID_INTERFACE_FIFO     (0x0)     /* TPM 2.0 */
#define TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO (0 << 4)  /* TPM 2.0 */
#define TPM_TIS_IFACE_ID_CAP_5_LOCALITIES   (1 << 8)  /* TPM 2.0 */
#define TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED  (1 << 13) /* TPM 2.0 */
#define TPM_TIS_IFACE_ID_INT_SEL_LOCK       (1 << 19) /* TPM 2.0 */

#define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS1_3 \
    (TPM_TIS_IFACE_ID_INTERFACE_TIS1_3 | \
     (~0u << 4)/* all of it is don't care */)

/* if backend was a TPM 2.0: */
#define TPM_TIS_IFACE_ID_SUPPORTED_FLAGS2_0 \
    (TPM_TIS_IFACE_ID_INTERFACE_FIFO | \
     TPM_TIS_IFACE_ID_INTERFACE_VER_FIFO | \
     TPM_TIS_IFACE_ID_CAP_5_LOCALITIES | \
     TPM_TIS_IFACE_ID_CAP_TIS_SUPPORTED)

#define TPM_TIS_TPM_DID       0x0001
#define TPM_TIS_TPM_VID       PCI_VENDOR_ID_IBM
#define TPM_TIS_TPM_RID       0x0001

#define TPM_TIS_NO_DATA_BYTE  0xff


REG32(CRB_LOC_STATE, 0x00)
  FIELD(CRB_LOC_STATE, tpmEstablished, 0, 1)
  FIELD(CRB_LOC_STATE, locAssigned, 1, 1)
  FIELD(CRB_LOC_STATE, activeLocality, 2, 3)
  FIELD(CRB_LOC_STATE, reserved, 5, 2)
  FIELD(CRB_LOC_STATE, tpmRegValidSts, 7, 1)
REG32(CRB_LOC_CTRL, 0x08)
REG32(CRB_LOC_STS, 0x0C)
  FIELD(CRB_LOC_STS, Granted, 0, 1)
  FIELD(CRB_LOC_STS, beenSeized, 1, 1)
REG32(CRB_INTF_ID, 0x30)
  FIELD(CRB_INTF_ID, InterfaceType, 0, 4)
  FIELD(CRB_INTF_ID, InterfaceVersion, 4, 4)
  FIELD(CRB_INTF_ID, CapLocality, 8, 1)
  FIELD(CRB_INTF_ID, CapCRBIdleBypass, 9, 1)
  FIELD(CRB_INTF_ID, Reserved1, 10, 1)
  FIELD(CRB_INTF_ID, CapDataXferSizeSupport, 11, 2)
  FIELD(CRB_INTF_ID, CapFIFO, 13, 1)
  FIELD(CRB_INTF_ID, CapCRB, 14, 1)
  FIELD(CRB_INTF_ID, CapIFRes, 15, 2)
  FIELD(CRB_INTF_ID, InterfaceSelector, 17, 2)
  FIELD(CRB_INTF_ID, IntfSelLock, 19, 1)
  FIELD(CRB_INTF_ID, Reserved2, 20, 4)
  FIELD(CRB_INTF_ID, RID, 24, 8)
REG32(CRB_INTF_ID2, 0x34)
  FIELD(CRB_INTF_ID2, VID, 0, 16)
  FIELD(CRB_INTF_ID2, DID, 16, 16)
REG32(CRB_CTRL_EXT, 0x38)
REG32(CRB_CTRL_REQ, 0x40)
REG32(CRB_CTRL_STS, 0x44)
  FIELD(CRB_CTRL_STS, tpmSts, 0, 1)
  FIELD(CRB_CTRL_STS, tpmIdle, 1, 1)
REG32(CRB_CTRL_CANCEL, 0x48)
REG32(CRB_CTRL_START, 0x4C)
REG32(CRB_INT_ENABLED, 0x50)
REG32(CRB_INT_STS, 0x54)
REG32(CRB_CTRL_CMD_SIZE, 0x58)
REG32(CRB_CTRL_CMD_LADDR, 0x5C)
REG32(CRB_CTRL_CMD_HADDR, 0x60)
REG32(CRB_CTRL_RSP_SIZE, 0x64)
REG32(CRB_CTRL_RSP_ADDR, 0x68)
REG32(CRB_DATA_BUFFER, 0x80)

#define TPM_CRB_ADDR_BASE           0xFED40000
#define TPM_CRB_ADDR_SIZE           0x1000
#define TPM_CRB_ADDR_CTRL           (TPM_CRB_ADDR_BASE + A_CRB_CTRL_REQ)
#define TPM_CRB_R_MAX               R_CRB_DATA_BUFFER

#define TPM_LOG_AREA_MINIMUM_SIZE   (64 * KiB)

#define TPM_TCPA_ACPI_CLASS_CLIENT  0
#define TPM_TCPA_ACPI_CLASS_SERVER  1

#define TPM2_ACPI_CLASS_CLIENT      0
#define TPM2_ACPI_CLASS_SERVER      1

#define TPM2_START_METHOD_MMIO      6
#define TPM2_START_METHOD_CRB       7

/*
 * Physical Presence Interface
 */
#define TPM_PPI_ADDR_SIZE           0x400
#define TPM_PPI_ADDR_BASE           0xFED45000

#define TPM_PPI_VERSION_NONE        0
#define TPM_PPI_VERSION_1_30        1

/* whether function is blocked by BIOS settings; bits 0, 1, 2 */
#define TPM_PPI_FUNC_NOT_IMPLEMENTED     (0 << 0)
#define TPM_PPI_FUNC_BIOS_ONLY           (1 << 0)
#define TPM_PPI_FUNC_BLOCKED             (2 << 0)
#define TPM_PPI_FUNC_ALLOWED_USR_REQ     (3 << 0)
#define TPM_PPI_FUNC_ALLOWED_USR_NOT_REQ (4 << 0)
#define TPM_PPI_FUNC_MASK                (7 << 0)

/* TPM TIS I2C registers */
#define TPM_I2C_REG_LOC_SEL              0x00
#define TPM_I2C_REG_ACCESS               0x04
#define TPM_I2C_REG_INT_ENABLE           0x08
#define TPM_I2C_REG_INT_CAPABILITY       0x14
#define TPM_I2C_REG_STS                  0x18
#define TPM_I2C_REG_DATA_FIFO            0x24
#define TPM_I2C_REG_INTF_CAPABILITY      0x30
#define TPM_I2C_REG_I2C_DEV_ADDRESS      0x38
#define TPM_I2C_REG_DATA_CSUM_ENABLE     0x40
#define TPM_I2C_REG_DATA_CSUM_GET        0x44
#define TPM_I2C_REG_DID_VID              0x48
#define TPM_I2C_REG_RID                  0x4c
#define TPM_I2C_REG_UNKNOWN              0xff

/* I2C specific interface capabilities */
#define TPM_I2C_CAP_INTERFACE_TYPE     (0x2 << 0)       /* FIFO interface */
#define TPM_I2C_CAP_INTERFACE_VER      (0x0 << 4)       /* TCG I2C intf 1.0 */
#define TPM_I2C_CAP_TPM2_FAMILY        (0x1 << 7)       /* TPM 2.0 family. */
#define TPM_I2C_CAP_DEV_ADDR_CHANGE    (0x0 << 27)      /* No dev addr chng */
#define TPM_I2C_CAP_BURST_COUNT_STATIC (0x1 << 29)      /* Burst count static */
#define TPM_I2C_CAP_LOCALITY_CAP       (0x1 << 25)      /* 0-5 locality */
#define TPM_I2C_CAP_BUS_SPEED          (3   << 21)      /* std and fast mode */

/*
 * TPM_I2C_STS masks for read/writing bits from/to TIS
 * TPM_STS mask for read bits 31:26 must be zero
 */
#define TPM_I2C_STS_READ_MASK          0x00ffffdd
#define TPM_I2C_STS_WRITE_MASK         0x03000062

/* Checksum enabled. */
#define TPM_DATA_CSUM_ENABLED     0x1

/*
 * TPM_I2C_INT_ENABLE mask. Linux kernel does not support
 * interrupts hence setting it to 0.
 */
#define TPM_I2C_INT_ENABLE_MASK   0x0

void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev);

#endif /* CONFIG_TPM */

#endif /* HW_ACPI_TPM_H */