xref: /freebsd/sys/dev/tpm/tpm_crb.c (revision 7c375af72ef3f631e89431ae32a855d806e6ec98)
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 /* Attach/detach callbacks */
80 typedef bool (sm_attach_t)(struct tpmcrb_sc *, void *, size_t);
81 typedef void (sm_detach_t)(struct tpmcrb_sc *);
82 /* State change notification (timeout == 0 for 'no timeout') */
83 typedef bool (sm_statechange_t)(struct tpmcrb_sc *, int);
84 
85 struct tpmcrb_sm_cfg {
86 	sm_attach_t		*sm_attach;
87 	sm_detach_t		*sm_detach;
88 	sm_statechange_t	*sm_statechange;
89 	sm_statechange_t	*sm_cmdready;
90 };
91 
92 static sm_attach_t		pluton_attach;
93 static sm_detach_t		pluton_detach;
94 static sm_statechange_t		pluton_doorbell;
95 
96 static const struct tpmcrb_sm_cfg_map {
97 	int				acpi_sm;
98 	const char			*desc;
99 	const struct tpmcrb_sm_cfg	sm_cfg;
100 } tpmcrb_sm_cfg_map[] = {
101 	{
102 		.acpi_sm = TPM2_START_METHOD_CRB,
103 		.desc = "Trusted Platform Module 2.0, CRB mode",
104 		.sm_cfg = { NULL },	/* No notifications required */
105 	},
106 	{
107 		.acpi_sm = ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON,
108 		.desc = "Trusted Platform Module 2.0, CRB mode (Pluton)",
109 		.sm_cfg = {
110 			.sm_attach = &pluton_attach,
111 			.sm_detach = &pluton_detach,
112 			.sm_statechange = &pluton_doorbell,
113 			.sm_cmdready = &pluton_doorbell,
114 		},
115 	},
116 };
117 
118 struct tpmcrb_sc {
119 	struct tpm_sc	base;
120 	const struct tpmcrb_sm_cfg	*sm_cfg;
121 	union {
122 		/*
123 		 * StartMethod data.  The Pluton start/reply mailbox
124 		 * registers may live outside of the _CRS window, so they get
125 		 * their own bus_space mapping.
126 		 */
127 		struct {
128 			bus_space_tag_t		bst;
129 			bus_space_handle_t	start_bsh;
130 			bus_space_handle_t	reply_bsh;
131 		} pluton;
132 	};
133 	bus_size_t	cmd_off;
134 	bus_size_t	rsp_off;
135 	size_t		cmd_buf_size;
136 	size_t		rsp_buf_size;
137 };
138 
139 int tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t size);
140 
141 static int tpmcrb_acpi_probe(device_t dev);
142 static int tpmcrb_attach(device_t dev);
143 static int tpmcrb_detach(device_t dev);
144 
145 static ACPI_STATUS tpmcrb_fix_buff_offsets(ACPI_RESOURCE *res, void *arg);
146 
147 static bool tpm_wait_for_u32(struct tpm_sc *sc, bus_size_t off,
148     uint32_t mask, uint32_t val, int32_t timeout);
149 static bool tpmcrb_request_locality(struct tpm_sc *sc, int locality);
150 static void tpmcrb_relinquish_locality(struct tpm_sc *sc);
151 static bool tpmcrb_cancel_cmd(struct tpm_sc *sc);
152 
153 char *tpmcrb_ids[] = {"MSFT0101", NULL};
154 
155 static const struct tpmcrb_sm_cfg_map *
156 tpmcrb_acpi_startmethod_cfg(int method)
157 {
158 	const struct tpmcrb_sm_cfg_map *entry;
159 
160 	for (size_t i = 0; i < nitems(tpmcrb_sm_cfg_map); i++) {
161 		entry = &tpmcrb_sm_cfg_map[i];
162 
163 		if (method == entry->acpi_sm)
164 			return (entry);
165 	}
166 
167 	return (NULL);
168 }
169 
170 static int
171 tpmcrb_acpi_probe(device_t dev)
172 {
173 	int err, smethod;
174 	const struct tpmcrb_sm_cfg_map *sm_cfg_map;
175 	ACPI_TABLE_TPM23 *tbl;
176 	ACPI_STATUS status;
177 
178 	err = ACPI_ID_PROBE(device_get_parent(dev), dev, tpmcrb_ids, NULL);
179 	if (err > 0)
180 		return (err);
181 	/*Find TPM2 Header*/
182 	status = AcpiGetTable(ACPI_SIG_TPM2, 1, (ACPI_TABLE_HEADER **) &tbl);
183 	if (ACPI_FAILURE(status))
184 		return (ENXIO);
185 
186 	smethod = tbl->StartMethod;
187 	AcpiPutTable((ACPI_TABLE_HEADER *)tbl);
188 
189 	sm_cfg_map = tpmcrb_acpi_startmethod_cfg(smethod);
190 	if (sm_cfg_map == NULL)
191 		return (ENXIO);
192 
193 	device_set_desc(dev, sm_cfg_map->desc);
194 	return (0);
195 }
196 
197 static ACPI_STATUS
198 tpmcrb_fix_buff_offsets(ACPI_RESOURCE *res, void *arg)
199 {
200 	struct tpmcrb_sc *crb_sc;
201 	size_t length;
202 	uint32_t base_addr;
203 
204 	crb_sc = (struct tpmcrb_sc *)arg;
205 
206 	if (res->Type != ACPI_RESOURCE_TYPE_FIXED_MEMORY32)
207 		return (AE_OK);
208 
209 	base_addr = res->Data.FixedMemory32.Address;
210 	length = res->Data.FixedMemory32.AddressLength;
211 
212 	if (crb_sc->cmd_off > base_addr && crb_sc->cmd_off < base_addr + length)
213 		crb_sc->cmd_off -= base_addr;
214 	if (crb_sc->rsp_off > base_addr && crb_sc->rsp_off < base_addr + length)
215 		crb_sc->rsp_off -= base_addr;
216 
217 	return (AE_OK);
218 }
219 
220 static bool
221 tpmcrb_attach_startmethod(struct tpmcrb_sc *crb_sc)
222 {
223 	const struct tpmcrb_sm_cfg_map *sm_cfg_map;
224 	const struct tpmcrb_sm_cfg *sm_cfg;
225 	ACPI_TABLE_TPM23 *tbl;
226 	void *smdata;
227 	ACPI_STATUS status;
228 	bool ret;
229 
230 	/*
231 	 * Grab what we need from the StartMethod.
232 	 */
233 	status = AcpiGetTable(ACPI_SIG_TPM2, 1, (ACPI_TABLE_HEADER **)(void **)&tbl);
234 	if (ACPI_FAILURE(status))
235 		return (false);
236 
237 	sm_cfg_map = tpmcrb_acpi_startmethod_cfg(tbl->StartMethod);
238 	MPASS(sm_cfg_map != NULL);
239 	sm_cfg = &sm_cfg_map->sm_cfg;
240 
241 	crb_sc->sm_cfg = sm_cfg;
242 	smdata = tbl + 1;
243 	if (sm_cfg->sm_attach != NULL) {
244 		ret = (*sm_cfg->sm_attach)(crb_sc, smdata,
245 		    tbl->Header.Length - sizeof(*tbl));
246 	} else {
247 		ret = true;
248 	}
249 
250 	AcpiPutTable((ACPI_TABLE_HEADER *)tbl);
251 	return (ret);
252 }
253 
254 static int
255 tpmcrb_attach(device_t dev)
256 {
257 	struct tpmcrb_sc *crb_sc;
258 	struct tpm_sc *sc;
259 	ACPI_HANDLE handle;
260 	ACPI_STATUS status;
261 	int result;
262 
263 	crb_sc = device_get_softc(dev);
264 	sc = &crb_sc->base;
265 	handle = acpi_get_handle(dev);
266 	sc->dev = dev;
267 
268 	sx_init(&sc->dev_lock, "TPM driver lock");
269 
270 	sc->mem_rid = 0;
271 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
272 					     RF_ACTIVE);
273 	if (sc->mem_res == NULL) {
274 		tpmcrb_detach(dev);
275 		return (ENXIO);
276 	}
277 
278 	if (!tpmcrb_attach_startmethod(crb_sc)) {
279 		tpmcrb_detach(dev);
280 		return (ENXIO);
281 	}
282 
283 	if(!tpmcrb_request_locality(sc, 0)) {
284 		tpmcrb_detach(dev);
285 		return (ENXIO);
286 	}
287 
288 	/*
289 	 * Disable all interrupts for now, since I don't have a device that
290 	 * works in CRB mode and supports them.
291 	 */
292 	AND4(sc, TPM_CRB_INT_ENABLE, ~TPM_CRB_INT_ENABLE_BIT);
293 	sc->interrupts = false;
294 
295 	/*
296 	 * Read addresses of Tx/Rx buffers and their sizes. Note that they
297 	 * can be implemented by a single buffer. Also for some reason CMD
298 	 * addr is stored in two 4 byte neighboring registers, whereas RSP is
299 	 * stored in a single 8 byte one.
300 	 */
301 #ifdef __amd64__
302 	crb_sc->rsp_off = TPM_READ_8(sc->dev, TPM_CRB_CTRL_RSP_ADDR);
303 #else
304 	crb_sc->rsp_off = TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_ADDR);
305 	crb_sc->rsp_off |= ((uint64_t) TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_HADDR) << 32);
306 #endif
307 	crb_sc->cmd_off = TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_LADDR);
308 	crb_sc->cmd_off |= ((uint64_t) TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_HADDR) << 32);
309 	crb_sc->cmd_buf_size = TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_SIZE);
310 	crb_sc->rsp_buf_size = TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_SIZE);
311 
312 	tpmcrb_relinquish_locality(sc);
313 
314 	/* Emulator returns address in acpi space instead of an offset */
315 	status = AcpiWalkResources(handle, "_CRS", tpmcrb_fix_buff_offsets,
316 		    (void *)crb_sc);
317 	if (ACPI_FAILURE(status)) {
318 		tpmcrb_detach(dev);
319 		return (ENXIO);
320 	}
321 
322 	if (crb_sc->rsp_off == crb_sc->cmd_off) {
323 		/*
324 		 * If Tx/Rx buffers are implemented as one they have to be of
325 		 * same size
326 		 */
327 		if (crb_sc->cmd_buf_size != crb_sc->rsp_buf_size) {
328 			device_printf(sc->dev,
329 			    "Overlapping Tx/Rx buffers have different sizes\n");
330 			tpmcrb_detach(dev);
331 			return (ENXIO);
332 		}
333 	}
334 
335 	result = tpm20_init(sc);
336 	if (result != 0)
337 		tpmcrb_detach(dev);
338 
339 	return (result);
340 }
341 
342 static int
343 tpmcrb_detach(device_t dev)
344 {
345 	struct tpmcrb_sc *crb_sc;
346 	struct tpm_sc *sc;
347 
348 	crb_sc = device_get_softc(dev);
349 	sc = &crb_sc->base;
350 	tpm20_release(sc);
351 
352 	if (crb_sc->sm_cfg != NULL && crb_sc->sm_cfg->sm_detach != NULL)
353 		(*crb_sc->sm_cfg->sm_detach)(crb_sc);
354 
355 	if (sc->mem_res != NULL)
356 		bus_release_resource(dev, SYS_RES_MEMORY,
357 		    sc->mem_rid, sc->mem_res);
358 
359 	return (0);
360 }
361 
362 static bool
363 tpm_wait_for_u32(struct tpm_sc *sc, bus_size_t off, uint32_t mask, uint32_t val,
364     int32_t timeout)
365 {
366 
367 	/* Check for condition */
368 	if ((TPM_READ_4(sc->dev, off) & mask) == val)
369 		return (true);
370 
371 	while (timeout > 0) {
372 		if ((TPM_READ_4(sc->dev, off) & mask) == val)
373 			return (true);
374 
375 		pause("TPM in polling mode", 1);
376 		timeout -= tick;
377 	}
378 	return (false);
379 }
380 
381 static bool
382 tpmcrb_request_locality(struct tpm_sc *sc, int locality)
383 {
384 	uint32_t mask;
385 
386 	/* Currently we only support Locality 0 */
387 	if (locality != 0)
388 		return (false);
389 
390 	mask = TPM_LOC_STATE_VALID | TPM_LOC_STATE_ASSIGNED;
391 
392 	OR4(sc, TPM_LOC_CTRL, TPM_LOC_CTRL_REQUEST);
393 	if (!tpm_wait_for_u32(sc, TPM_LOC_STATE, mask, mask, TPM_TIMEOUT_C))
394 		return (false);
395 
396 	return (true);
397 }
398 
399 static void
400 tpmcrb_relinquish_locality(struct tpm_sc *sc)
401 {
402 
403 	OR4(sc, TPM_LOC_CTRL, TPM_LOC_CTRL_RELINQUISH);
404 }
405 
406 static bool
407 tpmcrb_cancel_cmd(struct tpm_sc *sc)
408 {
409 	uint32_t mask = ~0;
410 
411 	TPM_WRITE_4(sc->dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CMD);
412 	if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START,
413 		    mask, ~mask, TPM_TIMEOUT_B)) {
414 		device_printf(sc->dev,
415 		    "Device failed to cancel command\n");
416 		return (false);
417 	}
418 
419 	TPM_WRITE_4(sc->dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
420 	return (true);
421 }
422 
423 static bool
424 tpmcrb_notify_cmdready(struct tpmcrb_sc *crb_sc, int timeout)
425 {
426 	sm_statechange_t *cmdready_fn;
427 
428 	cmdready_fn = crb_sc->sm_cfg->sm_cmdready;
429 	if (cmdready_fn == NULL)
430 		return (true);
431 
432 	return ((*cmdready_fn)(crb_sc, timeout));
433 }
434 
435 static bool
436 tpmcrb_notify_state_changing(struct tpmcrb_sc *crb_sc, int timeout)
437 {
438 	sm_statechange_t *statechange_fn;
439 
440 	statechange_fn = crb_sc->sm_cfg->sm_statechange;
441 	if (statechange_fn == NULL)
442 		return (true);
443 
444 	return ((*statechange_fn)(crb_sc, timeout));
445 }
446 
447 static bool
448 tpmcrb_state_idle(struct tpmcrb_sc *crb_sc, bool wait)
449 {
450 	struct tpm_sc *sc;
451 	int mask, timeout;
452 
453 	timeout = wait ? TPM_TIMEOUT_C : 0;
454 
455 	sc = &crb_sc->base;
456 	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
457 
458 	if (!tpmcrb_notify_state_changing(crb_sc, timeout))
459 		return (false);
460 
461 	if (timeout > 0) {
462 		mask = TPM_CRB_CTRL_STS_IDLE_BIT;
463 		if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, mask,
464 		    timeout))
465 			return (false);
466 	}
467 
468 	return (true);
469 }
470 
471 static bool
472 tpmcrb_state_ready(struct tpmcrb_sc *crb_sc, bool wait)
473 {
474 	struct tpm_sc *sc;
475 	int mask, timeout;
476 
477 	timeout = wait ? TPM_TIMEOUT_C : 0;
478 
479 	sc = &crb_sc->base;
480 	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY);
481 
482 	if (!tpmcrb_notify_state_changing(crb_sc, timeout))
483 		return (false);
484 
485 	if (timeout > 0) {
486 		mask = TPM_CRB_CTRL_REQ_GO_READY;
487 		if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, !mask,
488 		    timeout))
489 			return (false);
490 	}
491 
492 	return (true);
493 }
494 
495 int
496 tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length)
497 {
498 	struct tpmcrb_sc *crb_sc;
499 	struct tpm_sc *sc;
500 	uint32_t mask, curr_cmd;
501 	int bytes_available, error, timeout;
502 	bool command_started, locality;
503 
504 	crb_sc = device_get_softc(dev);
505 	sc = &crb_sc->base;
506 
507 	sx_assert(&sc->dev_lock, SA_XLOCKED);
508 	command_started = false;
509 	locality = false;
510 
511 	if (length > crb_sc->cmd_buf_size) {
512 		device_printf(dev,
513 		    "Requested transfer is bigger than buffer size\n");
514 		return (E2BIG);
515 	}
516 
517 	if (!tpmcrb_request_locality(sc, 0)) {
518 		device_printf(dev,
519 		    "Failed to obtain locality\n");
520 		return (EIO);
521 	}
522 	locality = true;
523 
524 	/*
525 	 * Only check for the error once we own the locality: some
526 	 * implementations do not return meaningful values in the control area
527 	 * before then.  An AMD Pluton fTPM using the plain CRB start method
528 	 * reads all-ones, which looks like a permanently stuck tpmSts.
529 	 */
530 	if (TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_ERR_BIT) {
531 		device_printf(dev,
532 		    "Device has Error bit set\n");
533 		error = EIO;
534 		goto out;
535 	}
536 	/* Clear cancellation bit */
537 	TPM_WRITE_4(dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
538 
539 	/* Switch device to idle state if necessary */
540 	if (!(TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) {
541 		if (!tpmcrb_state_idle(crb_sc, true)) {
542 			device_printf(dev,
543 			    "Failed to transition to idle state\n");
544 			error = EIO;
545 			goto out;
546 		}
547 	}
548 
549 	/* Switch to ready state */
550 	if (!tpmcrb_state_ready(crb_sc, true)) {
551 		device_printf(dev,
552 		    "Failed to transition to ready state\n");
553 		error = EIO;
554 		goto out;
555 	}
556 
557 	/*
558 	 * Calculate timeout for current command.
559 	 * Command code is passed in bytes 6-10.
560 	 */
561 	curr_cmd = be32toh(*(uint32_t *) (&priv->buf[6]));
562 	timeout = tpm20_get_timeout(curr_cmd);
563 
564 	/* Send command and tell device to process it. */
565 	bus_write_region_stream_1(sc->mem_res, crb_sc->cmd_off,
566 	    priv->buf, length);
567 	TPM_WRITE_BARRIER(dev, crb_sc->cmd_off, length);
568 
569 	TPM_WRITE_4(dev, TPM_CRB_CTRL_START, TPM_CRB_CTRL_START_CMD);
570 	TPM_WRITE_BARRIER(dev, TPM_CRB_CTRL_START, 4);
571 	command_started = true;
572 
573 	if (!tpmcrb_notify_cmdready(crb_sc, timeout)) {
574 		device_printf(dev,
575 		    "Timeout while waiting for device to ready\n");
576 		if (!tpmcrb_cancel_cmd(sc)) {
577 			error = EIO;
578 			goto out;
579 		}
580 	}
581 
582 	mask = ~0;
583 	if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START, mask, ~mask, timeout)) {
584 		device_printf(dev,
585 		    "Timeout while waiting for device to process cmd\n");
586 		if (!tpmcrb_cancel_cmd(sc)) {
587 			error = EIO;
588 			goto out;
589 		}
590 	}
591 
592 	/* Read response header. Length is passed in bytes 2 - 6. */
593 	bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off,
594 	    priv->buf, TPM_HEADER_SIZE);
595 	bytes_available = be32toh(*(uint32_t *) (&priv->buf[2]));
596 
597 	if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) {
598 		device_printf(dev,
599 		    "Incorrect response size: %d\n",
600 		    bytes_available);
601 		error = EIO;
602 		goto out;
603 	}
604 
605 	bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE,
606 	      &priv->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE);
607 
608 	priv->offset = 0;
609 	priv->len = bytes_available;
610 	error = 0;
611 
612 out:
613 	if (locality) {
614 		if (error != 0 && command_started &&
615 		    (TPM_READ_4(dev, TPM_CRB_CTRL_START) &
616 		    TPM_CRB_CTRL_START_CMD) != 0)
617 			(void)tpmcrb_cancel_cmd(sc);
618 		if (!tpmcrb_state_idle(crb_sc, false)) {
619 			device_printf(dev,
620 			    "Failed to transition to idle state post-send\n");
621 			if (error == 0)
622 				error = EIO;
623 		}
624 		tpmcrb_relinquish_locality(sc);
625 	}
626 
627 	return (error);
628 }
629 
630 /* StartMethod Implementation Details */
631 
632 /** Pluton **/
633 struct tpmcrb_startmethod_pluton {
634 	uint64_t		sm_startaddr;
635 	uint64_t		sm_replyaddr;
636 };
637 
638 static bool
639 pluton_attach(struct tpmcrb_sc *crb_sc, void *smdataregion, size_t datasz)
640 {
641 	struct tpmcrb_startmethod_pluton *smdata;
642 	struct tpm_sc *sc;
643 	bus_space_tag_t bst;
644 
645 	if (datasz < sizeof(*smdata))
646 		return (false);
647 
648 	smdata = smdataregion;
649 	sc = &crb_sc->base;
650 
651 	/*
652 	 * The start/reply mailbox registers are not necessarily part of
653 	 * the CRB register window described by _CRS, so we map them
654 	 * independently.
655 	 */
656 	bst = rman_get_bustag(sc->mem_res);
657 	if (bus_space_map(bst, smdata->sm_startaddr, sizeof(uint32_t), 0,
658 	    &crb_sc->pluton.start_bsh) != 0) {
659 		device_printf(sc->dev,
660 		    "Failed to map Pluton start register at %#jx\n",
661 		    (uintmax_t)smdata->sm_startaddr);
662 		return (false);
663 	}
664 
665 	if (bus_space_map(bst, smdata->sm_replyaddr, sizeof(uint32_t), 0,
666 	    &crb_sc->pluton.reply_bsh) != 0) {
667 		device_printf(sc->dev,
668 		    "Failed to map Pluton reply register at %#jx\n",
669 		    (uintmax_t)smdata->sm_replyaddr);
670 		bus_space_unmap(bst, crb_sc->pluton.start_bsh,
671 		    sizeof(uint32_t));
672 		return (false);
673 	}
674 
675 	crb_sc->pluton.bst = bst;
676 	return (true);
677 }
678 
679 static void
680 pluton_detach(struct tpmcrb_sc *crb_sc)
681 {
682 
683 	if (crb_sc->pluton.bst == 0)
684 		return;
685 
686 	bus_space_unmap(crb_sc->pluton.bst, crb_sc->pluton.start_bsh,
687 	    sizeof(uint32_t));
688 	bus_space_unmap(crb_sc->pluton.bst, crb_sc->pluton.reply_bsh,
689 	    sizeof(uint32_t));
690 }
691 
692 static bool
693 pluton_wait_reply(struct tpmcrb_sc *crb_sc, int32_t timeout)
694 {
695 	for (;;) {
696 		/*
697 		 * Always read at least once, and try one more time after we hit
698 		 * the timeout.
699 		 */
700 		if (bus_space_read_4(crb_sc->pluton.bst,
701 		    crb_sc->pluton.reply_bsh, 0) == 1)
702 			return (true);
703 		else if (timeout <= 0)
704 			break;
705 
706 		pause("TPM in polling mode", 1);
707 		timeout -= tick;
708 	}
709 
710 	return (false);
711 }
712 
713 static bool
714 pluton_doorbell(struct tpmcrb_sc *crb_sc, int timeout)
715 {
716 	bus_space_write_4(crb_sc->pluton.bst, crb_sc->pluton.start_bsh, 0, 1);
717 	bus_space_barrier(crb_sc->pluton.bst, crb_sc->pluton.start_bsh, 0,
718 	    sizeof(uint32_t), BUS_SPACE_BARRIER_WRITE);
719 
720 	/*
721 	 * We assume at timeout == 0 that they're not really interested in a
722 	 * reply immediately.  Otherwise, we poll for a reply at least once,
723 	 * even with low timeouts.
724 	 */
725 	if (timeout <= 0)
726 		return (true);
727 	return (pluton_wait_reply(crb_sc, timeout));
728 }
729 
730 /* ACPI Driver */
731 static device_method_t	tpmcrb_methods[] = {
732 	DEVMETHOD(device_probe,		tpmcrb_acpi_probe),
733 	DEVMETHOD(device_attach,	tpmcrb_attach),
734 	DEVMETHOD(device_detach,	tpmcrb_detach),
735 	DEVMETHOD(device_shutdown,	tpm20_shutdown),
736 	DEVMETHOD(device_suspend,	tpm20_suspend),
737 	DEVMETHOD(device_resume,	tpm20_resume),
738 	DEVMETHOD(tpm_transmit,		tpmcrb_transmit),
739 	{0, 0}
740 };
741 
742 DEFINE_CLASS_1(tpmcrb, tpmcrb_driver, tpmcrb_methods, sizeof(struct tpmcrb_sc),
743     tpm_bus_driver);
744 
745 DRIVER_MODULE(tpmcrb, acpi, tpmcrb_driver, 0, 0);
746