blob: fbfb816cdbc1b9c48f055ad0a973bdfcd1060235 [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.
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070014 */
15
16/*
17 * The code in this file has been heavily based on the article "Writing a TPM
18 * Device Driver" published on http://ptgmedia.pearsoncmg.com and the
19 * submission by Stefan Berger on Qemu-devel mailing list.
20 *
21 * One principal difference is that in the simplest config the other than 0
22 * TPM localities do not get mapped by some devices (for instance, by
23 * Infineon slb9635), so this driver provides access to locality 0 only.
24 */
25
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070026#include <stdlib.h>
27#include <string.h>
28#include <delay.h>
29#include <arch/io.h>
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070030#include <console/console.h>
Stefan Reinauerd518c7a2013-11-04 17:38:32 -080031#include <tpm.h>
Stefan Reinauerfd4f4132013-06-19 12:25:44 -070032#include <arch/early_variables.h>
Duncan Lauriedd281ed2014-10-30 15:20:19 -070033#include <device/pnp.h>
34#include "chip.h"
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070035
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070036#define PREFIX "lpc_tpm: "
37
38/* coreboot wrapper for TPM driver (start) */
39#define TPM_DEBUG(fmt, args...) \
Denis 'GNUtoo' Carikli0e92bb02016-02-20 17:32:03 +010040 if (IS_ENABLED(CONFIG_DEBUG_TPM)) { \
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070041 printk(BIOS_DEBUG, PREFIX); \
42 printk(BIOS_DEBUG, fmt , ##args); \
43 }
Aaron Durbinc4220022013-07-24 16:02:14 -050044#define TPM_DEBUG_IO_READ(reg_, val_) \
45 TPM_DEBUG("Read reg 0x%x returns 0x%x\n", (reg_), (val_))
46#define TPM_DEBUG_IO_WRITE(reg_, val_) \
47 TPM_DEBUG("Write reg 0x%x with 0x%x\n", (reg_), (val_))
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070048#define printf(x...) printk(BIOS_ERR, x)
49
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070050/* coreboot wrapper for TPM driver (end) */
51
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070052/* the macro accepts the locality value, but only locality 0 is operational */
53#define TIS_REG(LOCALITY, REG) \
54 (void *)(CONFIG_TPM_TIS_BASE_ADDRESS + (LOCALITY << 12) + REG)
55
56/* hardware registers' offsets */
57#define TIS_REG_ACCESS 0x0
58#define TIS_REG_INT_ENABLE 0x8
59#define TIS_REG_INT_VECTOR 0xc
60#define TIS_REG_INT_STATUS 0x10
61#define TIS_REG_INTF_CAPABILITY 0x14
62#define TIS_REG_STS 0x18
Aaron Durbinc4220022013-07-24 16:02:14 -050063#define TIS_REG_BURST_COUNT 0x19
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070064#define TIS_REG_DATA_FIFO 0x24
65#define TIS_REG_DID_VID 0xf00
66#define TIS_REG_RID 0xf04
67
68/* Some registers' bit field definitions */
69#define TIS_STS_VALID (1 << 7) /* 0x80 */
70#define TIS_STS_COMMAND_READY (1 << 6) /* 0x40 */
71#define TIS_STS_TPM_GO (1 << 5) /* 0x20 */
72#define TIS_STS_DATA_AVAILABLE (1 << 4) /* 0x10 */
73#define TIS_STS_EXPECT (1 << 3) /* 0x08 */
74#define TIS_STS_RESPONSE_RETRY (1 << 1) /* 0x02 */
75
76#define TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */
77#define TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */
78#define TIS_ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */
79#define TIS_ACCESS_SEIZE (1 << 3) /* 0x08 */
80#define TIS_ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */
81#define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */
82#define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */
83
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070084/*
85 * Error value returned if a tpm register does not enter the expected state
86 * after continuous polling. No actual TPM register reading ever returns ~0,
87 * so this value is a safe error indication to be mixed with possible status
88 * register values.
89 */
90#define TPM_TIMEOUT_ERR (~0)
91
92/* Error value returned on various TPM driver errors */
93#define TPM_DRIVER_ERR (~0)
94
95 /* 1 second is plenty for anything TPM does.*/
96#define MAX_DELAY_US (1000 * 1000)
97
Stefan Reinauer3008bbad2011-10-11 14:46:25 -070098/*
99 * Structures defined below allow creating descriptions of TPM vendor/device
100 * ID information for run time discovery. The only device the system knows
101 * about at this time is Infineon slb9635
102 */
103struct device_name {
104 u16 dev_id;
105 const char * const dev_name;
106};
107
108struct vendor_name {
109 u16 vendor_id;
110 const char * vendor_name;
Stefan Reinauerc668af72011-10-27 21:28:25 +0000111 const struct device_name* dev_names;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700112};
113
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700114static const struct device_name atmel_devices[] = {
115 {0x3204, "AT97SC3204"},
116 {0xffff}
117};
118
Stefan Reinauerc668af72011-10-27 21:28:25 +0000119static const struct device_name infineon_devices[] = {
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700120 {0x000b, "SLB9635 TT 1.2"},
Subrataf4d65872015-05-14 14:38:07 +0530121 {0x001a, "SLB9660 TT 1.2"},
Subrata Banik5b8c4a72016-11-11 09:28:45 +0530122#if IS_ENABLED(CONFIG_TPM2)
123 {0x001b, "SLB9670 TT 2.0"},
124#else
Wenkai Du641529b2015-05-29 10:54:27 -0700125 {0x001b, "SLB9670 TT 1.2"},
Subrata Banik5b8c4a72016-11-11 09:28:45 +0530126#endif
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700127 {0xffff}
128};
129
130static const struct device_name nuvoton_devices[] = {
131 {0x00fe, "NPCT420AA V2"},
132 {0xffff}
133};
134
135static const struct device_name stmicro_devices[] = {
136 {0x0000, "ST33ZP24" },
137 {0xffff}
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700138};
139
140static const struct vendor_name vendor_names[] = {
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700141 {0x1114, "Atmel", atmel_devices},
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700142 {0x15d1, "Infineon", infineon_devices},
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700143 {0x1050, "Nuvoton", nuvoton_devices},
144 {0x104a, "ST Microelectronics", stmicro_devices},
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700145};
146
147/*
148 * Cached vendor/device ID pair to indicate that the device has been already
149 * discovered
150 */
Stefan Reinauerc668af72011-10-27 21:28:25 +0000151static u32 vendor_dev_id CAR_GLOBAL;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700152
Aaron Durbinc4220022013-07-24 16:02:14 -0500153static inline u8 tpm_read_status(int locality)
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700154{
Julius Werner2f37bd62015-02-19 14:51:15 -0800155 u8 value = read8(TIS_REG(locality, TIS_REG_STS));
Aaron Durbinc4220022013-07-24 16:02:14 -0500156 TPM_DEBUG_IO_READ(TIS_REG_STS, value);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700157 return value;
158}
159
Aaron Durbinc4220022013-07-24 16:02:14 -0500160static inline void tpm_write_status(u8 sts, int locality)
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700161{
Aaron Durbinc4220022013-07-24 16:02:14 -0500162 TPM_DEBUG_IO_WRITE(TIS_REG_STS, sts);
Julius Werner2f37bd62015-02-19 14:51:15 -0800163 write8(TIS_REG(locality, TIS_REG_STS), sts);
Aaron Durbinc4220022013-07-24 16:02:14 -0500164}
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700165
Aaron Durbinc4220022013-07-24 16:02:14 -0500166static inline u8 tpm_read_data(int locality)
167{
Julius Werner2f37bd62015-02-19 14:51:15 -0800168 u8 value = read8(TIS_REG(locality, TIS_REG_DATA_FIFO));
Aaron Durbinc4220022013-07-24 16:02:14 -0500169 TPM_DEBUG_IO_READ(TIS_REG_DATA_FIFO, value);
170 return value;
171}
172
173static inline void tpm_write_data(u8 data, int locality)
174{
175 TPM_DEBUG_IO_WRITE(TIS_REG_STS, data);
Julius Werner2f37bd62015-02-19 14:51:15 -0800176 write8(TIS_REG(locality, TIS_REG_DATA_FIFO), data);
Aaron Durbinc4220022013-07-24 16:02:14 -0500177}
178
179static inline u16 tpm_read_burst_count(int locality)
180{
181 u16 count;
Julius Werner2f37bd62015-02-19 14:51:15 -0800182 count = read8(TIS_REG(locality, TIS_REG_BURST_COUNT));
183 count |= read8(TIS_REG(locality, TIS_REG_BURST_COUNT + 1)) << 8;
Aaron Durbinc4220022013-07-24 16:02:14 -0500184 TPM_DEBUG_IO_READ(TIS_REG_BURST_COUNT, count);
185 return count;
186}
187
188static inline u8 tpm_read_access(int locality)
189{
Julius Werner2f37bd62015-02-19 14:51:15 -0800190 u8 value = read8(TIS_REG(locality, TIS_REG_ACCESS));
Aaron Durbinc4220022013-07-24 16:02:14 -0500191 TPM_DEBUG_IO_READ(TIS_REG_ACCESS, value);
192 return value;
193}
194
195static inline void tpm_write_access(u8 data, int locality)
196{
197 TPM_DEBUG_IO_WRITE(TIS_REG_ACCESS, data);
Julius Werner2f37bd62015-02-19 14:51:15 -0800198 write8(TIS_REG(locality, TIS_REG_ACCESS), data);
Aaron Durbinc4220022013-07-24 16:02:14 -0500199}
200
201static inline u32 tpm_read_did_vid(int locality)
202{
Julius Werner2f37bd62015-02-19 14:51:15 -0800203 u32 value = read32(TIS_REG(locality, TIS_REG_DID_VID));
Aaron Durbinc4220022013-07-24 16:02:14 -0500204 TPM_DEBUG_IO_READ(TIS_REG_DID_VID, value);
205 return value;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700206}
207
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700208static inline void tpm_write_int_vector(int vector, int locality)
209{
210 TPM_DEBUG_IO_WRITE(TIS_REG_INT_VECTOR, vector);
Julius Werner2f37bd62015-02-19 14:51:15 -0800211 write8(TIS_REG(locality, TIS_REG_INT_VECTOR), vector & 0xf);
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700212}
213
214static inline void tpm_write_int_polarity(int polarity, int locality)
215{
216 /* Set polarity and leave all other bits at 0 */
217 u32 value = (polarity & 0x3) << 3;
218 TPM_DEBUG_IO_WRITE(TIS_REG_INT_ENABLE, value);
Julius Werner2f37bd62015-02-19 14:51:15 -0800219 write32(TIS_REG(locality, TIS_REG_INT_ENABLE), value);
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700220}
221
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700222/*
Aaron Durbinc4220022013-07-24 16:02:14 -0500223 * tis_wait_sts()
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700224 *
Aaron Durbinc4220022013-07-24 16:02:14 -0500225 * Wait for at least a second for a status to change its state to match the
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700226 * expected state. Normally the transition happens within microseconds.
227 *
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700228 * @locality - locality
229 * @mask - bitmask for the bitfield(s) to watch
230 * @expected - value the field(s) are supposed to be set to
231 *
Aaron Durbinc4220022013-07-24 16:02:14 -0500232 * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700233 */
Aaron Durbinc4220022013-07-24 16:02:14 -0500234static int tis_wait_sts(int locality, u8 mask, u8 expected)
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700235{
236 u32 time_us = MAX_DELAY_US;
237 while (time_us > 0) {
Aaron Durbinc4220022013-07-24 16:02:14 -0500238 u8 value = tpm_read_status(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700239 if ((value & mask) == expected)
Aaron Durbinc4220022013-07-24 16:02:14 -0500240 return 0;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700241 udelay(1); /* 1 us */
242 time_us--;
243 }
244 return TPM_TIMEOUT_ERR;
245}
246
Aaron Durbinc4220022013-07-24 16:02:14 -0500247static inline int tis_wait_ready(int locality)
248{
249 return tis_wait_sts(locality, TIS_STS_COMMAND_READY,
250 TIS_STS_COMMAND_READY);
251}
252
253static inline int tis_wait_valid(int locality)
254{
255 return tis_wait_sts(locality, TIS_STS_VALID, TIS_STS_VALID);
256}
257
258static inline int tis_wait_valid_data(int locality)
259{
260 const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
261 return tis_wait_sts(locality, has_data, has_data);
262}
263
264static inline int tis_has_valid_data(int locality)
265{
266 const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
267 return (tpm_read_status(locality) & has_data) == has_data;
268}
269
270static inline int tis_expect_data(int locality)
271{
272 return !!(tpm_read_status(locality) & TIS_STS_EXPECT);
273}
274
275/*
276 * tis_wait_access()
277 *
278 * Wait for at least a second for a access to change its state to match the
279 * expected state. Normally the transition happens within microseconds.
280 *
281 * @locality - locality
282 * @mask - bitmask for the bitfield(s) to watch
283 * @expected - value the field(s) are supposed to be set to
284 *
285 * Returns 0 on success or TPM_TIMEOUT_ERR on timeout.
286 */
287static int tis_wait_access(int locality, u8 mask, u8 expected)
288{
289 u32 time_us = MAX_DELAY_US;
290 while (time_us > 0) {
291 u8 value = tpm_read_access(locality);
292 if ((value & mask) == expected)
293 return 0;
294 udelay(1); /* 1 us */
295 time_us--;
296 }
297 return TPM_TIMEOUT_ERR;
298}
299
300static inline int tis_wait_dropped_access(int locality)
301{
302 return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY, 0);
303}
304
305static inline int tis_wait_received_access(int locality)
306{
307 return tis_wait_access(locality, TIS_ACCESS_ACTIVE_LOCALITY,
308 TIS_ACCESS_ACTIVE_LOCALITY);
309}
310
311static inline int tis_has_access(int locality)
312{
313 return !!(tpm_read_access(locality) & TIS_ACCESS_ACTIVE_LOCALITY);
314}
315
316static inline void tis_request_access(int locality)
317{
318 tpm_write_access(TIS_ACCESS_REQUEST_USE, locality);
319}
320
321static inline void tis_drop_access(int locality)
322{
323 tpm_write_access(TIS_ACCESS_ACTIVE_LOCALITY, locality);
324}
325
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700326/*
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700327 * PC Client Specific TPM Interface Specification section 11.2.12:
328 *
329 * Software must be prepared to send two writes of a "1" to command ready
330 * field: the first to indicate successful read of all the data, thus
331 * clearing the data from the ReadFIFO and freeing the TPM's resources,
332 * and the second to indicate to the TPM it is about to send a new command.
333 *
334 * In practice not all TPMs behave the same so it is necessary to be
335 * flexible when trying to set command ready.
336 *
337 * Returns 0 on success if the TPM is ready for transactions.
338 * Returns TPM_TIMEOUT_ERR if the command ready bit does not get set.
339 */
340static int tis_command_ready(u8 locality)
341{
342 u32 status;
343
344 /* 1st attempt to set command ready */
Aaron Durbinc4220022013-07-24 16:02:14 -0500345 tpm_write_status(TIS_STS_COMMAND_READY, locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700346
347 /* Wait for response */
Aaron Durbinc4220022013-07-24 16:02:14 -0500348 status = tpm_read_status(locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700349
350 /* Check if command ready is set yet */
351 if (status & TIS_STS_COMMAND_READY)
352 return 0;
353
354 /* 2nd attempt to set command ready */
Aaron Durbinc4220022013-07-24 16:02:14 -0500355 tpm_write_status(TIS_STS_COMMAND_READY, locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700356
Aaron Durbinc4220022013-07-24 16:02:14 -0500357 return tis_wait_ready(locality);
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700358}
359
360/*
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700361 * Probe the TPM device and try determining its manufacturer/device name.
362 *
363 * Returns 0 on success (the device is found or was found during an earlier
364 * invocation) or TPM_DRIVER_ERR if the device is not found.
365 */
366static u32 tis_probe(void)
367{
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700368 const char *device_name = "unknown";
369 const char *vendor_name = device_name;
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700370 const struct device_name *dev;
371 u32 didvid;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700372 u16 vid, did;
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700373 int i;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700374
Aaron Durbincb997d32013-05-10 00:40:56 -0500375 if (car_get_var(vendor_dev_id))
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700376 return 0; /* Already probed. */
377
Aaron Durbinc4220022013-07-24 16:02:14 -0500378 didvid = tpm_read_did_vid(0);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700379 if (!didvid || (didvid == 0xffffffff)) {
380 printf("%s: No TPM device found\n", __FUNCTION__);
381 return TPM_DRIVER_ERR;
382 }
383
Aaron Durbincb997d32013-05-10 00:40:56 -0500384 car_set_var(vendor_dev_id, didvid);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700385
386 vid = didvid & 0xffff;
387 did = (didvid >> 16) & 0xffff;
388 for (i = 0; i < ARRAY_SIZE(vendor_names); i++) {
389 int j = 0;
390 u16 known_did;
391 if (vid == vendor_names[i].vendor_id) {
392 vendor_name = vendor_names[i].vendor_name;
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700393 } else {
394 continue;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700395 }
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700396 dev = &vendor_names[i].dev_names[j];
397 while ((known_did = dev->dev_id) != 0xffff) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700398 if (known_did == did) {
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700399 device_name = dev->dev_name;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700400 break;
401 }
402 j++;
Subrata41b08d92015-05-14 14:38:07 +0530403 dev = &vendor_names[i].dev_names[j];
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700404 }
405 break;
406 }
407 /* this will have to be converted into debug printout */
Duncan Laurie17ba9442015-09-03 16:00:49 -0700408 printk(BIOS_INFO, "Found TPM %s by %s\n", device_name, vendor_name);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700409 return 0;
410}
411
412/*
413 * tis_senddata()
414 *
415 * send the passed in data to the TPM device.
416 *
417 * @data - address of the data to send, byte by byte
418 * @len - length of the data to send
419 *
420 * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does
421 * not accept the entire command).
422 */
423static u32 tis_senddata(const u8 * const data, u32 len)
424{
425 u32 offset = 0;
426 u16 burst = 0;
427 u32 max_cycles = 0;
428 u8 locality = 0;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700429
Aaron Durbinc4220022013-07-24 16:02:14 -0500430 if (tis_wait_ready(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700431 printf("%s:%d - failed to get 'command_ready' status\n",
432 __FILE__, __LINE__);
433 return TPM_DRIVER_ERR;
434 }
Aaron Durbinc4220022013-07-24 16:02:14 -0500435 burst = tpm_read_burst_count(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700436
437 while (1) {
438 unsigned count;
439
440 /* Wait till the device is ready to accept more data. */
441 while (!burst) {
442 if (max_cycles++ == MAX_DELAY_US) {
443 printf("%s:%d failed to feed %d bytes of %d\n",
444 __FILE__, __LINE__, len - offset, len);
445 return TPM_DRIVER_ERR;
446 }
447 udelay(1);
Aaron Durbinc4220022013-07-24 16:02:14 -0500448 burst = tpm_read_burst_count(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700449 }
450
451 max_cycles = 0;
452
453 /*
454 * Calculate number of bytes the TPM is ready to accept in one
455 * shot.
456 *
457 * We want to send the last byte outside of the loop (hence
458 * the -1 below) to make sure that the 'expected' status bit
459 * changes to zero exactly after the last byte is fed into the
460 * FIFO.
461 */
462 count = min(burst, len - offset - 1);
463 while (count--)
Aaron Durbinc4220022013-07-24 16:02:14 -0500464 tpm_write_data(data[offset++], locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700465
Aaron Durbinc4220022013-07-24 16:02:14 -0500466 if (tis_wait_valid(locality) || !tis_expect_data(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700467 printf("%s:%d TPM command feed overflow\n",
468 __FILE__, __LINE__);
469 return TPM_DRIVER_ERR;
470 }
471
Aaron Durbinc4220022013-07-24 16:02:14 -0500472 burst = tpm_read_burst_count(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700473 if ((offset == (len - 1)) && burst)
474 /*
475 * We need to be able to send the last byte to the
476 * device, so burst size must be nonzero before we
477 * break out.
478 */
479 break;
480 }
481
482 /* Send the last byte. */
Aaron Durbinc4220022013-07-24 16:02:14 -0500483 tpm_write_data(data[offset++], locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700484
485 /*
486 * Verify that TPM does not expect any more data as part of this
487 * command.
488 */
Aaron Durbinc4220022013-07-24 16:02:14 -0500489 if (tis_wait_valid(locality) || tis_expect_data(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700490 printf("%s:%d unexpected TPM status 0x%x\n",
Aaron Durbinc4220022013-07-24 16:02:14 -0500491 __FILE__, __LINE__, tpm_read_status(locality));
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700492 return TPM_DRIVER_ERR;
493 }
494
495 /* OK, sitting pretty, let's start the command execution. */
Aaron Durbinc4220022013-07-24 16:02:14 -0500496 tpm_write_status(TIS_STS_TPM_GO, locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700497
498 return 0;
499}
500
501/*
502 * tis_readresponse()
503 *
504 * read the TPM device response after a command was issued.
505 *
506 * @buffer - address where to read the response, byte by byte.
507 * @len - pointer to the size of buffer
508 *
509 * On success stores the number of received bytes to len and returns 0. On
510 * errors (misformatted TPM data or synchronization problems) returns
511 * TPM_DRIVER_ERR.
512 */
513static u32 tis_readresponse(u8 *buffer, size_t *len)
514{
515 u16 burst_count;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700516 u32 offset = 0;
517 u8 locality = 0;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700518 u32 expected_count = *len;
519 int max_cycles = 0;
520
521 /* Wait for the TPM to process the command */
Aaron Durbinc4220022013-07-24 16:02:14 -0500522 if (tis_wait_valid_data(locality)) {
523 printf("%s:%d failed processing command\n", __FILE__, __LINE__);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700524 return TPM_DRIVER_ERR;
525 }
526
527 do {
Aaron Durbinc4220022013-07-24 16:02:14 -0500528 while ((burst_count = tpm_read_burst_count(locality)) == 0) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700529 if (max_cycles++ == MAX_DELAY_US) {
530 printf("%s:%d TPM stuck on read\n",
531 __FILE__, __LINE__);
532 return TPM_DRIVER_ERR;
533 }
534 udelay(1);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700535 }
536
537 max_cycles = 0;
538
539 while (burst_count-- && (offset < expected_count)) {
Aaron Durbinc4220022013-07-24 16:02:14 -0500540 buffer[offset++] = tpm_read_data(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700541 if (offset == 6) {
542 /*
543 * We got the first six bytes of the reply,
544 * let's figure out how many bytes to expect
545 * total - it is stored as a 4 byte number in
546 * network order, starting with offset 2 into
547 * the body of the reply.
548 */
549 u32 real_length;
550 memcpy(&real_length,
551 buffer + 2,
552 sizeof(real_length));
553 expected_count = be32_to_cpu(real_length);
554
555 if ((expected_count < offset) ||
556 (expected_count > *len)) {
557 printf("%s:%d bad response size %d\n",
558 __FILE__, __LINE__,
559 expected_count);
560 return TPM_DRIVER_ERR;
561 }
562 }
563 }
564
565 /* Wait for the next portion */
Aaron Durbinc4220022013-07-24 16:02:14 -0500566 if (tis_wait_valid(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700567 printf("%s:%d failed to read response\n",
568 __FILE__, __LINE__);
569 return TPM_DRIVER_ERR;
570 }
571
572 if (offset == expected_count)
573 break; /* We got all we need */
574
Aaron Durbinc4220022013-07-24 16:02:14 -0500575 } while (tis_has_valid_data(locality));
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700576
Aaron Durbinc4220022013-07-24 16:02:14 -0500577 /* * Make sure we indeed read all there was. */
578 if (tis_has_valid_data(locality)) {
579 printf("%s:%d wrong receive status: %x %d bytes left\n",
580 __FILE__, __LINE__, tpm_read_status(locality),
581 tpm_read_burst_count(locality));
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700582 return TPM_DRIVER_ERR;
583 }
584
585 /* Tell the TPM that we are done. */
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700586 if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
587 return TPM_DRIVER_ERR;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700588
589 *len = offset;
590 return 0;
591}
592
593/*
594 * tis_init()
595 *
596 * Initialize the TPM device. Returns 0 on success or TPM_DRIVER_ERR on
597 * failure (in case device probing did not succeed).
598 */
599int tis_init(void)
600{
601 if (tis_probe())
602 return TPM_DRIVER_ERR;
603 return 0;
604}
605
606/*
607 * tis_open()
608 *
609 * Requests access to locality 0 for the caller. After all commands have been
610 * completed the caller is supposed to call tis_close().
611 *
612 * Returns 0 on success, TPM_DRIVER_ERR on failure.
613 */
614int tis_open(void)
615{
616 u8 locality = 0; /* we use locality zero for everything */
617
618 if (tis_close())
619 return TPM_DRIVER_ERR;
620
621 /* now request access to locality */
Aaron Durbinc4220022013-07-24 16:02:14 -0500622 tis_request_access(locality);
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700623
624 /* did we get a lock? */
Aaron Durbinc4220022013-07-24 16:02:14 -0500625 if (tis_wait_received_access(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700626 printf("%s:%d - failed to lock locality %d\n",
627 __FILE__, __LINE__, locality);
628 return TPM_DRIVER_ERR;
629 }
630
Stefan Reinauerc908fc72012-04-30 16:33:44 -0700631 /* Certain TPMs seem to need some delay here or they hang... */
632 udelay(10);
633
634 if (tis_command_ready(locality) == TPM_TIMEOUT_ERR)
635 return TPM_DRIVER_ERR;
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700636
637 return 0;
638}
639
640/*
641 * tis_close()
642 *
Martin Roth56889792013-07-09 21:39:46 -0600643 * terminate the current session with the TPM by releasing the locked
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700644 * locality. Returns 0 on success of TPM_DRIVER_ERR on failure (in case lock
645 * removal did not succeed).
646 */
647int tis_close(void)
648{
649 u8 locality = 0;
Aaron Durbinc4220022013-07-24 16:02:14 -0500650 if (tis_has_access(locality)) {
651 tis_drop_access(locality);
652 if (tis_wait_dropped_access(locality)) {
Stefan Reinauer3008bbad2011-10-11 14:46:25 -0700653 printf("%s:%d - failed to release locality %d\n",
654 __FILE__, __LINE__, locality);
655 return TPM_DRIVER_ERR;
656 }
657 }
658 return 0;
659}
660
661/*
662 * tis_sendrecv()
663 *
664 * Send the requested data to the TPM and then try to get its response
665 *
666 * @sendbuf - buffer of the data to send
667 * @send_size size of the data to send
668 * @recvbuf - memory to save the response to
669 * @recv_len - pointer to the size of the response buffer
670 *
671 * Returns 0 on success (and places the number of response bytes at recv_len)
672 * or TPM_DRIVER_ERR on failure.
673 */
674int tis_sendrecv(const uint8_t *sendbuf, size_t send_size,
675 uint8_t *recvbuf, size_t *recv_len)
676{
677 if (tis_senddata(sendbuf, send_size)) {
678 printf("%s:%d failed sending data to TPM\n",
679 __FILE__, __LINE__);
680 return TPM_DRIVER_ERR;
681 }
682
683 return tis_readresponse(recvbuf, recv_len);
684}
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700685
686#ifdef __RAMSTAGE__
687
688/*
689 * tis_setup_interrupt()
690 *
691 * Set up the interrupt vector and polarity for locality 0 and
692 * disable all interrupts so they are unused in firmware but can
693 * be enabled by the OS.
694 *
695 * The values used here must match what is passed in the TPM ACPI
696 * device if ACPI is used on the platform.
697 *
698 * @vector - TPM interrupt vector
699 * @polarity - TPM interrupt polarity
700 *
701 * Returns 0 on success, TPM_DRIVER_ERR on failure.
702 */
703static int tis_setup_interrupt(int vector, int polarity)
704{
705 u8 locality = 0;
706 int has_access = tis_has_access(locality);
707
708 /* Open connection and request access if not already granted */
709 if (!has_access && tis_open() < 0)
710 return TPM_DRIVER_ERR;
711
712 /* Set TPM interrupt vector */
713 tpm_write_int_vector(vector, locality);
714
715 /* Set TPM interupt polarity and disable interrupts */
716 tpm_write_int_polarity(polarity, locality);
717
718 /* Close connection if it was opened */
719 if (!has_access && tis_close() < 0)
720 return TPM_DRIVER_ERR;
721
722 return 0;
723}
724
725static void lpc_tpm_read_resources(struct device *dev)
726{
727 /* Static 5K memory region specified in Kconfig */
728 mmio_resource(dev, 0, CONFIG_TPM_TIS_BASE_ADDRESS >> 10, 0x5000 >> 10);
729}
730
731static void lpc_tpm_set_resources(struct device *dev)
732{
733 tpm_config_t *config = (tpm_config_t *)dev->chip_info;
734 struct resource *res;
735
736 for (res = dev->resource_list; res; res = res->next) {
737 if (!(res->flags & IORESOURCE_ASSIGNED))
738 continue;
739
740 if (res->flags & IORESOURCE_IRQ) {
741 /* Set interrupt vector */
742 tis_setup_interrupt((int)res->base,
743 config->irq_polarity);
744 } else {
Duncan Lauriedd281ed2014-10-30 15:20:19 -0700745 continue;
746 }
747
748 res->flags |= IORESOURCE_STORED;
749 report_resource_stored(dev, res, " <tpm>");
750 }
751}
752
753static struct device_operations lpc_tpm_ops = {
754 .read_resources = &lpc_tpm_read_resources,
755 .set_resources = &lpc_tpm_set_resources,
756};
757
758static struct pnp_info pnp_dev_info[] = {
759 { .flags = PNP_IRQ0 }
760};
761
762static void enable_dev(struct device *dev)
763{
764 pnp_enable_devices(dev, &lpc_tpm_ops,
765 ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
766}
767
768struct chip_operations drivers_pc80_tpm_ops = {
769 CHIP_NAME("LPC TPM")
770 .enable_dev = enable_dev
771};
772
773#endif /* __RAMSTAGE__ */