1 /*-
2 * Copyright (c) 2018 Stormshield.
3 * Copyright (c) 2018 Semihalf.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 #include "tpm20.h"
30
31 /*
32 * CRB register space as defined in
33 * TCG_PC_Client_Platform_TPM_Profile_PTP_2.0_r1.03_v22
34 */
35 #define TPM_LOC_STATE 0x0
36 #define TPM_LOC_CTRL 0x8
37 #define TPM_LOC_STS 0xC
38 #define TPM_CRB_INTF_ID 0x30
39 #define TPM_CRB_CTRL_EXT 0x38
40 #define TPM_CRB_CTRL_REQ 0x40
41 #define TPM_CRB_CTRL_STS 0x44
42 #define TPM_CRB_CTRL_CANCEL 0x48
43 #define TPM_CRB_CTRL_START 0x4C
44 #define TPM_CRB_INT_ENABLE 0x50
45 #define TPM_CRB_INT_STS 0x54
46 #define TPM_CRB_CTRL_CMD_SIZE 0x58
47 #define TPM_CRB_CTRL_CMD_LADDR 0x5C
48 #define TPM_CRB_CTRL_CMD_HADDR 0x60
49 #define TPM_CRB_CTRL_RSP_SIZE 0x64
50 #define TPM_CRB_CTRL_RSP_ADDR 0x68
51 #define TPM_CRB_CTRL_RSP_HADDR 0x6c
52 #define TPM_CRB_DATA_BUFFER 0x80
53
54 #define TPM_LOC_STATE_ESTB BIT(0)
55 #define TPM_LOC_STATE_ASSIGNED BIT(1)
56 #define TPM_LOC_STATE_ACTIVE_MASK 0x9C
57 #define TPM_LOC_STATE_VALID BIT(7)
58
59 #define TPM_CRB_INTF_ID_TYPE_CRB 0x1
60 #define TPM_CRB_INTF_ID_TYPE 0x7
61
62 #define TPM_LOC_CTRL_REQUEST BIT(0)
63 #define TPM_LOC_CTRL_RELINQUISH BIT(1)
64
65 #define TPM_CRB_CTRL_REQ_GO_READY BIT(0)
66 #define TPM_CRB_CTRL_REQ_GO_IDLE BIT(1)
67
68 #define TPM_CRB_CTRL_STS_ERR_BIT BIT(0)
69 #define TPM_CRB_CTRL_STS_IDLE_BIT BIT(1)
70
71 #define TPM_CRB_CTRL_CANCEL_CMD 0x1
72 #define TPM_CRB_CTRL_CANCEL_CLEAR 0x0
73
74 #define TPM_CRB_CTRL_START_CMD BIT(0)
75
76 #define TPM_CRB_INT_ENABLE_BIT BIT(31)
77
78 struct tpmcrb_sc {
79 struct tpm_sc base;
80 bus_size_t cmd_off;
81 bus_size_t rsp_off;
82 size_t cmd_buf_size;
83 size_t rsp_buf_size;
84 };
85
86 int tpmcrb_transmit(struct tpm_sc *sc, size_t size);
87
88 static int tpmcrb_acpi_probe(device_t dev);
89 static int tpmcrb_attach(device_t dev);
90 static int tpmcrb_detach(device_t dev);
91
92 static ACPI_STATUS tpmcrb_fix_buff_offsets(ACPI_RESOURCE *res, void *arg);
93
94 static bool tpm_wait_for_u32(struct tpm_sc *sc, bus_size_t off,
95 uint32_t mask, uint32_t val, int32_t timeout);
96 static bool tpmcrb_request_locality(struct tpm_sc *sc, int locality);
97 static void tpmcrb_relinquish_locality(struct tpm_sc *sc);
98 static bool tpmcrb_cancel_cmd(struct tpm_sc *sc);
99
100 char *tpmcrb_ids[] = {"MSFT0101", NULL};
101
102 static int
tpmcrb_acpi_probe(device_t dev)103 tpmcrb_acpi_probe(device_t dev)
104 {
105 int err;
106 ACPI_TABLE_TPM23 *tbl;
107 ACPI_STATUS status;
108 err = ACPI_ID_PROBE(device_get_parent(dev), dev, tpmcrb_ids, NULL);
109 if (err > 0)
110 return (err);
111 /*Find TPM2 Header*/
112 status = AcpiGetTable(ACPI_SIG_TPM2, 1, (ACPI_TABLE_HEADER **) &tbl);
113 if(ACPI_FAILURE(status) ||
114 tbl->StartMethod != TPM2_START_METHOD_CRB)
115 return (ENXIO);
116
117 device_set_desc(dev, "Trusted Platform Module 2.0, CRB mode");
118 return (err);
119 }
120
121 static ACPI_STATUS
tpmcrb_fix_buff_offsets(ACPI_RESOURCE * res,void * arg)122 tpmcrb_fix_buff_offsets(ACPI_RESOURCE *res, void *arg)
123 {
124 struct tpmcrb_sc *crb_sc;
125 size_t length;
126 uint32_t base_addr;
127
128 crb_sc = (struct tpmcrb_sc *)arg;
129
130 if (res->Type != ACPI_RESOURCE_TYPE_FIXED_MEMORY32)
131 return (AE_OK);
132
133 base_addr = res->Data.FixedMemory32.Address;
134 length = res->Data.FixedMemory32.AddressLength;
135
136 if (crb_sc->cmd_off > base_addr && crb_sc->cmd_off < base_addr + length)
137 crb_sc->cmd_off -= base_addr;
138 if (crb_sc->rsp_off > base_addr && crb_sc->rsp_off < base_addr + length)
139 crb_sc->rsp_off -= base_addr;
140
141 return (AE_OK);
142 }
143
144 static int
tpmcrb_attach(device_t dev)145 tpmcrb_attach(device_t dev)
146 {
147 struct tpmcrb_sc *crb_sc;
148 struct tpm_sc *sc;
149 ACPI_HANDLE handle;
150 ACPI_STATUS status;
151 int result;
152
153 crb_sc = device_get_softc(dev);
154 sc = &crb_sc->base;
155 handle = acpi_get_handle(dev);
156
157 sc->dev = dev;
158
159 sc->mem_rid = 0;
160 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
161 RF_ACTIVE);
162 if (sc->mem_res == NULL)
163 return (ENXIO);
164
165 if(!tpmcrb_request_locality(sc, 0)) {
166 bus_release_resource(dev, SYS_RES_MEMORY,
167 sc->mem_rid, sc->mem_res);
168 return (ENXIO);
169 }
170
171 /*
172 * Disable all interrupts for now, since I don't have a device that
173 * works in CRB mode and supports them.
174 */
175 AND4(sc, TPM_CRB_INT_ENABLE, ~TPM_CRB_INT_ENABLE_BIT);
176 sc->interrupts = false;
177
178 /*
179 * Read addresses of Tx/Rx buffers and their sizes. Note that they
180 * can be implemented by a single buffer. Also for some reason CMD
181 * addr is stored in two 4 byte neighboring registers, whereas RSP is
182 * stored in a single 8 byte one.
183 */
184 #ifdef __amd64__
185 crb_sc->rsp_off = RD8(sc, TPM_CRB_CTRL_RSP_ADDR);
186 #else
187 crb_sc->rsp_off = RD4(sc, TPM_CRB_CTRL_RSP_ADDR);
188 crb_sc->rsp_off |= ((uint64_t) RD4(sc, TPM_CRB_CTRL_RSP_HADDR) << 32);
189 #endif
190 crb_sc->cmd_off = RD4(sc, TPM_CRB_CTRL_CMD_LADDR);
191 crb_sc->cmd_off |= ((uint64_t) RD4(sc, TPM_CRB_CTRL_CMD_HADDR) << 32);
192 crb_sc->cmd_buf_size = RD4(sc, TPM_CRB_CTRL_CMD_SIZE);
193 crb_sc->rsp_buf_size = RD4(sc, TPM_CRB_CTRL_RSP_SIZE);
194
195 tpmcrb_relinquish_locality(sc);
196
197 /* Emulator returns address in acpi space instead of an offset */
198 status = AcpiWalkResources(handle, "_CRS", tpmcrb_fix_buff_offsets,
199 (void *)crb_sc);
200 if (ACPI_FAILURE(status)) {
201 tpmcrb_detach(dev);
202 return (ENXIO);
203 }
204
205 if (crb_sc->rsp_off == crb_sc->cmd_off) {
206 /*
207 * If Tx/Rx buffers are implemented as one they have to be of
208 * same size
209 */
210 if (crb_sc->cmd_buf_size != crb_sc->rsp_buf_size) {
211 device_printf(sc->dev,
212 "Overlapping Tx/Rx buffers have different sizes\n");
213 tpmcrb_detach(dev);
214 return (ENXIO);
215 }
216 }
217
218 sc->transmit = tpmcrb_transmit;
219
220 result = tpm20_init(sc);
221 if (result != 0)
222 tpmcrb_detach(dev);
223
224 return (result);
225 }
226
227 static int
tpmcrb_detach(device_t dev)228 tpmcrb_detach(device_t dev)
229 {
230 struct tpm_sc *sc;
231
232 sc = device_get_softc(dev);
233 tpm20_release(sc);
234
235 if (sc->mem_res != NULL)
236 bus_release_resource(dev, SYS_RES_MEMORY,
237 sc->mem_rid, sc->mem_res);
238
239 return (0);
240 }
241
242 static bool
tpm_wait_for_u32(struct tpm_sc * sc,bus_size_t off,uint32_t mask,uint32_t val,int32_t timeout)243 tpm_wait_for_u32(struct tpm_sc *sc, bus_size_t off, uint32_t mask, uint32_t val,
244 int32_t timeout)
245 {
246
247 /* Check for condition */
248 if ((RD4(sc, off) & mask) == val)
249 return (true);
250
251 while (timeout > 0) {
252 if ((RD4(sc, off) & mask) == val)
253 return (true);
254
255 pause("TPM in polling mode", 1);
256 timeout -= tick;
257 }
258 return (false);
259 }
260
261 static bool
tpmcrb_request_locality(struct tpm_sc * sc,int locality)262 tpmcrb_request_locality(struct tpm_sc *sc, int locality)
263 {
264 uint32_t mask;
265
266 /* Currently we only support Locality 0 */
267 if (locality != 0)
268 return (false);
269
270 mask = TPM_LOC_STATE_VALID | TPM_LOC_STATE_ASSIGNED;
271
272 OR4(sc, TPM_LOC_CTRL, TPM_LOC_CTRL_REQUEST);
273 if (!tpm_wait_for_u32(sc, TPM_LOC_STATE, mask, mask, TPM_TIMEOUT_C))
274 return (false);
275
276 return (true);
277 }
278
279 static void
tpmcrb_relinquish_locality(struct tpm_sc * sc)280 tpmcrb_relinquish_locality(struct tpm_sc *sc)
281 {
282
283 OR4(sc, TPM_LOC_CTRL, TPM_LOC_CTRL_RELINQUISH);
284 }
285
286 static bool
tpmcrb_cancel_cmd(struct tpm_sc * sc)287 tpmcrb_cancel_cmd(struct tpm_sc *sc)
288 {
289 uint32_t mask = ~0;
290
291 WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CMD);
292 if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START,
293 mask, ~mask, TPM_TIMEOUT_B)) {
294 device_printf(sc->dev,
295 "Device failed to cancel command\n");
296 return (false);
297 }
298
299 WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
300 return (true);
301 }
302
303 int
tpmcrb_transmit(struct tpm_sc * sc,size_t length)304 tpmcrb_transmit(struct tpm_sc *sc, size_t length)
305 {
306 struct tpmcrb_sc *crb_sc;
307 uint32_t mask, curr_cmd;
308 int timeout, bytes_available;
309
310 crb_sc = (struct tpmcrb_sc *)sc;
311
312 sx_assert(&sc->dev_lock, SA_XLOCKED);
313
314 if (length > crb_sc->cmd_buf_size) {
315 device_printf(sc->dev,
316 "Requested transfer is bigger than buffer size\n");
317 return (E2BIG);
318 }
319
320 if (RD4(sc, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_ERR_BIT) {
321 device_printf(sc->dev,
322 "Device has Error bit set\n");
323 return (EIO);
324 }
325 if (!tpmcrb_request_locality(sc, 0)) {
326 device_printf(sc->dev,
327 "Failed to obtain locality\n");
328 return (EIO);
329 }
330 /* Clear cancellation bit */
331 WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
332
333 /* Switch device to idle state if necessary */
334 if (!(RD4(sc, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) {
335 OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
336
337 mask = TPM_CRB_CTRL_STS_IDLE_BIT;
338 if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
339 mask, mask, TPM_TIMEOUT_C)) {
340 device_printf(sc->dev,
341 "Failed to transition to idle state\n");
342 return (EIO);
343 }
344 }
345 /* Switch to ready state */
346 OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY);
347
348 mask = TPM_CRB_CTRL_REQ_GO_READY;
349 if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
350 mask, !mask, TPM_TIMEOUT_C)) {
351 device_printf(sc->dev,
352 "Failed to transition to ready state\n");
353 return (EIO);
354 }
355
356 /*
357 * Calculate timeout for current command.
358 * Command code is passed in bytes 6-10.
359 */
360 curr_cmd = be32toh(*(uint32_t *) (&sc->buf[6]));
361 timeout = tpm20_get_timeout(curr_cmd);
362
363 /* Send command and tell device to process it. */
364 bus_write_region_stream_1(sc->mem_res, crb_sc->cmd_off,
365 sc->buf, length);
366 bus_barrier(sc->mem_res, crb_sc->cmd_off,
367 length, BUS_SPACE_BARRIER_WRITE);
368
369 WR4(sc, TPM_CRB_CTRL_START, TPM_CRB_CTRL_START_CMD);
370 bus_barrier(sc->mem_res, TPM_CRB_CTRL_START,
371 4, BUS_SPACE_BARRIER_WRITE);
372
373 mask = ~0;
374 if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START, mask, ~mask, timeout)) {
375 device_printf(sc->dev,
376 "Timeout while waiting for device to process cmd\n");
377 if (!tpmcrb_cancel_cmd(sc))
378 return (EIO);
379 }
380
381 /* Read response header. Length is passed in bytes 2 - 6. */
382 bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off,
383 sc->buf, TPM_HEADER_SIZE);
384 bytes_available = be32toh(*(uint32_t *) (&sc->buf[2]));
385
386 if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) {
387 device_printf(sc->dev,
388 "Incorrect response size: %d\n",
389 bytes_available);
390 return (EIO);
391 }
392
393 bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE,
394 &sc->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE);
395
396 OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
397
398 tpmcrb_relinquish_locality(sc);
399 sc->pending_data_length = bytes_available;
400
401 return (0);
402 }
403
404 /* ACPI Driver */
405 static device_method_t tpmcrb_methods[] = {
406 DEVMETHOD(device_probe, tpmcrb_acpi_probe),
407 DEVMETHOD(device_attach, tpmcrb_attach),
408 DEVMETHOD(device_detach, tpmcrb_detach),
409 DEVMETHOD(device_shutdown, tpm20_shutdown),
410 DEVMETHOD(device_suspend, tpm20_suspend),
411 {0, 0}
412 };
413 static driver_t tpmcrb_driver = {
414 "tpmcrb", tpmcrb_methods, sizeof(struct tpmcrb_sc),
415 };
416
417 devclass_t tpmcrb_devclass;
418 DRIVER_MODULE(tpmcrb, acpi, tpmcrb_driver, tpmcrb_devclass, 0, 0);
419