[coreboot-gerrit] Change in coreboot[master]: drivers/spi/tpm: Make SPI TPM driver CAR-safe

Furquan Shaikh (Code Review) gerrit at coreboot.org
Wed Apr 5 20:31:05 CEST 2017


Furquan Shaikh has submitted this change and it was merged. ( https://review.coreboot.org/19114 )

Change subject: drivers/spi/tpm: Make SPI TPM driver CAR-safe
......................................................................


drivers/spi/tpm: Make SPI TPM driver CAR-safe

1. Use proper CAR semantics for global/static variables.
2. Use spi_* functions directly instead of using a global structure to
store pointers to those functions.

BUG=b:36873582

Change-Id: I1fc52ab797ef0cbd3793a387d68198efc5dde58c
Signed-off-by: Furquan Shaikh <furquan at chromium.org>
Reviewed-on: https://review.coreboot.org/19114
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
M src/drivers/spi/tpm/tpm.c
1 file changed, 49 insertions(+), 51 deletions(-)

Approvals:
  Aaron Durbin: Looks good to me, approved
  build bot (Jenkins): Verified



diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c
index cd1fbdf..1c5e535 100644
--- a/src/drivers/spi/tpm/tpm.c
+++ b/src/drivers/spi/tpm/tpm.c
@@ -15,6 +15,7 @@
  * Specification Revision 00.43".
  */
 
+#include <arch/early_variables.h>
 #include <commonlib/endian.h>
 #include <console/console.h>
 #include <delay.h>
@@ -35,25 +36,11 @@
 #define TPM_RID_REG       (TPM_LOCALITY_0_SPI_BASE + 0xf04)
 #define TPM_FW_VER	  (TPM_LOCALITY_0_SPI_BASE + 0xf90)
 
-/* SPI Interface descriptor used by the driver. */
-struct tpm_spi_if {
-	struct spi_slave slave;
-	int (*cs_assert)(const struct spi_slave *slave);
-	void (*cs_deassert)(const struct spi_slave *slave);
-	int  (*xfer)(const struct spi_slave *slave, const void *dout,
-		     size_t bytesout, void *din,
-		     size_t bytesin);
-};
-
-/* Use the common SPI driver wrapper as the interface callbacks. */
-static struct tpm_spi_if tpm_if = {
-	.cs_assert = spi_claim_bus,
-	.cs_deassert = spi_release_bus,
-	.xfer = spi_xfer
-};
+/* SPI slave structure for TPM device. */
+static struct spi_slave g_spi_slave CAR_GLOBAL;
 
 /* Cached TPM device identification. */
-static struct tpm2_info tpm_info;
+static struct tpm2_info g_tpm_info CAR_GLOBAL;
 
 /*
  * TODO(vbendeb): make CONFIG_DEBUG_TPM an int to allow different level of
@@ -100,16 +87,16 @@
 
 void tpm2_get_info(struct tpm2_info *info)
 {
-	*info = tpm_info;
+	*info = car_get_var(g_tpm_info);
 }
 
 __attribute__((weak)) int tis_plat_irq_status(void)
 {
-	static int warning_displayed;
+	static int warning_displayed CAR_GLOBAL;
 
-	if (!warning_displayed) {
+	if (!car_get_var(warning_displayed)) {
 		printk(BIOS_WARNING, "WARNING: tis_plat_irq_status() not implemented, wasting 10ms to wait on Cr50!\n");
-		warning_displayed = 1;
+		car_set_var(warning_displayed, 1);
 	}
 	mdelay(10);
 
@@ -148,18 +135,19 @@
 	uint8_t byte;
 	int i;
 	struct stopwatch sw;
-	static int tpm_sync_needed;
+	static int tpm_sync_needed CAR_GLOBAL;
+	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
 
 	/* Wait for tpm to finish previous transaction if needed */
-	if (tpm_sync_needed)
+	if (car_get_var(tpm_sync_needed))
 		tpm_sync();
 	else
-		tpm_sync_needed = 1;
+		car_set_var(tpm_sync_needed, 1);
 
 	/* Try to wake cr50 if it is asleep. */
-	tpm_if.cs_assert(&tpm_if.slave);
+	spi_claim_bus(spi_slave);
 	udelay(1);
-	tpm_if.cs_deassert(&tpm_if.slave);
+	spi_release_bus(spi_slave);
 	udelay(100);
 
 	/*
@@ -174,7 +162,7 @@
 		header.body[i + 1] = (addr >> (8 * (2 - i))) & 0xff;
 
 	/* CS assert wakes up the slave. */
-	tpm_if.cs_assert(&tpm_if.slave);
+	spi_claim_bus(spi_slave);
 
 	/*
 	 * The TCG TPM over SPI specification introduces the notion of SPI
@@ -201,7 +189,7 @@
 	 * to require to stall the master, this would present an issue.
 	 * crosbug.com/p/52132 has been opened to track this.
 	 */
-	tpm_if.xfer(&tpm_if.slave, header.body, sizeof(header.body), NULL, 0);
+	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
@@ -212,10 +200,10 @@
 	do {
 		if (stopwatch_expired(&sw)) {
 			printk(BIOS_ERR, "TPM flow control failure\n");
-			tpm_if.cs_deassert(&tpm_if.slave);
+			spi_release_bus(spi_slave);
 			return 0;
 		}
-		tpm_if.xfer(&tpm_if.slave, NULL, 0, &byte, 1);
+		spi_xfer(spi_slave, NULL, 0, &byte, 1);
 	} while (!(byte & 1));
 	return 1;
 }
