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 #include #include +#include #include #include #include @@ -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__); @@ -73,23 +77,6 @@ __weak int tis_plat_irq_status(void) return 1; } -/* - * 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 #include #include +#include #include #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