summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorCraig Hesling <hesling@chromium.org>2020-01-07 12:52:30 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-15 01:10:54 +0000
commit58bd6e33611249d3e40260aa7aecc29900a69cea (patch)
tree91dbd4a1aa62b588366104214d1e6a288c7e4e2a /chip
parentb55607c5df6e4a8f1b80b5bcbb0a938b3674b464 (diff)
downloadchrome-ec-58bd6e33611249d3e40260aa7aecc29900a69cea.tar.gz
stm32h7: Pass write protect settings to RW
Preserving these setting is purely cosmetic, since the enforcement for these settings is done in hardware. These simply reflect the state of the hardware settings, which allows other methods to have more precise errors and statuses. Noticeable Changes: - RW will now known that all_now has been set in RO. Before, all_now had been set in RO (hw enforced), but RW was not aware of this. Running the command flashinfo in RW will now reflect all_now. - The flashwrite and flasherase commands check if all_now is set before starting. They properly return access-denied if all_now is set, but since RW was not aware that all_now, it would return some other error. BRANCH=nocturne,hatch BUG=none TEST=none Change-Id: Iab5511722c114adf1b514e941032bc1c3d33341c Signed-off-by: Craig Hesling <hesling@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1987843 Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/stm32/flash-stm32h7.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/chip/stm32/flash-stm32h7.c b/chip/stm32/flash-stm32h7.c
index 5f5d1ef528..a541b962d2 100644
--- a/chip/stm32/flash-stm32h7.c
+++ b/chip/stm32/flash-stm32h7.c
@@ -61,6 +61,16 @@ static int option_disabled;
/* Is physical flash stuck protected? (avoid reboot loop) */
static int stuck_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 access_disabled;
+ int option_disabled;
+ int stuck_locked;
+};
+
static inline int calculate_flash_timeout(void)
{
return (FLASH_TIMEOUT_US *
@@ -454,6 +464,32 @@ uint32_t flash_physical_get_writable_flags(uint32_t cur_flags)
return ret;
}
+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. We simply need to represent these
+ * irreversible flags to other components.
+ */
+ if (reset_flags & EC_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)) {
+ access_disabled = prev->access_disabled;
+ option_disabled = prev->option_disabled;
+ stuck_locked = prev->stuck_locked;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
int flash_pre_init(void)
{
uint32_t reset_flags = system_get_reset_flags();
@@ -461,6 +497,9 @@ int flash_pre_init(void)
uint32_t unwanted_prot_flags = EC_FLASH_PROTECT_ALL_NOW |
EC_FLASH_PROTECT_ERROR_INCONSISTENT;
+ if (flash_physical_restore_state())
+ return EC_SUCCESS;
+
/*
* If we have already jumped between images, an earlier image could
* have applied write protection. Nothing additional needs to be done.
@@ -510,3 +549,19 @@ int flash_pre_init(void)
/* That doesn't return, so if we're still here that's an error */
return EC_ERROR_UNKNOWN;
}
+
+/*****************************************************************************/
+/* Hooks */
+
+static void flash_preserve_state(void)
+{
+ const struct flash_wp_state state = {
+ .access_disabled = access_disabled,
+ .option_disabled = option_disabled,
+ .stuck_locked = stuck_locked,
+ };
+
+ system_add_jump_tag(FLASH_SYSJUMP_TAG, FLASH_HOOK_VERSION,
+ sizeof(state), &state);
+}
+DECLARE_HOOK(HOOK_SYSJUMP, flash_preserve_state, HOOK_PRIO_DEFAULT);