xref: /freebsd/sys/dev/tpm/tpm_crb.c (revision 10eea8dc8c4f3d2a3495e7fb08837d91adf465e9)
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(device_t dev, 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 	sc->dev = dev;
157 
158 	sx_init(&sc->dev_lock, "TPM driver lock");
159 	sc->buf = malloc(TPM_BUFSIZE, M_TPM20, M_WAITOK);
160 
161 	sc->mem_rid = 0;
162 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
163 					     RF_ACTIVE);
164 	if (sc->mem_res == NULL) {
165 		tpmcrb_detach(dev);
166 		return (ENXIO);
167 	}
168 
169 	if(!tpmcrb_request_locality(sc, 0)) {
170 		tpmcrb_detach(dev);
171 		return (ENXIO);
172 	}
173 
174 	/*
175 	 * Disable all interrupts for now, since I don't have a device that
176 	 * works in CRB mode and supports them.
177 	 */
178 	AND4(sc, TPM_CRB_INT_ENABLE, ~TPM_CRB_INT_ENABLE_BIT);
179 	sc->interrupts = false;
180 
181 	/*
182 	 * Read addresses of Tx/Rx buffers and their sizes. Note that they
183 	 * can be implemented by a single buffer. Also for some reason CMD
184 	 * addr is stored in two 4 byte neighboring registers, whereas RSP is
185 	 * stored in a single 8 byte one.
186 	 */
187 #ifdef __amd64__
188 	crb_sc->rsp_off = TPM_READ_8(sc->dev, TPM_CRB_CTRL_RSP_ADDR);
189 #else
190 	crb_sc->rsp_off = TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_ADDR);
191 	crb_sc->rsp_off |= ((uint64_t) TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_HADDR) << 32);
192 #endif
193 	crb_sc->cmd_off = TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_LADDR);
194 	crb_sc->cmd_off |= ((uint64_t) TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_HADDR) << 32);
195 	crb_sc->cmd_buf_size = TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_SIZE);
196 	crb_sc->rsp_buf_size = TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_SIZE);
197 
198 	tpmcrb_relinquish_locality(sc);
199 
200 	/* Emulator returns address in acpi space instead of an offset */
201 	status = AcpiWalkResources(handle, "_CRS", tpmcrb_fix_buff_offsets,
202 		    (void *)crb_sc);
203 	if (ACPI_FAILURE(status)) {
204 		tpmcrb_detach(dev);
205 		return (ENXIO);
206 	}
207 
208 	if (crb_sc->rsp_off == crb_sc->cmd_off) {
209 		/*
210 		 * If Tx/Rx buffers are implemented as one they have to be of
211 		 * same size
212 		 */
213 		if (crb_sc->cmd_buf_size != crb_sc->rsp_buf_size) {
214 			device_printf(sc->dev,
215 			    "Overlapping Tx/Rx buffers have different sizes\n");
216 			tpmcrb_detach(dev);
217 			return (ENXIO);
218 		}
219 	}
220 
221 	result = tpm20_init(sc);
222 	if (result != 0)
223 		tpmcrb_detach(dev);
224 
225 	return (result);
226 }
227 
228 static int
tpmcrb_detach(device_t dev)229 tpmcrb_detach(device_t dev)
230 {
231 	struct tpm_sc *sc;
232 
233 	sc = device_get_softc(dev);
234 	tpm20_release(sc);
235 
236 	if (sc->mem_res != NULL)
237 		bus_release_resource(dev, SYS_RES_MEMORY,
238 		    sc->mem_rid, sc->mem_res);
239 
240 	return (0);
241 }
242 
243 static bool
tpm_wait_for_u32(struct tpm_sc * sc,bus_size_t off,uint32_t mask,uint32_t val,int32_t timeout)244 tpm_wait_for_u32(struct tpm_sc *sc, bus_size_t off, uint32_t mask, uint32_t val,
245     int32_t timeout)
246 {
247 
248 	/* Check for condition */
249 	if ((TPM_READ_4(sc->dev, off) & mask) == val)
250 		return (true);
251 
252 	while (timeout > 0) {
253 		if ((TPM_READ_4(sc->dev, off) & mask) == val)
254 			return (true);
255 
256 		pause("TPM in polling mode", 1);
257 		timeout -= tick;
258 	}
259 	return (false);
260 }
261 
262 static bool
tpmcrb_request_locality(struct tpm_sc * sc,int locality)263 tpmcrb_request_locality(struct tpm_sc *sc, int locality)
264 {
265 	uint32_t mask;
266 
267 	/* Currently we only support Locality 0 */
268 	if (locality != 0)
269 		return (false);
270 
271 	mask = TPM_LOC_STATE_VALID | TPM_LOC_STATE_ASSIGNED;
272 
273 	OR4(sc, TPM_LOC_CTRL, TPM_LOC_CTRL_REQUEST);
274 	if (!tpm_wait_for_u32(sc, TPM_LOC_STATE, mask, mask, TPM_TIMEOUT_C))
275 		return (false);
276 
277 	return (true);
278 }
279 
280 static void
tpmcrb_relinquish_locality(struct tpm_sc * sc)281 tpmcrb_relinquish_locality(struct tpm_sc *sc)
282 {
283 
284 	OR4(sc, TPM_LOC_CTRL, TPM_LOC_CTRL_RELINQUISH);
285 }
286 
287 static bool
tpmcrb_cancel_cmd(struct tpm_sc * sc)288 tpmcrb_cancel_cmd(struct tpm_sc *sc)
289 {
290 	uint32_t mask = ~0;
291 
292 	TPM_WRITE_4(sc->dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CMD);
293 	if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START,
294 		    mask, ~mask, TPM_TIMEOUT_B)) {
295 		device_printf(sc->dev,
296 		    "Device failed to cancel command\n");
297 		return (false);
298 	}
299 
300 	TPM_WRITE_4(sc->dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
301 	return (true);
302 }
303 
304 int
tpmcrb_transmit(device_t dev,size_t length)305 tpmcrb_transmit(device_t dev, size_t length)
306 {
307 	struct tpmcrb_sc *crb_sc;
308 	struct tpm_sc *sc;
309 	uint32_t mask, curr_cmd;
310 	int timeout, bytes_available;
311 
312 	crb_sc = device_get_softc(dev);
313 	sc = &crb_sc->base;
314 
315 	sx_assert(&sc->dev_lock, SA_XLOCKED);
316 
317 	if (length > crb_sc->cmd_buf_size) {
318 		device_printf(dev,
319 		    "Requested transfer is bigger than buffer size\n");
320 		return (E2BIG);
321 	}
322 
323 	if (TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_ERR_BIT) {
324 		device_printf(dev,
325 		    "Device has Error bit set\n");
326 		return (EIO);
327 	}
328 	if (!tpmcrb_request_locality(sc, 0)) {
329 		device_printf(dev,
330 		    "Failed to obtain locality\n");
331 		return (EIO);
332 	}
333 	/* Clear cancellation bit */
334 	TPM_WRITE_4(dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
335 
336 	/* Switch device to idle state if necessary */
337 	if (!(TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) {
338 		OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
339 
340 		mask = TPM_CRB_CTRL_STS_IDLE_BIT;
341 		if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
342 			    mask, mask, TPM_TIMEOUT_C)) {
343 			device_printf(dev,
344 			    "Failed to transition to idle state\n");
345 			return (EIO);
346 		}
347 	}
348 	/* Switch to ready state */
349 	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY);
350 
351 	mask = TPM_CRB_CTRL_REQ_GO_READY;
352 	if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
353 		    mask, !mask, TPM_TIMEOUT_C)) {
354 		device_printf(dev,
355 		    "Failed to transition to ready state\n");
356 		return (EIO);
357 	}
358 
359 	/*
360 	 * Calculate timeout for current command.
361 	 * Command code is passed in bytes 6-10.
362 	 */
363 	curr_cmd = be32toh(*(uint32_t *) (&sc->buf[6]));
364 	timeout = tpm20_get_timeout(curr_cmd);
365 
366 	/* Send command and tell device to process it. */
367 	bus_write_region_stream_1(sc->mem_res, crb_sc->cmd_off,
368 	    sc->buf, length);
369 	TPM_WRITE_BARRIER(dev, crb_sc->cmd_off, length);
370 
371 	TPM_WRITE_4(dev, TPM_CRB_CTRL_START, TPM_CRB_CTRL_START_CMD);
372 	TPM_WRITE_BARRIER(dev, TPM_CRB_CTRL_START, 4);
373 
374 	mask = ~0;
375 	if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START, mask, ~mask, timeout)) {
376 		device_printf(dev,
377 		    "Timeout while waiting for device to process cmd\n");
378 		if (!tpmcrb_cancel_cmd(sc))
379 			return (EIO);
380 	}
381 
382 	/* Read response header. Length is passed in bytes 2 - 6. */
383 	bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off,
384 	    sc->buf, TPM_HEADER_SIZE);
385 	bytes_available = be32toh(*(uint32_t *) (&sc->buf[2]));
386 
387 	if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) {
388 		device_printf(dev,
389 		    "Incorrect response size: %d\n",
390 		    bytes_available);
391 		return (EIO);
392 	}
393 
394 	bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE,
395 	      &sc->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE);
396 
397 	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
398 
399 	tpmcrb_relinquish_locality(sc);
400 	sc->pending_data_length = bytes_available;
401 	sc->total_length = bytes_available;
402 
403 	return (0);
404 }
405 
406 /* ACPI Driver */
407 static device_method_t	tpmcrb_methods[] = {
408 	DEVMETHOD(device_probe,		tpmcrb_acpi_probe),
409 	DEVMETHOD(device_attach,	tpmcrb_attach),
410 	DEVMETHOD(device_detach,	tpmcrb_detach),
411 	DEVMETHOD(device_shutdown,	tpm20_shutdown),
412 	DEVMETHOD(device_suspend,	tpm20_suspend),
413 	DEVMETHOD(tpm_transmit,		tpmcrb_transmit),
414 	{0, 0}
415 };
416 
417 DEFINE_CLASS_1(tpmcrb, tpmcrb_driver, tpmcrb_methods, sizeof(struct tpmcrb_sc),
418     tpm_bus_driver);
419 
420 DRIVER_MODULE(tpmcrb, acpi, tpmcrb_driver, 0, 0);
421