diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2016-11-21 18:01:51 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-12-01 19:59:09 -0800 |
commit | 1bdf8584bb659f44512ec0c88a210d7e60b688bd (patch) | |
tree | 0d84e589b449fc9e2ba7d0d686268360bc9ce7bc | |
parent | d95b9fc18c9633fe4b22ead2be450438bbc2dc29 (diff) | |
download | chrome-ec-1bdf8584bb659f44512ec0c88a210d7e60b688bd.tar.gz |
npcx: flash: Use common code for SPI flash protect reg translation
Common code is more flexible and supports more parts, so delete the
npcx-only register translation code.
BUG=chrome-os-partner:60029
BRANCH=gru
TEST=Manual on gru, run 'flashrom -p ec --wp-enable' and check that 0x28
gets written to SR1, which matches our desired 'protect botton 128KB',
according to the datasheet. Also run 'flashrom -p ec --erase' then read
back EC SPI contents, verify ROM is erased except for first 128KB
region.
Change-Id: I526401997ff7ec77f2a6047a4a9af74a671ed69a
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/413228
Reviewed-by: David Hendricks <dhendrix@chromium.org>
(cherry picked from commit 43634d36d273887b1f2349c333a7b4b229a83365)
Reviewed-on: https://chromium-review.googlesource.com/415498
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
-rw-r--r-- | board/eve/board.h | 1 | ||||
-rw-r--r-- | board/kevin/board.h | 2 | ||||
-rw-r--r-- | board/npcx_evb/board.h | 1 | ||||
-rw-r--r-- | board/npcx_evb_arm/board.h | 1 | ||||
-rw-r--r-- | board/pyro/board.h | 1 | ||||
-rw-r--r-- | board/reef/board.h | 1 | ||||
-rw-r--r-- | board/snappy/board.h | 1 | ||||
-rw-r--r-- | board/wheatley/board.h | 1 | ||||
-rw-r--r-- | chip/npcx/flash.c | 161 | ||||
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | include/config.h | 3 |
11 files changed, 18 insertions, 156 deletions
diff --git a/board/eve/board.h b/board/eve/board.h index 2212fecb85..591484f007 100644 --- a/board/eve/board.h +++ b/board/eve/board.h @@ -29,6 +29,7 @@ #define CONFIG_LID_SWITCH #define CONFIG_LTO #define CONFIG_PWM +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SPI_FLASH_W25X40 #define CONFIG_UART_HOST 0 #define CONFIG_VBOOT_HASH diff --git a/board/kevin/board.h b/board/kevin/board.h index 854c9a7099..676a7c4af3 100644 --- a/board/kevin/board.h +++ b/board/kevin/board.h @@ -25,6 +25,8 @@ #define CONFIG_PWM_DISPLIGHT #define CONFIG_SPI #define CONFIG_SPI_MASTER +#define CONFIG_SPI_FLASH_GD25LQ40 +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands for testing */ diff --git a/board/npcx_evb/board.h b/board/npcx_evb/board.h index f6386c82c5..265a5544e3 100644 --- a/board/npcx_evb/board.h +++ b/board/npcx_evb/board.h @@ -19,6 +19,7 @@ #define CONFIG_SPI_FLASH_PORT 0 #define CONFIG_SPI_FLASH #define CONFIG_FLASH_SIZE 0x00800000 /* 8MB spi flash */ +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SPI_FLASH_W25Q64 #define CONFIG_I2C #define CONFIG_I2C_MASTER diff --git a/board/npcx_evb_arm/board.h b/board/npcx_evb_arm/board.h index bc0e748bdd..932aa663f0 100644 --- a/board/npcx_evb_arm/board.h +++ b/board/npcx_evb_arm/board.h @@ -16,6 +16,7 @@ /* Optional features */ #define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands for testing */ #define CONFIG_FLASH_SIZE 0x00800000 /* 8MB spi flash */ +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SPI_FLASH_W25Q64 #define CONFIG_I2C #define CONFIG_I2C_MASTER diff --git a/board/pyro/board.h b/board/pyro/board.h index 2871f85bff..4f11757d40 100644 --- a/board/pyro/board.h +++ b/board/pyro/board.h @@ -149,6 +149,7 @@ #define WIRELESS_GPIO_WLAN_POWER GPIO_WIRELESS_GPIO_WLAN_POWER #define CONFIG_FLASH_SIZE 524288 +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SPI_FLASH_W25Q40 /* FIXME: Should be GD25LQ40? */ /* diff --git a/board/reef/board.h b/board/reef/board.h index 80157e91df..c43ec225df 100644 --- a/board/reef/board.h +++ b/board/reef/board.h @@ -154,6 +154,7 @@ #define WIRELESS_GPIO_WLAN_POWER GPIO_WIRELESS_GPIO_WLAN_POWER #define CONFIG_FLASH_SIZE 524288 +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SPI_FLASH_W25Q40 /* FIXME: Should be GD25LQ40? */ /* diff --git a/board/snappy/board.h b/board/snappy/board.h index 26f2dcd9ad..1bf0e3b0aa 100644 --- a/board/snappy/board.h +++ b/board/snappy/board.h @@ -148,6 +148,7 @@ #define WIRELESS_GPIO_WLAN_POWER GPIO_WIRELESS_GPIO_WLAN_POWER #define CONFIG_FLASH_SIZE 524288 +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SPI_FLASH_W25Q40 /* FIXME: Should be GD25LQ40? */ /* diff --git a/board/wheatley/board.h b/board/wheatley/board.h index 780341f475..71cbb9ddaf 100644 --- a/board/wheatley/board.h +++ b/board/wheatley/board.h @@ -91,6 +91,7 @@ #define CONFIG_VBOOT_HASH #define CONFIG_FLASH_SIZE 0x80000 /* 512 KB Flash used for EC */ +#define CONFIG_SPI_FLASH_REGS #define CONFIG_SPI_FLASH_W25X40 #define CONFIG_TEMP_SENSOR diff --git a/chip/npcx/flash.c b/chip/npcx/flash.c index 493899e3c0..790fd77d97 100644 --- a/chip/npcx/flash.c +++ b/chip/npcx/flash.c @@ -8,6 +8,7 @@ #include "flash.h" #include "host_command.h" #include "registers.h" +#include "spi_flash_reg.h" #include "switch.h" #include "system.h" #include "timer.h" @@ -204,159 +205,6 @@ void flash_get_jedec_id(uint8_t *dest) #endif /* CONFIG_HOSTCMD_FLASH_SPI_INFO */ -/*****************************************************************************/ -/* flash protection functions */ -/* Use a copy function of spi_flash.c in flash driver */ -/** - * Computes block write protection range from registers - * Returns start == len == 0 for no protection - * - * @param sr1 Status register 1 - * @param sr2 Status register 2 - * @param start Output pointer for protection start offset - * @param len Output pointer for protection length - * - * @return EC_SUCCESS, or non-zero if any error. - */ -static int reg_to_protect(uint8_t sr1, uint8_t sr2, unsigned int *start, - unsigned int *len) -{ - int blocks; - int size; - uint8_t cmp; - uint8_t sec; - uint8_t tb; - uint8_t bp; - - /* Determine flags */ - cmp = (sr2 & SPI_FLASH_SR2_CMP) ? 1 : 0; - sec = (sr1 & SPI_FLASH_SR1_SEC) ? 1 : 0; - tb = (sr1 & SPI_FLASH_SR1_TB) ? 1 : 0; - bp = (sr1 & (SPI_FLASH_SR1_BP2 | SPI_FLASH_SR1_BP1 | SPI_FLASH_SR1_BP0)) - >> 2; - - /* Bad pointers or invalid data */ - if (!start || !len || sr1 == -1 || sr2 == -1) - return EC_ERROR_INVAL; - - /* Not defined by datasheet */ - if (sec && bp == 6) - return EC_ERROR_INVAL; - - /* Determine granularity (4kb sector or 64kb block) */ - /* Computation using 2 * 1024 is correct */ - size = sec ? (2 * 1024) : (64 * 1024); - - /* Determine number of blocks */ - /* Equivalent to pow(2, bp) with pow(2, 0) = 0 */ - blocks = bp ? (1 << bp) : 0; - /* Datasheet specifies don't care for BP == 4, BP == 5 */ - if (sec && bp == 5) - blocks = (1 << 4); - - /* Determine number of bytes */ - *len = size * blocks; - - /* Determine bottom/top of memory to protect */ - *start = tb ? 0 : (CONFIG_FLASH_SIZE - *len); - - /* Reverse computations if complement set */ - if (cmp) { - *start = *start + *len; - *len = CONFIG_FLASH_SIZE - *len; - } - - /* - * If SRP0 is not set, flash is not protected because status register - * can be rewritten. - */ - if (!(sr1 & SPI_FLASH_SR1_SRP0)) { - /* Set protection inconsistent if len != 0*/ - if (*len != 0) - flag_prot_inconsistent = 1; - *start = *len = 0; - return EC_SUCCESS; - } - /* Flag for checking protection inconsistent */ - flag_prot_inconsistent = 0; - - return EC_SUCCESS; -} - -/** - * Computes block write protection registers from range - * - * @param start Desired protection start offset - * @param len Desired protection length - * @param sr1 Output pointer for status register 1 - * @param sr2 Output pointer for status register 2 - * - * @return EC_SUCCESS, or non-zero if any error. - */ -static int protect_to_reg(unsigned int start, unsigned int len, - uint8_t *sr1, uint8_t *sr2) -{ - char cmp = 0; - char sec = 0; - char tb = 0; - char bp = 0; - int blocks; - int size; - - /* Bad pointers */ - if (!sr1 || !sr2 || *sr1 == -1 || *sr2 == -1) - return EC_ERROR_INVAL; - - /* Invalid data */ - if ((start && !len) || start + len > CONFIG_FLASH_SIZE) - return EC_ERROR_INVAL; - - /* Set complement bit based on whether length is power of 2 */ - if ((len & (len - 1)) != 0) { - cmp = 1; - start = start + len; - len = CONFIG_FLASH_SIZE - len; - } - - /* Set bottom/top bit based on start address */ - /* Do not set if len == 0 or len == CONFIG_FLASH_SIZE */ - if (!start && (len % CONFIG_FLASH_SIZE)) - tb = 1; - - /* Set sector bit and determine block length based on protect length */ - if (len == 0 || len >= 128 * 1024) { - sec = 0; - size = 64 * 1024; - } else if (len >= 4 * 1024 && len <= 32 * 1024) { - sec = 1; - size = 2 * 1024; - } else - return EC_ERROR_INVAL; - - /* Determine number of blocks */ - if (len % size != 0) - return EC_ERROR_INVAL; - blocks = len / size; - - /* Determine bp = log2(blocks) with log2(0) = 0 */ - bp = blocks ? __fls(blocks) : 0; - - /* Clear bits */ - *sr1 &= ~(SPI_FLASH_SR1_SEC | SPI_FLASH_SR1_TB - | SPI_FLASH_SR1_BP2 | SPI_FLASH_SR1_BP1 | SPI_FLASH_SR1_BP0); - *sr2 &= ~SPI_FLASH_SR2_CMP; - - /* Set bits */ - *sr1 |= (sec ? SPI_FLASH_SR1_SEC : 0) | (tb ? SPI_FLASH_SR1_TB : 0) - | (bp << 2); - *sr2 |= (cmp ? SPI_FLASH_SR2_CMP : 0); - - /* Set SRP0 so status register can't be changed */ - *sr1 |= SPI_FLASH_SR1_SRP0; - - return EC_SUCCESS; -} - static void flash_uma_lock(int enable) { if (enable && !all_protected) { @@ -403,7 +251,8 @@ static int flash_set_status_for_prot(int reg1, int reg2) /* Unlock physical flash operations */ flash_lock_mapped_storage(0); - reg_to_protect(reg1, reg2, &addr_prot_start, &addr_prot_length); + spi_flash_reg_to_protect(reg1, reg2, + &addr_prot_start, &addr_prot_length); return EC_SUCCESS; } @@ -436,7 +285,7 @@ static int flash_check_prot_reg(unsigned int offset, unsigned int bytes) return EC_ERROR_INVAL; /* Compute current protect range */ - rv = reg_to_protect(sr1, sr2, &start, &len); + rv = spi_flash_reg_to_protect(sr1, sr2, &start, &len); if (rv) return rv; @@ -459,7 +308,7 @@ static int flash_write_prot_reg(unsigned int offset, unsigned int bytes) return EC_ERROR_INVAL; /* Compute desired protect range */ - rv = protect_to_reg(offset, bytes, &sr1, &sr2); + rv = spi_flash_protect_to_reg(offset, bytes, &sr1, &sr2); if (rv) return rv; diff --git a/common/build.mk b/common/build.mk index 6a3ac51b61..4010903e18 100644 --- a/common/build.mk +++ b/common/build.mk @@ -82,6 +82,7 @@ common-$(CONFIG_SMBUS)+= smbus.o common-$(CONFIG_SOFTWARE_CLZ)+=clz.o common-$(CONFIG_CMD_SPI_XFER)+=spi_commands.o common-$(CONFIG_SPI_FLASH)+=spi_flash.o spi_flash_reg.o +common-$(CONFIG_SPI_FLASH_REGS)+=spi_flash_reg.o common-$(CONFIG_SPI_NOR)+=spi_nor.o common-$(CONFIG_SWITCH)+=switch.o common-$(CONFIG_SW_CRC)+=crc.o diff --git a/include/config.h b/include/config.h index 76a5e9805d..39e7667c3c 100644 --- a/include/config.h +++ b/include/config.h @@ -1756,6 +1756,9 @@ /* Support SPI flash */ #undef CONFIG_SPI_FLASH +/* Support SPI flash protection register translation */ +#undef CONFIG_SPI_FLASH_REGS + /* Define the SPI port to use to access the flash */ #undef CONFIG_SPI_FLASH_PORT |