aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/i2c/tpm/cr50.c20
-rw-r--r--src/drivers/spi/tpm/tpm.c28
-rw-r--r--src/drivers/tpm/cr50.c16
-rw-r--r--src/drivers/tpm/cr50.h3
-rw-r--r--src/security/tpm/tis.h2
-rw-r--r--src/security/tpm/tss/vendor/cr50/Kconfig10
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