summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi8
-rw-r--r--src/flash/nor/pic32mx.c75
-rw-r--r--src/target/mips_ejtag.h2
3 files changed, 83 insertions, 2 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 98fc6900..da2782b1 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -4523,10 +4523,10 @@ flash bank ocl 0 0 0 0 $_TARGETNAME
@deffn {Flash Driver} pic32mx
The PIC32MX microcontrollers are based on the MIPS 4K cores,
and integrate flash memory.
-@emph{The current implementation is incomplete.}
@example
-flash bank pix32mx 0 0 0 0 $_TARGETNAME
+flash bank pix32mx 0x1fc00000 0 0 0 $_TARGETNAME
+flash bank pix32mx 0x1d000000 0 0 0 $_TARGETNAME
@end example
@comment numerous *disabled* commands are defined:
@@ -4538,6 +4538,10 @@ Some pic32mx-specific commands are defined:
Programs the specified 32-bit @var{value} at the given @var{address}
in the specified chip @var{bank}.
@end deffn
+@deffn Command {pic32mx unlock} bank
+Unlock and erase specified chip @var{bank}.
+This will remove any Code Protection.
+@end deffn
@end deffn
@deffn {Flash Driver} stellaris
diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c
index c46264c5..36744e6f 100644
--- a/src/flash/nor/pic32mx.c
+++ b/src/flash/nor/pic32mx.c
@@ -31,6 +31,7 @@
#include "pic32mx.h"
#include <target/algorithm.h>
#include <target/mips32.h>
+#include <target/mips_m4k.h>
static const struct pic32mx_devs_s {
uint8_t devid;
@@ -664,6 +665,73 @@ COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
return ERROR_OK;
}
+COMMAND_HANDLER(pic32mx_handle_unlock_command)
+{
+ uint32_t mchip_cmd;
+ struct target *target = NULL;
+ struct mips_m4k_common *mips_m4k;
+ struct mips_ejtag *ejtag_info;
+ int timeout = 10;
+
+ if (CMD_ARGC < 1)
+ {
+ command_print(CMD_CTX, "pic32mx unlock <bank>");
+ return ERROR_OK;
+ }
+
+ struct flash_bank *bank;
+ int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ target = bank->target;
+ mips_m4k = target_to_m4k(target);
+ ejtag_info = &mips_m4k->mips32.ejtag_info;
+
+ /* we have to use the MTAP to perform a full erase */
+ mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);
+ mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);
+
+ /* first check status of device */
+ mchip_cmd = MCHP_STATUS;
+ mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
+ if (mchip_cmd & (1 << 7))
+ {
+ /* device is not locked */
+ command_print(CMD_CTX, "pic32mx is already unlocked, erasing anyway");
+ }
+
+ /* unlock/erase device */
+ mchip_cmd = MCHP_ASERT_RST;
+ mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
+
+ mchip_cmd = MCHP_ERASE;
+ mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
+
+ do {
+ mchip_cmd = MCHP_STATUS;
+ mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
+ if (timeout-- == 0)
+ {
+ LOG_DEBUG("timeout waiting for unlock: 0x%" PRIx32 "", mchip_cmd);
+ break;
+ }
+ alive_sleep(1);
+ } while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3))));
+
+ mchip_cmd = MCHP_DE_ASSERT_RST;
+ mips_ejtag_drscan_8(ejtag_info, &mchip_cmd);
+
+ /* select ejtag tap */
+ mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
+
+ command_print(CMD_CTX, "pic32mx unlocked.\n"
+ "INFO: a reset or power cycle is required "
+ "for the new settings to take effect.");
+
+ return ERROR_OK;
+}
+
static const struct command_registration pic32mx_exec_command_handlers[] = {
{
.name = "pgm_word",
@@ -671,6 +739,13 @@ static const struct command_registration pic32mx_exec_command_handlers[] = {
.mode = COMMAND_EXEC,
.help = "program a word",
},
+ {
+ .name = "unlock",
+ .handler = pic32mx_handle_unlock_command,
+ .mode = COMMAND_EXEC,
+ .usage = "[bank_id]",
+ .help = "Unlock/Erase entire device.",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h
index 164edd01..f302a706 100644
--- a/src/target/mips_ejtag.h
+++ b/src/target/mips_ejtag.h
@@ -48,6 +48,8 @@
/* microchip specific cmds */
#define MCHP_ASERT_RST 0xd1
#define MCHP_DE_ASSERT_RST 0xd0
+#define MCHP_ERASE 0xfc
+#define MCHP_STATUS 0x00
/* ejtag control register bits ECR */
#define EJTAG_CTRL_TOF (1 << 1)