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