diff options
author | Nicolas Boichat <drinkcat@google.com> | 2017-02-14 11:13:52 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-02-25 08:36:41 -0800 |
commit | 2dcfd2446cbc0133d1351c018956c46717751e65 (patch) | |
tree | d69c6f9c5a0db457daf64f7835858fbd3fa9f157 /common | |
parent | f4174ddaa431ea8fccfda3e0efa66a34b46896d5 (diff) | |
download | chrome-ec-2dcfd2446cbc0133d1351c018956c46717751e65.tar.gz |
flash: Add ROLLBACK flash region, that can be protected separately
ROLLBACK region will be used to store rollback information, and
can be protected independently of RW (it can only be protected when
RO is protected, though).
This is only supported on stm32f0 currently.
BRANCH=none
BUG=chrome-os-partner:61671
TEST=on hammer (stm32f072)
flashinfo => RO+RW not protected
flashwp true; reboot => only RO protected
flashwp all; reboot => RO+RW+RB protected
flashwp noall; reboot => only RO protected
flashwp rw; reboot => only RO+RW protected
flashwp rb; reboot => RO+RW+RB protected
flashwp norb; reboot => RO+RW protected
flashwp all; reboot => RO+RW+RB protected
flashwp norw; reboot => RO+RB protected
TEST=on reef, rb/norb commands not available
Change-Id: I45ffc66d91cf3699ecff025e5114c59a73dc8274
Reviewed-on: https://chromium-review.googlesource.com/430519
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/flash.c | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/common/flash.c b/common/flash.c index 673c962295..020dbd727e 100644 --- a/common/flash.c +++ b/common/flash.c @@ -526,9 +526,15 @@ uint32_t flash_get_protect(void) int i; /* Region protection status */ int not_protected[FLASH_REGION_COUNT] = {0}; +#ifdef CONFIG_ROLLBACK /* Flags that must be set to set ALL_NOW flag. */ const uint32_t all_flags = EC_FLASH_PROTECT_RO_NOW | + EC_FLASH_PROTECT_RW_NOW | + EC_FLASH_PROTECT_ROLLBACK_NOW; +#else + const uint32_t all_flags = EC_FLASH_PROTECT_RO_NOW | EC_FLASH_PROTECT_RW_NOW; +#endif /* Read write protect GPIO */ #ifdef CONFIG_WP_ALWAYS @@ -555,6 +561,14 @@ uint32_t flash_get_protect(void) int bank_flag = is_ro ? EC_FLASH_PROTECT_RO_NOW : EC_FLASH_PROTECT_RW_NOW; +#ifdef CONFIG_ROLLBACK + if (i >= ROLLBACK_BANK_OFFSET && + i < ROLLBACK_BANK_OFFSET + ROLLBACK_BANK_COUNT) { + region = FLASH_REGION_ROLLBACK; + bank_flag = EC_FLASH_PROTECT_ROLLBACK_NOW; + } +#endif + if (flash_physical_get_protect(i)) { /* At least one bank in the region is protected */ flags |= bank_flag; @@ -572,8 +586,8 @@ uint32_t flash_get_protect(void) flags |= EC_FLASH_PROTECT_ALL_NOW; /* - * If the RW banks are protected but the RO banks aren't, that's - * inconsistent. + * If the RW or ROLLBACK banks are protected but the RO banks aren't, + * that's inconsistent. * * Note that we check this before adding in the physical flags below, * since some chips can also protect ALL_NOW for the current boot by @@ -597,6 +611,7 @@ int flash_set_protect(uint32_t mask, uint32_t flags) int rv; int old_flags_at_boot = flash_get_protect() & (EC_FLASH_PROTECT_RO_AT_BOOT | EC_FLASH_PROTECT_RW_AT_BOOT | + EC_FLASH_PROTECT_ROLLBACK_AT_BOOT | EC_FLASH_PROTECT_ALL_AT_BOOT); int new_flags_at_boot = old_flags_at_boot; @@ -630,21 +645,32 @@ int flash_set_protect(uint32_t mask, uint32_t flags) new_flags_at_boot &= ~(mask & EC_FLASH_PROTECT_RO_AT_BOOT); new_flags_at_boot |= flags & EC_FLASH_PROTECT_RO_AT_BOOT; - /* Removing ALL must also remove RW */ + /* Removing ALL must also remove RW/ROLLBACK */ if ((mask & EC_FLASH_PROTECT_ALL_AT_BOOT) && !(flags & EC_FLASH_PROTECT_ALL_AT_BOOT)) { new_flags_at_boot &= ~EC_FLASH_PROTECT_ALL_AT_BOOT; #ifdef CONFIG_FLASH_PROTECT_RW new_flags_at_boot &= ~EC_FLASH_PROTECT_RW_AT_BOOT; #endif +#ifdef CONFIG_ROLLBACK + new_flags_at_boot &= ~EC_FLASH_PROTECT_ROLLBACK_AT_BOOT; +#endif } #ifdef CONFIG_FLASH_PROTECT_RW /* Removing RW must also remove ALL (otherwise nothing will happen). */ if ((mask & EC_FLASH_PROTECT_RW_AT_BOOT) && !(flags & EC_FLASH_PROTECT_RW_AT_BOOT)) { - new_flags_at_boot &= ~EC_FLASH_PROTECT_ALL_AT_BOOT; new_flags_at_boot &= ~EC_FLASH_PROTECT_RW_AT_BOOT; + new_flags_at_boot &= ~EC_FLASH_PROTECT_ALL_AT_BOOT; + } +#endif + +#ifdef CONFIG_ROLLBACK + if ((mask & EC_FLASH_PROTECT_ROLLBACK_AT_BOOT) && + !(flags & EC_FLASH_PROTECT_ROLLBACK_AT_BOOT)) { + new_flags_at_boot &= ~EC_FLASH_PROTECT_ROLLBACK_AT_BOOT; + new_flags_at_boot &= ~EC_FLASH_PROTECT_ALL_AT_BOOT; } #endif @@ -664,8 +690,8 @@ int flash_set_protect(uint32_t mask, uint32_t flags) return retval; /* - * The case where ALL/RW_AT_BOOT is unset is already covered above, - * so we do not need to mask it out. + * The case where ALL/RW/ROLLBACK_AT_BOOT is unset is already covered + * above, so we do not need to mask it out. */ new_flags_at_boot |= flags & EC_FLASH_PROTECT_ALL_AT_BOOT; @@ -673,6 +699,10 @@ int flash_set_protect(uint32_t mask, uint32_t flags) new_flags_at_boot |= flags & EC_FLASH_PROTECT_RW_AT_BOOT; #endif +#ifdef CONFIG_ROLLBACK + new_flags_at_boot |= flags & EC_FLASH_PROTECT_ROLLBACK_AT_BOOT; +#endif + if (new_flags_at_boot != old_flags_at_boot) { rv = flash_protect_at_boot(new_flags_at_boot); if (rv) @@ -729,6 +759,12 @@ static int command_flash_info(int argc, char **argv) ccputs(" STUCK"); if (i & EC_FLASH_PROTECT_ERROR_INCONSISTENT) ccputs(" INCONSISTENT"); +#ifdef CONFIG_ROLLBACK + if (i & EC_FLASH_PROTECT_ROLLBACK_AT_BOOT) + ccputs(" rollback_at_boot"); + if (i & EC_FLASH_PROTECT_ROLLBACK_NOW) + ccputs(" rollback_now"); +#endif ccputs("\n"); ccputs("Protected now:"); @@ -882,6 +918,14 @@ static int command_flash_wp(int argc, char **argv) return flash_set_protect(EC_FLASH_PROTECT_RW_AT_BOOT, 0); #endif +#ifdef CONFIG_ROLLBACK + if (!strcasecmp(argv[1], "rb")) + return flash_set_protect(EC_FLASH_PROTECT_ROLLBACK_AT_BOOT, -1); + + if (!strcasecmp(argv[1], "norb")) + return flash_set_protect(EC_FLASH_PROTECT_ROLLBACK_AT_BOOT, 0); +#endif + /* Do this last, since anything starting with 'n' means "no" */ if (parse_bool(argv[1], &val)) return flash_set_protect(EC_FLASH_PROTECT_RO_AT_BOOT, @@ -894,6 +938,9 @@ DECLARE_CONSOLE_COMMAND(flashwp, command_flash_wp, #ifdef CONFIG_FLASH_PROTECT_RW " | rw | norw" #endif +#ifdef CONFIG_ROLLBACK + " | rb | norb" +#endif , "Modify flash write protect"); /*****************************************************************************/ |