Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/39693 )
Change subject: drivers/spi/tpm: Add support for non CR50 SPI TPM2 ......................................................................
drivers/spi/tpm: Add support for non CR50 SPI TPM2
Add support for a STM SPI TPM2 by adding checks for CR50. Tested using ST33HTPH2E32.
Change-Id: I015497ca078979a44ba2b84e4995493de1f7247b Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/drivers/spi/tpm/Kconfig M src/drivers/spi/tpm/tis.c M src/drivers/spi/tpm/tpm.c M src/security/tpm/Kconfig 4 files changed, 46 insertions(+), 25 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/93/39693/1
diff --git a/src/drivers/spi/tpm/Kconfig b/src/drivers/spi/tpm/Kconfig index be43e23..8c4bace 100644 --- a/src/drivers/spi/tpm/Kconfig +++ b/src/drivers/spi/tpm/Kconfig @@ -19,3 +19,10 @@ select SPI_TPM help Board has SPI TPM support + +config MAINBOARD_HAS_SPI_TPM + bool + default n + select SPI_TPM + help + Board has SPI TPM support diff --git a/src/drivers/spi/tpm/tis.c b/src/drivers/spi/tpm/tis.c index 6230751..60dc705 100644 --- a/src/drivers/spi/tpm/tis.c +++ b/src/drivers/spi/tpm/tis.c @@ -18,6 +18,7 @@ } dev_map[] = { { 0x15d1, 0x001b, "SLB9670" }, { 0x1ae0, 0x0028, "CR50" }, + { 0x104a, 0x0000, "ST33HTPH2E32" }, };
static const char *tis_get_dev_name(struct tpm2_info *info) diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c index 62d1bba..7db92d5 100644 --- a/src/drivers/spi/tpm/tpm.c +++ b/src/drivers/spi/tpm/tpm.c @@ -104,7 +104,7 @@ */ static int start_transaction(int read_write, size_t bytes, unsigned int addr) { - spi_frame_header header; + spi_frame_header header, header_resp; uint8_t byte; int i; struct stopwatch sw; @@ -114,7 +114,7 @@ * First Cr50 access in each coreboot stage where TPM is used will be * prepended by a wake up pulse on the CS line. */ - int wakeup_needed = 1; + int wakeup_needed = CONFIG(TPM2_CR50);
/* Wait for TPM to finish previous transaction if needed */ if (tpm_sync_needed) { @@ -181,26 +181,28 @@ * transmitted by the TPM during the transaction's last byte. * * We know that cr50 is guaranteed to set the flow control bit to 0 - * during the header transfer, but real TPM2 might be fast enough not - * to require to stall the master, this would present an issue. + * during the header transfer. Real TPM2 are fast enough to not require + * to stall the master. They might still use this feature, so test the + * last bit after shifting in the address bytes. * crosbug.com/p/52132 has been opened to track this. */ - spi_xfer(&spi_slave, header.body, sizeof(header.body), NULL, 0); - - /* - * Now poll the bus until TPM removes the stall bit. Give it up to 100 - * ms to sort it out - it could be saving stuff in nvram at some - * point. - */ - stopwatch_init_msecs_expire(&sw, 100); - do { - if (stopwatch_expired(&sw)) { - printk(BIOS_ERR, "TPM flow control failure\n"); - spi_release_bus(&spi_slave); - return 0; - } - spi_xfer(&spi_slave, NULL, 0, &byte, 1); - } while (!(byte & 1)); + spi_xfer(&spi_slave, header.body, sizeof(header.body), &header_resp, sizeof(header_resp.body)); + if (CONFIG(TPM2_CR50) || !(header_resp.body[3] & 1)) { + /* + * Now poll the bus until TPM removes the stall bit. Give it up to 100 + * ms to sort it out - it could be saving stuff in nvram at some + * point. + */ + stopwatch_init_msecs_expire(&sw, 100); + do { + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "TPM flow control failure\n"); + spi_release_bus(&spi_slave); + return 0; + } + spi_xfer(&spi_slave, NULL, 0, &byte, 1); + } while (!(byte & 1)); + } return 1; }
@@ -408,7 +410,8 @@
/* Device/vendor ID values of the TPM devices this driver supports. */ static const uint32_t supported_did_vids[] = { - 0x00281ae0 /* H1 based Cr50 security chip. */ + 0x00281ae0, /* H1 based Cr50 security chip. */ + 0x0000104a /* ST33HTPH2E32 */ };
int tpm2_init(struct spi_slave *spi_if) @@ -454,7 +457,7 @@
printk(BIOS_INFO, " done!\n");
- if (ENV_VERSTAGE || ENV_BOOTBLOCK) + if (ENV_VERSTAGE || ENV_BOOTBLOCK || !CONFIG(VBOOT)) /* * Claim locality 0, do it only during the first * initialization after reset. @@ -462,7 +465,10 @@ if (!tpm2_claim_locality()) return -1;
- read_tpm_sts(&status); + if (!read_tpm_sts(&status)) { + printk(BIOS_ERR, "Reading status reg failed\n"); + return -1; + } if ((status & TPM_STS_FAMILY_MASK) != TPM_STS_FAMILY_TPM_2_0) { printk(BIOS_ERR, "unexpected TPM family value, status: %#x\n", status); diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index 1766939..7baff87 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -26,7 +26,14 @@ default y if MAINBOARD_HAS_TPM2 || USER_TPM2 depends on MAINBOARD_HAS_I2C_TPM_GENERIC || MAINBOARD_HAS_LPC_TPM \ || MAINBOARD_HAS_I2C_TPM_ATMEL || MAINBOARD_HAS_I2C_TPM_CR50 \ - || MAINBOARD_HAS_SPI_TPM_CR50 || MAINBOARD_HAS_CRB_TPM + || MAINBOARD_HAS_SPI_TPM_CR50 || MAINBOARD_HAS_CRB_TPM \ + || MAINBOARD_HAS_SPI_TPM +config TPM2_CR50 + bool + default y if MAINBOARD_HAS_TPM2 || USER_TPM2 + depends on MAINBOARD_HAS_I2C_TPM_CR50 || MAINBOARD_HAS_SPI_TPM_CR50 + help + A software TPM2 running in Google's security chip.
config MAINBOARD_HAS_TPM1 bool @@ -56,7 +63,7 @@ bool "2.0" depends on MAINBOARD_HAS_I2C_TPM_GENERIC || MAINBOARD_HAS_LPC_TPM \ || MAINBOARD_HAS_I2C_TPM_ATMEL || MAINBOARD_HAS_I2C_TPM_CR50 \ - || MAINBOARD_HAS_SPI_TPM_CR50 || MAINBOARD_HAS_CRB_TPM + || MAINBOARD_HAS_SPI_TPM_CR50 || MAINBOARD_HAS_CRB_TPM || MAINBOARD_HAS_SPI_TPM help Enable this option to enable TPM 2.0 support in coreboot.