diff options
author | Yu-Ping Wu <yupingso@chromium.org> | 2022-05-17 09:33:18 +0800 |
---|---|---|
committer | Julius Werner <jwerner@chromium.org> | 2022-06-08 00:28:27 +0000 |
commit | ae1e702e7b10ea2695be706ae53013b5b0817cb3 (patch) | |
tree | c7b408f7ae21d0ab048c4a272c390263f1849109 /src | |
parent | 20b58bc882c40b80584cb0d035acbda8daf95ed0 (diff) |
drivers/tpm/cr50: Add TPM IRQ timeout Kconfig option
The current 10ms timeout for SPI TPM IRQ is not enough for platforms
using ti50 (such as corsola). Therefore, introduce a new Kconfig option
'GOOGLE_TPM_IRQ_TIMEOUT_MS'.
For platforms using cr50, we need to support legacy pre-ready-IRQ cr50
factory images during the initial boot, so the timeout remains 100ms for
I2C TPM and 10ms for SPI TPM. For all the other platforms using ti50,
the default timeout is increased to 750ms, as suggested by the ti50 team
(apronin@google.com).
BUG=b:232327704
TEST=emerge-corsola coreboot
BRANCH=none
Change-Id: I8dbb919e4a421a99a994913613a33738a49f5956
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/64412
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/drivers/i2c/tpm/cr50.c | 20 | ||||
-rw-r--r-- | src/drivers/spi/tpm/tpm.c | 28 | ||||
-rw-r--r-- | src/drivers/tpm/cr50.c | 16 | ||||
-rw-r--r-- | src/drivers/tpm/cr50.h | 3 | ||||
-rw-r--r-- | src/security/tpm/tis.h | 2 | ||||
-rw-r--r-- | src/security/tpm/tss/vendor/cr50/Kconfig | 10 |
6 files changed, 41 insertions, 38 deletions
diff --git a/src/drivers/i2c/tpm/cr50.c b/src/drivers/i2c/tpm/cr50.c index 0130b93169..696533969c 100644 --- a/src/drivers/i2c/tpm/cr50.c +++ b/src/drivers/i2c/tpm/cr50.c @@ -34,7 +34,6 @@ #define CR50_TIMEOUT_LONG_MS 2000 /* Long timeout while waiting for TPM */ #define CR50_TIMEOUT_SHORT_MS 2 /* Short timeout during transactions */ #define CR50_TIMEOUT_NOIRQ_MS 20 /* Timeout for TPM ready without IRQ */ -#define CR50_TIMEOUT_IRQ_MS 100 /* Timeout for TPM ready with IRQ */ #define CR50_DID_VID 0x00281ae0L #define TI50_DID_VID 0x504a6666L @@ -60,21 +59,6 @@ __weak int tis_plat_irq_status(void) return 1; } -/* Wait for interrupt to indicate the TPM is ready */ -static int cr50_i2c_wait_tpm_ready(void) -{ - struct stopwatch sw; - - stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_IRQ_MS); - - while (!tis_plat_irq_status()) - if (stopwatch_expired(&sw)) { - printk(BIOS_ERR, "Cr50 i2c TPM IRQ timeout!\n"); - return -1; - } - return 0; -} - /* * cr50_i2c_read() - read from TPM register * @@ -103,7 +87,7 @@ static int cr50_i2c_read(uint8_t addr, uint8_t *buffer, size_t len) } /* Wait for TPM to be ready with response data */ - if (cr50_i2c_wait_tpm_ready() < 0) + if (cr50_wait_tpm_ready() != CB_SUCCESS) return -1; /* Read response data from the TPM */ @@ -149,7 +133,7 @@ static int cr50_i2c_write(uint8_t addr, const uint8_t *buffer, size_t len) } /* Wait for TPM to be ready */ - return cr50_i2c_wait_tpm_ready(); + return cr50_wait_tpm_ready() == CB_SUCCESS ? 0 : -1; } /* diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c index 8625a7921b..5645e57d82 100644 --- a/src/drivers/spi/tpm/tpm.c +++ b/src/drivers/spi/tpm/tpm.c @@ -15,6 +15,7 @@ #include <commonlib/endian.h> #include <console/console.h> #include <delay.h> +#include <drivers/tpm/cr50.h> #include <endian.h> #include <security/tpm/tis.h> #include <string.h> @@ -63,6 +64,9 @@ __weak int tis_plat_irq_status(void) { static int warning_displayed; + if (!CONFIG(TPM_GOOGLE)) + dead_code(); + if (!warning_displayed) { printk(BIOS_WARNING, "%s() not implemented, wasting 10ms to wait on" " Cr50!\n", __func__); @@ -74,23 +78,6 @@ __weak int tis_plat_irq_status(void) } /* - * TPM may trigger a IRQ after finish processing previous transfer. - * Waiting for this IRQ to sync TPM status. - */ -static enum cb_err tpm_sync(void) -{ - struct stopwatch sw; - - stopwatch_init_msecs_expire(&sw, 10); - while (!tis_plat_irq_status()) { - if (stopwatch_expired(&sw)) - return CB_ERR; - } - - return CB_SUCCESS; -} - -/* * Each TPM2 SPI transaction starts the same: CS is asserted, the 4 byte * header is sent to the TPM, the master waits til TPM is ready to continue. */ @@ -113,7 +100,7 @@ static enum cb_err start_transaction(int read_write, size_t bytes, unsigned int /* Wait for TPM to finish previous transaction if needed */ if (tpm_sync_needed) { - if (tpm_sync() != CB_SUCCESS) + if (cr50_wait_tpm_ready() != CB_SUCCESS) printk(BIOS_ERR, "Timeout waiting for TPM IRQ!\n"); /* @@ -431,8 +418,9 @@ int tpm2_init(struct spi_slave *spi_if) memcpy(&spi_slave, spi_if, sizeof(*spi_if)); - /* clear any pending IRQs */ - tis_plat_irq_status(); + /* Clear any pending IRQs. */ + if (CONFIG(TPM_GOOGLE)) + tis_plat_irq_status(); /* * 150 ms should be enough to synchronize with the TPM even under the diff --git a/src/drivers/tpm/cr50.c b/src/drivers/tpm/cr50.c index 887cf767b7..1724b8d0f6 100644 --- a/src/drivers/tpm/cr50.c +++ b/src/drivers/tpm/cr50.c @@ -3,6 +3,7 @@ #include <drivers/spi/tpm/tpm.h> #include <security/tpm/tis.h> #include <string.h> +#include <timer.h> #include <types.h> #define CR50_DID_VID 0x00281ae0L @@ -234,3 +235,18 @@ success: *version = cr50_firmware_version; return CB_SUCCESS; } + +enum cb_err cr50_wait_tpm_ready(void) +{ + struct stopwatch sw; + + stopwatch_init_msecs_expire(&sw, CONFIG_GOOGLE_TPM_IRQ_TIMEOUT_MS); + + while (!tis_plat_irq_status()) + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "Cr50 TPM IRQ timeout!\n"); + return CB_ERR; + } + + return CB_SUCCESS; +} diff --git a/src/drivers/tpm/cr50.h b/src/drivers/tpm/cr50.h index b39d7442c5..7ff63fa3c7 100644 --- a/src/drivers/tpm/cr50.h +++ b/src/drivers/tpm/cr50.h @@ -21,4 +21,7 @@ enum cb_err cr50_get_firmware_version(struct cr50_firmware_version *version); /* Set the BOARD_CFG register depending on Cr50 Kconfigs */ enum cb_err cr50_set_board_cfg(void); +/* Wait for IRQ to indicate the TPM is ready */ +enum cb_err cr50_wait_tpm_ready(void); + #endif /* __DRIVERS_TPM_CR50_H__ */ diff --git a/src/security/tpm/tis.h b/src/security/tpm/tis.h index 660ec81231..8868e1a0fe 100644 --- a/src/security/tpm/tis.h +++ b/src/security/tpm/tis.h @@ -76,6 +76,8 @@ int tis_close(void); int tis_sendrecv(const u8 *sendbuf, size_t send_size, u8 *recvbuf, size_t *recv_len); +/* TODO: This is supposed to be used only for Google TPM. + Consider moving this to drivers/tpm/cr50.h. */ /* * tis_plat_irq_status() * diff --git a/src/security/tpm/tss/vendor/cr50/Kconfig b/src/security/tpm/tss/vendor/cr50/Kconfig index 1fad3c0686..547f0fde3e 100644 --- a/src/security/tpm/tss/vendor/cr50/Kconfig +++ b/src/security/tpm/tss/vendor/cr50/Kconfig @@ -40,4 +40,14 @@ config TI50_FIRMWARE_VERSION_NOT_SUPPORTED FW < 0.0.15. The config will be removed once all Ti50 stocks are updated to 0.0.15 or higher. +config GOOGLE_TPM_IRQ_TIMEOUT_MS + int + default 100 if TPM_GOOGLE_CR50 && I2C_TPM + default 10 if TPM_GOOGLE_CR50 + default 750 + help + Timeout in milliseconds for waiting for TPM IRQ. Default to 100ms/10ms on platforms + using Cr50 in order to support legacy pre-ready-IRQ cr50 factory images. Default to + 750ms otherwise. + endif |