i2c tpm: Remove mostly useless delay code/tables.

I assume from the code in the TPM driver that the TPM spec defines
different types of delays and timeouts which each have a particular
duration, and that the TPM can tell you how long each type is if you ask
it. There was a large table, some members of a data structure, and a
function or two which managed the timeouts and figured their value for
different operations.  The timeout values for the various "ordinals"
were never set in the vendor specific data structure, however, and
always defaulted to 2 minutes.  Similarly the timeouts a, b, c, and d
were never overridden from their defaults.  This change gets rid of all
the timeout management code and makes the "ordinal" timeout 2 minutes
and the a, b, c, and d timeouts 2 seconds, the larger of the two default
values.

This is a port from depthcharge to coreboot, original change:
https://chromium-review.googlesource.com/#/c/168363/

BUG=None
TEST=Built and booted on kirby
BRANCH=None
Signed-off-by: Gabe Black <gabeblack@google.com>
Signed-off-by: Stefan Reinauer <reinauer@google.com>

Change-Id: I79696d6329184ca07f6a1be4f6ca85e1655a7aaf
Reviewed-on: https://chromium-review.googlesource.com/168583
Reviewed-by: Gabe Black <gabeblack@chromium.org>
Tested-by: Stefan Reinauer <reinauer@google.com>
Commit-Queue: Stefan Reinauer <reinauer@google.com>
This commit is contained in:
Stefan Reinauer 2013-09-09 10:45:08 -07:00 committed by chrome-internal-fetch
commit b22395a73f
3 changed files with 10 additions and 338 deletions

View file

