summaryrefslogtreecommitdiff
path: root/src/flash/nor/core.c
diff options
context:
space:
mode:
authorØyvind Harboe <oyvind.harboe@zylin.com>2010-05-05 15:08:34 +0200
committerØyvind Harboe <oyvind.harboe@zylin.com>2010-05-05 15:24:25 +0200
commit737c9b6258c6e68714ae264ff36126eb5d382d6a (patch)
tree508ba9ecd384a3f4d2fda13231d5fe53161e8c78 /src/flash/nor/core.c
parentf7e0f3c285e9b1578184da886792e02d253ea687 (diff)
downloadopenocd+libswd-737c9b6258c6e68714ae264ff36126eb5d382d6a.tar.gz
openocd+libswd-737c9b6258c6e68714ae264ff36126eb5d382d6a.tar.bz2
openocd+libswd-737c9b6258c6e68714ae264ff36126eb5d382d6a.tar.xz
openocd+libswd-737c9b6258c6e68714ae264ff36126eb5d382d6a.zip
flash: stop caching protection state
There are a million reasons why cached protection state might be stale: power cycling of target, reset, code executing on the target, etc. The "flash protect_check" command is now gone. This is *always* executed when running a "flash info". As a bonus for more a more robust approach, lots of code could be deleted. Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Diffstat (limited to 'src/flash/nor/core.c')
-rw-r--r--src/flash/nor/core.c100
1 files changed, 11 insertions, 89 deletions
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index e07ca1f6..936f07ca 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -54,74 +54,27 @@ int flash_driver_erase(struct flash_bank *bank, int first, int last)
int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
{
int retval;
- bool updated = false;
-
- /* NOTE: "first == last" means (un?)protect just that sector.
- code including Lower level ddrivers may rely on this "first <= last"
- * invariant.
- */
/* callers may not supply illegal parameters ... */
if (first < 0 || first > last || last >= bank->num_sectors)
+ {
+ LOG_ERROR("illegal sector range");
return ERROR_FAIL;
+ }
/* force "set" to 0/1 */
set = !!set;
- /*
- * Filter out what trivial nonsense we can, so drivers don't have to.
+ /* DANGER!
*
- * Don't tell drivers to change to the current state... it's needless,
- * and reducing the amount of work to be done (potentially to nothing)
- * speeds at least some things up.
- */
-scan:
- for (int i = first; i <= last; i++) {
- struct flash_sector *sector = bank->sectors + i;
-
- /* Only filter requests to protect the already-protected, or
- * to unprotect the already-unprotected. Changing from the
- * unknown state (-1) to a known one is unwise but allowed;
- * protection status is best checked first.
- */
- if (sector->is_protected != set)
- continue;
-
- /* Shrink this range of sectors from the start; don't overrun
- * the end. Also shrink from the end; don't overun the start.
- *
- * REVISIT we could handle discontiguous regions by issuing
- * more than one driver request. How much would that matter?
- */
- if (i == first && i != last) {
- updated = true;
- first++;
- } else if (i == last && i != first) {
- updated = true;
- last--;
- }
- }
-
- /* updating the range affects the tests in the scan loop above; so
- * re-scan, to make sure we didn't miss anything.
- */
- if (updated) {
- updated = false;
- goto scan;
- }
-
- /* Single sector, already protected? Nothing to do!
- * We may have trimmed our parameters into this degenerate case.
+ * We must not use any cached information about protection state!!!!
*
- * FIXME repeating the "is_protected==set" test is a giveaway that
- * this fast-exit belongs earlier, in the trim-it-down loop; mve.
- * */
- if (first == last && bank->sectors[first].is_protected == set)
- return ERROR_OK;
-
-
- /* Note that we don't pass illegal parameters to drivers; any
- * trimming just turns one valid range into another one.
+ * There are a million things that could change the protect state:
+ *
+ * the target could have reset, power cycled, been hot plugged,
+ * the application could have run, etc.
+ *
+ * Drivers only receive valid sector range.
*/
retval = bank->driver->protect(bank, set, first, last);
if (retval != ERROR_OK)
@@ -754,34 +707,3 @@ 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;
- }
- }
-}