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:
Daniel Beer 2013-12-03 07:27:13 +13:00
parent fac574a447
commit 5c1805ff2b
14 changed files with 87 additions and 5 deletions

View File

@ -30,7 +30,8 @@ typedef enum {
DEVICE_CTL_RESET,
DEVICE_CTL_RUN,
DEVICE_CTL_HALT,
DEVICE_CTL_STEP
DEVICE_CTL_STEP,
DEVICE_CTL_SECURE
} device_ctl_t;
typedef enum {

View File

@ -170,6 +170,10 @@ static int fet3_ctl(device_t dev_base, device_ctl_t type)
if (v3hil_single_step(&fet->hil) < 0)
return -1;
return v3hil_update_regs(&fet->hil);
default:
printc_err("fet3: unsupported operation\n");
return -1;
}
return 0;

View File

@ -708,6 +708,13 @@ int fet_ctl(device_t dev_base, device_ctl_t action)
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;

View File

@ -308,6 +308,10 @@ static int gdbc_ctl(device_t dev_base, device_ctl_t op)
case DEVICE_CTL_RESET:
return do_reset(dev);
default:
printc_err("gdbc: unsupported operation\n");
return -1;
}
return 0;

View File

@ -566,8 +566,8 @@ static int goodfet_ctl(device_t dev_base, device_ctl_t type)
case DEVICE_CTL_HALT:
return goodfet_halt(gc);
case DEVICE_CTL_STEP:
printc_err("goodfet: single-stepping not implemented\n");
default:
printc_err("goodfet: unsupported operation\n");
return -1;
}

View File

@ -403,6 +403,7 @@ static int loadbsl_ctl(device_t base, device_ctl_t type)
default:
printc_err("loadbsl: CPU control is not possible\n");
return -1;
}
return 0;

View File

@ -290,8 +290,8 @@ static int pif_ctl(device_t dev_base, device_ctl_t type)
jtag_get_device(&dev->jtag);
break;
case DEVICE_CTL_STEP:
printc_err("pif: single-stepping not implemented\n");
default:
printc_err("pif: unsupported operation\n");
return -1;
}

View File

@ -696,6 +696,10 @@ static int sim_ctl(device_t dev_base, device_ctl_t op)
case DEVICE_CTL_RUN:
dev->running = 1;
return 0;
default:
printc_err("sim: unsupported operation\n");
return -1;
}
return 0;

View File

@ -64,6 +64,7 @@ struct tilib_device {
STATUS_T TIDLL (*MSP430_Reset)(long method, long execute,
long releaseJTAG);
STATUS_T TIDLL (*MSP430_Erase)(long type, long address, long length);
STATUS_T TIDLL (*MSP430_Secure)(void);
STATUS_T TIDLL (*MSP430_Error_Number)(void);
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)
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");
if (!dev->MSP430_Error_Number)
return -1;
@ -510,6 +515,13 @@ static int tilib_ctl(device_t dev_base, device_ctl_t op)
case DEVICE_CTL_STEP:
return do_step(dev);
case DEVICE_CTL_SECURE:
if (dev->MSP430_Secure() < 0) {
report_error(dev, "MSP430_Secure");
return -1;
}
return 0;
}
return 0;

View File

@ -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
defining the alias. To avoid alias substitution when interpreting
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"
Show a list of active breakpoints. Breakpoints can be added and removed
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
segment. If in doubt, do not enable this. Currently, the tilib and uif
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)"
This option controls the default TCP port for the GDB server, if no
argument is given to the "\fBgdb\fR" command.

View File

@ -175,6 +175,15 @@ const struct cmddb_record commands[] = {
.help =
"reset\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",

View File

@ -31,6 +31,7 @@
#include "util.h"
#include "prog.h"
#include "dis.h"
#include "opdb.h"
int cmd_regs(char **arg)
{
@ -832,3 +833,21 @@ int cmd_fill(char **arg)
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);
}

View File

@ -39,5 +39,6 @@ int cmd_setwatch_w(char **arg);
int cmd_delbreak(char **arg);
int cmd_break(char **arg);
int cmd_fill(char **arg);
int cmd_blow_jtag_fuse(char **arg);
#endif

View File

@ -103,6 +103,16 @@ static const struct opdb_key keys[] = {
.defval = {
.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"
}
};