[coreboot-gerrit] New patch to review for coreboot: 7164ccd soc/intel/common: Add function to protect MRC cache

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Fri Apr 10 00:57:11 CEST 2015


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9494

-gerrit

commit 7164ccd56ddebf9acadcb5a0fd9f9875b792b03e
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Thu Jan 15 15:49:07 2015 -0800

    soc/intel/common: Add function to protect MRC cache
    
    Add support for applying write protection to the MRC cache
    region in SPI flash.
    
    This is only enabled if there is write protect GPIO that is
    set, and the flash status register reports that the flash
    chip is currently write protected.
    
    Then it will call out to a SOC specific function that will
    enable write protection on the RW_MRC_CACHE region of flash.
    
    The implementation is not quite as clean as I would like because
    there is not a common flash protect interface across SOCs so
    instead it relies on a new Kconfig variable to be set that will
    indicate a SOC implements the function to protect a region of
    SPI flash.
    
    BUG=chrome-os-partner:28234
    BRANCH=broadwell
    TEST=build and boot on samus
    1) with either WPSW=0 or SRP0=0 the PRR is not applied
    2) with both WPSW=1 and SRP0=1 the PRR is applied
    
    Change-Id: If5907b7ddf3f966c546ae32dc99aa815beb27587
    Signed-off-by: Stefan Reinauer <reinauer at chromium.org>
    Original-Commit-Id: a3e0e71dfd7339aab171a26b67aec465a3f332d6
    Original-Change-Id: I94e54e4723b1dcdacbb6a05f047d0c0ebc7d8711
    Original-Signed-off-by: Duncan Laurie <dlaurie at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/241170
    Original-Reviewed-by: Shawn N <shawnn at chromium.org>
---
 src/soc/intel/common/Kconfig     |  4 ++++
 src/soc/intel/common/mrc_cache.c | 21 +++++++++++++++++++
 src/soc/intel/common/nvm.c       | 44 ++++++++++++++++++++++++++++++++++++++++
 src/soc/intel/common/nvm.h       |  6 ++++++
 4 files changed, 75 insertions(+)

diff --git a/src/soc/intel/common/Kconfig b/src/soc/intel/common/Kconfig
index 8b02a4a..aadd64d 100644
--- a/src/soc/intel/common/Kconfig
+++ b/src/soc/intel/common/Kconfig
@@ -14,6 +14,10 @@ config MRC_SETTINGS_CACHE_SIZE
 	hex
 	default 0x10000
 
+config MRC_SETTINGS_PROTECT
+	bool "Enable protection on MRC settings"
+	default n
+
 endif # CACHE_MRC_SETTINGS
 
 endif # HAVE_MRC
diff --git a/src/soc/intel/common/mrc_cache.c b/src/soc/intel/common/mrc_cache.c
index 5860201..f854046 100644
--- a/src/soc/intel/common/mrc_cache.c
+++ b/src/soc/intel/common/mrc_cache.c
@@ -247,6 +247,25 @@ mrc_cache_next_slot(const struct mrc_data_region *region,
 	return next_slot;
 }
 
+/* Protect RW_MRC_CACHE region with a Protected Range Register */
+static int protect_mrc_cache(const struct mrc_data_region *region)
+{
+#if IS_ENABLED(CONFIG_MRC_SETTINGS_PROTECT)
+	if (nvm_is_write_protected() <= 0) {
+		printk(BIOS_INFO, "NOT enabling PRR for RW_MRC_CACHE region\n");
+		return 1;
+	}
+
+	if (nvm_protect(region->base, region->size) < 0) {
+		printk(BIOS_ERR, "ERROR setting PRR for RW_MRC_CACHE region\n");
+		return -1;
+	}
+
+	printk(BIOS_INFO, "Enabled Protected Range on RW_MRC_CACHE region\n");
+#endif
+	return 0;
+}
+
 static void update_mrc_cache(void *unused)
 {
 	const struct mrc_saved_data *current_boot;
@@ -279,6 +298,7 @@ static void update_mrc_cache(void *unused)
 		    !memcmp(&current_saved->data[0], &current_boot->data[0],
 		            current_saved->size)) {
 			printk(BIOS_DEBUG, "MRC cache up to date.\n");
+			protect_mrc_cache(&region);
 			return;
 		}
 	}
@@ -301,6 +321,7 @@ static void update_mrc_cache(void *unused)
 		printk(BIOS_DEBUG, "Failure writing MRC cache to %p.\n",
 		       next_slot);
 	}
+	protect_mrc_cache(&region);
 }
 
 BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, update_mrc_cache, NULL);
diff --git a/src/soc/intel/common/nvm.c b/src/soc/intel/common/nvm.c
index 791422f..8ff4fd6 100644
--- a/src/soc/intel/common/nvm.c
+++ b/src/soc/intel/common/nvm.c
@@ -23,6 +23,10 @@
 #include <string.h>
 #include <spi-generic.h>
 #include <spi_flash.h>
+#include <soc/spi.h>
+#if CONFIG_CHROMEOS
+#include <vendorcode/google/chromeos/chromeos.h>
+#endif
 #include "nvm.h"
 
 /* This module assumes the flash is memory mapped just below 4GiB in the
@@ -80,3 +84,43 @@ int nvm_write(void *start, const void *data, size_t size)
 		return -1;
 	return flash->write(flash, to_flash_offset(start), size, data);
 }
+
+/* Read flash status register to determine if write protect is active */
+int nvm_is_write_protected(void)
+{
+	u8 sr1;
+	u8 wp_gpio = 0;
+	u8 wp_spi;
+
+	if (nvm_init() < 0)
+		return -1;
+
+#if IS_ENABLED(CONFIG_CHROMEOS)
+	/* Read Write Protect GPIO if available */
+	wp_gpio = get_write_protect_state();
+#endif
+
+	/* Read Status Register 1 */
+	if (spi_flash_status(flash, &sr1) < 0) {
+		printk(BIOS_ERR, "Failed to read SPI status register 1\n");
+		return -1;
+	}
+	wp_spi = !!(sr1 & 0x80);
+
+	printk(BIOS_DEBUG, "SPI flash protection: WPSW=%d SRP0=%d\n",
+	       wp_gpio, wp_spi);
+
+	return wp_gpio && wp_spi;
+}
+
+/* Apply protection to a range of flash */
+int nvm_protect(void *start, size_t size)
+{
+#if IS_ENABLED(CONFIG_MRC_SETTINGS_PROTECT)
+	if (nvm_init() < 0)
+		return -1;
+	return spi_flash_protect(to_flash_offset(start), size);
+#else
+	return -1;
+#endif
+}
diff --git a/src/soc/intel/common/nvm.h b/src/soc/intel/common/nvm.h
index d332d83..2e6b364 100644
--- a/src/soc/intel/common/nvm.h
+++ b/src/soc/intel/common/nvm.h
@@ -31,4 +31,10 @@ int nvm_erase(void *start, size_t size);
 /* Write data to NVM. Returns 0 on success < 0 on error.  */
 int nvm_write(void *start, const void *data, size_t size);
 
+/* Determine if flash device is write protected */
+int nvm_is_write_protected(void);
+
+/* Apply protection to a range of flash */
+int nvm_protect(void *start, size_t size);
+
 #endif /* _COMMON_NVM_H_ */



More information about the coreboot-gerrit mailing list