summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/g/flash.c2
-rw-r--r--chip/mec1322/flash.c27
-rw-r--r--chip/npcx/flash.c37
-rw-r--r--chip/stm32/flash-f.c19
-rw-r--r--chip/stm32/flash-stm32f4.c2
-rw-r--r--chip/stm32/flash-stm32l.c13
-rw-r--r--common/flash.c52
-rw-r--r--include/flash.h17
8 files changed, 81 insertions, 88 deletions
diff --git a/chip/g/flash.c b/chip/g/flash.c
index f0bd8e1529..3b02a5d014 100644
--- a/chip/g/flash.c
+++ b/chip/g/flash.c
@@ -105,7 +105,7 @@ uint32_t flash_physical_get_writable_flags(uint32_t cur_flags)
return 0; /* no flags writable */
}
-int flash_physical_protect_at_boot(enum flash_wp_range range)
+int flash_physical_protect_at_boot(uint32_t new_flags)
{
return EC_SUCCESS; /* yeah, I did it. */
}
diff --git a/chip/mec1322/flash.c b/chip/mec1322/flash.c
index 1564b93b48..2cd8dd156d 100644
--- a/chip/mec1322/flash.c
+++ b/chip/mec1322/flash.c
@@ -187,32 +187,31 @@ uint32_t flash_physical_get_writable_flags(uint32_t cur_flags)
* Once write protect is enabled, it will stay enabled until HW PIN is
* de-asserted and SRP register is unset.
*
- * However, this implementation treats FLASH_WP_ALL as FLASH_WP_RO but
- * tries to remember if "all" region is protected.
+ * However, this implementation treats EC_FLASH_PROTECT_ALL_AT_BOOT as
+ * EC_FLASH_PROTECT_RO_AT_BOOT but tries to remember if "all" region
+ * is protected.
*
- * @param range The range to protect.
+ * @param new_flags to protect (only EC_FLASH_PROTECT_*_AT_BOOT are
+ * taken care of)
* @return EC_SUCCESS, or nonzero if error.
*/
-int flash_physical_protect_at_boot(enum flash_wp_range range)
+int flash_physical_protect_at_boot(uint32_t new_flags)
{
int offset, size, ret;
enum spi_flash_wp flashwp = SPI_WP_NONE;
- switch (range) {
- case FLASH_WP_NONE:
+ if ((new_flags & (EC_FLASH_PROTECT_RO_AT_BOOT |
+ EC_FLASH_PROTECT_ALL_AT_BOOT)) == 0) {
+ /* Clear protection */
offset = size = 0;
flashwp = SPI_WP_NONE;
- break;
- case FLASH_WP_ALL:
- entire_flash_locked = 1;
- /* Fallthrough */
- case FLASH_WP_RO:
+ } else {
+ if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT)
+ entire_flash_locked = 1;
+
offset = CONFIG_WP_STORAGE_OFF;
size = CONFIG_WP_STORAGE_SIZE;
flashwp = SPI_WP_HARDWARE;
- break;
- default:
- return EC_ERROR_INVAL;
}
ret = spi_flash_set_protect(offset, size);
diff --git a/chip/npcx/flash.c b/chip/npcx/flash.c
index a11679c231..6d54b61126 100644
--- a/chip/npcx/flash.c
+++ b/chip/npcx/flash.c
@@ -571,31 +571,28 @@ int flash_physical_protect_now(int all)
}
-int flash_physical_protect_at_boot(enum flash_wp_range range)
+int flash_physical_protect_at_boot(uint32_t new_flags)
{
- switch (range) {
- case FLASH_WP_NONE:
+ int ret;
+
+ if ((new_flags & (EC_FLASH_PROTECT_RO_AT_BOOT |
+ EC_FLASH_PROTECT_ALL_AT_BOOT)) == 0) {
/* Clear protection bits in status register */
return flash_set_status_for_prot(0, 0);
- case FLASH_WP_RO:
- /* Protect read-only */
- return flash_write_prot_reg(CONFIG_WP_STORAGE_OFF,
- CONFIG_WP_STORAGE_SIZE,
- 1);
- case FLASH_WP_ALL:
- flash_write_prot_reg(CONFIG_WP_STORAGE_OFF,
- CONFIG_WP_STORAGE_SIZE,
- 1);
+ }
- /*
- * Set UMA_LOCK bit for locking all UMA transaction.
- * But we still can read directly from flash mapping address
- */
+ ret = flash_write_prot_reg(CONFIG_WP_STORAGE_OFF,
+ CONFIG_WP_STORAGE_SIZE,
+ 1);
+
+ /*
+ * Set UMA_LOCK bit for locking all UMA transaction.
+ * But we still can read directly from flash mapping address
+ */
+ if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT)
flash_uma_lock(1);
- return EC_SUCCESS;
- default:
- return EC_ERROR_INVAL;
- }
+
+ return ret;
}
uint32_t flash_physical_get_valid_flags(void)
diff --git a/chip/stm32/flash-f.c b/chip/stm32/flash-f.c
index 09a52ded2e..0c99ec398d 100644
--- a/chip/stm32/flash-f.c
+++ b/chip/stm32/flash-f.c
@@ -338,12 +338,11 @@ static int flash_physical_get_protect_at_boot(int block)
return (!(val & (1 << (block % 8)))) ? 1 : 0;
}
-int flash_physical_protect_at_boot(enum flash_wp_range range)
+int flash_physical_protect_at_boot(uint32_t new_flags)
{
int block;
int i;
int original_val[4], val[4];
- enum flash_wp_range cur_range;
for (i = 0; i < 4; ++i)
original_val[i] = val[i] = read_optb(i * 2 + 8);
@@ -351,14 +350,14 @@ int flash_physical_protect_at_boot(enum flash_wp_range range)
for (block = WP_BANK_OFFSET;
block < WP_BANK_OFFSET + PHYSICAL_BANKS;
block++) {
+ int protect = new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT;
int byte_off = STM32_OPTB_WRP_OFF(block/8) / 2 - 4;
- if (block >= WP_BANK_OFFSET + WP_BANK_COUNT)
- cur_range = FLASH_WP_ALL;
- else
- cur_range = FLASH_WP_RO;
+ if (block >= WP_BANK_OFFSET &&
+ block < WP_BANK_OFFSET + WP_BANK_COUNT)
+ protect |= new_flags & EC_FLASH_PROTECT_RO_AT_BOOT;
- if (cur_range <= range)
+ if (protect)
val[byte_off] = val[byte_off] & (~(1 << (block % 8)));
else
val[byte_off] = val[byte_off] | (1 << (block % 8));
@@ -434,7 +433,8 @@ int flash_pre_init(void)
* update to the write protect register and reboot so
* it takes effect.
*/
- flash_physical_protect_at_boot(FLASH_WP_RO);
+ flash_physical_protect_at_boot(
+ EC_FLASH_PROTECT_RO_AT_BOOT);
need_reset = 1;
}
@@ -448,8 +448,7 @@ int flash_pre_init(void)
* go away.
*/
flash_protect_at_boot(
- (prot_flags & EC_FLASH_PROTECT_RO_AT_BOOT) ?
- FLASH_WP_RO : FLASH_WP_NONE);
+ prot_flags & EC_FLASH_PROTECT_RO_AT_BOOT);
need_reset = 1;
}
} else {
diff --git a/chip/stm32/flash-stm32f4.c b/chip/stm32/flash-stm32f4.c
index 48815d6956..6b6b64f73a 100644
--- a/chip/stm32/flash-stm32f4.c
+++ b/chip/stm32/flash-stm32f4.c
@@ -196,7 +196,7 @@ static void clear_flash_errors(void)
/*****************************************************************************/
/* Physical layer APIs */
-int flash_physical_protect_at_boot(enum flash_wp_range range)
+int flash_physical_protect_at_boot(uint32_t new_flags)
{
return EC_SUCCESS;
}
diff --git a/chip/stm32/flash-stm32l.c b/chip/stm32/flash-stm32l.c
index ce292bb58d..f796f4efaa 100644
--- a/chip/stm32/flash-stm32l.c
+++ b/chip/stm32/flash-stm32l.c
@@ -317,20 +317,20 @@ int flash_physical_get_protect(int block)
return STM32_FLASH_WRPR & (1 << block);
}
-int flash_physical_protect_at_boot(enum flash_wp_range range)
+int flash_physical_protect_at_boot(uint32_t new_flags)
{
uint32_t prot;
uint32_t mask = ((1 << WP_BANK_COUNT) - 1) << WP_BANK_OFFSET;
int rv;
- if (range == FLASH_WP_ALL)
+ if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT)
return EC_ERROR_UNIMPLEMENTED;
/* Read the current protection status */
prot = read_optb_wrp();
/* Set/clear bits */
- if (range == FLASH_WP_RO)
+ if (new_flags & EC_FLASH_PROTECT_RO_AT_BOOT)
prot |= mask;
else
prot &= ~mask;
@@ -448,7 +448,7 @@ int flash_pre_init(void)
* update to the write protect register and reboot so
* it takes effect.
*/
- flash_protect_at_boot(FLASH_WP_RO);
+ flash_protect_at_boot(EC_FLASH_PROTECT_RO_AT_BOOT);
need_reset = 1;
}
@@ -457,9 +457,8 @@ int flash_pre_init(void)
* Write protect register was in an inconsistent state.
* Set it back to a good state and reboot.
*/
- flash_protect_at_boot(
- (prot_flags & EC_FLASH_PROTECT_RO_AT_BOOT) ?
- FLASH_WP_RO : FLASH_WP_NONE);
+ flash_protect_at_boot(prot_flags &
+ EC_FLASH_PROTECT_RO_AT_BOOT);
need_reset = 1;
}
} else if (prot_flags & (EC_FLASH_PROTECT_RO_NOW |
diff --git a/common/flash.c b/common/flash.c
index 9c56864365..3555125b8a 100644
--- a/common/flash.c
+++ b/common/flash.c
@@ -478,14 +478,13 @@ int flash_write_serial(const char *serialno)
#endif
}
-int flash_protect_at_boot(enum flash_wp_range range)
+int flash_protect_at_boot(uint32_t new_flags)
{
#ifdef CONFIG_FLASH_PSTATE
- uint32_t new_flags =
- (range != FLASH_WP_NONE) ? EC_FLASH_PROTECT_RO_AT_BOOT : 0;
+ uint32_t new_pstate_flags = new_flags & EC_FLASH_PROTECT_RO_AT_BOOT;
/* Read the current persist state from flash */
- if (flash_read_pstate() != new_flags) {
+ if (flash_read_pstate() != new_pstate_flags) {
/* Need to update pstate */
int rv;
@@ -496,7 +495,7 @@ int flash_protect_at_boot(enum flash_wp_range range)
#endif
/* Write the desired flags */
- rv = flash_write_pstate(new_flags);
+ rv = flash_write_pstate(new_pstate_flags);
if (rv)
return rv;
}
@@ -513,12 +512,12 @@ int flash_protect_at_boot(enum flash_wp_range range)
* This assumes PSTATE immediately follows RO, which it does on
* all STM32 platforms (which are the only ones with this config).
*/
- flash_physical_protect_at_boot(range);
+ flash_physical_protect_at_boot(new_flags);
#endif
return EC_SUCCESS;
#else
- return flash_physical_protect_at_boot(range);
+ return flash_physical_protect_at_boot(new_flags);
#endif
}
@@ -586,8 +585,9 @@ int flash_set_protect(uint32_t mask, uint32_t flags)
{
int retval = EC_SUCCESS;
int rv;
- enum flash_wp_range range = FLASH_WP_NONE;
- int need_set_protect = 0;
+ int old_flags_at_boot = flash_get_protect() &
+ (EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_ALL_AT_BOOT);
+ int new_flags_at_boot = old_flags_at_boot;
/*
* Process flags we can set. Track the most recent error, but process
@@ -612,21 +612,19 @@ int flash_set_protect(uint32_t mask, uint32_t flags)
* 2. RO_AT_BOOT was not set, but it's requested to be set by
* the caller of flash_set_protect().
*/
- if (mask & EC_FLASH_PROTECT_RO_AT_BOOT) {
- range = (flags & EC_FLASH_PROTECT_RO_AT_BOOT) ?
- FLASH_WP_RO : FLASH_WP_NONE;
- need_set_protect = 1;
- }
+
+ new_flags_at_boot &= ~(mask & EC_FLASH_PROTECT_RO_AT_BOOT);
+ new_flags_at_boot |= mask & flags & EC_FLASH_PROTECT_RO_AT_BOOT;
+
if ((mask & EC_FLASH_PROTECT_ALL_AT_BOOT) &&
- !(flags & EC_FLASH_PROTECT_ALL_AT_BOOT)) {
- if (flash_get_protect() & EC_FLASH_PROTECT_RO_AT_BOOT)
- range = FLASH_WP_RO;
- need_set_protect = 1;
- }
- if (need_set_protect) {
- rv = flash_protect_at_boot(range);
+ !(flags & EC_FLASH_PROTECT_ALL_AT_BOOT))
+ new_flags_at_boot &= ~EC_FLASH_PROTECT_ALL_AT_BOOT;
+
+ if (new_flags_at_boot != old_flags_at_boot) {
+ rv = flash_protect_at_boot(new_flags_at_boot);
if (rv)
retval = rv;
+ old_flags_at_boot = new_flags_at_boot;
}
/*
@@ -637,9 +635,15 @@ int flash_set_protect(uint32_t mask, uint32_t flags)
EC_FLASH_PROTECT_RO_AT_BOOT))
return retval;
- if ((mask & EC_FLASH_PROTECT_ALL_AT_BOOT) &&
- (flags & EC_FLASH_PROTECT_ALL_AT_BOOT)) {
- rv = flash_protect_at_boot(FLASH_WP_ALL);
+ /*
+ * The case where ALL_AT_BOOT is unset is already covered above,
+ * but this does not hurt.
+ */
+ new_flags_at_boot &= ~(mask & EC_FLASH_PROTECT_ALL_AT_BOOT);
+ new_flags_at_boot |= mask & flags & EC_FLASH_PROTECT_ALL_AT_BOOT;
+
+ if (new_flags_at_boot != old_flags_at_boot) {
+ rv = flash_protect_at_boot(new_flags_at_boot);
if (rv)
retval = rv;
}
diff --git a/include/flash.h b/include/flash.h
index e0873028f5..caa6d0b897 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -26,13 +26,6 @@
#define PSTATE_BANK_COUNT 0
#endif
-/* Range of write protection */
-enum flash_wp_range {
- FLASH_WP_NONE = 0,
- FLASH_WP_RO,
- FLASH_WP_ALL,
-};
-
/*****************************************************************************/
/* Low-level methods, for use by flash_common. */
@@ -86,10 +79,11 @@ uint32_t flash_physical_get_protect_flags(void);
/**
* Enable/disable protecting firmware/pstate at boot.
*
- * @param range The range to protect
+ * @param new_flags to protect (only EC_FLASH_PROTECT_*_AT_BOOT are
+ * taken care of)
* @return non-zero if error.
*/
-int flash_physical_protect_at_boot(enum flash_wp_range range);
+int flash_physical_protect_at_boot(uint32_t new_flags);
/**
* Protect flash now.
@@ -154,10 +148,11 @@ int flash_is_erased(uint32_t offset, int size);
* protect pin is deasserted, the protect setting is ignored, and the entire
* flash will be writable.
*
- * @param range The range to protect.
+ * @param new_flags to protect (only EC_FLASH_PROTECT_*_AT_BOOT are
+ * taken care of)
* @return EC_SUCCESS, or nonzero if error.
*/
-int flash_protect_at_boot(enum flash_wp_range range);
+int flash_protect_at_boot(uint32_t new_flags);
/*****************************************************************************/
/* High-level interface for use by other modules. */