diff options
author | Craig Hesling <hesling@chromium.org> | 2020-01-07 12:52:30 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-15 01:10:54 +0000 |
commit | 58bd6e33611249d3e40260aa7aecc29900a69cea (patch) | |
tree | 91dbd4a1aa62b588366104214d1e6a288c7e4e2a /chip | |
parent | b55607c5df6e4a8f1b80b5bcbb0a938b3674b464 (diff) | |
download | chrome-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.c | 55 |
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); |