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