[coreboot-gerrit] Change in coreboot[master]: drivers/spi/winbond: Add function to lock flash's status register

Patrick Rudolph (Code Review) gerrit at coreboot.org
Thu Sep 20 13:13:28 CEST 2018


Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/28697


Change subject: drivers/spi/winbond: Add function to lock flash's status register
......................................................................

drivers/spi/winbond: Add function to lock flash's status register

Add a new function pointer to lock down the status register.
Allows to enable various write-protection schemes.

Change-Id: I90e0fcdcf531b53c0fc1ffcfdb3b5ab522f088f5
Signed-off-by: Patrick Rudolph <patrick.rudolph at 9elements.com>
---
M src/drivers/spi/spi_flash.c
M src/drivers/spi/winbond.c
M src/include/spi_flash.h
3 files changed, 107 insertions(+), 0 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/97/28697/1

diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index 9127a5d..577ce4b 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -432,6 +432,27 @@
 	return -1;
 }
 
+int spi_flash_enable_write_protect(const struct spi_flash *flash,
+				  const enum spi_flash_status_reg_lockdown mode,
+				  const bool non_volatile)
+{
+	int ret;
+
+	if (!flash)
+		return -1;
+
+	if (!flash->ops->enable_write_protect) {
+		printk(BIOS_WARNING, "SPI: Enabling write-protection is not "
+		       "implemented for this vendor.\n");
+		return 0;
+	}
+
+	ret = flash->ops->enable_write_protect(flash, mode, non_volatile);
+	if (ret != 0)
+		printk(BIOS_ERR, "SPI: Failed to enable write-protection\n");
+	return ret;
+}
+
 int spi_flash_is_write_protected(const struct spi_flash *flash,
 				 const struct region *region)
 {
diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c
index 0272d5a..7b751f7 100644
--- a/src/drivers/spi/winbond.c
+++ b/src/drivers/spi/winbond.c
@@ -515,6 +515,63 @@
 	return ret;
 }
 
+/*
+ * Available on all devices.
+ * Protect a region starting from start of flash or end of flash.
+ * The caller must provide a valid protected region size.
+ * SEC isn't supported and set to zero.
+ * Write block protect bits to Status/Status2 Reg and leave status register
+ * unlocked.
+ *
+ * @param flash The handle to flash working on
+ * @param region The region to write protect
+ * @param non_volatile Write status register non-volatile
+ *
+ * Returns:
+ * -1    on error
+ *  0    on success
+ */
+
+static int
+winbond_enable_write_protect(const struct spi_flash *flash,
+			     const enum spi_flash_status_reg_lockdown mode,
+			     const bool non_volatile)
+{
+	const struct winbond_spi_flash_params *params;
+	u8 mask, val;
+	int ret;
+
+	params = (const struct winbond_spi_flash_params *)flash->driver_private;
+	if (!params)
+		return -1;
+
+	if (mode > SPI_WRITE_PROTECTION_PERMANENT)
+		return -1;
+
+	if (params->bp_bits == 3) {
+		val = (union status_reg1_bp3){ .srp0 = !!(mode & 1) }.u;
+		mask = (union status_reg1_bp3){ .srp0 = 1 }.u;
+	} else {
+		val = (union status_reg1_bp4){ .srp0 = !!(mode & 1) }.u;
+		mask = (union status_reg1_bp4){ .srp0 = 1 }.u;
+	}
+
+	ret = winbond_flash_cmd_status(flash, 0, mask, val, non_volatile);
+	if (ret)
+		return ret;
+
+	val = (union status_reg2){ .srp1 = !!(mode & 2) }.u;
+	mask = (union status_reg2){ .srp1 = 1 }.u;
+
+	ret = winbond_flash_cmd_status(flash, 1, mask, val, non_volatile);
+	if (ret)
+		return ret;
+
+	printk(BIOS_DEBUG, "WINBOND: locked flash status register, mode %u\n",
+	       mode);
+	return 0;
+}
+
 static const struct spi_flash_ops spi_flash_ops = {
 	.write = winbond_write,
 	.erase = spi_flash_cmd_erase,
@@ -526,6 +583,7 @@
 #endif
 	.get_write_protection = winbond_get_write_protection,
 	.set_write_protection = winbond_set_write_protection,
+	.enable_write_protect = winbond_enable_write_protect,
 };
 
 int spi_flash_probe_winbond(const struct spi_slave *spi, u8 *idcode,
diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h
index 3f0c0fa..55c7992 100644
--- a/src/include/spi_flash.h
+++ b/src/include/spi_flash.h
@@ -26,6 +26,13 @@
 
 struct spi_flash;
 
+enum spi_flash_status_reg_lockdown {
+	SPI_WRITE_PROTECTION_NONE = 0,
+	SPI_WRITE_PROTECTION_PIN,
+	SPI_WRITE_PROTECTION_REBOOT,
+	SPI_WRITE_PROTECTION_PERMANENT
+};
+
 /*
  * Representation of SPI flash operations:
  * read:	Flash read operation.
@@ -63,6 +70,10 @@
 	int (*set_write_protection)(const struct spi_flash *flash,
 				    const struct region *region,
 				    const bool non_volatile);
+
+	int (*enable_write_protect)(const struct spi_flash *flash,
+				const enum spi_flash_status_reg_lockdown mode,
+				const bool non_volatile);
 };
 
 struct spi_flash {
@@ -119,6 +130,23 @@
 int spi_flash_status(const struct spi_flash *flash, u8 *reg);
 
 /*
+ * Lock down the the vendor dependent SPI flash status register.
+ * Call this after setting the flash write protection bits.
+ *
+ * @param flash : A SPI flash device
+ * @param mode: The lockdown-mode to apply
+ * @param non_volatile: Write status register non-volatile
+ *
+ * Returns:
+ *  -1   on error
+ *   0   on success
+ */
+
+int spi_flash_enable_write_protect(const struct spi_flash *flash,
+				  const enum spi_flash_status_reg_lockdown mode,
+				  const bool non_volatile);
+
+/*
  * Return the vendor dependent SPI flash write protection state.
  * @param flash : A SPI flash device
  * @param region: A subregion of the device's region

-- 
To view, visit https://review.coreboot.org/28697
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I90e0fcdcf531b53c0fc1ffcfdb3b5ab522f088f5
Gerrit-Change-Number: 28697
Gerrit-PatchSet: 1
Gerrit-Owner: Patrick Rudolph <patrick.rudolph at 9elements.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180920/b4723704/attachment-0001.html>


More information about the coreboot-gerrit mailing list