From b22395a73f361c38626911808332a3706b2334fe Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Mon, 9 Sep 2013 10:45:08 -0700 Subject: [PATCH] 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 Signed-off-by: Stefan Reinauer Change-Id: I79696d6329184ca07f6a1be4f6ca85e1655a7aaf Reviewed-on: https://chromium-review.googlesource.com/168583 Reviewed-by: Gabe Black Tested-by: Stefan Reinauer Commit-Queue: Stefan Reinauer --- src/drivers/i2c/tpm/tpm.c | 307 +----------------------------- src/drivers/i2c/tpm/tpm.h | 2 - src/drivers/i2c/tpm/tpm_tis_i2c.c | 39 +--- 3 files changed, 10 insertions(+), 338 deletions(-) diff --git a/src/drivers/i2c/tpm/tpm.c b/src/drivers/i2c/tpm/tpm.c index e099dfea75..d31cc79878 100644 --- a/src/drivers/i2c/tpm/tpm.c +++ b/src/drivers/i2c/tpm/tpm.c @@ -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); diff --git a/src/drivers/i2c/tpm/tpm.h b/src/drivers/i2c/tpm/tpm.h index 758f3444d6..daddc591e4 100644 --- a/src/drivers/i2c/tpm/tpm.h +++ b/src/drivers/i2c/tpm/tpm.h @@ -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 { diff --git a/src/drivers/i2c/tpm/tpm_tis_i2c.c b/src/drivers/i2c/tpm/tpm_tis_i2c.c index 58e94001ae..e700c3ab95 100644 --- a/src/drivers/i2c/tpm/tpm_tis_i2c.c +++ b/src/drivers/i2c/tpm/tpm_tis_i2c.c @@ -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;