blob: ba2561df12feed91f65f7a7364a428f18a69c465 [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
Patrick Georgib890a122015-03-26 15:17:45 +010017 * Foundation, Inc.
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070018 */
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
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070030#include <stdlib.h>
31#include <string.h>
32#include <delay.h>
33#include <arch/io.h>
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070034#include <console/console.h>
Stefan Reinauerd518c7a2013-11-04 17:38:32 -080035#include <tpm.h>
Stefan Reinauerfd4f4132013-06-19 12:25:44 -070036#include <arch/early_variables.h>
Duncan Lauriedd281ed2014-10-30 15:20:19 -070037#include <device/pnp.h>
38#include "chip.h"
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070039
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070040#define PREFIX "lpc_tpm: "
41
42/* coreboot wrapper for TPM driver (start) */
43#define TPM_DEBUG(fmt, args...) \
Stefan Reinauerdfb098d2011-11-17 12:50:54 -080044 if (CONFIG_DEBUG_TPM) { \
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070045 printk(BIOS_DEBUG, PREFIX); \
46 printk(BIOS_DEBUG, fmt , ##args); \
47 }
Aaron Durbinc4220022013-07-24 16:02:14 -050048#define TPM_DEBUG_IO_READ(reg_, val_) \
49 TPM_DEBUG("Read reg 0x%x returns 0x%x\n", (reg_), (val_))
50#define TPM_DEBUG_IO_WRITE(reg_, val_) \
51 TPM_DEBUG("Write reg 0x%x with 0x%x\n", (reg_), (val_))
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070052#define printf(x...) printk(BIOS_ERR, x)
53
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070054/* coreboot wrapper for TPM driver (end) */
55
56#ifndef CONFIG_TPM_TIS_BASE_ADDRESS
57/* Base TPM address standard for x86 systems */
58#define CONFIG_TPM_TIS_BASE_ADDRESS 0xfed40000
59#endif
60
61/* the macro accepts the locality value, but only locality 0 is operational */
62#define TIS_REG(LOCALITY, REG) \
63 (void *)(CONFIG_TPM_TIS_BASE_ADDRESS + (LOCALITY << 12) + REG)
64
65/* hardware registers' offsets */
66#define TIS_REG_ACCESS 0x0
67#define TIS_REG_INT_ENABLE 0x8
68#define TIS_REG_INT_VECTOR 0xc
69#define TIS_REG_INT_STATUS 0x10
70#define TIS_REG_INTF_CAPABILITY 0x14
71#define TIS_REG_STS 0x18
Aaron Durbinc4220022013-07-24 16:02:14 -050072#define TIS_REG_BURST_COUNT 0x19
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070073#define TIS_REG_DATA_FIFO 0x24
74#define TIS_REG_DID_VID 0xf00
75#define TIS_REG_RID 0xf04
76
77/* Some registers' bit field definitions */
78#define TIS_STS_VALID (1 << 7) /* 0x80 */
79#define TIS_STS_COMMAND_READY (1 << 6) /* 0x40 */
80#define TIS_STS_TPM_GO (1 << 5) /* 0x20 */
81#define TIS_STS_DATA_AVAILABLE (1 << 4) /* 0x10 */
82#define TIS_STS_EXPECT (1 << 3) /* 0x08 */
83#define TIS_STS_RESPONSE_RETRY (1 << 1) /* 0x02 */
84
85#define TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */
86#define TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */
87#define TIS_ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */
88#define TIS_ACCESS_SEIZE (1 << 3) /* 0x08 */
89#define TIS_ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */
90#define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */
91#define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
92
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070093/*
94 * Error value returned if a tpm register does not enter the expected state
95 * after continuous polling. No actual TPM register reading ever returns ~0,
96 * so this value is a safe error indication to be mixed with possible status
97 * register values.
98 */
99#define TPM_TIMEOUT_ERR (~0)
100
101/* Error value returned on various TPM driver errors */
102#define TPM_DRIVER_ERR (~0)
103
104 /* 1 second is plenty for anything TPM does.*/
105#define MAX_DELAY_US (1000 * 1000)
106
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700107/*
108 * Structures defined below allow creating descriptions of TPM vendor/device
109 * ID information for run time discovery. The only device the system knows
110 * about at this time is Infineon slb9635
111 */
112struct device_name {
113 u16 dev_id;
114 const char * const dev_name;
115};
116
117struct vendor_name {
118 u16 vendor_id;
119 const char * vendor_name;
Stefan Reinauerc668af72011-10-27 21:28:25 +0000120 const struct device_name* dev_names;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700121};
122
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700123static const struct device_name atmel_devices[] = {
124 {0x3204, "AT97SC3204"},
125 {0xffff}
126};
127
Stefan Reinauerc668af72011-10-27 21:28:25 +0000128static const struct device_name infineon_devices[] = {
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700129 {0x000b, "SLB9635 TT 1.2"},
Subrataf4d65872015-05-14 14:38:07 +0530130 {0x001a, "SLB9660 TT 1.2"},
Wenkai Du641529b2015-05-29 10:54:27 -0700131 {0x001b, "SLB9670 TT 1.2"},
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700132 {0xffff}
133};
134
135static const struct device_name nuvoton_devices[] = {
136 {0x00fe, "NPCT420AA V2"},
137 {0xffff}
138};
139
140static const struct device_name stmicro_devices[] = {
141 {0x0000, "ST33ZP24" },
142 {0xffff}
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700143};
144
145static const struct vendor_name vendor_names[] = {
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700146 {0x1114, "Atmel", atmel_devices},
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700147 {0x15d1, "Infineon", infineon_devices},
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700148 {0x1050, "Nuvoton", nuvoton_devices},
149 {0x104a, "ST Microelectronics", stmicro_devices},
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700150};
151
152/*
153 * Cached vendor/device ID pair to indicate that the device has been already
154 * discovered
155 */
Stefan Reinauerc668af72011-10-27 21:28:25 +0000156static u32 vendor_dev_id CAR_GLOBAL;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700157
Aaron Durbinc4220022013-07-24 16:02:14 -0500158static inline u8 tpm_read_status(int locality)
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700159{
Julius Werner2f37bd62015-02-19 14:51:15 -0800160 u8 value = read8(TIS_REG(locality, TIS_REG_STS));
Aaron Durbinc4220022013-07-24 16:02:14 -0500161 TPM_DEBUG_IO_READ(TIS_REG_STS, value);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700162 return value;
163}
164
Aaron Durbinc4220022013-07-24 16:02:14 -0500165static inline void tpm_write_status(u8 sts, int locality)
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700166{
Aaron Durbinc4220022013-07-24 16:02:14 -0500167 TPM_DEBUG_IO_WRITE(TIS_REG_STS, sts);
Julius Werner2f37bd62015-02-19 14:51:15 -0800168 write8(TIS_REG(locality, TIS_REG_STS), sts);
Aaron Durbinc4220022013-07-24 16:02:14 -0500169}
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700170
Aaron Durbinc4220022013-07-24 16:02:14 -0500171static inline u8 tpm_read_data(int locality)
172{
Julius Werner2f37bd62015-02-19 14:51:15 -0800173 u8 value = read8(TIS_REG(locality, TIS_REG_DATA_FIFO));
Aaron Durbinc4220022013-07-24 16:02:14 -0500174 TPM_DEBUG_IO_READ(TIS_REG_DATA_FIFO, value);
175 return value;
176}
177
178static inline void tpm_write_data(u8 data, int locality)
179{
180 TPM_DEBUG_IO_WRITE(TIS_REG_STS, data);
Julius Werner2f37bd62015-02-19 14:51:15 -0800181 write8(TIS_REG(locality, TIS_REG_DATA_FIFO), data);
Aaron Durbinc4220022013-07-24 16:02:14 -0500182}
183
184static inline u16 tpm_read_burst_count(int locality)
185{
186 u16 count;
Julius Werner2f37bd62015-02-19 14:51:15 -0800187 count = read8(TIS_REG(locality, TIS_REG_BURST_COUNT));
188 count |= read8(TIS_REG(locality, TIS_REG_BURST_COUNT + 1)) << 8;
Aaron Durbinc4220022013-07-24 16:02:14 -0500189 TPM_DEBUG_IO_READ(TIS_REG_BURST_COUNT, count);
190 return count;
191}
192
193static inline u8 tpm_read_access(int locality)
194{
Julius Werner2f37bd62015-02-19 14:51:15 -0800195 u8 value = read8(TIS_REG(locality, TIS_REG_ACCESS));
Aaron Durbinc4220022013-07-24 16:02:14 -0500196 TPM_DEBUG_IO_READ(TIS_REG_ACCESS, value);
197 return value;
198}
199
200static inline void tpm_write_access(u8 data, int locality)
201{
202 TPM_DEBUG_IO_WRITE(TIS_REG_ACCESS, data);
Julius Werner2f37bd62015-02-19 14:51:15 -0800203 write8(TIS_REG(locality, TIS_REG_ACCESS), data);
Aaron Durbinc4220022013-07-24 16:02:14 -0500204}
205
206static inline u32 tpm_read_did_vid(int locality)
207{
Julius Werner2f37bd62015-02-19 14:51:15 -0800208 u32 value = read32(TIS_REG(locality, TIS_REG_DID_VID));
Aaron Durbinc4220022013-07-24 16:02:14 -0500209 TPM_DEBUG_IO_READ(TIS_REG_DID_VID, value);
210 return value;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700211}
212
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700213static inline void tpm_write_int_vector(int vector, int locality)
214{
215 TPM_DEBUG_IO_WRITE(TIS_REG_INT_VECTOR, vector);
Julius Werner2f37bd62015-02-19 14:51:15 -0800216 write8(TIS_REG(locality, TIS_REG_INT_VECTOR), vector & 0xf);
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700217}
218
219static inline void tpm_write_int_polarity(int polarity, int locality)
220{
221 /* Set polarity and leave all other bits at 0 */
222 u32 value = (polarity & 0x3) << 3;
223 TPM_DEBUG_IO_WRITE(TIS_REG_INT_ENABLE, value);
Julius Werner2f37bd62015-02-19 14:51:15 -0800224 write32(TIS_REG(locality, TIS_REG_INT_ENABLE), value);
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700225}
226
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700227/*
Aaron Durbinc4220022013-07-24 16:02:14 -0500228 * tis_wait_sts()
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700229 *
Aaron Durbinc4220022013-07-24 16:02:14 -0500230 * Wait for at least a second for a status to change its state to match the
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700231 * expected state. Normally the transition happens within microseconds.
232 *
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700233 * @locality - locality
234 * @mask - bitmask for the bitfield(s) to watch
235 * @expected - value the field(s) are supposed to be set to
236 *
Aaron Durbinc4220022013-07-24 16:02:14 -0500237 * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700238 */
Aaron Durbinc4220022013-07-24 16:02:14 -0500239static int tis_wait_sts(int locality, u8 mask, u8 expected)
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700240{
241 u32 time_us = MAX_DELAY_US;
242 while (time_us > 0) {
Aaron Durbinc4220022013-07-24 16:02:14 -0500243 u8 value = tpm_read_status(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700244 if ((value & mask) == expected)
Aaron Durbinc4220022013-07-24 16:02:14 -0500245 return 0;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700246 udelay(1); /* 1 us */
247 time_us--;
248 }
249 return TPM_TIMEOUT_ERR;
250}
251
Aaron Durbinc4220022013-07-24 16:02:14 -0500252static inline int tis_wait_ready(int locality)
253{
254 return tis_wait_sts(locality, TIS_STS_COMMAND_READY,
255 TIS_STS_COMMAND_READY);
256}
257
258static inline int tis_wait_valid(int locality)
259{
260 return tis_wait_sts(locality, TIS_STS_VALID, TIS_STS_VALID);
261}
262
263static inline int tis_wait_valid_data(int locality)
264{
265 const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
266 return tis_wait_sts(locality, has_data, has_data);
267}
268
269static inline int tis_has_valid_data(int locality)
270{
271 const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
272 return (tpm_read_status(locality) & has_data) == has_data;
273}
274
275static inline int tis_expect_data(int locality)
276{
277 return !!(tpm_read_status(locality) & TIS_STS_EXPECT);
278}
279
280/*
281 * tis_wait_access()
282 *
283 * Wait for at least a second for a access to change its state to match the
284 * expected state. Normally the transition happens within microseconds.
285 *
286 * @locality - locality
287 * @mask - bitmask for the bitfield(s) to watch
288 * @expected - value the field(s) are supposed to be set to
289 *
290 * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
291 */
292static int tis_wait_access(int locality, u8 mask, u8 expected)
293{
294 u32 time_us = MAX_DELAY_US;
295 while (time_us > 0) {
296 u8 value = tpm_read_access(locality);
297 if ((value & mask) == expected)
298 return 0;
299 udelay(1); /* 1 us */
300 time_us--;
301 }
302 return TPM_TIMEOUT_ERR;
303}
304
305static inline int tis_wait_dropped_access(int locality)
306{
307 return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY, 0);
308}
309
310static inline int tis_wait_received_access(int locality)
311{
312 return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY,
313 TIS_ACCESS_ACTIVE_LOCALITY);
314}
315
316static inline int tis_has_access(int locality)
317{
318 return !!(tpm_read_access(locality) & TIS_ACCESS_ACTIVE_LOCALITY);
319}
320
321static inline void tis_request_access(int locality)
322{
323 tpm_write_access(TIS_ACCESS_REQUEST_USE, locality);
324}
325
326static inline void tis_drop_access(int locality)
327{
328 tpm_write_access(TIS_ACCESS_ACTIVE_LOCALITY, locality);
329}
330
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700331/*
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700332 * PC Client Specific TPM Interface Specification section 11.2.12:
333 *
334 * Software must be prepared to send two writes of a "1" to command ready
335 * field: the first to indicate successful read of all the data, thus
336 * clearing the data from the ReadFIFO and freeing the TPM's resources,
337 * and the second to indicate to the TPM it is about to send a new command.
338 *
339 * In practice not all TPMs behave the same so it is necessary to be
340 * flexible when trying to set command ready.
341 *
342 * Returns 0 on success if the TPM is ready for transactions.
343 * Returns TPM_TIMEOUT_ERR if the command ready bit does not get set.
344 */
345static int tis_command_ready(u8 locality)
346{
347 u32 status;
348
349 /* 1st attempt to set command ready */
Aaron Durbinc4220022013-07-24 16:02:14 -0500350 tpm_write_status(TIS_STS_COMMAND_READY, locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700351
352 /* Wait for response */
Aaron Durbinc4220022013-07-24 16:02:14 -0500353 status = tpm_read_status(locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700354
355 /* Check if command ready is set yet */
356 if (status & TIS_STS_COMMAND_READY)
357 return 0;
358
359 /* 2nd attempt to set command ready */
Aaron Durbinc4220022013-07-24 16:02:14 -0500360 tpm_write_status(TIS_STS_COMMAND_READY, locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700361
Aaron Durbinc4220022013-07-24 16:02:14 -0500362 return tis_wait_ready(locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700363}
364
365/*
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700366 * Probe the TPM device and try determining its manufacturer/device name.
367 *
368 * Returns 0 on success (the device is found or was found during an earlier
369 * invocation) or TPM_DRIVER_ERR if the device is not found.
370 */
371static u32 tis_probe(void)
372{
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700373 const char *device_name = "unknown";
374 const char *vendor_name = device_name;
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700375 const struct device_name *dev;
376 u32 didvid;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700377 u16 vid, did;
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700378 int i;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700379
Aaron Durbincb997d32013-05-10 00:40:56 -0500380 if (car_get_var(vendor_dev_id))
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700381 return 0; /* Already probed. */
382
Aaron Durbinc4220022013-07-24 16:02:14 -0500383 didvid = tpm_read_did_vid(0);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700384 if (!didvid || (didvid == 0xffffffff)) {
385 printf("%s: No TPM device found\n", __FUNCTION__);
386 return TPM_DRIVER_ERR;
387 }
388
Aaron Durbincb997d32013-05-10 00:40:56 -0500389 car_set_var(vendor_dev_id, didvid);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700390
391 vid = didvid & 0xffff;
392 did = (didvid >> 16) & 0xffff;
393 for (i = 0; i < ARRAY_SIZE(vendor_names); i++) {
394 int j = 0;
395 u16 known_did;
396 if (vid == vendor_names[i].vendor_id) {
397 vendor_name = vendor_names[i].vendor_name;
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700398 } else {
399 continue;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700400 }
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700401 dev = &vendor_names[i].dev_names[j];
402 while ((known_did = dev->dev_id) != 0xffff) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700403 if (known_did == did) {
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700404 device_name = dev->dev_name;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700405 break;
406 }
407 j++;
Subrata41b08d92015-05-14 14:38:07 +0530408 dev = &vendor_names[i].dev_names[j];
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700409 }
410 break;
411 }
412 /* this will have to be converted into debug printout */
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700413 printf("Found TPM %s by %s\n", device_name, vendor_name);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700414 return 0;
415}
416
417/*
418 * tis_senddata()
419 *
420 * send the passed in data to the TPM device.
421 *
422 * @data - address of the data to send, byte by byte
423 * @len - length of the data to send
424 *
425 * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does
426 * not accept the entire command).
427 */
428static u32 tis_senddata(const u8 * const data, u32 len)
429{
430 u32 offset = 0;
431 u16 burst = 0;
432 u32 max_cycles = 0;
433 u8 locality = 0;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700434
Aaron Durbinc4220022013-07-24 16:02:14 -0500435 if (tis_wait_ready(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700436 printf("%s:%d - failed to get 'command_ready' status\n",
437 __FILE__, __LINE__);
438 return TPM_DRIVER_ERR;
439 }
Aaron Durbinc4220022013-07-24 16:02:14 -0500440 burst = tpm_read_burst_count(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700441
442 while (1) {
443 unsigned count;
444
445 /* Wait till the device is ready to accept more data. */
446 while (!burst) {
447 if (max_cycles++ == MAX_DELAY_US) {
448 printf("%s:%d failed to feed %d bytes of %d\n",
449 __FILE__, __LINE__, len - offset, len);
450 return TPM_DRIVER_ERR;
451 }
452 udelay(1);
Aaron Durbinc4220022013-07-24 16:02:14 -0500453 burst = tpm_read_burst_count(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700454 }
455
456 max_cycles = 0;
457
458 /*
459 * Calculate number of bytes the TPM is ready to accept in one
460 * shot.
461 *
462 * We want to send the last byte outside of the loop (hence
463 * the -1 below) to make sure that the 'expected' status bit
464 * changes to zero exactly after the last byte is fed into the
465 * FIFO.
466 */
467 count = min(burst, len - offset - 1);
468 while (count--)
Aaron Durbinc4220022013-07-24 16:02:14 -0500469 tpm_write_data(data[offset++], locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700470
Aaron Durbinc4220022013-07-24 16:02:14 -0500471 if (tis_wait_valid(locality) || !tis_expect_data(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700472 printf("%s:%d TPM command feed overflow\n",
473 __FILE__, __LINE__);
474 return TPM_DRIVER_ERR;
475 }
476
Aaron Durbinc4220022013-07-24 16:02:14 -0500477 burst = tpm_read_burst_count(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700478 if ((offset == (len - 1)) && burst)
479 /*
480 * We need to be able to send the last byte to the
481 * device, so burst size must be nonzero before we
482 * break out.
483 */
484 break;
485 }
486
487 /* Send the last byte. */
Aaron Durbinc4220022013-07-24 16:02:14 -0500488 tpm_write_data(data[offset++], locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700489
490 /*
491 * Verify that TPM does not expect any more data as part of this
492 * command.
493 */
Aaron Durbinc4220022013-07-24 16:02:14 -0500494 if (tis_wait_valid(locality) || tis_expect_data(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700495 printf("%s:%d unexpected TPM status 0x%x\n",
Aaron Durbinc4220022013-07-24 16:02:14 -0500496 __FILE__, __LINE__, tpm_read_status(locality));
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700497 return TPM_DRIVER_ERR;
498 }
499
500 /* OK, sitting pretty, let's start the command execution. */
Aaron Durbinc4220022013-07-24 16:02:14 -0500501 tpm_write_status(TIS_STS_TPM_GO, locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700502
503 return 0;
504}
505
506/*
507 * tis_readresponse()
508 *
509 * read the TPM device response after a command was issued.
510 *
511 * @buffer - address where to read the response, byte by byte.
512 * @len - pointer to the size of buffer
513 *
514 * On success stores the number of received bytes to len and returns 0. On
515 * errors (misformatted TPM data or synchronization problems) returns
516 * TPM_DRIVER_ERR.
517 */
518static u32 tis_readresponse(u8 *buffer, size_t *len)
519{
520 u16 burst_count;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700521 u32 offset = 0;
522 u8 locality = 0;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700523 u32 expected_count = *len;
524 int max_cycles = 0;
525
526 /* Wait for the TPM to process the command */
Aaron Durbinc4220022013-07-24 16:02:14 -0500527 if (tis_wait_valid_data(locality)) {
528 printf("%s:%d failed processing command\n", __FILE__, __LINE__);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700529 return TPM_DRIVER_ERR;
530 }
531
532 do {
Aaron Durbinc4220022013-07-24 16:02:14 -0500533 while ((burst_count = tpm_read_burst_count(locality)) == 0) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700534 if (max_cycles++ == MAX_DELAY_US) {
535 printf("%s:%d TPM stuck on read\n",
536 __FILE__, __LINE__);
537 return TPM_DRIVER_ERR;
538 }
539 udelay(1);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700540 }
541
542 max_cycles = 0;
543
544 while (burst_count-- && (offset < expected_count)) {
Aaron Durbinc4220022013-07-24 16:02:14 -0500545 buffer[offset++] = tpm_read_data(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700546 if (offset == 6) {
547 /*
548 * We got the first six bytes of the reply,
549 * let's figure out how many bytes to expect
550 * total - it is stored as a 4 byte number in
551 * network order, starting with offset 2 into
552 * the body of the reply.
553 */
554 u32 real_length;
555 memcpy(&real_length,
556 buffer + 2,
557 sizeof(real_length));
558 expected_count = be32_to_cpu(real_length);
559
560 if ((expected_count < offset) ||
561 (expected_count > *len)) {
562 printf("%s:%d bad response size %d\n",
563 __FILE__, __LINE__,
564 expected_count);
565 return TPM_DRIVER_ERR;
566 }
567 }
568 }
569
570 /* Wait for the next portion */
Aaron Durbinc4220022013-07-24 16:02:14 -0500571 if (tis_wait_valid(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700572 printf("%s:%d failed to read response\n",
573 __FILE__, __LINE__);
574 return TPM_DRIVER_ERR;
575 }
576
577 if (offset == expected_count)
578 break; /* We got all we need */
579
Aaron Durbinc4220022013-07-24 16:02:14 -0500580 } while (tis_has_valid_data(locality));
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700581
Aaron Durbinc4220022013-07-24 16:02:14 -0500582 /* * Make sure we indeed read all there was. */
583 if (tis_has_valid_data(locality)) {
584 printf("%s:%d wrong receive status: %x %d bytes left\n",
585 __FILE__, __LINE__, tpm_read_status(locality),
586 tpm_read_burst_count(locality));
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700587 return TPM_DRIVER_ERR;
588 }
589
590 /* Tell the TPM that we are done. */
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700591 if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
592 return TPM_DRIVER_ERR;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700593
594 *len = offset;
595 return 0;
596}
597
598/*
599 * tis_init()
600 *
601 * Initialize the TPM device. Returns 0 on success or TPM_DRIVER_ERR on
602 * failure (in case device probing did not succeed).
603 */
604int tis_init(void)
605{
606 if (tis_probe())
607 return TPM_DRIVER_ERR;
608 return 0;
609}
610
611/*
612 * tis_open()
613 *
614 * Requests access to locality 0 for the caller. After all commands have been
615 * completed the caller is supposed to call tis_close().
616 *
617 * Returns 0 on success, TPM_DRIVER_ERR on failure.
618 */
619int tis_open(void)
620{
621 u8 locality = 0; /* we use locality zero for everything */
622
623 if (tis_close())
624 return TPM_DRIVER_ERR;
625
626 /* now request access to locality */
Aaron Durbinc4220022013-07-24 16:02:14 -0500627 tis_request_access(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700628
629 /* did we get a lock? */
Aaron Durbinc4220022013-07-24 16:02:14 -0500630 if (tis_wait_received_access(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700631 printf("%s:%d - failed to lock locality %d\n",
632 __FILE__, __LINE__, locality);
633 return TPM_DRIVER_ERR;
634 }
635
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700636 /* Certain TPMs seem to need some delay here or they hang... */
637 udelay(10);
638
639 if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
640 return TPM_DRIVER_ERR;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700641
642 return 0;
643}
644
645/*
646 * tis_close()
647 *
Martin Roth56889792013-07-09 21:39:46 -0600648 * terminate the current session with the TPM by releasing the locked
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700649 * locality. Returns 0 on success of TPM_DRIVER_ERR on failure (in case lock
650 * removal did not succeed).
651 */
652int tis_close(void)
653{
654 u8 locality = 0;
Aaron Durbinc4220022013-07-24 16:02:14 -0500655 if (tis_has_access(locality)) {
656 tis_drop_access(locality);
657 if (tis_wait_dropped_access(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700658 printf("%s:%d - failed to release locality %d\n",
659 __FILE__, __LINE__, locality);
660 return TPM_DRIVER_ERR;
661 }
662 }
663 return 0;
664}
665
666/*
667 * tis_sendrecv()
668 *
669 * Send the requested data to the TPM and then try to get its response
670 *
671 * @sendbuf - buffer of the data to send
672 * @send_size size of the data to send
673 * @recvbuf - memory to save the response to
674 * @recv_len - pointer to the size of the response buffer
675 *
676 * Returns 0 on success (and places the number of response bytes at recv_len)
677 * or TPM_DRIVER_ERR on failure.
678 */
679int tis_sendrecv(const uint8_t *sendbuf, size_t send_size,
680 uint8_t *recvbuf, size_t *recv_len)
681{
682 if (tis_senddata(sendbuf, send_size)) {
683 printf("%s:%d failed sending data to TPM\n",
684 __FILE__, __LINE__);
685 return TPM_DRIVER_ERR;
686 }
687
688 return tis_readresponse(recvbuf, recv_len);
689}
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700690
691#ifdef __RAMSTAGE__
692
693/*
694 * tis_setup_interrupt()
695 *
696 * Set up the interrupt vector and polarity for locality 0 and
697 * disable all interrupts so they are unused in firmware but can
698 * be enabled by the OS.
699 *
700 * The values used here must match what is passed in the TPM ACPI
701 * device if ACPI is used on the platform.
702 *
703 * @vector - TPM interrupt vector
704 * @polarity - TPM interrupt polarity
705 *
706 * Returns 0 on success, TPM_DRIVER_ERR on failure.
707 */
708static int tis_setup_interrupt(int vector, int polarity)
709{
710 u8 locality = 0;
711 int has_access = tis_has_access(locality);
712
713 /* Open connection and request access if not already granted */
714 if (!has_access && tis_open() < 0)
715 return TPM_DRIVER_ERR;
716
717 /* Set TPM interrupt vector */
718 tpm_write_int_vector(vector, locality);
719
720 /* Set TPM interupt polarity and disable interrupts */
721 tpm_write_int_polarity(polarity, locality);
722
723 /* Close connection if it was opened */
724 if (!has_access && tis_close() < 0)
725 return TPM_DRIVER_ERR;
726
727 return 0;
728}
729
730static void lpc_tpm_read_resources(struct device *dev)
731{
732 /* Static 5K memory region specified in Kconfig */
733 mmio_resource(dev, 0, CONFIG_TPM_TIS_BASE_ADDRESS >> 10, 0x5000 >> 10);
734}
735
736static void lpc_tpm_set_resources(struct device *dev)
737{
738 tpm_config_t *config = (tpm_config_t *)dev->chip_info;
739 struct resource *res;
740
741 for (res = dev->resource_list; res; res = res->next) {
742 if (!(res->flags & IORESOURCE_ASSIGNED))
743 continue;
744
745 if (res->flags & IORESOURCE_IRQ) {
746 /* Set interrupt vector */
747 tis_setup_interrupt((int)res->base,
748 config->irq_polarity);
749 } else {
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700750 continue;
751 }
752
753 res->flags |= IORESOURCE_STORED;
754 report_resource_stored(dev, res, " <tpm>");
755 }
756}
757
758static struct device_operations lpc_tpm_ops = {
759 .read_resources = &lpc_tpm_read_resources,
760 .set_resources = &lpc_tpm_set_resources,
761};
762
763static struct pnp_info pnp_dev_info[] = {
764 { .flags = PNP_IRQ0 }
765};
766
767static void enable_dev(struct device *dev)
768{
769 pnp_enable_devices(dev, &lpc_tpm_ops,
770 ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
771}
772
773struct chip_operations drivers_pc80_tpm_ops = {
774 CHIP_NAME("LPC TPM")
775 .enable_dev = enable_dev
776};
777
778#endif /* __RAMSTAGE__ */