xref: /openbmc/u-boot/drivers/tpm/tpm_tis_lpc.c (revision 983c72f4)
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22 
23 /*
24  * The code in this file is based on the article "Writing a TPM Device Driver"
25  * published on http://ptgmedia.pearsoncmg.com.
26  *
27  * One principal difference is that in the simplest config the other than 0
28  * TPM localities do not get mapped by some devices (for instance, by Infineon
29  * slb9635), so this driver provides access to locality 0 only.
30  */
31 
32 #include <common.h>
33 #include <asm/io.h>
34 #include <tpm.h>
35 
36 #define PREFIX "lpc_tpm: "
37 
38 struct tpm_locality {
39 	u32 access;
40 	u8 padding0[4];
41 	u32 int_enable;
42 	u8 vector;
43 	u8 padding1[3];
44 	u32 int_status;
45 	u32 int_capability;
46 	u32 tpm_status;
47 	u8 padding2[8];
48 	u8 data;
49 	u8 padding3[3803];
50 	u32 did_vid;
51 	u8 rid;
52 	u8 padding4[251];
53 };
54 
55 /*
56  * This pointer refers to the TPM chip, 5 of its localities are mapped as an
57  * array.
58  */
59 #define TPM_TOTAL_LOCALITIES	5
60 static struct tpm_locality *lpc_tpm_dev =
61 	(struct tpm_locality *)CONFIG_TPM_TIS_BASE_ADDRESS;
62 
63 /* Some registers' bit field definitions */
64 #define TIS_STS_VALID                  (1 << 7) /* 0x80 */
65 #define TIS_STS_COMMAND_READY          (1 << 6) /* 0x40 */
66 #define TIS_STS_TPM_GO                 (1 << 5) /* 0x20 */
67 #define TIS_STS_DATA_AVAILABLE         (1 << 4) /* 0x10 */
68 #define TIS_STS_EXPECT                 (1 << 3) /* 0x08 */
69 #define TIS_STS_RESPONSE_RETRY         (1 << 1) /* 0x02 */
70 
71 #define TIS_ACCESS_TPM_REG_VALID_STS   (1 << 7) /* 0x80 */
72 #define TIS_ACCESS_ACTIVE_LOCALITY     (1 << 5) /* 0x20 */
73 #define TIS_ACCESS_BEEN_SEIZED         (1 << 4) /* 0x10 */
74 #define TIS_ACCESS_SEIZE               (1 << 3) /* 0x08 */
75 #define TIS_ACCESS_PENDING_REQUEST     (1 << 2) /* 0x04 */
76 #define TIS_ACCESS_REQUEST_USE         (1 << 1) /* 0x02 */
77 #define TIS_ACCESS_TPM_ESTABLISHMENT   (1 << 0) /* 0x01 */
78 
79 #define TIS_STS_BURST_COUNT_MASK       (0xffff)
80 #define TIS_STS_BURST_COUNT_SHIFT      (8)
81 
82 /*
83  * Error value returned if a tpm register does not enter the expected state
84  * after continuous polling. No actual TPM register reading ever returns -1,
85  * so this value is a safe error indication to be mixed with possible status
86  * register values.
87  */
88 #define TPM_TIMEOUT_ERR			(-1)
89 
90 /* Error value returned on various TPM driver errors. */
91 #define TPM_DRIVER_ERR		(1)
92 
93  /* 1 second is plenty for anything TPM does. */
94 #define MAX_DELAY_US	(1000 * 1000)
95 
96 /* Retrieve burst count value out of the status register contents. */
97 static u16 burst_count(u32 status)
98 {
99 	return (status >> TIS_STS_BURST_COUNT_SHIFT) & TIS_STS_BURST_COUNT_MASK;
100 }
101 
102 /*
103  * Structures defined below allow creating descriptions of TPM vendor/device
104  * ID information for run time discovery. The only device the system knows
105  * about at this time is Infineon slb9635.
106  */
107 struct device_name {
108 	u16 dev_id;
109 	const char * const dev_name;
110 };
111 
112 struct vendor_name {
113 	u16 vendor_id;
114 	const char *vendor_name;
115 	const struct device_name *dev_names;
116 };
117 
118 static const struct device_name infineon_devices[] = {
119 	{0xb, "SLB9635 TT 1.2"},
120 	{0}
121 };
122 
123 static const struct vendor_name vendor_names[] = {
124 	{0x15d1, "Infineon", infineon_devices},
125 };
126 
127 /*
128  * Cached vendor/device ID pair to indicate that the device has been already
129  * discovered.
130  */
131 static u32 vendor_dev_id;
132 
133 /* TPM access wrappers to support tracing */
134 static u8 tpm_read_byte(const u8 *ptr)
135 {
136 	u8  ret = readb(ptr);
137 	debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n",
138 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, ret);
139 	return ret;
140 }
141 
142 static u32 tpm_read_word(const u32 *ptr)
143 {
144 	u32  ret = readl(ptr);
145 	debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n",
146 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, ret);
147 	return ret;
148 }
149 
150 static void tpm_write_byte(u8 value, u8 *ptr)
151 {
152 	debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n",
153 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, value);
154 	writeb(value, ptr);
155 }
156 
157 static void tpm_write_word(u32 value, u32 *ptr)
158 {
159 	debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n",
160 	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, value);
161 	writel(value, ptr);
162 }
163 
164 /*
165  * tis_wait_reg()
166  *
167  * Wait for at least a second for a register to change its state to match the
168  * expected state. Normally the transition happens within microseconds.
169  *
170  * @reg - pointer to the TPM register
171  * @mask - bitmask for the bitfield(s) to watch
172  * @expected - value the field(s) are supposed to be set to
173  *
174  * Returns the register contents in case the expected value was found in the
175  * appropriate register bits, or TPM_TIMEOUT_ERR on timeout.
176  */
177 static u32 tis_wait_reg(u32 *reg, u8 mask, u8 expected)
178 {
179 	u32 time_us = MAX_DELAY_US;
180 
181 	while (time_us > 0) {
182 		u32 value = tpm_read_word(reg);
183 		if ((value & mask) == expected)
184 			return value;
185 		udelay(1); /* 1 us */
186 		time_us--;
187 	}
188 	return TPM_TIMEOUT_ERR;
189 }
190 
191 /*
192  * Probe the TPM device and try determining its manufacturer/device name.
193  *
194  * Returns 0 on success (the device is found or was found during an earlier
195  * invocation) or TPM_DRIVER_ERR if the device is not found.
196  */
197 int tis_init(void)
198 {
199 	u32 didvid = tpm_read_word(&lpc_tpm_dev[0].did_vid);
200 	int i;
201 	const char *device_name = "unknown";
202 	const char *vendor_name = device_name;
203 	u16 vid, did;
204 
205 	if (vendor_dev_id)
206 		return 0;  /* Already probed. */
207 
208 	if (!didvid || (didvid == 0xffffffff)) {
209 		printf("%s: No TPM device found\n", __func__);
210 		return TPM_DRIVER_ERR;
211 	}
212 
213 	vendor_dev_id = didvid;
214 
215 	vid = didvid & 0xffff;
216 	did = (didvid >> 16) & 0xffff;
217 	for (i = 0; i < ARRAY_SIZE(vendor_names); i++) {
218 		int j = 0;
219 		u16 known_did;
220 
221 		if (vid == vendor_names[i].vendor_id)
222 			vendor_name = vendor_names[i].vendor_name;
223 
224 		while ((known_did = vendor_names[i].dev_names[j].dev_id) != 0) {
225 			if (known_did == did) {
226 				device_name =
227 					vendor_names[i].dev_names[j].dev_name;
228 				break;
229 			}
230 			j++;
231 		}
232 		break;
233 	}
234 
235 	printf("Found TPM %s by %s\n", device_name, vendor_name);
236 	return 0;
237 }
238 
239 /*
240  * tis_senddata()
241  *
242  * send the passed in data to the TPM device.
243  *
244  * @data - address of the data to send, byte by byte
245  * @len - length of the data to send
246  *
247  * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does
248  * not accept the entire command).
249  */
250 static u32 tis_senddata(const u8 * const data, u32 len)
251 {
252 	u32 offset = 0;
253 	u16 burst = 0;
254 	u32 max_cycles = 0;
255 	u8 locality = 0;
256 	u32 value;
257 
258 	value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
259 			     TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY);
260 	if (value == TPM_TIMEOUT_ERR) {
261 		printf("%s:%d - failed to get 'command_ready' status\n",
262 		       __FILE__, __LINE__);
263 		return TPM_DRIVER_ERR;
264 	}
265 	burst = burst_count(value);
266 
267 	while (1) {
268 		unsigned count;
269 
270 		/* Wait till the device is ready to accept more data. */
271 		while (!burst) {
272 			if (max_cycles++ == MAX_DELAY_US) {
273 				printf("%s:%d failed to feed %d bytes of %d\n",
274 				       __FILE__, __LINE__, len - offset, len);
275 				return TPM_DRIVER_ERR;
276 			}
277 			udelay(1);
278 			burst = burst_count(tpm_read_word(&lpc_tpm_dev
279 						     [locality].tpm_status));
280 		}
281 
282 		max_cycles = 0;
283 
284 		/*
285 		 * Calculate number of bytes the TPM is ready to accept in one
286 		 * shot.
287 		 *
288 		 * We want to send the last byte outside of the loop (hence
289 		 * the -1 below) to make sure that the 'expected' status bit
290 		 * changes to zero exactly after the last byte is fed into the
291 		 * FIFO.
292 		 */
293 		count = min(burst, len - offset - 1);
294 		while (count--)
295 			tpm_write_byte(data[offset++],
296 				  &lpc_tpm_dev[locality].data);
297 
298 		value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
299 				     TIS_STS_VALID, TIS_STS_VALID);
300 
301 		if ((value == TPM_TIMEOUT_ERR) || !(value & TIS_STS_EXPECT)) {
302 			printf("%s:%d TPM command feed overflow\n",
303 			       __FILE__, __LINE__);
304 			return TPM_DRIVER_ERR;
305 		}
306 
307 		burst = burst_count(value);
308 		if ((offset == (len - 1)) && burst) {
309 			/*
310 			 * We need to be able to send the last byte to the
311 			 * device, so burst size must be nonzero before we
312 			 * break out.
313 			 */
314 			break;
315 		}
316 	}
317 
318 	/* Send the last byte. */
319 	tpm_write_byte(data[offset++], &lpc_tpm_dev[locality].data);
320 	/*
321 	 * Verify that TPM does not expect any more data as part of this
322 	 * command.
323 	 */
324 	value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
325 			     TIS_STS_VALID, TIS_STS_VALID);
326 	if ((value == TPM_TIMEOUT_ERR) || (value & TIS_STS_EXPECT)) {
327 		printf("%s:%d unexpected TPM status 0x%x\n",
328 		       __FILE__, __LINE__, value);
329 		return TPM_DRIVER_ERR;
330 	}
331 
332 	/* OK, sitting pretty, let's start the command execution. */
333 	tpm_write_word(TIS_STS_TPM_GO, &lpc_tpm_dev[locality].tpm_status);
334 	return 0;
335 }
336 
337 /*
338  * tis_readresponse()
339  *
340  * read the TPM device response after a command was issued.
341  *
342  * @buffer - address where to read the response, byte by byte.
343  * @len - pointer to the size of buffer
344  *
345  * On success stores the number of received bytes to len and returns 0. On
346  * errors (misformatted TPM data or synchronization problems) returns
347  * TPM_DRIVER_ERR.
348  */
349 static u32 tis_readresponse(u8 *buffer, u32 *len)
350 {
351 	u16 burst;
352 	u32 value;
353 	u32 offset = 0;
354 	u8 locality = 0;
355 	const u32 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
356 	u32 expected_count = *len;
357 	int max_cycles = 0;
358 
359 	/* Wait for the TPM to process the command. */
360 	value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
361 			      has_data, has_data);
362 	if (value == TPM_TIMEOUT_ERR) {
363 		printf("%s:%d failed processing command\n",
364 		       __FILE__, __LINE__);
365 		return TPM_DRIVER_ERR;
366 	}
367 
368 	do {
369 		while ((burst = burst_count(value)) == 0) {
370 			if (max_cycles++ == MAX_DELAY_US) {
371 				printf("%s:%d TPM stuck on read\n",
372 				       __FILE__, __LINE__);
373 				return TPM_DRIVER_ERR;
374 			}
375 			udelay(1);
376 			value = tpm_read_word(&lpc_tpm_dev
377 					      [locality].tpm_status);
378 		}
379 
380 		max_cycles = 0;
381 
382 		while (burst-- && (offset < expected_count)) {
383 			buffer[offset++] = tpm_read_byte(&lpc_tpm_dev
384 							 [locality].data);
385 
386 			if (offset == 6) {
387 				/*
388 				 * We got the first six bytes of the reply,
389 				 * let's figure out how many bytes to expect
390 				 * total - it is stored as a 4 byte number in
391 				 * network order, starting with offset 2 into
392 				 * the body of the reply.
393 				 */
394 				u32 real_length;
395 				memcpy(&real_length,
396 				       buffer + 2,
397 				       sizeof(real_length));
398 				expected_count = be32_to_cpu(real_length);
399 
400 				if ((expected_count < offset) ||
401 				    (expected_count > *len)) {
402 					printf("%s:%d bad response size %d\n",
403 					       __FILE__, __LINE__,
404 					       expected_count);
405 					return TPM_DRIVER_ERR;
406 				}
407 			}
408 		}
409 
410 		/* Wait for the next portion. */
411 		value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
412 				     TIS_STS_VALID, TIS_STS_VALID);
413 		if (value == TPM_TIMEOUT_ERR) {
414 			printf("%s:%d failed to read response\n",
415 			       __FILE__, __LINE__);
416 			return TPM_DRIVER_ERR;
417 		}
418 
419 		if (offset == expected_count)
420 			break;	/* We got all we needed. */
421 
422 	} while ((value & has_data) == has_data);
423 
424 	/*
425 	 * Make sure we indeed read all there was. The TIS_STS_VALID bit is
426 	 * known to be set.
427 	 */
428 	if (value & TIS_STS_DATA_AVAILABLE) {
429 		printf("%s:%d wrong receive status %x\n",
430 		       __FILE__, __LINE__, value);
431 		return TPM_DRIVER_ERR;
432 	}
433 
434 	/* Tell the TPM that we are done. */
435 	tpm_write_word(TIS_STS_COMMAND_READY, &lpc_tpm_dev
436 		  [locality].tpm_status);
437 	*len = offset;
438 	return 0;
439 }
440 
441 int tis_open(void)
442 {
443 	u8 locality = 0; /* we use locality zero for everything. */
444 
445 	if (tis_close())
446 		return TPM_DRIVER_ERR;
447 
448 	/* now request access to locality. */
449 	tpm_write_word(TIS_ACCESS_REQUEST_USE, &lpc_tpm_dev[locality].access);
450 
451 	/* did we get a lock? */
452 	if (tis_wait_reg(&lpc_tpm_dev[locality].access,
453 			 TIS_ACCESS_ACTIVE_LOCALITY,
454 			 TIS_ACCESS_ACTIVE_LOCALITY) == TPM_TIMEOUT_ERR) {
455 		printf("%s:%d - failed to lock locality %d\n",
456 		       __FILE__, __LINE__, locality);
457 		return TPM_DRIVER_ERR;
458 	}
459 
460 	tpm_write_word(TIS_STS_COMMAND_READY,
461 		       &lpc_tpm_dev[locality].tpm_status);
462 	return 0;
463 }
464 
465 int tis_close(void)
466 {
467 	u8 locality = 0;
468 
469 	if (tpm_read_word(&lpc_tpm_dev[locality].access) &
470 	    TIS_ACCESS_ACTIVE_LOCALITY) {
471 		tpm_write_word(TIS_ACCESS_ACTIVE_LOCALITY,
472 			       &lpc_tpm_dev[locality].access);
473 
474 		if (tis_wait_reg(&lpc_tpm_dev[locality].access,
475 				 TIS_ACCESS_ACTIVE_LOCALITY, 0) ==
476 		    TPM_TIMEOUT_ERR) {
477 			printf("%s:%d - failed to release locality %d\n",
478 			       __FILE__, __LINE__, locality);
479 			return TPM_DRIVER_ERR;
480 		}
481 	}
482 	return 0;
483 }
484 
485 int tis_sendrecv(const u8 *sendbuf, size_t send_size,
486 		 u8 *recvbuf, size_t *recv_len)
487 {
488 	if (tis_senddata(sendbuf, send_size)) {
489 		printf("%s:%d failed sending data to TPM\n",
490 		       __FILE__, __LINE__);
491 		return TPM_DRIVER_ERR;
492 	}
493 
494 	return tis_readresponse(recvbuf, (u32 *)recv_len);
495 }
496