summaryrefslogtreecommitdiff
path: root/src/flash
diff options
context:
space:
mode:
Diffstat (limited to 'src/flash')
-rw-r--r--src/flash/nor/core.c31
-rw-r--r--src/flash/nor/core.h4
2 files changed, 35 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.