summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/flash/nor/core.c31
-rw-r--r--src/flash/nor/core.h4
-rw-r--r--src/target/target.c9
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;
}