@ -44,311 +44,6 @@
/* global structure for tpm chip data */
struct tpm_chip g_chip;
enum tpm_duration {
TPM_SHORT = 0,
TPM_MEDIUM = 1,
TPM_LONG = 2,
TPM_UNDEFINED,
};
#define TPM_MAX_ORDINAL 243
#define TPM_MAX_PROTECTED_ORDINAL 12
#define TPM_PROTECTED_ORDINAL_MASK 0xFF
/*
* Array with one entry per ordinal defining the maximum amount
* of time the chip could take to return the result. The ordinal
* designation of short, medium or long is defined in a table in
* TCG Specification TPM Main Part 2 TPM Structures Section 17. The
* values of the SHORT, MEDIUM, and LONG durations are retrieved
* from the chip during initialization with a call to tpm_get_timeouts.
*/
static const uint8_t tpm_prot_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
TPM_UNDEFINED, /* 0 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 5 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 10 */
TPM_SHORT,
};
static const uint8_t tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
TPM_UNDEFINED, /* 0 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 5 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 10 */
TPM_SHORT,
TPM_MEDIUM,
TPM_LONG,
TPM_LONG,
TPM_MEDIUM, /* 15 */
TPM_SHORT,
TPM_SHORT,
TPM_MEDIUM,
TPM_LONG,
TPM_SHORT, /* 20 */
TPM_SHORT,
TPM_MEDIUM,
TPM_MEDIUM,
TPM_MEDIUM,
TPM_SHORT, /* 25 */
TPM_SHORT,
TPM_MEDIUM,
TPM_SHORT,
TPM_SHORT,
TPM_MEDIUM, /* 30 */
TPM_LONG,
TPM_MEDIUM,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT, /* 35 */
TPM_MEDIUM,
TPM_MEDIUM,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_MEDIUM, /* 40 */
TPM_LONG,
TPM_MEDIUM,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT, /* 45 */
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_LONG,
TPM_MEDIUM, /* 50 */
TPM_MEDIUM,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 55 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_MEDIUM, /* 60 */
TPM_MEDIUM,
TPM_MEDIUM,
TPM_SHORT,
TPM_SHORT,
TPM_MEDIUM, /* 65 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 70 */
TPM_SHORT,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 75 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_LONG, /* 80 */
TPM_UNDEFINED,
TPM_MEDIUM,
TPM_LONG,
TPM_SHORT,
TPM_UNDEFINED, /* 85 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 90 */
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_UNDEFINED, /* 95 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_MEDIUM, /* 100 */
TPM_SHORT,
TPM_SHORT,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 105 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 110 */
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT, /* 115 */
TPM_SHORT,
TPM_SHORT,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_LONG, /* 120 */
TPM_LONG,
TPM_MEDIUM,
TPM_UNDEFINED,
TPM_SHORT,
TPM_SHORT, /* 125 */
TPM_SHORT,
TPM_LONG,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT, /* 130 */
TPM_MEDIUM,
TPM_UNDEFINED,
TPM_SHORT,
TPM_MEDIUM,
TPM_UNDEFINED, /* 135 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 140 */
TPM_SHORT,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 145 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 150 */
TPM_MEDIUM,
TPM_MEDIUM,
TPM_SHORT,
TPM_SHORT,
TPM_UNDEFINED, /* 155 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 160 */
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 165 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_LONG, /* 170 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 175 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_MEDIUM, /* 180 */
TPM_SHORT,
TPM_MEDIUM,
TPM_MEDIUM,
TPM_MEDIUM,
TPM_MEDIUM, /* 185 */
TPM_SHORT,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 190 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 195 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 200 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT,
TPM_SHORT, /* 205 */
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_MEDIUM, /* 210 */
TPM_UNDEFINED,
TPM_MEDIUM,
TPM_MEDIUM,
TPM_MEDIUM,
TPM_UNDEFINED, /* 215 */
TPM_MEDIUM,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT,
TPM_SHORT, /* 220 */
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_SHORT,
TPM_UNDEFINED, /* 225 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 230 */
TPM_LONG,
TPM_MEDIUM,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED, /* 235 */
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_UNDEFINED,
TPM_SHORT, /* 240 */
TPM_UNDEFINED,
TPM_MEDIUM,
};
/*
* Returns max number of milliseconds to wait
*/
static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
uint32_t ordinal)
{
int duration_idx = TPM_UNDEFINED;
int duration = 0;
if (ordinal < TPM_MAX_ORDINAL)
duration_idx = tpm_ordinal_duration[ordinal];
else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
TPM_MAX_PROTECTED_ORDINAL)
duration_idx =
tpm_prot_ordinal_duration[ordinal &
TPM_PROTECTED_ORDINAL_MASK];
if (duration_idx != TPM_UNDEFINED)
duration = chip->vendor.duration[duration_idx];
if (duration <= 0)
return 2 * 60 * 1000; /*two minutes timeout*/
else
return duration;
}
#define TPM_CMD_COUNT_BYTE 2
#define TPM_CMD_ORDINAL_BYTE 6
@ -384,7 +79,7 @@ ssize_t tpm_transmit(const uint8_t *buf, size_t bufsiz)
if (chip->vendor.irq)
goto out_recv;
int timeout = tpm_calc_ordinal_duration(chip, ordinal) / TPM_TIMEOUT;
int timeout = 2 * 60 * 1000; /* two minutes timeout */
while (timeout) {
ASSERT(chip->vendor.status);
uint8_t status = chip->vendor.status(chip);

View file

@ -65,8 +65,6 @@ struct tpm_vendor_specific {
void (*cancel)(struct tpm_chip *);
uint8_t(*status)(struct tpm_chip *);
int locality;
unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
unsigned long duration[3]; /* msec */
};
struct tpm_chip {

View file

@ -249,11 +249,6 @@ enum tis_status {
TPM_STS_DATA_EXPECT = 0x08,
};
enum tis_defaults {
TIS_SHORT_TIMEOUT = 750, /* ms */
TIS_LONG_TIMEOUT = 2000, /* 2 sec */
};
#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
#define TPM_STS(l) (0x0001 | ((l) << 4))
#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
@ -300,7 +295,7 @@ static int request_locality(struct tpm_chip *chip, int loc)
iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
/* wait for burstcount */
int timeout = chip->vendor.timeout_a / TPM_TIMEOUT;
int timeout = 2 * 1000; /* 2s timeout */
while (timeout) {
if (check_locality(chip, loc) >= 0)
return loc;
@ -334,8 +329,7 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
uint8_t buf[3];
/* wait for burstcount */
/* which timeout value, spec has 2 answers (c & d) */
int timeout = chip->vendor.timeout_d / TPM_TIMEOUT;
int timeout = 2 * 1000; /* 2s timeout */
while (timeout) {
/* Note: STS is little endian */
if (iic_tpm_read(TPM_STS(chip->vendor.locality) + 1, buf, 3) < 0)
@ -351,20 +345,14 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
return -1; //EBUSY;
}
static int wait_for_stat(struct tpm_chip *chip, uint8_t mask,
unsigned long timeout, int *status)
static int wait_for_stat(struct tpm_chip *chip, uint8_t mask, int *status)
{
/* check current status */
*status = tpm_tis_i2c_status(chip);
if ((*status & mask) == mask)
return 0;
timeout /= TPM_TIMEOUT;
unsigned long timeout = 2 * 1024;
while (timeout) {
mdelay(TPM_TIMEOUT);
*status = tpm_tis_i2c_status(chip);
if ((*status & mask) == mask)
return 0;
mdelay(TPM_TIMEOUT);
timeout--;
}
@ -432,7 +420,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, uint8_t *buf, size_t count)
goto out;
}
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
wait_for_stat(chip, TPM_STS_VALID, &status);
if (status & TPM_STS_DATA_AVAIL) { /* retry? */
printk(BIOS_DEBUG, "tpm_tis_i2c_recv: Error left over data\n");
size = -1; //EIO;
@ -462,9 +450,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
status = tpm_tis_i2c_status(chip);
if ((status & TPM_STS_COMMAND_READY) == 0) {
tpm_tis_i2c_ready(chip);
if (wait_for_stat
(chip, TPM_STS_COMMAND_READY,
chip->vendor.timeout_b, &status) < 0) {
if (wait_for_stat(chip, TPM_STS_COMMAND_READY, &status) < 0) {
rc = -1; //ETIME;
goto out_err;
}
@ -490,8 +476,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
if (rc == 0)
count += burstcnt;
wait_for_stat(chip, TPM_STS_VALID,
chip->vendor.timeout_c, &status);
wait_for_stat(chip, TPM_STS_VALID, &status);
if ((status & TPM_STS_DATA_EXPECT) == 0) {
rc = -1; //EIO;
@ -502,7 +487,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
/* write last byte */
iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
wait_for_stat(chip, TPM_STS_VALID, &status);
if ((status & TPM_STS_DATA_EXPECT) != 0) {
rc = -1; //EIO;
goto out_err;
@ -553,12 +538,6 @@ int tpm_vendor_init(unsigned bus, uint32_t dev_addr)
/* Disable interrupts (not supported) */
chip->vendor.irq = 0;
/* Default timeouts */
chip->vendor.timeout_a = TIS_SHORT_TIMEOUT;
chip->vendor.timeout_b = TIS_LONG_TIMEOUT;
chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
if (request_locality(chip, 0) != 0) {
rc = -1; //ENODEV;
goto out_err;