[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