diff options
author | Werner Zeh <werner.zeh@siemens.com> | 2021-10-11 15:27:12 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-10-25 16:11:55 +0000 |
commit | 92ab611c7055dc33aca822e098e19baa84eb975a (patch) | |
tree | 54e83d41e50dcd71cbcdc870c4a6c4b436757305 /src/drivers/pc80 | |
parent | 299649a31c7bccf5b7102b37e8f8bf0f151280f7 (diff) |
drivers/pc80/tpm: Use stopwatch for timeout-loops
There are manual timeout-loops which use a fixed value and udelay().
In all cases there is a debug printk() inside this loop which, when
enabled, takes way longer than the counted microsecond delay. This
leads to the result that e.g. a 1 second delay takes nearly an eternity
if the debug messages are enabled due to the longer function execution
time.
This patch uses the stopwatch scheme for the timeout-loops which still
makes sure that the timeout period is maintained while it takes longer
function calls like printk() into account. In order to keep the minimum
delay between two register accesses on the TPM keep the udelay(1)-call.
TEST=Enable TPM debug messages on a board where the TPM hits a timeout
by failure and make sure that the debug messages occur in the log
just in the timeout period. It still works as expected if the debug
messages are disabled.
Change-Id: I8fd261c9d60a9a60509c847dbc4983bc05f41d48
Signed-off-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/58240
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Diffstat (limited to 'src/drivers/pc80')
-rw-r--r-- | src/drivers/pc80/tpm/tis.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/src/drivers/pc80/tpm/tis.c b/src/drivers/pc80/tpm/tis.c index 2b29acfaa9..c209e5a39e 100644 --- a/src/drivers/pc80/tpm/tis.c +++ b/src/drivers/pc80/tpm/tis.c @@ -22,6 +22,7 @@ #include <security/tpm/tis.h> #include <device/pnp.h> #include <drivers/tpm/tpm_ppi.h> +#include <timer.h> #include "chip.h" #define PREFIX "lpc_tpm: " @@ -84,7 +85,7 @@ #define TPM_DRIVER_ERR (~0) /* 1 second is plenty for anything TPM does.*/ -#define MAX_DELAY_US (1000 * 1000) +#define MAX_DELAY_US USECS_PER_SEC /* * Structures defined below allow creating descriptions of TPM vendor/device @@ -238,7 +239,7 @@ static inline u32 tpm_read_int_polarity(int locality) /* * tis_wait_sts() * - * Wait for at least a second for a status to change its state to match the + * Wait for at most a second for a status to change its state to match the * expected state. Normally the transition happens within microseconds. * * @locality - locality @@ -249,14 +250,15 @@ static inline u32 tpm_read_int_polarity(int locality) */ static int tis_wait_sts(int locality, u8 mask, u8 expected) { - u32 time_us = MAX_DELAY_US; - while (time_us > 0) { + struct stopwatch sw; + + stopwatch_init_usecs_expire(&sw, MAX_DELAY_US); + do { u8 value = tpm_read_status(locality); if ((value & mask) == expected) return 0; - udelay(1); /* 1 us */ - time_us--; - } + udelay(1); + } while (!stopwatch_expired(&sw)); return TPM_TIMEOUT_ERR; } @@ -291,7 +293,7 @@ static inline int tis_expect_data(int locality) /* * tis_wait_access() * - * Wait for at least a second for a access to change its state to match the + * Wait for at most a second for a access to change its state to match the * expected state. Normally the transition happens within microseconds. * * @locality - locality @@ -302,14 +304,15 @@ static inline int tis_expect_data(int locality) */ static int tis_wait_access(int locality, u8 mask, u8 expected) { - u32 time_us = MAX_DELAY_US; - while (time_us > 0) { + struct stopwatch sw; + + stopwatch_init_usecs_expire(&sw, MAX_DELAY_US); + do { u8 value = tpm_read_access(locality); if ((value & mask) == expected) return 0; - udelay(1); /* 1 us */ - time_us--; - } + udelay(1); + } while (!stopwatch_expired(&sw)); return TPM_TIMEOUT_ERR; } @@ -440,7 +443,6 @@ static u32 tis_senddata(const u8 *const data, u32 len) { u32 offset = 0; u16 burst = 0; - u32 max_cycles = 0; u8 locality = 0; if (tis_wait_ready(locality)) { @@ -452,10 +454,12 @@ static u32 tis_senddata(const u8 *const data, u32 len) while (1) { unsigned int count; + struct stopwatch sw; /* Wait till the device is ready to accept more data. */ + stopwatch_init_usecs_expire(&sw, MAX_DELAY_US); while (!burst) { - if (max_cycles++ == MAX_DELAY_US) { + if (stopwatch_expired(&sw)) { printf("%s:%d failed to feed %d bytes of %d\n", __FILE__, __LINE__, len - offset, len); return TPM_DRIVER_ERR; @@ -464,8 +468,6 @@ static u32 tis_senddata(const u8 *const data, u32 len) burst = tpm_read_burst_count(locality); } - max_cycles = 0; - /* * Calculate number of bytes the TPM is ready to accept in one * shot. |