summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2015-01-15 15:42:43 -0800
committerStefan Reinauer <stefan.reinauer@coreboot.org>2015-04-10 20:16:30 +0200
commitf059b241ad1ebd6b2084578b9284a19d018e8800 (patch)
tree13175b038d5c2f15df63ee73360696cb9a7391d1 /src/soc
parentf9a6a82ea64074ba401213256011f4875b2763de (diff)
downloadcoreboot-f059b241ad1ebd6b2084578b9284a19d018e8800.tar.xz
broadwell: Add function to apply PRR to a range of SPI flash
This function will use the next available/free protected range register to cover the specified region of flash and write protect it until the next reset. This will be used by the common MRC cache code to protect the RW_MRC_CACHE region after it is updated. In order to communicate to the common NVM code that this function is defined also enable CONFIG_MRC_SETTINGS_PROTECT variable. BUG=chrome-os-partner:28234 BRANCH=broadwell TEST=build and boot on samus Change-Id: I710c6a69f725479411ed978cc615e1bb78fb42b8 Signed-off-by: Stefan Reinauer <reinauer@chromium.org> Original-Commit-Id: 25365433be0f190e10a96d9946b8ea90c883b78a Original-Change-Id: I4a4cd27f9f4a94b9134dcba623f33b114299818f Original-Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/241129 Original-Reviewed-by: Shawn N <shawnn@chromium.org> Reviewed-on: http://review.coreboot.org/9493 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/broadwell/Kconfig1
-rw-r--r--src/soc/intel/broadwell/include/soc/spi.h10
-rw-r--r--src/soc/intel/broadwell/spi.c39
3 files changed, 50 insertions, 0 deletions
diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig
index 2e70f45eea..e14476abbd 100644
--- a/src/soc/intel/broadwell/Kconfig
+++ b/src/soc/intel/broadwell/Kconfig
@@ -16,6 +16,7 @@ config CPU_SPECIFIC_OPTIONS
select BACKUP_DEFAULT_SMM_REGION
select CACHE_MRC_BIN
select CACHE_MRC_SETTINGS
+ select MRC_SETTINGS_PROTECT
select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM
select CACHE_ROM
select CAR_MIGRATION
diff --git a/src/soc/intel/broadwell/include/soc/spi.h b/src/soc/intel/broadwell/include/soc/spi.h
index 8b95f70a5f..1449e29cda 100644
--- a/src/soc/intel/broadwell/include/soc/spi.h
+++ b/src/soc/intel/broadwell/include/soc/spi.h
@@ -35,6 +35,14 @@
#define SPIBAR_FDOC 0xb0
#define SPIBAR_FDOD 0xb4
+#define SPI_PRR_MAX 5
+#define SPI_PRR(x) (0x74 + ((x) * 4))
+#define SPI_PRR_SHIFT 12
+#define SPI_PRR_MASK 0x1fff
+#define SPI_PRR_BASE_SHIFT 0
+#define SPI_PRR_LIMIT_SHIFT 16
+#define SPI_PRR_WPE (1 << 31)
+
#define SPIBAR_PREOP 0x94
#define SPIBAR_OPTYPE 0x96
#define SPIBAR_OPMENU_LOWER 0x98
@@ -97,4 +105,6 @@
#define SPIBAR_SSFC_DATA (1 << 14)
#define SPIBAR_SSFC_GO (1 << 1)
+int spi_flash_protect(u32 start, u32 size);
+
#endif
diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c
index 6d2f103d8a..0fca05951b 100644
--- a/src/soc/intel/broadwell/spi.c
+++ b/src/soc/intel/broadwell/spi.c
@@ -29,6 +29,8 @@
#include <device/pci_ids.h>
#include <spi-generic.h>
#include <soc/pci_devs.h>
+#include <soc/rcba.h>
+#include <soc/spi.h>
#ifdef __SMM__
#define pci_read_config_byte(dev, reg, targ)\
@@ -637,3 +639,40 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
return 0;
}
+
+/* Use first empty Protected Range Register to cover region of flash */
+int spi_flash_protect(u32 start, u32 size)
+{
+ u32 end = start + size - 1;
+ u32 reg;
+ int prr;
+
+ /* Find first empty PRR */
+ for (prr = 0; prr < SPI_PRR_MAX; prr++) {
+ reg = SPIBAR32(SPI_PRR(prr));
+ if (reg == 0)
+ break;
+ }
+ if (prr >= SPI_PRR_MAX) {
+ printk(BIOS_ERR, "ERROR: No SPI PRR free!\n");
+ return -1;
+ }
+
+ /* Set protected range base and limit */
+ reg = ((end >> SPI_PRR_SHIFT) & SPI_PRR_MASK);
+ reg <<= SPI_PRR_LIMIT_SHIFT;
+ reg |= ((start >> SPI_PRR_SHIFT) & SPI_PRR_MASK);
+ reg |= SPI_PRR_WPE;
+
+ /* Set the PRR register and verify it is protected */
+ SPIBAR32(SPI_PRR(prr)) = reg;
+ reg = SPIBAR32(SPI_PRR(prr));
+ if (!(reg & SPI_PRR_WPE)) {
+ printk(BIOS_ERR, "ERROR: Unable to set SPI PRR %d\n", prr);
+ return -1;
+ }
+
+ printk(BIOS_INFO, "%s: PRR %d is enabled for range 0x%08x-0x%08x\n",
+ __func__, prr, start, end);
+ return 0;
+}