[coreboot-gerrit] Patch set updated for coreboot: drivers/i2c/tpm: Make driver safe for use in x86 pre-ram

Duncan Laurie (dlaurie@chromium.org) gerrit at coreboot.org
Fri Sep 2 01:28:11 CEST 2016


Duncan Laurie (dlaurie at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16394

-gerrit

commit 89d95fde8c507a243d21ae21d02b5b86a6b50d62
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Wed Aug 31 13:51:14 2016 -0700

    drivers/i2c/tpm: Make driver safe for use in x86 pre-ram
    
    Use CAR accessors where needed for accessing static data.
    In some cases this required some minor restructuring to pass
    in a variable instead of use a global one.
    
    Tested by enabling I2C TPM on reef and compiling successfully.
    
    Change-Id: I8e02fbcebf5fe10c4122632eda1c48b247478289
    Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/drivers/i2c/tpm/tis.c | 24 ++++++++-------
 src/drivers/i2c/tpm/tpm.c | 76 +++++++++++++++++++++++------------------------
 src/drivers/i2c/tpm/tpm.h |  8 ++---
 3 files changed, 54 insertions(+), 54 deletions(-)

diff --git a/src/drivers/i2c/tpm/tis.c b/src/drivers/i2c/tpm/tis.c
index 0404109..c6173b4 100644
--- a/src/drivers/i2c/tpm/tis.c
+++ b/src/drivers/i2c/tpm/tis.c
@@ -13,6 +13,7 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/early_variables.h>
 #include <stdint.h>
 #include <string.h>
 #include <assert.h>
@@ -26,7 +27,7 @@
 #include <console/console.h>
 
 /* global structure for tpm chip data */
-struct tpm_chip g_chip;
+static struct tpm_chip g_chip CAR_GLOBAL;
 
 #define TPM_CMD_COUNT_BYTE 2
 #define TPM_CMD_ORDINAL_BYTE 6
@@ -34,18 +35,18 @@ struct tpm_chip g_chip;
 
 int tis_open(void)
 {
+	struct tpm_chip *chip = car_get_var_ptr(&g_chip);
 	int rc;
 
-	if (g_chip.is_open) {
+	if (chip->is_open) {
 		printk(BIOS_DEBUG, "tis_open() called twice.\n");
 		return -1;
 	}
 
-	rc = tpm_vendor_init(CONFIG_DRIVER_TPM_I2C_BUS,
-				CONFIG_DRIVER_TPM_I2C_ADDR);
-
+	rc = tpm_vendor_init(chip, CONFIG_DRIVER_TPM_I2C_BUS,
+			     CONFIG_DRIVER_TPM_I2C_ADDR);
 	if (rc < 0)
-		g_chip.is_open = 0;
+		chip->is_open = 0;
 
 	if (rc) {
 		return -1;
@@ -56,9 +57,11 @@ int tis_open(void)
 
 int tis_close(void)
 {
-	if (g_chip.is_open) {
-		tpm_vendor_cleanup(&g_chip);
-		g_chip.is_open = 0;
+	struct tpm_chip *chip = car_get_var_ptr(&g_chip);
+
+	if (chip->is_open) {
+		tpm_vendor_cleanup(chip);
+		chip->is_open = 0;
 	}
 
 	return 0;
@@ -104,8 +107,7 @@ static ssize_t tpm_transmit(const uint8_t *buf, size_t bufsiz)
 {
 	int rc;
 	uint32_t count, ordinal;
-
-	struct tpm_chip *chip = &g_chip;
+	struct tpm_chip *chip = car_get_var_ptr(&g_chip);
 
 	memcpy(&count, buf + TPM_CMD_COUNT_BYTE, sizeof(count));
 	count = be32_to_cpu(count);
diff --git a/src/drivers/i2c/tpm/tpm.c b/src/drivers/i2c/tpm/tpm.c
index 306005f..c62ab69 100644
--- a/src/drivers/i2c/tpm/tpm.c
+++ b/src/drivers/i2c/tpm/tpm.c
@@ -28,6 +28,7 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/early_variables.h>
 #include <stdint.h>
 #include <string.h>
 #include <types.h>
@@ -78,10 +79,7 @@ struct tpm_inf_dev {
 	enum i2c_chip_type chip_type;
 };
 
-static struct tpm_inf_dev tpm_dev = {
-	.bus = -1,
-	.addr = TPM_I2C_ADDR
-};
+static struct tpm_inf_dev g_tpm_dev CAR_GLOBAL;
 
 /*
  * iic_tpm_read() - read from TPM register
@@ -99,15 +97,18 @@ static struct tpm_inf_dev tpm_dev = {
  */
 static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len)
 {
+	struct tpm_inf_dev *tpm_dev = car_get_var_ptr(&g_tpm_dev);
 	int rc;
 	int count;
 
-	if (tpm_dev.bus < 0)
+	if (tpm_dev->addr == 0)
 		return -1;
-	if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
+	if ((tpm_dev->chip_type == SLB9635) ||
+	    (tpm_dev->chip_type == UNKNOWN)) {
 		/* slb9635 protocol should work in both cases */
 		for (count = 0; count < MAX_COUNT; count++) {
-			rc = i2c_write_raw(tpm_dev.bus, tpm_dev.addr, &addr, 1);
+			rc = i2c_write_raw(tpm_dev->bus, tpm_dev->addr,
+					   &addr, 1);
 			if (rc == 0)
 				break;  /* success, break to skip sleep */
 
@@ -123,7 +124,7 @@ static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len)
 		 */
 		for (count = 0; count < MAX_COUNT; count++) {
 			udelay(SLEEP_DURATION);
-			rc = i2c_read_raw(tpm_dev.bus, tpm_dev.addr,
+			rc = i2c_read_raw(tpm_dev->bus, tpm_dev->addr,
 					  buffer, len);
 			if (rc == 0)
 				break;  /* success, break to skip sleep */
@@ -136,13 +137,13 @@ static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len)
 		 * retries should usually not be needed, but are kept just to
 		 * be safe on the safe side.
 		 */
-		struct i2c_seg aseg = { .read = 0, .chip = tpm_dev.addr,
+		struct i2c_seg aseg = { .read = 0, .chip = tpm_dev->addr,
 					.buf = &addr, .len = 1 };
-		struct i2c_seg dseg = { .read = 1, .chip = tpm_dev.addr,
+		struct i2c_seg dseg = { .read = 1, .chip = tpm_dev->addr,
 					.buf = buffer, .len = len };
 		for (count = 0; count < MAX_COUNT; count++) {
-			rc = i2c_transfer(tpm_dev.bus, &aseg, 1) ||
-			     i2c_transfer(tpm_dev.bus, &dseg, 1);
+			rc = i2c_transfer(tpm_dev->bus, &aseg, 1) ||
+			     i2c_transfer(tpm_dev->bus, &dseg, 1);
 			if (rc == 0)
 				break;  /* break here to skip sleep */
 			udelay(SLEEP_DURATION);
@@ -161,6 +162,7 @@ static int iic_tpm_write_generic(uint8_t addr, uint8_t *buffer, size_t len,
 				unsigned int sleep_time,
 				uint8_t max_count)
 {
+	struct tpm_inf_dev *tpm_dev = car_get_var_ptr(&g_tpm_dev);
 	int rc = 0;
 	int count;
 
@@ -170,14 +172,14 @@ static int iic_tpm_write_generic(uint8_t addr, uint8_t *buffer, size_t len,
 	}
 
 	/* prepare send buffer */
-	tpm_dev.buf[0] = addr;
-	memcpy(&(tpm_dev.buf[1]), buffer, len);
+	tpm_dev->buf[0] = addr;
+	memcpy(&(tpm_dev->buf[1]), buffer, len);
 
-	if (tpm_dev.bus < 0)
+	if (tpm_dev->addr == 0)
 		return -1;
 	for (count = 0; count < max_count; count++) {
-		rc = i2c_write_raw(tpm_dev.bus, tpm_dev.addr,
-				   tpm_dev.buf, len + 1);
+		rc = i2c_write_raw(tpm_dev->bus, tpm_dev->addr,
+				   tpm_dev->buf, len + 1);
 		if (rc == 0)
 			break;  /* success, break to skip sleep */
 
@@ -480,34 +482,30 @@ out_err:
 	return -1;
 }
 
-static struct tpm_vendor_specific tpm_tis_i2c = {
-	.status = tpm_tis_i2c_status,
-	.recv = tpm_tis_i2c_recv,
-	.send = tpm_tis_i2c_send,
-	.cancel = tpm_tis_i2c_ready,
-	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_canceled = TPM_STS_COMMAND_READY,
-};
-
 /* Initialization of I2C TPM */
 
-int tpm_vendor_init(unsigned bus, uint32_t dev_addr)
+int tpm_vendor_init(struct tpm_chip *chip, unsigned bus, uint32_t dev_addr)
 {
+	struct tpm_inf_dev *tpm_dev = car_get_var_ptr(&g_tpm_dev);
 	uint32_t vendor;
 	unsigned int old_addr;
-	struct tpm_chip *chip;
-	extern struct tpm_chip g_chip;
 
-	old_addr = tpm_dev.addr;
+	old_addr = tpm_dev->addr;
 	if (dev_addr != 0)
-		tpm_dev.addr = dev_addr;
-	tpm_dev.bus = bus;
+		tpm_dev->addr = dev_addr;
+	tpm_dev->bus = bus;
 
-	chip = &g_chip;
-	memcpy(&chip->vendor, &tpm_tis_i2c, sizeof(struct tpm_vendor_specific));
+	memset(&chip->vendor, 0, sizeof(struct tpm_vendor_specific));
 	chip->is_open = 1;
 
+	chip->vendor.status = &tpm_tis_i2c_status;
+	chip->vendor.recv = &tpm_tis_i2c_recv;
+	chip->vendor.send = &tpm_tis_i2c_send;
+	chip->vendor.cancel = &tpm_tis_i2c_ready;
+	chip->vendor.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
+	chip->vendor.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
+	chip->vendor.req_canceled = TPM_STS_COMMAND_READY;
+
 	/* Disable interrupts (not supported) */
 	chip->vendor.irq = 0;
 
@@ -519,16 +517,16 @@ int tpm_vendor_init(unsigned bus, uint32_t dev_addr)
 		goto out_release;
 
 	if (vendor == TPM_TIS_I2C_DID_VID_9645) {
-		tpm_dev.chip_type = SLB9645;
+		tpm_dev->chip_type = SLB9645;
 	} else if (be32_to_cpu(vendor) == TPM_TIS_I2C_DID_VID_9635) {
-		tpm_dev.chip_type = SLB9635;
+		tpm_dev->chip_type = SLB9635;
 	} else {
 		printk(BIOS_DEBUG, "Vendor ID 0x%08x not recognized.\n", vendor);
 		goto out_release;
 	}
 
 	printk(BIOS_DEBUG, "1.2 TPM (chip type %s device-id 0x%X)\n",
-		 chip_name[tpm_dev.chip_type], vendor >> 16);
+		 chip_name[tpm_dev->chip_type], vendor >> 16);
 
 	/*
 	 * A timeout query to TPM can be placed here.
@@ -541,7 +539,7 @@ out_release:
 	release_locality(chip, 0, 1);
 
 out_err:
-	tpm_dev.addr = old_addr;
+	tpm_dev->addr = old_addr;
 	return -1;
 }
 
diff --git a/src/drivers/i2c/tpm/tpm.h b/src/drivers/i2c/tpm/tpm.h
index 625679d..7dfd594 100644
--- a/src/drivers/i2c/tpm/tpm.h
+++ b/src/drivers/i2c/tpm/tpm.h
@@ -47,9 +47,9 @@ enum tpm_timeout {
 struct tpm_chip;
 
 struct tpm_vendor_specific {
-	const uint8_t req_complete_mask;
-	const uint8_t req_complete_val;
-	const uint8_t req_canceled;
+	uint8_t req_complete_mask;
+	uint8_t req_complete_val;
+	uint8_t req_canceled;
 	int irq;
 	int (*recv)(struct tpm_chip *, uint8_t *, size_t);
 	int (*send)(struct tpm_chip *, uint8_t *, size_t);
@@ -121,7 +121,7 @@ struct tpm_cmd_t {
 
 /* ---------- Interface for TPM vendor ------------ */
 
-int tpm_vendor_init(unsigned bus, uint32_t dev_addr);
+int tpm_vendor_init(struct tpm_chip *chip, unsigned bus, uint32_t dev_addr);
 
 void tpm_vendor_cleanup(struct tpm_chip *chip);
 



More information about the coreboot-gerrit mailing list