Rizwan Qureshi has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/30559
Change subject: drivers/spi: Add controller protection type ......................................................................
drivers/spi: Add controller protection type
Some SPI controllers support both READ and WRITE protection add a variable to teh protect API for the callers to specify the kind of protection that is requested. Also, update the callers and actual protect API implementation.
BUG=None BRANCH=None TEST=test that the mrc cache is protected as expected on soraka. Also tried if the read protection is applied correctly.
Change-Id: I093884c4768b08a378f21242ac82e430ac013d15 Signed-off-by: Rizwan Qureshi rizwan.qureshi@intel.com --- M src/drivers/mrc_cache/mrc_cache.c M src/drivers/spi/spi_flash.c M src/include/spi-generic.h M src/include/spi_flash.h M src/soc/intel/broadwell/include/soc/spi.h M src/soc/intel/broadwell/spi.c M src/soc/intel/common/block/fast_spi/fast_spi_flash.c 7 files changed, 37 insertions(+), 11 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/30559/1
diff --git a/src/drivers/mrc_cache/mrc_cache.c b/src/drivers/mrc_cache/mrc_cache.c index 4dd0dbc..20026b7 100644 --- a/src/drivers/mrc_cache/mrc_cache.c +++ b/src/drivers/mrc_cache/mrc_cache.c @@ -462,7 +462,8 @@ if (!IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH)) return 0;
- return spi_flash_ctrlr_protect_region(boot_device_spi_flash(), r); + return spi_flash_ctrlr_protect_region(boot_device_spi_flash(), r, + WRITE_PROTECT); }
/* Protect mrc region with a Protected Range Register */ diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index 57bdaf4..7874d25 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -573,7 +573,8 @@
int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, - const struct region *region) + const struct region *region, + enum ctrlr_prot_type type) { const struct spi_ctrlr *ctrlr; struct region flash_region = { 0 }; @@ -592,7 +593,7 @@ return -1;
if (ctrlr->flash_protect) - return ctrlr->flash_protect(flash, region); + return ctrlr->flash_protect(flash, region, type);
return -1; } diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index e3e7f82..f071ef0 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -97,6 +97,11 @@
struct spi_flash;
+enum ctrlr_prot_type{ + READ_PROTECT = 1, + WRITE_PROTECT = 2, +}; + enum { /* Deduct the command length from the spi_crop_chunk() calculation for sizing a transaction. */ @@ -144,7 +149,8 @@ int (*flash_probe)(const struct spi_slave *slave, struct spi_flash *flash); int (*flash_protect)(const struct spi_flash *flash, - const struct region *region); + const struct region *region, + enum ctrlr_prot_type type); };
/*----------------------------------------------------------------------- diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h index 09908eb..1498909 100644 --- a/src/include/spi_flash.h +++ b/src/include/spi_flash.h @@ -207,7 +207,8 @@ /* Protect a region of spi flash using its controller, if available. Returns * < 0 on error, else 0 on success. */ int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, - const struct region *region); + const struct region *region, + enum ctrlr_prot_type type);
/* * This function is provided to support spi flash command-response transactions. diff --git a/src/soc/intel/broadwell/include/soc/spi.h b/src/soc/intel/broadwell/include/soc/spi.h index 588af17..5ad62fd 100644 --- a/src/soc/intel/broadwell/include/soc/spi.h +++ b/src/soc/intel/broadwell/include/soc/spi.h @@ -38,6 +38,7 @@ #define SPI_PRR_BASE_SHIFT 0 #define SPI_PRR_LIMIT_SHIFT 16 #define SPI_PRR_WPE (1 << 31) +#define SPI_PRR_RPE (1 << 15)
#define SPIBAR_PREOP 0x94 #define SPIBAR_OPTYPE 0x96 diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index 2317c9a..a027446 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -615,11 +615,13 @@
/* Use first empty Protected Range Register to cover region of flash */ static int spi_flash_protect(const struct spi_flash *flash, - const struct region *region) + const struct region *region, + enum ctrlr_prot_type type) { u32 start = region_offset(region); u32 end = start + region_sz(region) - 1; u32 reg; + u32 protect_mask; int prr;
/* Find first empty PRR */ @@ -637,12 +639,18 @@ 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; + + if (type & WRITE_PROTECT) + protect_mask |= SPI_PRR_WPE; + if (type & READ_PROTECT) + protect_mask |= SPI_PRR_RPE; + + reg |= protect_mask;
/* Set the PRR register and verify it is protected */ SPIBAR32(SPI_PRR(prr)) = reg; reg = SPIBAR32(SPI_PRR(prr)); - if (!(reg & SPI_PRR_WPE)) { + if (!(reg & protect_mask)) { printk(BIOS_ERR, "ERROR: Unable to set SPI PRR %d\n", prr); return -1; } diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c index 4579b19..a56fe8b 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c @@ -367,11 +367,13 @@ * Protected Range (FPR) register if available. */ static int fast_spi_flash_protect(const struct spi_flash *flash, - const struct region *region) + const struct region *region, + enum ctrlr_prot_type type) { u32 start = region_offset(region); u32 end = start + region_sz(region) - 1; u32 reg; + u32 protect_mask = 0; int fpr; uintptr_t fpr_base; BOILERPLATE_CREATE_CTX(ctx); @@ -392,12 +394,18 @@ }
/* Set protected range base and limit */ - reg = SPI_FPR(start, end) | SPI_FPR_WPE; + + if (type & WRITE_PROTECT) + protect_mask |= SPI_FPR_WPE; + if (type & READ_PROTECT) + protect_mask |= SPI_FPR_RPE; + + reg = SPI_FPR(start, end) | protect_mask;
/* Set the FPR register and verify it is protected */ write32((void *)fpr_base, reg); reg = read32((void *)fpr_base); - if (!(reg & SPI_FPR_WPE)) { + if (!(reg & protect_mask)) { printk(BIOS_ERR, "ERROR: Unable to set SPI FPR %d\n", fpr); return -1; }