summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2017-02-14 11:13:52 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-02-25 08:36:41 -0800
commit2dcfd2446cbc0133d1351c018956c46717751e65 (patch)
treed69c6f9c5a0db457daf64f7835858fbd3fa9f157 /common
parentf4174ddaa431ea8fccfda3e0efa66a34b46896d5 (diff)
downloadchrome-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.c59
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");
/*****************************************************************************/