blob: 8e94303e71c2c5bef12ce55b91268f6fc6bdd3c9 [file] [log] [blame]
Stefan Reinauer3008bbad2011-10-11 14:46:25 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/*
21 * The code in this file has been heavily based on the article "Writing a TPM
22 * Device Driver" published on http://ptgmedia.pearsoncmg.com and the
23 * submission by Stefan Berger on Qemu-devel mailing list.
24 *
25 * One principal difference is that in the simplest config the other than 0
26 * TPM localities do not get mapped by some devices (for instance, by
27 * Infineon slb9635), so this driver provides access to locality 0 only.
28 */
29
30/* #define DEBUG */
31#include <stdlib.h>
32#include <string.h>
33#include <delay.h>
34#include <arch/io.h>
35#include <arch/byteorder.h>
36#include <console/console.h>
37#include <pc80/tpm.h>
Stefan Reinauerc668af72011-10-27 21:28:25 +000038#include <cpu/x86/car.h>
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070039
40#ifdef DEBUG
41#define TPM_DEBUG_ON 1
42#else
43#define TPM_DEBUG_ON 0
44#endif
45
46#define PREFIX "lpc_tpm: "
47
48/* coreboot wrapper for TPM driver (start) */
49#define TPM_DEBUG(fmt, args...) \
50 if (TPM_DEBUG_ON) { \
51 printk(BIOS_DEBUG, PREFIX); \
52 printk(BIOS_DEBUG, fmt , ##args); \
53 }
54#define printf(x...) printk(BIOS_ERR, x)
55
56#define min(a,b) MIN(a,b)
57#define max(a,b) MAX(a,b)
58#define readb(_a) (*(volatile unsigned char *) (_a))
59#define writeb(_v, _a) (*(volatile unsigned char *) (_a) = (_v))
60#define readl(_a) (*(volatile unsigned long *) (_a))
61#define writel(_v, _a) (*(volatile unsigned long *) (_a) = (_v))
62/* coreboot wrapper for TPM driver (end) */
63
64#ifndef CONFIG_TPM_TIS_BASE_ADDRESS
65/* Base TPM address standard for x86 systems */
66#define CONFIG_TPM_TIS_BASE_ADDRESS 0xfed40000
67#endif
68
69/* the macro accepts the locality value, but only locality 0 is operational */
70#define TIS_REG(LOCALITY, REG) \
71 (void *)(CONFIG_TPM_TIS_BASE_ADDRESS + (LOCALITY << 12) + REG)
72
73/* hardware registers' offsets */
74#define TIS_REG_ACCESS 0x0
75#define TIS_REG_INT_ENABLE 0x8
76#define TIS_REG_INT_VECTOR 0xc
77#define TIS_REG_INT_STATUS 0x10
78#define TIS_REG_INTF_CAPABILITY 0x14
79#define TIS_REG_STS 0x18
80#define TIS_REG_DATA_FIFO 0x24
81#define TIS_REG_DID_VID 0xf00
82#define TIS_REG_RID 0xf04
83
84/* Some registers' bit field definitions */
85#define TIS_STS_VALID (1 << 7) /* 0x80 */
86#define TIS_STS_COMMAND_READY (1 << 6) /* 0x40 */
87#define TIS_STS_TPM_GO (1 << 5) /* 0x20 */
88#define TIS_STS_DATA_AVAILABLE (1 << 4) /* 0x10 */
89#define TIS_STS_EXPECT (1 << 3) /* 0x08 */
90#define TIS_STS_RESPONSE_RETRY (1 << 1) /* 0x02 */
91
92#define TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */
93#define TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */
94#define TIS_ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */
95#define TIS_ACCESS_SEIZE (1 << 3) /* 0x08 */
96#define TIS_ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */
97#define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */
98#define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
99
100#define TIS_STS_BURST_COUNT_MASK (0xffff)
101#define TIS_STS_BURST_COUNT_SHIFT (8)
102
103/*
104 * Error value returned if a tpm register does not enter the expected state
105 * after continuous polling. No actual TPM register reading ever returns ~0,
106 * so this value is a safe error indication to be mixed with possible status
107 * register values.
108 */
109#define TPM_TIMEOUT_ERR (~0)
110
111/* Error value returned on various TPM driver errors */
112#define TPM_DRIVER_ERR (~0)
113
114 /* 1 second is plenty for anything TPM does.*/
115#define MAX_DELAY_US (1000 * 1000)
116
117/* Retrieve burst count value out of the status register contents. */
118#define BURST_COUNT(status) ((u16)(((status) >> TIS_STS_BURST_COUNT_SHIFT) & \
119 TIS_STS_BURST_COUNT_MASK))
120
121/*
122 * Structures defined below allow creating descriptions of TPM vendor/device
123 * ID information for run time discovery. The only device the system knows
124 * about at this time is Infineon slb9635
125 */
126struct device_name {
127 u16 dev_id;
128 const char * const dev_name;
129};
130
131struct vendor_name {
132 u16 vendor_id;
133 const char * vendor_name;
Stefan Reinauerc668af72011-10-27 21:28:25 +0000134 const struct device_name* dev_names;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700135};
136
Stefan Reinauerc668af72011-10-27 21:28:25 +0000137static const struct device_name infineon_devices[] = {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700138 {0xb, "SLB9635 TT 1.2"},
139 {0}
140};
141
142static const struct vendor_name vendor_names[] = {
143 {0x15d1, "Infineon", infineon_devices},
144};
145
146/*
147 * Cached vendor/device ID pair to indicate that the device has been already
148 * discovered
149 */
Stefan Reinauerc668af72011-10-27 21:28:25 +0000150static u32 vendor_dev_id CAR_GLOBAL;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700151
152static int is_byte_reg(u32 reg)
153{
154 /*
155 * These TPM registers are 8 bits wide and as such require byte access
156 * on writes and truncated value on reads.
157 */
158 return ((reg == TIS_REG_ACCESS) ||
159 (reg == TIS_REG_INT_VECTOR) ||
160 (reg == TIS_REG_DATA_FIFO));
161}
162
163/* TPM access functions are carved out to make tracing easier. */
164static u32 tpm_read(int locality, u32 reg)
165{
166 u32 value;
167 /*
168 * Data FIFO register must be read and written in byte access mode,
169 * otherwise the FIFO values are returned 4 bytes at a time.
170 */
171 if (is_byte_reg(reg))
172 value = readb(TIS_REG(locality, reg));
173 else
174 value = readl(TIS_REG(locality, reg));
175
176 TPM_DEBUG("Read reg 0x%x returns 0x%x\n", reg, value);
177 return value;
178}
179
180static void tpm_write(u32 value, int locality, u32 reg)
181{
182 TPM_DEBUG("Write reg 0x%x with 0x%x\n", reg, value);
183
184 if (is_byte_reg(reg))
185 writeb(value & 0xff, TIS_REG(locality, reg));
186 else
187 writel(value, TIS_REG(locality, reg));
188}
189
190/*
191 * tis_wait_reg()
192 *
193 * Wait for at least a second for a register to change its state to match the
194 * expected state. Normally the transition happens within microseconds.
195 *
196 * @reg - the TPM register offset
197 * @locality - locality
198 * @mask - bitmask for the bitfield(s) to watch
199 * @expected - value the field(s) are supposed to be set to
200 *
201 * Returns the register contents in case the expected value was found in the
202 * appropriate register bits, or TPM_TIMEOUT_ERR on timeout.
203 */
204static u32 tis_wait_reg(u8 reg, u8 locality, u8 mask, u8 expected)
205{
206 u32 time_us = MAX_DELAY_US;
207 while (time_us > 0) {
208 u32 value = tpm_read(locality, reg);
209 if ((value & mask) == expected)
210 return value;
211 udelay(1); /* 1 us */
212 time_us--;
213 }
214 return TPM_TIMEOUT_ERR;
215}
216
217/*
218 * Probe the TPM device and try determining its manufacturer/device name.
219 *
220 * Returns 0 on success (the device is found or was found during an earlier
221 * invocation) or TPM_DRIVER_ERR if the device is not found.
222 */
223static u32 tis_probe(void)
224{
225 u32 didvid = tpm_read(0, TIS_REG_DID_VID);
226 int i;
227 const char *device_name = "unknown";
228 const char *vendor_name = device_name;
229 u16 vid, did;
230
231 if (vendor_dev_id)
232 return 0; /* Already probed. */
233
234 if (!didvid || (didvid == 0xffffffff)) {
235 printf("%s: No TPM device found\n", __FUNCTION__);
236 return TPM_DRIVER_ERR;
237 }
238
239 vendor_dev_id = didvid;
240
241 vid = didvid & 0xffff;
242 did = (didvid >> 16) & 0xffff;
243 for (i = 0; i < ARRAY_SIZE(vendor_names); i++) {
244 int j = 0;
245 u16 known_did;
246 if (vid == vendor_names[i].vendor_id) {
247 vendor_name = vendor_names[i].vendor_name;
248 }
249 while ((known_did = vendor_names[i].dev_names[j].dev_id) != 0) {
250 if (known_did == did) {
251 device_name =
252 vendor_names[i].dev_names[j].dev_name;
253 break;
254 }
255 j++;
256 }
257 break;
258 }
259 /* this will have to be converted into debug printout */
260 TPM_DEBUG("Found TPM %s by %s\n", device_name, vendor_name);
261 return 0;
262}
263
264/*
265 * tis_senddata()
266 *
267 * send the passed in data to the TPM device.
268 *
269 * @data - address of the data to send, byte by byte
270 * @len - length of the data to send
271 *
272 * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does
273 * not accept the entire command).
274 */
275static u32 tis_senddata(const u8 * const data, u32 len)
276{
277 u32 offset = 0;
278 u16 burst = 0;
279 u32 max_cycles = 0;
280 u8 locality = 0;
281 u32 value;
282
283 value = tis_wait_reg(TIS_REG_STS, locality, TIS_STS_COMMAND_READY,
284 TIS_STS_COMMAND_READY);
285 if (value == TPM_TIMEOUT_ERR) {
286 printf("%s:%d - failed to get 'command_ready' status\n",
287 __FILE__, __LINE__);
288 return TPM_DRIVER_ERR;
289 }
290 burst = BURST_COUNT(value);
291
292 while (1) {
293 unsigned count;
294
295 /* Wait till the device is ready to accept more data. */
296 while (!burst) {
297 if (max_cycles++ == MAX_DELAY_US) {
298 printf("%s:%d failed to feed %d bytes of %d\n",
299 __FILE__, __LINE__, len - offset, len);
300 return TPM_DRIVER_ERR;
301 }
302 udelay(1);
303 burst = BURST_COUNT(tpm_read(locality, TIS_REG_STS));
304 }
305
306 max_cycles = 0;
307
308 /*
309 * Calculate number of bytes the TPM is ready to accept in one
310 * shot.
311 *
312 * We want to send the last byte outside of the loop (hence
313 * the -1 below) to make sure that the 'expected' status bit
314 * changes to zero exactly after the last byte is fed into the
315 * FIFO.
316 */
317 count = min(burst, len - offset - 1);
318 while (count--)
319 tpm_write(data[offset++], locality, TIS_REG_DATA_FIFO);
320
321 value = tis_wait_reg(TIS_REG_STS, locality,
322 TIS_STS_VALID, TIS_STS_VALID);
323
324 if ((value == TPM_TIMEOUT_ERR) || !(value & TIS_STS_EXPECT)) {
325 printf("%s:%d TPM command feed overflow\n",
326 __FILE__, __LINE__);
327 return TPM_DRIVER_ERR;
328 }
329
330 burst = BURST_COUNT(value);
331 if ((offset == (len - 1)) && burst)
332 /*
333 * We need to be able to send the last byte to the
334 * device, so burst size must be nonzero before we
335 * break out.
336 */
337 break;
338 }
339
340 /* Send the last byte. */
341 tpm_write(data[offset++], locality, TIS_REG_DATA_FIFO);
342
343 /*
344 * Verify that TPM does not expect any more data as part of this
345 * command.
346 */
347 value = tis_wait_reg(TIS_REG_STS, locality,
348 TIS_STS_VALID, TIS_STS_VALID);
349 if ((value == TPM_TIMEOUT_ERR) || (value & TIS_STS_EXPECT)) {
350 printf("%s:%d unexpected TPM status 0x%x\n",
351 __FILE__, __LINE__, value);
352 return TPM_DRIVER_ERR;
353 }
354
355 /* OK, sitting pretty, let's start the command execution. */
356 tpm_write(TIS_STS_TPM_GO, locality, TIS_REG_STS);
357
358 return 0;
359}
360
361/*
362 * tis_readresponse()
363 *
364 * read the TPM device response after a command was issued.
365 *
366 * @buffer - address where to read the response, byte by byte.
367 * @len - pointer to the size of buffer
368 *
369 * On success stores the number of received bytes to len and returns 0. On
370 * errors (misformatted TPM data or synchronization problems) returns
371 * TPM_DRIVER_ERR.
372 */
373static u32 tis_readresponse(u8 *buffer, size_t *len)
374{
375 u16 burst_count;
376 u32 status;
377 u32 offset = 0;
378 u8 locality = 0;
379 const u32 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
380 u32 expected_count = *len;
381 int max_cycles = 0;
382
383 /* Wait for the TPM to process the command */
384 status = tis_wait_reg(TIS_REG_STS, locality, has_data, has_data);
385 if (status == TPM_TIMEOUT_ERR) {
386 printf("%s:%d failed processing command\n",
387 __FILE__, __LINE__);
388 return TPM_DRIVER_ERR;
389 }
390
391 do {
392 while ((burst_count = BURST_COUNT(status)) == 0) {
393 if (max_cycles++ == MAX_DELAY_US) {
394 printf("%s:%d TPM stuck on read\n",
395 __FILE__, __LINE__);
396 return TPM_DRIVER_ERR;
397 }
398 udelay(1);
399 status = tpm_read(locality, TIS_REG_STS);
400 }
401
402 max_cycles = 0;
403
404 while (burst_count-- && (offset < expected_count)) {
405 buffer[offset++] = (u8) tpm_read(locality,
406 TIS_REG_DATA_FIFO);
407 if (offset == 6) {
408 /*
409 * We got the first six bytes of the reply,
410 * let's figure out how many bytes to expect
411 * total - it is stored as a 4 byte number in
412 * network order, starting with offset 2 into
413 * the body of the reply.
414 */
415 u32 real_length;
416 memcpy(&real_length,
417 buffer + 2,
418 sizeof(real_length));
419 expected_count = be32_to_cpu(real_length);
420
421 if ((expected_count < offset) ||
422 (expected_count > *len)) {
423 printf("%s:%d bad response size %d\n",
424 __FILE__, __LINE__,
425 expected_count);
426 return TPM_DRIVER_ERR;
427 }
428 }
429 }
430
431 /* Wait for the next portion */
432 status = tis_wait_reg(TIS_REG_STS, locality,
433 TIS_STS_VALID, TIS_STS_VALID);
434 if (status == TPM_TIMEOUT_ERR) {
435 printf("%s:%d failed to read response\n",
436 __FILE__, __LINE__);
437 return TPM_DRIVER_ERR;
438 }
439
440 if (offset == expected_count)
441 break; /* We got all we need */
442
443 } while ((status & has_data) == has_data);
444
445 /*
446 * Make sure we indeed read all there was. The TIS_STS_VALID bit is
447 * known to be set.
448 */
449 if (status & TIS_STS_DATA_AVAILABLE) {
450 printf("%s:%d wrong receive status %x\n",
451 __FILE__, __LINE__, status);
452 return TPM_DRIVER_ERR;
453 }
454
455 /* Tell the TPM that we are done. */
456 tpm_write(TIS_STS_COMMAND_READY, locality, TIS_REG_STS);
457
458 *len = offset;
459 return 0;
460}
461
462/*
463 * tis_init()
464 *
465 * Initialize the TPM device. Returns 0 on success or TPM_DRIVER_ERR on
466 * failure (in case device probing did not succeed).
467 */
468int tis_init(void)
469{
470 if (tis_probe())
471 return TPM_DRIVER_ERR;
472 return 0;
473}
474
475/*
476 * tis_open()
477 *
478 * Requests access to locality 0 for the caller. After all commands have been
479 * completed the caller is supposed to call tis_close().
480 *
481 * Returns 0 on success, TPM_DRIVER_ERR on failure.
482 */
483int tis_open(void)
484{
485 u8 locality = 0; /* we use locality zero for everything */
486
487 if (tis_close())
488 return TPM_DRIVER_ERR;
489
490 /* now request access to locality */
491 tpm_write(TIS_ACCESS_REQUEST_USE, locality, TIS_REG_ACCESS);
492
493 /* did we get a lock? */
494 if (tis_wait_reg(TIS_REG_ACCESS, locality,
495 TIS_ACCESS_ACTIVE_LOCALITY,
496 TIS_ACCESS_ACTIVE_LOCALITY) == TPM_TIMEOUT_ERR) {
497 printf("%s:%d - failed to lock locality %d\n",
498 __FILE__, __LINE__, locality);
499 return TPM_DRIVER_ERR;
500 }
501
502 tpm_write(TIS_STS_COMMAND_READY, locality, TIS_REG_STS);
503
504 return 0;
505}
506
507/*
508 * tis_close()
509 *
510 * terminate the currect session with the TPM by releasing the locked
511 * locality. Returns 0 on success of TPM_DRIVER_ERR on failure (in case lock
512 * removal did not succeed).
513 */
514int tis_close(void)
515{
516 u8 locality = 0;
517 if (tpm_read(locality, TIS_REG_ACCESS) &
518 TIS_ACCESS_ACTIVE_LOCALITY) {
519 tpm_write(TIS_ACCESS_ACTIVE_LOCALITY, locality, TIS_REG_ACCESS);
520
521 if (tis_wait_reg(TIS_REG_ACCESS, locality,
522 TIS_ACCESS_ACTIVE_LOCALITY, 0) ==
523 TPM_TIMEOUT_ERR) {
524 printf("%s:%d - failed to release locality %d\n",
525 __FILE__, __LINE__, locality);
526 return TPM_DRIVER_ERR;
527 }
528 }
529 return 0;
530}
531
532/*
533 * tis_sendrecv()
534 *
535 * Send the requested data to the TPM and then try to get its response
536 *
537 * @sendbuf - buffer of the data to send
538 * @send_size size of the data to send
539 * @recvbuf - memory to save the response to
540 * @recv_len - pointer to the size of the response buffer
541 *
542 * Returns 0 on success (and places the number of response bytes at recv_len)
543 * or TPM_DRIVER_ERR on failure.
544 */
545int tis_sendrecv(const uint8_t *sendbuf, size_t send_size,
546 uint8_t *recvbuf, size_t *recv_len)
547{
548 if (tis_senddata(sendbuf, send_size)) {
549 printf("%s:%d failed sending data to TPM\n",
550 __FILE__, __LINE__);
551 return TPM_DRIVER_ERR;
552 }
553
554 return tis_readresponse(recvbuf, recv_len);
555}