summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS6
-rw-r--r--doc/openocd.texi15
-rw-r--r--src/flash/nor/stellaris.c66
3 files changed, 87 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index b39b3a8f..56c697ff 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,12 @@ Boundary Scan:
Target Layer:
Flash Layer:
+ New "stellaris recover" command, implements the procedure
+ to recover locked devices (restoring non-volatile
+ state to the factory defaults, including erasing
+ the flash and its protection bits, and possibly
+ re-enabling hardware debugging).
+
Board, Target, and Interface Configuration Scripts:
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 61e39b28..aa8bed1b 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -4497,6 +4497,21 @@ flash bank stellaris 0 0 0 0 $_TARGETNAME
@end example
@end deffn
+@deffn Command {stellaris recover bank_id}
+Performs the @emph{Recovering a "Locked" Device} procedure to
+restore the flash specified by @var{bank_id} and its associated
+nonvolatile registers to their factory default values (erased).
+This is the only way to remove flash protection or re-enable
+debugging if that capability has been disabled.
+
+Note that the final "power cycle the chip" step in this procedure
+must be performed by hand, since OpenOCD can't do it.
+@quotation Warning
+if more than one Stellaris chip is connected, the procedure is
+applied to all of them.
+@end quotation
+@end deffn
+
@deffn {Flash Driver} stm32x
All members of the STM32 microcontroller family from ST Microelectronics
include internal flash and use ARM Cortex M3 cores.
diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c
index 107b1c6d..21a0cffd 100644
--- a/src/flash/nor/stellaris.c
+++ b/src/flash/nor/stellaris.c
@@ -1170,13 +1170,79 @@ COMMAND_HANDLER(stellaris_handle_mass_erase_command)
return ERROR_OK;
}
+/**
+ * Perform the Stellaris "Recovering a 'Locked' Device procedure.
+ * This performs a mass erase and then restores all nonvolatile registers
+ * (including USER_* registers and flash lock bits) to their defaults.
+ * Accordingly, flash can be reprogrammed, and JTAG can be used.
+ *
+ * NOTE that DustDevil parts (at least rev A0 silicon) have errata which
+ * can affect this operation if flash protection has been enabled.
+ */
+COMMAND_HANDLER(stellaris_handle_recover_command)
+{
+ struct flash_bank *bank;
+ int retval;
+
+ retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* REVISIT ... it may be worth sanity checking that the AP is
+ * inactive before we start. ARM documents that switching a DP's
+ * mode while it's active can cause fault modes that need a power
+ * cycle to recover.
+ */
+
+ /* assert SRST */
+ if (!(jtag_get_reset_config() & RESET_HAS_SRST)) {
+ LOG_ERROR("Can't recover Stellaris flash without SRST");
+ return ERROR_FAIL;
+ }
+ jtag_add_reset(0, 1);
+
+ for (int i = 0; i < 5; i++) {
+ retval = dap_to_swd(bank->target);
+ if (retval != ERROR_OK)
+ goto done;
+
+ retval = dap_to_jtag(bank->target);
+ if (retval != ERROR_OK)
+ goto done;
+ }
+
+ /* de-assert SRST */
+ jtag_add_reset(0, 0);
+ retval = jtag_execute_queue();
+
+ /* wait 400+ msec ... OK, "1+ second" is simpler */
+ sleep(1);
+
+ /* USER INTERVENTION required for the power cycle
+ * Restarting OpenOCD is likely needed because of mode switching.
+ */
+ LOG_INFO("USER ACTION: "
+ "power cycle Stellaris chip, then restart OpenOCD.");
+
+done:
+ return retval;
+}
+
static const struct command_registration stellaris_exec_command_handlers[] = {
{
.name = "mass_erase",
.handler = stellaris_handle_mass_erase_command,
.mode = COMMAND_EXEC,
+ .usage = "bank_id",
.help = "erase entire device",
},
+ {
+ .name = "recover",
+ .handler = stellaris_handle_recover_command,
+ .mode = COMMAND_EXEC,
+ .usage = "bank_id",
+ .help = "recover locked device",
+ },
COMMAND_REGISTRATION_DONE
};
static const struct command_registration stellaris_command_handlers[] = {