@@ -228,10 +216,11 @@
 		       size_t bytes, const uint8_t *buffer,
 		       int force)
 {
-	static char prev_prefix;
-	static unsigned prev_reg;
-	static int current_char;
+	static char prev_prefix CAR_GLOBAL;
+	static unsigned prev_reg CAR_GLOBAL;
+	static int current_char CAR_GLOBAL;
 	const int BYTES_PER_LINE = 32;
+	int *current_char_ptr = car_get_var_ptr(&current_char);
 
 	if (!force) {
 		if (!debug_level_)
@@ -245,11 +234,12 @@
 	 * Do not print register address again if the last dump print was for
 	 * that register.
 	 */
-	if ((prev_prefix != *prefix) || (prev_reg != reg)) {
-		prev_prefix = *prefix;
-		prev_reg = reg;
+	if ((car_get_var(prev_prefix) != *prefix) ||
+		(car_get_var(prev_reg) != reg)) {
+		car_set_var(prev_prefix, *prefix);
+		car_set_var(prev_reg, reg);
 		printk(BIOS_DEBUG, "\n%s %2.2x:", prefix, reg);
-		current_char = 0;
+		*current_char_ptr = 0;
 	}
 
 	if ((reg != TPM_DATA_FIFO_REG) && (bytes == 4)) {
@@ -266,11 +256,12 @@
 		 * quantiites is printed byte at a time.
 		 */
 		for (i = 0; i < bytes; i++) {
-			if (current_char && !(current_char % BYTES_PER_LINE)) {
+			if (*current_char_ptr &&
+				!(*current_char_ptr % BYTES_PER_LINE)) {
 				printk(BIOS_DEBUG, "\n     ");
-				current_char = 0;
+				*current_char_ptr = 0;
 			}
-			current_char++;
+			(*current_char_ptr)++;
 			printk(BIOS_DEBUG, " %2.2x", buffer[i]);
 		}
 	}
@@ -282,7 +273,8 @@
  */
 static void write_bytes(const void *buffer, size_t bytes)
 {
-	tpm_if.xfer(&tpm_if.slave, buffer, bytes, NULL, 0);
+	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
+	spi_xfer(spi_slave, buffer, bytes, NULL, 0);
 }
 
 /*
@@ -291,7 +283,8 @@
  */
 static void read_bytes(void *buffer, size_t bytes)
 {
-	tpm_if.xfer(&tpm_if.slave, NULL, 0, buffer, bytes);
+	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
+	spi_xfer(spi_slave, NULL, 0, buffer, bytes);
 }
 
 /*
@@ -302,11 +295,12 @@
  */
 static int tpm2_write_reg(unsigned reg_number, const void *buffer, size_t bytes)
 {
+	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
 	trace_dump("W", reg_number, bytes, buffer, 0);
 	if (!start_transaction(false, bytes, reg_number))
 		return 0;
 	write_bytes(buffer, bytes);
-	tpm_if.cs_deassert(&tpm_if.slave);
+	spi_release_bus(spi_slave);
 	return 1;
 }
 
@@ -318,12 +312,13 @@
  */
 static int tpm2_read_reg(unsigned reg_number, void *buffer, size_t bytes)
 {
+	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
 	if (!start_transaction(true, bytes, reg_number)) {
 		memset(buffer, 0, bytes);
 		return 0;
 	}
 	read_bytes(buffer, bytes);
-	tpm_if.cs_deassert(&tpm_if.slave);
+	spi_release_bus(spi_slave);
 	trace_dump("R", reg_number, bytes, buffer, 0);
 	return 1;
 }
@@ -359,8 +354,10 @@
 {
 	uint32_t did_vid, status;
 	uint8_t cmd;
+	struct tpm2_info *tpm_info = car_get_var_ptr(&g_tpm_info);
+	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
 
-	memcpy(&tpm_if.slave, spi_if, sizeof(*spi_if));
+	memcpy(spi_slave, spi_if, sizeof(*spi_if));
 
 	/*
 	 * It is enough to check the first register read error status to bail
@@ -411,15 +408,15 @@
 	 * structure.
 	 */
 	tpm2_read_reg(TPM_RID_REG, &cmd, sizeof(cmd));
-	tpm_info.vendor_id = did_vid & 0xffff;
-	tpm_info.device_id = did_vid >> 16;
-	tpm_info.revision = cmd;
+	tpm_info->vendor_id = did_vid & 0xffff;
+	tpm_info->device_id = did_vid >> 16;
+	tpm_info->revision = cmd;
 
 	printk(BIOS_INFO, "Connected to device vid:did:rid of %4.4x:%4.4x:%2.2x\n",
-	       tpm_info.vendor_id, tpm_info.device_id, tpm_info.revision);
+	       tpm_info->vendor_id, tpm_info->device_id, tpm_info->revision);
 
 	/* Let's report device FW version if available. */
-	if (tpm_info.vendor_id == 0x1ae0) {
+	if (tpm_info->vendor_id == 0x1ae0) {
 		int chunk_count = 0;
 		size_t chunk_size;
 		/*
@@ -546,9 +543,10 @@
 	uint8_t *rsp_body = tpm2_response;
 	union fifo_transfer_buffer fifo_buffer;
 	const int HEADER_SIZE = 6;
+	struct tpm2_info *tpm_info = car_get_var_ptr(&g_tpm_info);
 
 	/* Do not try using an uninitialized TPM. */
-	if (!tpm_info.vendor_id)
+	if (!tpm_info->vendor_id)
 		return 0;
 
 	/* Skip the two byte tag, read the size field. */

-- 
To view, visit https://review.coreboot.org/19114
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I1fc52ab797ef0cbd3793a387d68198efc5dde58c
Gerrit-PatchSet: 4
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Furquan Shaikh <furquan at google.com>
Gerrit-Reviewer: Aaron Durbin <adurbin at chromium.org>
Gerrit-Reviewer: Duncan Laurie <dlaurie at chromium.org>
Gerrit-Reviewer: Furquan Shaikh <furquan at google.com>
Gerrit-Reviewer: Paul Menzel <paulepanter at users.sourceforge.net>
Gerrit-Reviewer: build bot (Jenkins)



More information about the coreboot-gerrit mailing list