summaryrefslogtreecommitdiff
path: root/src/drivers/pc80/tpm
diff options
context:
space:
mode:
authorWerner Zeh <werner.zeh@siemens.com>2021-10-11 15:27:12 +0200
committerFelix Held <felix-coreboot@felixheld.de>2021-10-25 16:11:55 +0000
commit92ab611c7055dc33aca822e098e19baa84eb975a (patch)
tree54e83d41e50dcd71cbcdc870c4a6c4b436757305 /src/drivers/pc80/tpm
parent299649a31c7bccf5b7102b37e8f8bf0f151280f7 (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/tpm')
-rw-r--r--src/drivers/pc80/tpm/tis.c36
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.