diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2015-01-15 15:42:43 -0800 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2015-04-10 20:16:30 +0200 |
commit | f059b241ad1ebd6b2084578b9284a19d018e8800 (patch) | |
tree | 13175b038d5c2f15df63ee73360696cb9a7391d1 /src/soc/intel/broadwell/spi.c | |
parent | f9a6a82ea64074ba401213256011f4875b2763de (diff) | |
download | coreboot-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/intel/broadwell/spi.c')
-rw-r--r-- | src/soc/intel/broadwell/spi.c | 39 |
1 files changed, 39 insertions, 0 deletions
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; +} |