JTAG fuse blow: add "blow_jtag_fuse" command.
Support exists for this command on FET-like devices (including Olimex) and the tilib driver.
This commit is contained in:
parent
fac574a447
commit
5c1805ff2b
|
@ -30,7 +30,8 @@ typedef enum {
|
||||||
DEVICE_CTL_RESET,
|
DEVICE_CTL_RESET,
|
||||||
DEVICE_CTL_RUN,
|
DEVICE_CTL_RUN,
|
||||||
DEVICE_CTL_HALT,
|
DEVICE_CTL_HALT,
|
||||||
DEVICE_CTL_STEP
|
DEVICE_CTL_STEP,
|
||||||
|
DEVICE_CTL_SECURE
|
||||||
} device_ctl_t;
|
} device_ctl_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -170,6 +170,10 @@ static int fet3_ctl(device_t dev_base, device_ctl_t type)
|
||||||
if (v3hil_single_step(&fet->hil) < 0)
|
if (v3hil_single_step(&fet->hil) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return v3hil_update_regs(&fet->hil);
|
return v3hil_update_regs(&fet->hil);
|
||||||
|
|
||||||
|
default:
|
||||||
|
printc_err("fet3: unsupported operation\n");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -708,6 +708,13 @@ int fet_ctl(device_t dev_base, device_ctl_t action)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DEVICE_CTL_SECURE:
|
||||||
|
if (fet_proto_xfer(&dev->proto, C_SECURE, NULL, 0, 0) < 0) {
|
||||||
|
printc_err("fet: failed to secure device\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -308,6 +308,10 @@ static int gdbc_ctl(device_t dev_base, device_ctl_t op)
|
||||||
|
|
||||||
case DEVICE_CTL_RESET:
|
case DEVICE_CTL_RESET:
|
||||||
return do_reset(dev);
|
return do_reset(dev);
|
||||||
|
|
||||||
|
default:
|
||||||
|
printc_err("gdbc: unsupported operation\n");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -566,8 +566,8 @@ static int goodfet_ctl(device_t dev_base, device_ctl_t type)
|
||||||
case DEVICE_CTL_HALT:
|
case DEVICE_CTL_HALT:
|
||||||
return goodfet_halt(gc);
|
return goodfet_halt(gc);
|
||||||
|
|
||||||
case DEVICE_CTL_STEP:
|
default:
|
||||||
printc_err("goodfet: single-stepping not implemented\n");
|
printc_err("goodfet: unsupported operation\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -403,6 +403,7 @@ static int loadbsl_ctl(device_t base, device_ctl_t type)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printc_err("loadbsl: CPU control is not possible\n");
|
printc_err("loadbsl: CPU control is not possible\n");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -290,8 +290,8 @@ static int pif_ctl(device_t dev_base, device_ctl_t type)
|
||||||
jtag_get_device(&dev->jtag);
|
jtag_get_device(&dev->jtag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVICE_CTL_STEP:
|
default:
|
||||||
printc_err("pif: single-stepping not implemented\n");
|
printc_err("pif: unsupported operation\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -696,6 +696,10 @@ static int sim_ctl(device_t dev_base, device_ctl_t op)
|
||||||
case DEVICE_CTL_RUN:
|
case DEVICE_CTL_RUN:
|
||||||
dev->running = 1;
|
dev->running = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printc_err("sim: unsupported operation\n");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -64,6 +64,7 @@ struct tilib_device {
|
||||||
STATUS_T TIDLL (*MSP430_Reset)(long method, long execute,
|
STATUS_T TIDLL (*MSP430_Reset)(long method, long execute,
|
||||||
long releaseJTAG);
|
long releaseJTAG);
|
||||||
STATUS_T TIDLL (*MSP430_Erase)(long type, long address, long length);
|
STATUS_T TIDLL (*MSP430_Erase)(long type, long address, long length);
|
||||||
|
STATUS_T TIDLL (*MSP430_Secure)(void);
|
||||||
STATUS_T TIDLL (*MSP430_Error_Number)(void);
|
STATUS_T TIDLL (*MSP430_Error_Number)(void);
|
||||||
const char *TIDLL (*MSP430_Error_String)(long errNumber);
|
const char *TIDLL (*MSP430_Error_String)(long errNumber);
|
||||||
|
|
||||||
|
@ -187,6 +188,10 @@ static int get_all_funcs(struct tilib_device *dev)
|
||||||
if (!dev->MSP430_Erase)
|
if (!dev->MSP430_Erase)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
dev->MSP430_Secure = get_func(dev->hnd, "MSP430_Secure");
|
||||||
|
if (!dev->MSP430_Secure)
|
||||||
|
return -1;
|
||||||
|
|
||||||
dev->MSP430_Error_Number = get_func(dev->hnd, "MSP430_Error_Number");
|
dev->MSP430_Error_Number = get_func(dev->hnd, "MSP430_Error_Number");
|
||||||
if (!dev->MSP430_Error_Number)
|
if (!dev->MSP430_Error_Number)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -510,6 +515,13 @@ static int tilib_ctl(device_t dev_base, device_ctl_t op)
|
||||||
|
|
||||||
case DEVICE_CTL_STEP:
|
case DEVICE_CTL_STEP:
|
||||||
return do_step(dev);
|
return do_step(dev);
|
||||||
|
|
||||||
|
case DEVICE_CTL_SECURE:
|
||||||
|
if (dev->MSP430_Secure() < 0) {
|
||||||
|
report_error(dev, "MSP430_Secure");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
10
mspdebug.man
10
mspdebug.man
|
@ -230,6 +230,10 @@ Define a command alias. The text \fIcommand\fR will be substituted for
|
||||||
a command plus arguments, if the entire text is wrapped in quotes when
|
a command plus arguments, if the entire text is wrapped in quotes when
|
||||||
defining the alias. To avoid alias substitution when interpreting
|
defining the alias. To avoid alias substitution when interpreting
|
||||||
commands, prefix the command with \\ (a backslash character).
|
commands, prefix the command with \\ (a backslash character).
|
||||||
|
.IP "\fBblow_jtag_fuse\fR"
|
||||||
|
Blow the device's JTAG fuse.
|
||||||
|
|
||||||
|
.B WARNING: this is an irreversible operation!
|
||||||
.IP "\fBbreak\fR"
|
.IP "\fBbreak\fR"
|
||||||
Show a list of active breakpoints. Breakpoints can be added and removed
|
Show a list of active breakpoints. Breakpoints can be added and removed
|
||||||
with the \fBsetbreak\fR and \fBdelbreak\fR commands. Each breakpoint is
|
with the \fBsetbreak\fR and \fBdelbreak\fR commands. Each breakpoint is
|
||||||
|
@ -735,6 +739,12 @@ BSL memory. If in doubt, do not enable this.
|
||||||
If set, some drivers will allow erase/program access to the info A
|
If set, some drivers will allow erase/program access to the info A
|
||||||
segment. If in doubt, do not enable this. Currently, the tilib and uif
|
segment. If in doubt, do not enable this. Currently, the tilib and uif
|
||||||
drivers are affected by this option.
|
drivers are affected by this option.
|
||||||
|
.IP "\fBenable_fuse_blow\fR"
|
||||||
|
If set, some drivers will allow the JTAG security fuse to be blown.
|
||||||
|
|
||||||
|
.B WARNING: this is an irreversible operation!
|
||||||
|
|
||||||
|
If in doubt, do not enable this option.
|
||||||
.IP "\fBgdb_default_port\fR (numeric)"
|
.IP "\fBgdb_default_port\fR (numeric)"
|
||||||
This option controls the default TCP port for the GDB server, if no
|
This option controls the default TCP port for the GDB server, if no
|
||||||
argument is given to the "\fBgdb\fR" command.
|
argument is given to the "\fBgdb\fR" command.
|
||||||
|
|
|
@ -175,6 +175,15 @@ const struct cmddb_record commands[] = {
|
||||||
.help =
|
.help =
|
||||||
"reset\n"
|
"reset\n"
|
||||||
" Reset (and halt) the CPU.\n"
|
" Reset (and halt) the CPU.\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "blow_jtag_fuse",
|
||||||
|
.func = cmd_blow_jtag_fuse,
|
||||||
|
.help =
|
||||||
|
"blow-jtag-fuse\n"
|
||||||
|
" Blow the device's JTAG fuse.\n"
|
||||||
|
"\n"
|
||||||
|
" \x1b[1mWARNING: this is an irreversible operation!\x1b[0m\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "erase",
|
.name = "erase",
|
||||||
|
|
19
ui/devcmd.c
19
ui/devcmd.c
|
@ -31,6 +31,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "prog.h"
|
#include "prog.h"
|
||||||
#include "dis.h"
|
#include "dis.h"
|
||||||
|
#include "opdb.h"
|
||||||
|
|
||||||
int cmd_regs(char **arg)
|
int cmd_regs(char **arg)
|
||||||
{
|
{
|
||||||
|
@ -832,3 +833,21 @@ int cmd_fill(char **arg)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmd_blow_jtag_fuse(char **arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
if (!opdb_get_boolean("enable_fuse_blow")) {
|
||||||
|
printc_err(
|
||||||
|
"blow_jtag_fuse: fuse blow has not been enabled.\n"
|
||||||
|
"\n"
|
||||||
|
"If you really want to blow the JTAG fuse, you need to set the option\n"
|
||||||
|
"\"enable_fuse_blow\" first. If in doubt, do not do this.\n"
|
||||||
|
"\n"
|
||||||
|
"\x1b[1mWARNING: this is in irreversible operation!\x1b[0m\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device_ctl(DEVICE_CTL_SECURE);
|
||||||
|
}
|
||||||
|
|
|
@ -39,5 +39,6 @@ int cmd_setwatch_w(char **arg);
|
||||||
int cmd_delbreak(char **arg);
|
int cmd_delbreak(char **arg);
|
||||||
int cmd_break(char **arg);
|
int cmd_break(char **arg);
|
||||||
int cmd_fill(char **arg);
|
int cmd_fill(char **arg);
|
||||||
|
int cmd_blow_jtag_fuse(char **arg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
10
util/opdb.c
10
util/opdb.c
|
@ -103,6 +103,16 @@ static const struct opdb_key keys[] = {
|
||||||
.defval = {
|
.defval = {
|
||||||
.numeric = 2000
|
.numeric = 2000
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "enable_fuse_blow",
|
||||||
|
.type = OPDB_TYPE_BOOLEAN,
|
||||||
|
.help =
|
||||||
|
"If set, some drivers will allow the JTAG security fuse to be blown.\n"
|
||||||
|
"\n"
|
||||||
|
"\x1b[1mWARNING: this is an irreversible operation!\x1b[0m\n"
|
||||||
|
"\n"
|
||||||
|
"If in doubt, do not enable this option.\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue