xref: /openbmc/u-boot/drivers/tpm/tpm_tis_lpc.c (revision 9c71a21d)
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 /*
8  * The code in this file is based on the article "Writing a TPM Device Driver"
9  * published on http://ptgmedia.pearsoncmg.com.
10  *
11  * One principal difference is that in the simplest config the other than 0
12  * TPM localities do not get mapped by some devices (for instance, by Infineon
13  * slb9635), so this driver provides access to locality 0 only.
14  */
15 
16 #include <common.h>
17 #include <dm.h>
18 #include <mapmem.h>
19 #include <tis.h>
20 #include <tpm.h>
21 #include <asm/io.h>
22 
23 #define PREFIX "lpc_tpm: "
24 
25 struct tpm_locality {
26 	u32 access;
27 	u8 padding0[4];
28 	u32 int_enable;
29 	u8 vector;
30 	u8 padding1[3];
31 	u32 int_status;
32 	u32 int_capability;
33 	u32 tpm_status;
34 	u8 padding2[8];
35 	u8 data;
36 	u8 padding3[3803];
37 	u32 did_vid;
38 	u8 rid;
39 	u8 padding4[251];
40 };
41 
42 struct tpm_tis_lpc_priv {
43 	struct tpm_locality *regs;
44 };
45 
46 /*
47  * This pointer refers to the TPM chip, 5 of its localities are mapped as an
48  * array.
49  */
50 #define TPM_TOTAL_LOCALITIES	5
51 
52 /* Some registers' bit field definitions */
53 #define TIS_STS_VALID                  (1 << 7) /* 0x80 */
54 #define TIS_STS_COMMAND_READY          (1 << 6) /* 0x40 */
55 #define TIS_STS_TPM_GO                 (1 << 5) /* 0x20 */
56 #define TIS_STS_DATA_AVAILABLE         (1 << 4) /* 0x10 */
57 #define TIS_STS_EXPECT                 (1 << 3) /* 0x08 */
58 #define TIS_STS_RESPONSE_RETRY         (1 << 1) /* 0x02 */
59 
60 #define TIS_ACCESS_TPM_REG_VALID_STS   (1 << 7) /* 0x80 */
61 #define TIS_ACCESS_ACTIVE_LOCALITY     (1 << 5) /* 0x20 */
62 #define TIS_ACCESS_BEEN_SEIZED         (1 << 4) /* 0x10 */
63 #define TIS_ACCESS_SEIZE               (1 << 3) /* 0x08 */
64 #define TIS_ACCESS_PENDING_REQUEST     (1 << 2) /* 0x04 */
65 #define TIS_ACCESS_REQUEST_USE         (1 << 1) /* 0x02 */
66 #define TIS_ACCESS_TPM_ESTABLISHMENT   (1 << 0) /* 0x01 */
67 
68 #define TIS_STS_BURST_COUNT_MASK       (0xffff)
69 #define TIS_STS_BURST_COUNT_SHIFT      (8)
70 
71  /* 1 second is plenty for anything TPM does. */
72 #define MAX_DELAY_US	(1000 * 1000)
73 
74 /* Retrieve burst count value out of the status register contents. */
75 static u16 burst_count(u32 status)
76 {
77 	return (status >> TIS_STS_BURST_COUNT_SHIFT) &
78 			TIS_STS_BURST_COUNT_MASK;
79 }
80 
81 /* TPM access wrappers to support tracing */
82 static u8 tpm_read_byte(struct tpm_tis_lpc_priv *priv, const u8 *ptr)
83 {
84 	u8  ret = readb(ptr);
85 	debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n",
86 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
87 	return ret;
88 }
89 
90 static u32 tpm_read_word(struct tpm_tis_lpc_priv *priv, const u32 *ptr)
91 {
92 	u32  ret = readl(ptr);
93 	debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n",
94 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
95 	return ret;
96 }
97 
98 static void tpm_write_byte(struct tpm_tis_lpc_priv *priv, u8 value, u8 *ptr)
99 {
100 	debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n",
101 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
102 	writeb(value, ptr);
103 }
104 
105 static void tpm_write_word(struct tpm_tis_lpc_priv *priv, u32 value,
106 			   u32 *ptr)
107 {
108 	debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n",
109 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
110 	writel(value, ptr);
111 }
112 
113 /*
114  * tis_wait_reg()
115  *
116  * Wait for at least a second for a register to change its state to match the
117  * expected state. Normally the transition happens within microseconds.
118  *
119  * @reg - pointer to the TPM register
120  * @mask - bitmask for the bitfield(s) to watch
121  * @expected - value the field(s) are supposed to be set to
122  *
123  * Returns the register contents in case the expected value was found in the
124  * appropriate register bits, or -ETIMEDOUT on timeout.
125  */
126 static int tis_wait_reg(struct tpm_tis_lpc_priv *priv, u32 *reg, u8 mask,
127 			u8 expected)
128 {
129 	u32 time_us = MAX_DELAY_US;
130 
131 	while (time_us > 0) {
132 		u32 value = tpm_read_word(priv, reg);
133 		if ((value & mask) == expected)
134 			return value;
135 		udelay(1); /* 1 us */
136 		time_us--;
137 	}
138 
139 	return -ETIMEDOUT;
140 }
141 
142 /*
143  * Probe the TPM device and try determining its manufacturer/device name.
144  *
145  * Returns 0 on success, -ve on error
146  */
147 static int tpm_tis_lpc_probe(struct udevice *dev)
148 {
149 	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
150 	u32 vid, did;
151 	fdt_addr_t addr;
152 	u32 didvid;
153 
154 	addr = dev_get_addr(dev);
155 	if (addr == FDT_ADDR_T_NONE)
156 		return -EINVAL;
157 	priv->regs = map_sysmem(addr, 0);
158 	didvid = tpm_read_word(priv, &priv->regs[0].did_vid);
159 
160 	vid = didvid & 0xffff;
161 	did = (didvid >> 16) & 0xffff;
162 	if (vid != 0x15d1 || did != 0xb) {
163 		debug("Invalid vendor/device ID %04x/%04x\n", vid, did);
164 		return -ENOSYS;
165 	}
166 
167 	debug("Found TPM %s by %s\n", "SLB9635 TT 1.2", "Infineon");
168 
169 	return 0;
170 }
171 
172 /*
173  * tis_senddata()
174  *
175  * send the passed in data to the TPM device.
176  *
177  * @data - address of the data to send, byte by byte
178  * @len - length of the data to send
179  *
180  * Returns 0 on success, -ve on error (in case the device does not accept
181  * the entire command).
182  */
183 static int tis_senddata(struct udevice *dev, const u8 *data, size_t len)
184 {
185 	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
186 	struct tpm_locality *regs = priv->regs;
187 	u32 offset = 0;
188 	u16 burst = 0;
189 	u32 max_cycles = 0;
190 	u8 locality = 0;
191 	u32 value;
192 
193 	value = tis_wait_reg(priv, &regs[locality].tpm_status,
194 			     TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY);
195 	if (value == -ETIMEDOUT) {
196 		printf("%s:%d - failed to get 'command_ready' status\n",
197 		       __FILE__, __LINE__);
198 		return value;
199 	}
200 	burst = burst_count(value);
201 
202 	while (1) {
203 		unsigned count;
204 
205 		/* Wait till the device is ready to accept more data. */
206 		while (!burst) {
207 			if (max_cycles++ == MAX_DELAY_US) {
208 				printf("%s:%d failed to feed %d bytes of %d\n",
209 				       __FILE__, __LINE__, len - offset, len);
210 				return -ETIMEDOUT;
211 			}
212 			udelay(1);
213 			burst = burst_count(tpm_read_word(priv,
214 					&regs[locality].tpm_status));
215 		}
216 
217 		max_cycles = 0;
218 
219 		/*
220 		 * Calculate number of bytes the TPM is ready to accept in one
221 		 * shot.
222 		 *
223 		 * We want to send the last byte outside of the loop (hence
224 		 * the -1 below) to make sure that the 'expected' status bit
225 		 * changes to zero exactly after the last byte is fed into the
226 		 * FIFO.
227 		 */
228 		count = min((u32)burst, len - offset - 1);
229 		while (count--)
230 			tpm_write_byte(priv, data[offset++],
231 				       &regs[locality].data);
232 
233 		value = tis_wait_reg(priv, &regs[locality].tpm_status,
234 				     TIS_STS_VALID, TIS_STS_VALID);
235 
236 		if ((value == -ETIMEDOUT) || !(value & TIS_STS_EXPECT)) {
237 			printf("%s:%d TPM command feed overflow\n",
238 			       __FILE__, __LINE__);
239 			return value == -ETIMEDOUT ? value : -EIO;
240 		}
241 
242 		burst = burst_count(value);
243 		if ((offset == (len - 1)) && burst) {
244 			/*
245 			 * We need to be able to send the last byte to the
246 			 * device, so burst size must be nonzero before we
247 			 * break out.
248 			 */
249 			break;
250 		}
251 	}
252 
253 	/* Send the last byte. */
254 	tpm_write_byte(priv, data[offset++], &regs[locality].data);
255 	/*
256 	 * Verify that TPM does not expect any more data as part of this
257 	 * command.
258 	 */
259 	value = tis_wait_reg(priv, &regs[locality].tpm_status,
260 			     TIS_STS_VALID, TIS_STS_VALID);
261 	if ((value == -ETIMEDOUT) || (value & TIS_STS_EXPECT)) {
262 		printf("%s:%d unexpected TPM status 0x%x\n",
263 		       __FILE__, __LINE__, value);
264 		return value == -ETIMEDOUT ? value : -EIO;
265 	}
266 
267 	/* OK, sitting pretty, let's start the command execution. */
268 	tpm_write_word(priv, TIS_STS_TPM_GO, &regs[locality].tpm_status);
269 	return 0;
270 }
271 
272 /*
273  * tis_readresponse()
274  *
275  * read the TPM device response after a command was issued.
276  *
277  * @buffer - address where to read the response, byte by byte.
278  * @len - pointer to the size of buffer
279  *
280  * On success stores the number of received bytes to len and returns 0. On
281  * errors (misformatted TPM data or synchronization problems) returns
282  * -ve value.
283  */
284 static int tis_readresponse(struct udevice *dev, u8 *buffer, size_t len)
285 {
286 	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
287 	struct tpm_locality *regs = priv->regs;
288 	u16 burst;
289 	u32 value;
290 	u32 offset = 0;
291 	u8 locality = 0;
292 	const u32 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
293 	u32 expected_count = len;
294 	int max_cycles = 0;
295 
296 	/* Wait for the TPM to process the command. */
297 	value = tis_wait_reg(priv, &regs[locality].tpm_status,
298 			      has_data, has_data);
299 	if (value == -ETIMEDOUT) {
300 		printf("%s:%d failed processing command\n",
301 		       __FILE__, __LINE__);
302 		return value;
303 	}
304 
305 	do {
306 		while ((burst = burst_count(value)) == 0) {
307 			if (max_cycles++ == MAX_DELAY_US) {
308 				printf("%s:%d TPM stuck on read\n",
309 				       __FILE__, __LINE__);
310 				return -EIO;
311 			}
312 			udelay(1);
313 			value = tpm_read_word(priv, &regs[locality].tpm_status);
314 		}
315 
316 		max_cycles = 0;
317 
318 		while (burst-- && (offset < expected_count)) {
319 			buffer[offset++] = tpm_read_byte(priv,
320 						&regs[locality].data);
321 
322 			if (offset == 6) {
323 				/*
324 				 * We got the first six bytes of the reply,
325 				 * let's figure out how many bytes to expect
326 				 * total - it is stored as a 4 byte number in
327 				 * network order, starting with offset 2 into
328 				 * the body of the reply.
329 				 */
330 				u32 real_length;
331 				memcpy(&real_length,
332 				       buffer + 2,
333 				       sizeof(real_length));
334 				expected_count = be32_to_cpu(real_length);
335 
336 				if ((expected_count < offset) ||
337 				    (expected_count > len)) {
338 					printf("%s:%d bad response size %d\n",
339 					       __FILE__, __LINE__,
340 					       expected_count);
341 					return -ENOSPC;
342 				}
343 			}
344 		}
345 
346 		/* Wait for the next portion. */
347 		value = tis_wait_reg(priv, &regs[locality].tpm_status,
348 				     TIS_STS_VALID, TIS_STS_VALID);
349 		if (value == -ETIMEDOUT) {
350 			printf("%s:%d failed to read response\n",
351 			       __FILE__, __LINE__);
352 			return value;
353 		}
354 
355 		if (offset == expected_count)
356 			break;	/* We got all we needed. */
357 
358 	} while ((value & has_data) == has_data);
359 
360 	/*
361 	 * Make sure we indeed read all there was. The TIS_STS_VALID bit is
362 	 * known to be set.
363 	 */
364 	if (value & TIS_STS_DATA_AVAILABLE) {
365 		printf("%s:%d wrong receive status %x\n",
366 		       __FILE__, __LINE__, value);
367 		return -EBADMSG;
368 	}
369 
370 	/* Tell the TPM that we are done. */
371 	tpm_write_word(priv, TIS_STS_COMMAND_READY,
372 		       &regs[locality].tpm_status);
373 
374 	return offset;
375 }
376 
377 static int tpm_tis_lpc_open(struct udevice *dev)
378 {
379 	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
380 	struct tpm_locality *regs = priv->regs;
381 	u8 locality = 0; /* we use locality zero for everything. */
382 	int ret;
383 
384 	/* now request access to locality. */
385 	tpm_write_word(priv, TIS_ACCESS_REQUEST_USE, &regs[locality].access);
386 
387 	/* did we get a lock? */
388 	ret = tis_wait_reg(priv, &regs[locality].access,
389 			 TIS_ACCESS_ACTIVE_LOCALITY,
390 			 TIS_ACCESS_ACTIVE_LOCALITY);
391 	if (ret == -ETIMEDOUT) {
392 		printf("%s:%d - failed to lock locality %d\n",
393 		       __FILE__, __LINE__, locality);
394 		return ret;
395 	}
396 
397 	tpm_write_word(priv, TIS_STS_COMMAND_READY,
398 		       &regs[locality].tpm_status);
399 	return 0;
400 }
401 
402 static int tpm_tis_lpc_close(struct udevice *dev)
403 {
404 	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
405 	struct tpm_locality *regs = priv->regs;
406 	u8 locality = 0;
407 
408 	if (tpm_read_word(priv, &regs[locality].access) &
409 	    TIS_ACCESS_ACTIVE_LOCALITY) {
410 		tpm_write_word(priv, TIS_ACCESS_ACTIVE_LOCALITY,
411 			       &regs[locality].access);
412 
413 		if (tis_wait_reg(priv, &regs[locality].access,
414 				 TIS_ACCESS_ACTIVE_LOCALITY, 0) == -ETIMEDOUT) {
415 			printf("%s:%d - failed to release locality %d\n",
416 			       __FILE__, __LINE__, locality);
417 			return -ETIMEDOUT;
418 		}
419 	}
420 	return 0;
421 }
422 
423 static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
424 {
425 	if (size < 50)
426 		return -ENOSPC;
427 
428 	return snprintf(buf, size, "1.2 TPM (vendor %s, chip %s)",
429 			"Infineon", "SLB9635 TT 1.2");
430 }
431 
432 
433 static const struct tpm_ops tpm_tis_lpc_ops = {
434 	.open		= tpm_tis_lpc_open,
435 	.close		= tpm_tis_lpc_close,
436 	.get_desc	= tpm_tis_get_desc,
437 	.send		= tis_senddata,
438 	.recv		= tis_readresponse,
439 };
440 
441 static const struct udevice_id tpm_tis_lpc_ids[] = {
442 	{ .compatible = "infineon,slb9635lpc" },
443 	{ }
444 };
445 
446 U_BOOT_DRIVER(tpm_tis_lpc) = {
447 	.name   = "tpm_tis_lpc",
448 	.id     = UCLASS_TPM,
449 	.of_match = tpm_tis_lpc_ids,
450 	.ops    = &tpm_tis_lpc_ops,
451 	.probe	= tpm_tis_lpc_probe,
452 	.priv_auto_alloc_size = sizeof(struct tpm_tis_lpc_priv),
453 };
454