diff options
author | Yuval Peress <peress@chromium.org> | 2021-02-09 23:54:48 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-02-12 19:57:54 +0000 |
commit | c9b0c9cb92e1440205336e0815fd03590d1d58eb (patch) | |
tree | 706ccc18bebd6b30f92f51963bd71f456e40c1a0 | |
parent | 282ce47b9dfe6b8f18e70ac871e531e25300d313 (diff) | |
download | chrome-ec-c9b0c9cb92e1440205336e0815fd03590d1d58eb.tar.gz |
zephyr: Add locking to shimmed flash.c
Add a mutex to the shimmed version of flash.c (see
chip/npcx/flash.c for reference). While I haven't run into this as
a direct issue yet, this could very possibly be where we were
running into the boot hang prior.
BRANCH=none
BUG=b:180112248, b:179900857, b:167392037
TEST=zmake testall
TEST=build volteer, flash, see that it boots.
Signed-off-by: Yuval Peress <peress@chromium.org>
Change-Id: I8013eba02545f96406399b8f4966e92bed1e9e9a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2686983
Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r-- | zephyr/shim/src/flash.c | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/zephyr/shim/src/flash.c b/zephyr/shim/src/flash.c index e2fff3d139..ce0dd456c3 100644 --- a/zephyr/shim/src/flash.c +++ b/zephyr/shim/src/flash.c @@ -12,6 +12,7 @@ #include "gpio.h" #include "registers.h" #include "spi_flash_reg.h" +#include "task.h" #include "util.h" LOG_MODULE_REGISTER(shim_flash, LOG_LEVEL_ERR); @@ -29,6 +30,16 @@ static uint8_t saved_sr2; #define CMD_READ_STATUS_REG 0x05 #define CMD_READ_STATUS_REG2 0x35 +static mutex_t flash_lock; +static int init_flash_mutex(const struct device *dev) +{ + ARG_UNUSED(dev); + + k_mutex_init(&flash_lock); + return 0; +} +SYS_INIT(init_flash_mutex, POST_KERNEL, 50); + static int flash_get_status1(void) { uint8_t reg; @@ -36,7 +47,14 @@ static int flash_get_status1(void) if (all_protected) return saved_sr1; + /* Lock physical flash operations */ + flash_lock_mapped_storage(1); + cros_flash_get_status_reg(cros_flash_dev, CMD_READ_STATUS_REG, ®); + + /* Unlock physical flash operations */ + flash_lock_mapped_storage(0); + return reg; } @@ -47,7 +65,14 @@ static int flash_get_status2(void) if (all_protected) return saved_sr1; + /* Lock physical flash operations */ + flash_lock_mapped_storage(1); + cros_flash_get_status_reg(cros_flash_dev, CMD_READ_STATUS_REG2, ®); + + /* Unlock physical flash operations */ + flash_lock_mapped_storage(0); + return reg; } @@ -113,10 +138,16 @@ static int flash_set_status_for_prot(int reg1, int reg2) flash_protect_int_flash(!gpio_get_level(GPIO_WP_L)); #endif /*_CONFIG_WP_ACTIVE_HIGH_*/ + /* Lock physical flash operations */ + flash_lock_mapped_storage(1); + regs[0] = reg1; regs[1] = reg2; flash_write_status_reg(regs); + /* Unlock physical flash operations */ + flash_lock_mapped_storage(0); + spi_flash_reg_to_protect(reg1, reg2, &addr_prot_start, &addr_prot_length); @@ -196,9 +227,20 @@ static int flash_write_prot_reg(unsigned int offset, unsigned int bytes, } /* TODO(b/174873770): Add calls to Zephyr code here */ +#ifdef CONFIG_EXTERNAL_STORAGE +void flash_lock_mapped_storage(int lock) +{ + if (lock) + mutex_lock(&flash_lock); + else + mutex_unlock(&flash_lock); +} +#endif int flash_physical_write(int offset, int size, const char *data) { + int rv; + /* Fail if offset, size, and data aren't at least word-aligned */ if ((offset | size | (uint32_t)(uintptr_t)data) & (CONFIG_FLASH_WRITE_SIZE - 1)) @@ -212,11 +254,21 @@ int flash_physical_write(int offset, int size, const char *data) if (flash_check_prot_range(offset, size)) return EC_ERROR_ACCESS_DENIED; - return cros_flash_physical_write(cros_flash_dev, offset, size, data); + /* Lock physical flash operations */ + flash_lock_mapped_storage(1); + + rv = cros_flash_physical_write(cros_flash_dev, offset, size, data); + + /* Unlock physical flash operations */ + flash_lock_mapped_storage(0); + + return rv; } int flash_physical_erase(int offset, int size) { + int rv; + /* check protection */ if (all_protected) return EC_ERROR_ACCESS_DENIED; @@ -225,7 +277,15 @@ int flash_physical_erase(int offset, int size) if (flash_check_prot_range(offset, size)) return EC_ERROR_ACCESS_DENIED; - return cros_flash_physical_erase(cros_flash_dev, offset, size); + /* Lock physical flash operations */ + flash_lock_mapped_storage(1); + + rv = cros_flash_physical_erase(cros_flash_dev, offset, size); + + /* Unlock physical flash operations */ + flash_lock_mapped_storage(0); + + return rv; } int flash_physical_get_protect(int bank) @@ -298,7 +358,16 @@ int flash_physical_protect_now(int all) int flash_physical_read(int offset, int size, char *data) { - return cros_flash_physical_read(cros_flash_dev, offset, size, data); + int rv; + + /* Lock physical flash operations */ + flash_lock_mapped_storage(1); + rv = cros_flash_physical_read(cros_flash_dev, offset, size, data); + + /* Unlock physical flash operations */ + flash_lock_mapped_storage(0); + + return rv; } static int flash_dev_init(const struct device *unused) |