diff options
-rw-r--r-- | src/flash/nor/core.c | 31 | ||||
-rw-r--r-- | src/flash/nor/core.h | 4 | ||||
-rw-r--r-- | src/target/target.c | 9 |
3 files changed, 44 insertions, 0 deletions
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index 2c615192..fc020a8a 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -657,3 +657,34 @@ int flash_write(struct target *target, struct image *image, { return flash_write_unlock(target, image, written, erase, false); } + +/** + * Invalidates cached flash state which a target can change as it runs. + * + * @param target The target being resumed + * + * OpenOCD caches some flash state for brief periods. For example, a sector + * that is protected must be unprotected before OpenOCD tries to write it, + * Also, a sector that's not erased must be erased before it's written. + * + * As a rule, OpenOCD and target firmware can both modify the flash, so when + * a target starts running, OpenOCD needs to invalidate its cached state. + */ +void nor_resume(struct target *target) +{ + struct flash_bank *bank; + + for (bank = flash_banks; bank; bank = bank->next) { + int i; + + if (bank->target != target) + continue; + + for (i = 0; i < bank->num_sectors; i++) { + struct flash_sector *sector = bank->sectors + i; + + sector->is_erased = -1; + sector->is_protected = -1; + } + } +} diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index b164b8dd..98763b7b 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -122,6 +122,10 @@ int flash_erase_address_range(struct target *target, */ int flash_write(struct target *target, struct image *image, uint32_t *written, int erase); + +/* invalidate cached state (targets may modify their own flash) */ +void nor_resume(struct target *target); + /** * Forces targets to re-examine their erase/protection state. * This routine must be called when the system may modify the status. diff --git a/src/target/target.c b/src/target/target.c index 9596302d..1eb14352 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -35,6 +35,7 @@ #include <helper/time_support.h> #include <jtag/jtag.h> +#include <flash/nor/core.h> #include "target.h" #include "target_type.h" @@ -472,6 +473,14 @@ int target_resume(struct target *target, int current, uint32_t address, int hand if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK) return retval; + /* Invalidate any cached protect/erase/... flash status, since + * almost all targets will now be able modify the flash by + * themselves. We want flash drivers and infrastructure to + * be able to rely on (non-invalidated) cached state. + * + * REVISIT do the same for NAND ; maybe other flash flavors too... + */ + nor_resume(target); return retval; } |