summaryrefslogtreecommitdiff
path: root/chip/stm32
diff options
context:
space:
mode:
authorGwendal Grignou <gwendal@chromium.org>2015-04-03 16:02:16 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-06-03 02:02:42 -0700
commit35f4d8acaa40050f10158459a04e0bf9b24149c6 (patch)
tree2fd1c6127874023ca44be4f3022704fdb29aa2f4 /chip/stm32
parent5c9118b311ed1d4059b9e51c3defcf5bce62de04 (diff)
downloadchrome-ec-35f4d8acaa40050f10158459a04e0bf9b24149c6.tar.gz
Add flash command support to boards with STM32F4
Add support to write and erase all flash with flashrom. Add support to use all the memory. Note that PSTATE must not used its own page, as the STM32F4 use big pages. BUG=b:38018926 BRANCH=none TEST=With flashrom, write all, RO, RW regions. Use flash command on the console, including flashwp Change-Id: I4f0aee1b3a4f342bdf4ca97bf5d8e8bcc153fd9c Signed-off-by: Gwendal Grignou <gwendal@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/264032 Commit-Ready: Wei-Ning Huang <wnhuang@chromium.org> Tested-by: Wei-Ning Huang <wnhuang@chromium.org> Reviewed-by: Alexandru M Stan <amstan@chromium.org>
Diffstat (limited to 'chip/stm32')
-rw-r--r--chip/stm32/build.mk1
-rw-r--r--chip/stm32/config-stm32f446.h51
-rw-r--r--chip/stm32/flash-f.c142
-rw-r--r--chip/stm32/flash-stm32f4.c354
-rw-r--r--chip/stm32/registers.h70
5 files changed, 233 insertions, 385 deletions
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index 797e4296e3..b44b3ac2fe 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -51,6 +51,7 @@ chip-$(CONFIG_FLASH_PHYSICAL)+=flash-$(CHIP_FAMILY).o
ifdef CONFIG_FLASH_PHYSICAL
chip-$(CHIP_FAMILY_STM32F0)+=flash-f.o
chip-$(CHIP_FAMILY_STM32F3)+=flash-f.o
+chip-$(CHIP_FAMILY_STM32F4)+=flash-f.o
endif
chip-$(CONFIG_ADC)+=adc-$(CHIP_FAMILY).o
chip-$(CONFIG_STM32_CHARGER_DETECT)+=charger_detect.o
diff --git a/chip/stm32/config-stm32f446.h b/chip/stm32/config-stm32f446.h
index 33b44b71a3..27ee939521 100644
--- a/chip/stm32/config-stm32f446.h
+++ b/chip/stm32/config-stm32f446.h
@@ -4,39 +4,35 @@
*/
/* Memory mapping */
-/* Flash physical size is: (512 * 1024)
- * We are limiting the ec.bin size to 128k to reduce flashing time.
- */
-#define CONFIG_FLASH_SIZE (128 * 1024)
-#define CONFIG_FLASH_BANK_SIZE (16 * 1024)
-
-/*
- * 8 "erase" sectors : 16KB/16KB/16KB/16KB/64KB/128KB/128KB/128KB
- * We won't use CONFIG_FLASH_ERASE_SIZE, it will be programmatically
- * set in flash-stm32f4.c. However it must be set or the common flash
- * code won't build. So we'll set it here.
- */
-#define CONFIG_FLASH_ERASE_SIZE (16 * 1024)
+#define CONFIG_FLASH_SIZE (512 * 1024)
-/* minimum write size for 3.3V. 1 for 1.8V */
-#define FLASH_WRITE_SIZE_1800 0x0001
-#define FLASH_WS_DIV_1800 16000000
-#define FLASH_WRITE_SIZE_3300 0x0004
-#define FLASH_WS_DIV_3300 30000000
-#define FLASH_WRITE_SIZE 0x0004
+/* 3 regions type: 16K, 64K and 128K */
+#define SIZE_16KB (16 * 1024)
+#define SIZE_64KB (64 * 1024)
+#define SIZE_128KB (128 * 1024)
+#define CONFIG_FLASH_REGION_TYPE_COUNT 3
+#define CONFIG_FLASH_MULTIPLE_REGION \
+ (5 + (CONFIG_FLASH_SIZE - SIZE_128KB) / SIZE_128KB)
-#define CONFIG_FLASH_WRITE_SIZE FLASH_WRITE_SIZE
+/* Erasing 128K can take up to 2s, need to defer erase. */
+#define CONFIG_FLASH_DEFERRED_ERASE
+
+/* minimum write size for 3.3V. 1 for 1.8V */
+#define STM32_FLASH_WRITE_SIZE_1800 1
+#define STM32_FLASH_WS_DIV_1800 16000000
+#define STM32_FLASH_WRITE_SIZE_3300 4
+#define STM32_FLASH_WS_DIV_3300 30000000
/* No page mode on STM32F, so no benefit to larger write sizes */
-#define CONFIG_FLASH_WRITE_IDEAL_SIZE FLASH_WRITE_SIZE
+#define CONFIG_FLASH_WRITE_IDEAL_SIZE CONFIG_FLASH_WRITE_SIZE
#define CONFIG_RAM_BASE 0x20000000
#define CONFIG_RAM_SIZE 0x00020000
#define CONFIG_RO_MEM_OFF 0
-#define CONFIG_RO_SIZE (48 * 1024)
-#define CONFIG_RW_MEM_OFF (64 * 1024)
-#define CONFIG_RW_SIZE (64 * 1024)
+#define CONFIG_RO_SIZE (256 * 1024)
+#define CONFIG_RW_MEM_OFF (256 * 1024)
+#define CONFIG_RW_SIZE (256 * 1024)
#define CONFIG_RO_STORAGE_OFF 0
#define CONFIG_RW_STORAGE_OFF 0
@@ -50,14 +46,13 @@
#define CONFIG_WP_STORAGE_OFF CONFIG_EC_PROTECTED_STORAGE_OFF
#define CONFIG_WP_STORAGE_SIZE CONFIG_EC_PROTECTED_STORAGE_SIZE
-/* PSTATE lives in one of the smaller blocks. */
-#define CONFIG_FLASH_PSTATE
-#define CONFIG_FW_PSTATE_SIZE (16 * 1024)
-#define CONFIG_FW_PSTATE_OFF (CONFIG_RO_SIZE)
#undef I2C_PORT_COUNT
#define I2C_PORT_COUNT 4
+/* Use PSTATE embedded in the RO image, not in its own erase block */
+#define CONFIG_FLASH_PSTATE
+#undef CONFIG_FLASH_PSTATE_BANK
/* Number of IRQ vectors on the NVIC */
#define CONFIG_IRQ_COUNT 97
diff --git a/chip/stm32/flash-f.c b/chip/stm32/flash-f.c
index 15be87beeb..9f7da82914 100644
--- a/chip/stm32/flash-f.c
+++ b/chip/stm32/flash-f.c
@@ -85,6 +85,35 @@ static void lock(void)
STM32_FLASH_CR |= FLASH_CR_LOCK;
}
+#ifdef CHIP_FAMILY_STM32F4
+static int write_optb(uint32_t mask, uint32_t value)
+{
+ int rv;
+
+ rv = wait_busy();
+ if (rv)
+ return rv;
+
+ /* The target byte is the value we want to write. */
+ if ((STM32_FLASH_OPTCR & mask) == value)
+ return EC_SUCCESS;
+
+ rv = unlock(OPT_LOCK);
+ if (rv)
+ return rv;
+
+ STM32_FLASH_OPTCR = (STM32_FLASH_OPTCR & ~mask) | value;
+ STM32_FLASH_OPTCR |= FLASH_OPTSTRT;
+
+ rv = wait_busy();
+ if (rv)
+ return rv;
+ lock();
+
+ return EC_SUCCESS;
+}
+#else
+static int write_optb(int byte, uint8_t value);
/*
* Option byte organization
*
@@ -202,6 +231,7 @@ static int write_optb(int byte, uint8_t value)
return EC_SUCCESS;
}
+#endif
/*****************************************************************************/
/* Physical layer APIs */
@@ -290,6 +320,12 @@ int flash_physical_erase(int offset, int size)
int res = EC_SUCCESS;
int sector_size;
int timeout_us;
+#ifdef CHIP_FAMILY_STM32F4
+ int sector = flash_bank_index(offset);
+ /* we take advantage of sector_size == erase_size */
+ if ((sector < 0) || (flash_bank_index(offset + size) < 0))
+ return EC_ERROR_INVAL; /* Invalid range */
+#endif
if (unlock(NO_EXTRA_LOCK) != EC_SUCCESS)
return EC_ERROR_UNKNOWN;
@@ -302,23 +338,30 @@ int flash_physical_erase(int offset, int size)
while (size > 0) {
timestamp_t deadline;
+#ifdef CHIP_FAMILY_STM32F4
+ sector_size = flash_bank_size(sector);
+ /* Timeout: from spec, proportional to the size
+ * inversely proportional to the write size.
+ */
+ timeout_us = sector_size * 4 / CONFIG_FLASH_WRITE_SIZE;
+#else
sector_size = CONFIG_FLASH_ERASE_SIZE;
timeout_us = FLASH_TIMEOUT_US;
+#endif
/* Do nothing if already erased */
if (flash_is_erased(offset, sector_size))
goto next_sector;
+#ifdef CHIP_FAMILY_STM32F4
+ /* select page to erase */
+ STM32_FLASH_CR = (STM32_FLASH_CR & ~STM32_FLASH_CR_SNB_MASK) |
+ (sector << STM32_FLASH_CR_SNB_OFFSET);
+#else
/* select page to erase */
STM32_FLASH_AR = CONFIG_PROGRAM_MEMORY_BASE + offset;
-
+#endif
/* set STRT bit : start erase */
STM32_FLASH_CR |= FLASH_CR_STRT;
- /*
- * Reload the watchdog timer to avoid watchdog reset during a
- * long erase operation.
- */
- watchdog_reload();
-
deadline.val = get_time().val + timeout_us;
/* Wait for erase to complete */
watchdog_reload();
@@ -342,6 +385,9 @@ int flash_physical_erase(int offset, int size)
next_sector:
size -= sector_size;
offset += sector_size;
+#ifdef CHIP_FAMILY_STM32F4
+ sector++;
+#endif
}
exit_er:
@@ -353,6 +399,63 @@ exit_er:
return res;
}
+#ifdef CHIP_FAMILY_STM32F4
+static int flash_physical_get_protect_at_boot(int block)
+{
+ /* 0: Write protection active on sector i. */
+ return !(STM32_OPTB_WP & STM32_OPTB_nWRP(block));
+}
+
+int flash_physical_protect_at_boot(uint32_t new_flags)
+{
+ int block;
+ int original_val, val;
+
+ original_val = val = STM32_OPTB_WP & STM32_OPTB_nWRP_ALL;
+
+ for (block = WP_BANK_OFFSET;
+ block < WP_BANK_OFFSET + PHYSICAL_BANKS;
+ block++) {
+ int protect = new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT;
+
+ if (block >= WP_BANK_OFFSET &&
+ block < WP_BANK_OFFSET + WP_BANK_COUNT)
+ protect |= new_flags & EC_FLASH_PROTECT_RO_AT_BOOT;
+#ifdef CONFIG_FLASH_PROTECT_RW
+ else
+ protect |= new_flags & EC_FLASH_PROTECT_RW_AT_BOOT;
+#endif
+
+ if (protect)
+ val &= ~(1 << block);
+ else
+ val |= 1 << block;
+ }
+ if (original_val != val) {
+ write_optb(STM32_FLASH_nWRP_ALL,
+ val << STM32_FLASH_nWRP_OFFSET);
+ }
+
+
+ return EC_SUCCESS;
+}
+
+static void unprotect_all_blocks(void)
+{
+ write_optb(STM32_FLASH_nWRP_ALL, STM32_FLASH_nWRP_ALL);
+}
+
+int flash_physical_protect_now(int all)
+{
+ if (all) {
+ write_optb(STM32_FLASH_nWRP_ALL, 0);
+ return EC_SUCCESS;
+ }
+ /* No way to protect just the RO flash until next boot */
+ return EC_ERROR_INVAL;
+}
+
+#else /* CHIP_FAMILY_STM32F4 */
static int flash_physical_get_protect_at_boot(int block)
{
uint8_t val = read_optb(STM32_OPTB_WRP_OFF(block/8));
@@ -408,6 +511,15 @@ int flash_physical_protect_at_boot(uint32_t new_flags)
return EC_SUCCESS;
}
+static void unprotect_all_blocks(void)
+{
+ int i;
+
+ for (i = 4; i < 8; ++i)
+ write_optb(i * 2, 0xff);
+}
+#endif
+
/**
* Check if write protect register state is inconsistent with RO_AT_BOOT and
* ALL_AT_BOOT state.
@@ -431,13 +543,6 @@ static int registers_need_reset(void)
return 0;
}
-static void unprotect_all_blocks(void)
-{
- int i;
- for (i = 4; i < 8; ++i)
- write_optb(i * 2, 0xff);
-}
-
/*****************************************************************************/
/* High-level APIs */
@@ -447,6 +552,15 @@ int flash_pre_init(void)
uint32_t prot_flags = flash_get_protect();
int need_reset = 0;
+
+#ifdef CHIP_FAMILY_STM32F4
+ unlock(NO_EXTRA_LOCK);
+ /* Set the proper write size */
+ STM32_FLASH_CR = (STM32_FLASH_CR & ~STM32_FLASH_CR_PSIZE_MASK) |
+ (31 - __builtin_clz(CONFIG_FLASH_WRITE_SIZE)) <<
+ STM32_FLASH_CR_PSIZE_OFFSET;
+ lock();
+#endif
if (flash_physical_restore_state())
return EC_SUCCESS;
diff --git a/chip/stm32/flash-stm32f4.c b/chip/stm32/flash-stm32f4.c
index 6b6b64f73a..95af3f1820 100644
--- a/chip/stm32/flash-stm32f4.c
+++ b/chip/stm32/flash-stm32f4.c
@@ -13,110 +13,53 @@
#include "hooks.h"
#include "registers.h"
#include "system.h"
-#include "panic.h"
-#include "watchdog.h"
-
-
-#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
+#include "util.h"
+/*****************************************************************************/
+/* Physical layer APIs */
/*
- * Approximate number of CPU cycles per iteration of the loop when polling
- * the flash status
+ * 8 "erase" sectors : 16KB/16KB/16KB/16KB/64KB/128KB/128KB/128KB
*/
-#define CYCLE_PER_FLASH_LOOP 10
-
-/* Flash page programming timeout. This is 2x the datasheet max. */
-#define FLASH_TIMEOUT_US 16000
-
-static inline int calculate_flash_timeout(void)
-{
- return (FLASH_TIMEOUT_US *
- (clock_get_freq() / SECOND) / CYCLE_PER_FLASH_LOOP);
-}
-
-
-/* Flag indicating whether we have locked down entire flash */
-static int entire_flash_locked;
-
-#define FLASH_SYSJUMP_TAG 0x5750 /* "WP" - Write Protect */
-#define FLASH_HOOK_VERSION 1
-/* The previous write protect state before sys jump */
-struct flash_wp_state {
- int entire_flash_locked;
+struct ec_flash_bank const flash_bank_array[] = {
+ {
+ .count = 4,
+ .size_exp = __fls(SIZE_16KB),
+ .write_size_exp = __fls(CONFIG_FLASH_WRITE_SIZE),
+ .erase_size_exp = __fls(SIZE_16KB),
+ .protect_size_exp = __fls(SIZE_16KB),
+ },
+ {
+ .count = 1,
+ .size_exp = __fls(SIZE_64KB),
+ .write_size_exp = __fls(CONFIG_FLASH_WRITE_SIZE),
+ .erase_size_exp = __fls(SIZE_64KB),
+ .protect_size_exp = __fls(SIZE_64KB),
+ },
+ {
+ .count = (CONFIG_FLASH_SIZE - SIZE_128KB) / SIZE_128KB,
+ .write_size_exp = __fls(CONFIG_FLASH_WRITE_SIZE),
+ .size_exp = __fls(SIZE_128KB),
+ .erase_size_exp = __fls(SIZE_128KB),
+ .protect_size_exp = __fls(SIZE_128KB),
+ },
};
/*****************************************************************************/
/* Physical layer APIs */
-/* Flash unlocking keys */
-#define PRG_LOCK 0
-#define KEY1 0x45670123
-#define KEY2 0xCDEF89AB
-
-static int unlock(void)
+int flash_physical_get_protect(int bank)
{
- /*
- * We may have already locked the flash module and get a bus fault
- * in the attempt to unlock. Need to disable bus fault handler now.
- */
- ignore_bus_fault(1);
-
- /* unlock CR if needed */
- if (STM32_FLASH_CR & FLASH_CR_LOCK) {
- STM32_FLASH_KEYR = KEY1;
- STM32_FLASH_KEYR = KEY2;
- }
-
- /* Re-enable bus fault handler */
- ignore_bus_fault(0);
-
- return (STM32_FLASH_CR & FLASH_CR_LOCK) ?
- EC_ERROR_UNKNOWN : EC_SUCCESS;
-}
-
-static void lock(void)
-{
- STM32_FLASH_CR = FLASH_CR_LOCK;
-}
-
-
-int flash_physical_get_protect(int block)
-{
- /* TODO: not sure if write protect can be implemented like this. */
- return 0;
+ return !(STM32_OPTB_WP & STM32_OPTB_nWRP(bank));
}
uint32_t flash_physical_get_protect_flags(void)
{
- return entire_flash_locked ? EC_FLASH_PROTECT_ALL_NOW : 0;
-}
-
-int flash_physical_protect_now(int all)
-{
- if (all) {
- /*
- * Lock by writing a wrong key to FLASH_KEYR. This triggers a
- * bus fault, so we need to disable bus fault handler while
- * doing this.
- *
- * This incorrect key fault causes the flash to become
- * permanenlty locked until reset, a correct keyring write
- * will not unlock it. In this way we can implement system
- * write protect.
- */
- ignore_bus_fault(1);
- STM32_FLASH_KEYR = 0xffffffff;
- ignore_bus_fault(0);
-
- entire_flash_locked = 1;
+ uint32_t flags = 0;
- /* Check if lock happened */
- if (STM32_FLASH_CR & FLASH_CR_LOCK)
- return EC_SUCCESS;
- }
+ if ((STM32_OPTB_WP & STM32_OPTB_nWRP_ALL) == 0)
+ flags |= EC_FLASH_PROTECT_ALL_NOW;
- /* No way to protect just the RO flash until next boot */
- return EC_ERROR_INVAL;
+ return flags;
}
uint32_t flash_physical_get_valid_flags(void)
@@ -147,238 +90,5 @@ uint32_t flash_physical_get_writable_flags(uint32_t cur_flags)
int flash_physical_restore_state(void)
{
- uint32_t reset_flags = system_get_reset_flags();
- int version, size;
- const struct flash_wp_state *prev;
-
- /*
- * If we have already jumped between images, an earlier image could
- * have applied write protection. Nothing additional needs to be done.
- */
- if (reset_flags & RESET_FLAG_SYSJUMP) {
- prev = (const struct flash_wp_state *)system_get_jump_tag(
- FLASH_SYSJUMP_TAG, &version, &size);
- if (prev && version == FLASH_HOOK_VERSION &&
- size == sizeof(*prev))
- entire_flash_locked = prev->entire_flash_locked;
- return 1;
- }
-
return 0;
}
-
-static int flash_idle(void)
-{
- timestamp_t deadline;
-
- deadline.val = get_time().val + FLASH_TIMEOUT_US;
- /* Wait for flash op to complete.
- * This function is used for both reads and writes, so
- * we need a long timeout, but a relatively short poll interval.
- */
- while ((STM32_FLASH_SR & FLASH_SR_BUSY) &&
- (get_time().val < deadline.val)) {
- usleep(1);
- }
-
- if (STM32_FLASH_SR & FLASH_SR_BUSY)
- return EC_ERROR_TIMEOUT;
-
- return EC_SUCCESS;
-}
-
-static void clear_flash_errors(void)
-{
- /* Clear previous error status */
- STM32_FLASH_SR = FLASH_SR_ERR_MASK;
-}
-
-/*****************************************************************************/
-/* Physical layer APIs */
-
-int flash_physical_protect_at_boot(uint32_t new_flags)
-{
- return EC_SUCCESS;
-}
-
-int flash_physical_write(int offset, int size, const char *data)
-{
- uint32_t *address = (uint32_t *)(CONFIG_MAPPED_STORAGE_BASE + offset);
- int res = EC_SUCCESS;
-
- if (unlock() != EC_SUCCESS) {
- res = EC_ERROR_UNKNOWN;
- goto exit_wr;
- }
-
- /* Wait for busy to clear */
- res = flash_idle();
- if (res)
- goto exit_wr;
- clear_flash_errors();
-
- /* set PG bit */
- STM32_FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
- STM32_FLASH_CR |= FLASH_CR_PSIZE(FLASH_CR_PSIZE_32);
- STM32_FLASH_CR |= FLASH_CR_PG;
-
- for (; size > 0; size -= sizeof(uint32_t)) {
- /*
- * Reload the watchdog timer to avoid watchdog reset when doing
- * long writing with interrupt disabled.
- */
- watchdog_reload();
-
- res = flash_idle();
- if (res)
- goto exit_wr;
-
- /* write the word */
- *address = data[0] + (data[1] << 8) +
- (data[2] << 16) + (data[3] << 24);
-
- address++;
- data += sizeof(uint32_t);
-
- res = flash_idle();
- if (res)
- goto exit_wr;
-
- if (STM32_FLASH_SR & FLASH_SR_BUSY) {
- res = EC_ERROR_TIMEOUT;
- goto exit_wr;
- }
-
- /* Check for error conditions - erase failed, voltage error,
- * protection error.
- */
- if (STM32_FLASH_SR & FLASH_SR_ERR_MASK) {
- res = EC_ERROR_UNKNOWN;
- goto exit_wr;
- }
- }
-
-exit_wr:
- /* Disable PG bit */
- STM32_FLASH_CR &= ~FLASH_CR_PG;
-
- lock();
-
- return res;
-}
-
-
-
-/* "@Internal Flash /0x08000000/04*016Kg,01*064Kg,03*128Kg" */
-struct flash_sector {
- int base;
- int size;
-};
-static const struct flash_sector sectors[] = {
- {(0 * 1024), (16 * 1024)},
- {(16 * 1024), (16 * 1024)},
- {(32 * 1024), (16 * 1024)},
- {(48 * 1024), (16 * 1024)},
- {(64 * 1024), (64 * 1024)},
- {(128 * 1024), (128 * 1024)},
- {(256 * 1024), (128 * 1024)},
- {(384 * 1024), (128 * 1024)}
-};
-static const int num_sectors = ARRAY_SIZE(sectors);
-
-int flash_physical_erase(int offset, int size)
-{
- int res = EC_SUCCESS;
- int start_sector;
- int end_sector;
-
- /* Check that offset/size align with sectors. */
- for (start_sector = 0; start_sector < num_sectors; start_sector++)
- if (offset == sectors[start_sector].base)
- break;
- for (end_sector = start_sector; end_sector < num_sectors; end_sector++)
- if ((offset + size) ==
- (sectors[end_sector].base + sectors[end_sector].size))
- break;
-
- /* We can only erase on sector boundaries. */
- if ((start_sector >= num_sectors) || (end_sector >= num_sectors))
- return EC_ERROR_PARAM1;
-
- if (unlock() != EC_SUCCESS)
- return EC_ERROR_UNKNOWN;
-
- res = flash_idle();
- if (res)
- goto exit_er;
-
- clear_flash_errors();
-
- for (; start_sector <= end_sector; start_sector++) {
- /* Do nothing if already erased */
- if (flash_is_erased(sectors[start_sector].base,
- sectors[start_sector].size))
- continue;
-
- res = flash_idle();
- if (res)
- goto exit_er;
-
- /* set Sector Erase bit and select sector */
- STM32_FLASH_CR = (STM32_FLASH_CR & ~FLASH_CR_SNB_MASK) |
- FLASH_CR_SER | FLASH_CR_SNB(start_sector);
-
- /* set STRT bit : start erase */
- STM32_FLASH_CR |= FLASH_CR_STRT;
-
- /*
- * Reload the watchdog timer to avoid watchdog reset during a
- * long erase operation.
- */
- watchdog_reload();
-
- /* Wait for erase to complete, this will be awhile */
- res = flash_idle();
- if (res)
- goto exit_er;
- /*
- * Check for error conditions - erase failed, voltage error,
- * protection error
- */
- if (STM32_FLASH_SR & FLASH_SR_ERR_MASK) {
- res = EC_ERROR_UNKNOWN;
- goto exit_er;
- }
- }
-
-exit_er:
- /* reset PER bit */
- STM32_FLASH_CR &= ~FLASH_CR_SER;
-
- lock();
-
- return res;
-}
-
-/*****************************************************************************/
-/* High-level APIs */
-
-int flash_pre_init(void)
-{
- return EC_SUCCESS;
-}
-
-/*****************************************************************************/
-/* Hooks */
-
-static void flash_preserve_state(void)
-{
- struct flash_wp_state state;
-
- state.entire_flash_locked = entire_flash_locked;
-
- system_add_jump_tag(FLASH_SYSJUMP_TAG, FLASH_HOOK_VERSION,
- sizeof(state), &state);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, flash_preserve_state, HOOK_PRIO_DEFAULT);
-
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index b885c8fcca..edc94b1b7d 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -1405,35 +1405,63 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
#define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00)
#define STM32_FLASH_ACR_LATENCY (1 << 0)
-#define STM32_FLASH_ACR_PRFTEN (1 << 8)
-#define STM32_FLASH_ACR_ICEN (1 << 9)
-#define STM32_FLASH_ACR_DCEN (1 << 10)
+#define STM32_FLASH_ACR_SHIFT 0
+#define STM32_FLASH_ACR_LAT_MASK 0xf
+#define STM32_FLASH_ACR_PRFTEN (1 << 8)
+#define STM32_FLASH_ACR_ICEN (1 << 9)
+#define STM32_FLASH_ACR_DCEN (1 << 10)
+#define STM32_FLASH_ACR_ICRST (1 << 11)
+#define STM32_FLASH_ACR_DCRST (1 << 12)
#define STM32_FLASH_KEYR REG32(STM32_FLASH_REGS_BASE + 0x04)
+#define FLASH_KEYR_KEY1 0x45670123
+#define FLASH_KEYR_KEY2 0xCDEF89AB
#define STM32_FLASH_OPTKEYR REG32(STM32_FLASH_REGS_BASE + 0x08)
+#define FLASH_OPTKEYR_KEY1 0x08192A3B
+#define FLASH_OPTKEYR_KEY2 0x4C5D6E7F
#define STM32_FLASH_SR REG32(STM32_FLASH_REGS_BASE + 0x0c)
-#define FLASH_SR_BUSY (1 << 16)
-#define FLASH_SR_ERR_MASK (0x1f3)
+#define FLASH_SR_EOP (1 << 0)
+#define FLASH_SR_OPERR (1 << 1)
+#define FLASH_SR_WRPERR (1 << 4)
+#define FLASH_SR_PGAERR (1 << 5)
+#define FLASH_SR_PGPERR (1 << 6)
+#define FLASH_SR_PGSERR (1 << 7)
+#define FLASH_SR_RDERR (1 << 8)
+#define FLASH_SR_ALL_ERR \
+ (FLASH_SR_OPERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | \
+ FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_RDERR)
+#define FLASH_SR_BUSY (1 << 16)
#define STM32_FLASH_CR REG32(STM32_FLASH_REGS_BASE + 0x10)
-#define FLASH_CR_PG (1 << 0)
-#define FLASH_CR_SER (1 << 1)
-#define FLASH_CR_STRT (1 << 16)
-#define FLASH_CR_LOCK (1 << 31)
-#define FLASH_CR_PSIZE(size) (((size) & 0x3) << 8)
-#define FLASH_CR_PSIZE_16 (1)
-#define FLASH_CR_PSIZE_32 (2)
-#define FLASH_CR_PSIZE_MASK FLASH_CR_PSIZE(0x3)
-#define FLASH_CR_SNB(sec) (((sec) & 0xf) << 3)
-#define FLASH_CR_SNB_MASK FLASH_CR_SNB(0xf)
-
+#define FLASH_CR_PG (1 << 0)
+#define FLASH_CR_PER (1 << 1)
+#define FLASH_CR_MER (1 << 2)
+#define STM32_FLASH_CR_SNB_OFFSET (3)
+#define STM32_FLASH_CR_SNB(sec) \
+ (((sec) & 0xf) << STM32_FLASH_CR_SNB_OFFSET)
+#define STM32_FLASH_CR_SNB_MASK (STM32_FLASH_CR_SNB(0xf))
+#define STM32_FLASH_CR_PSIZE_OFFSET (8)
+#define STM32_FLASH_CR_PSIZE(size) \
+ (((size) & 0x3) << STM32_FLASH_CR_PSIZE_OFFSET)
+#define STM32_FLASH_CR_PSIZE_MASK (STM32_FLASH_CR_PSIZE(0x3))
+#define FLASH_CR_STRT (1 << 16)
+#define FLASH_CR_LOCK (1 << 31)
#define STM32_FLASH_OPTCR REG32(STM32_FLASH_REGS_BASE + 0x14)
+#define FLASH_OPTLOCK (1 << 0)
+#define FLASH_OPTSTRT (1 << 1)
+#define STM32_FLASH_BOR_LEV_OFFSET (2)
+#define STM32_FLASH_RDP_MASK (0xFF << 8)
+#define STM32_FLASH_nWRP_OFFSET (16)
+#define STM32_FLASH_nWRP(_bank) (1 << (_bank + STM32_FLASH_nWRP_OFFSET))
+#define STM32_FLASH_nWRP_ALL (0xFF << STM32_FLASH_nWRP_OFFSET)
+#define STM32_FLASH_OPT_LOCKED (STM32_FLASH_OPTCR & FLASH_OPTLOCK)
#define STM32_OPTB_BASE 0x1FFFC000
-
-#define STM32_OPTB_RDP_OFF 0x00
-#define STM32_OPTB_USER_OFF 0x02
+#define STM32_OPTB_RDP_USER REG32(STM32_OPTB_BASE + 0x00)
+#define STM32_OPTB_RDP_OFF 0x00
+#define STM32_OPTB_USER_OFF 0x02
#define STM32_OPTB_WRP_OFF(n) (0x08 + (n&3) * 2)
-#define STM32_OPTB_WRP01 0x08
-#define STM32_OPTB_WRP23 0x0c
+#define STM32_OPTB_WP REG32(STM32_OPTB_BASE + 0x08)
+#define STM32_OPTB_nWRP(_bank) (1 << (_bank))
+#define STM32_OPTB_nWRP_ALL (0xFF)
#define STM32_OPTB_COMPL_SHIFT 8