diff --git a/drivers/tilib.c b/drivers/tilib.c index 984b29d..6037b4c 100644 --- a/drivers/tilib.c +++ b/drivers/tilib.c @@ -26,6 +26,7 @@ #include "tilib_defs.h" #include "thread.h" #include "ctrlc.h" +#include "opdb.h" #if defined(__Windows__) || defined(__CYGWIN__) static const char tilib_filename[] = "MSP430.DLL"; @@ -46,6 +47,7 @@ struct tilib_device { uint16_t bp_handles[DEVICE_MAX_BREAKPOINTS]; char uifPath[1024]; + fperm_t active_fperm; /* MSP430.h */ STATUS_T TIDLL (*MSP430_Initialize)(char *port, long *version); @@ -239,6 +241,39 @@ static void report_error(struct tilib_device *dev, const char *what) printc_err("tilib: %s: %s (error = %ld)\n", what, desc, err); } +static int refresh_fperm(struct tilib_device *dev) +{ + fperm_t fp = opdb_read_fperm(); + fperm_t delta = dev->active_fperm ^ fp; + + if (delta & FPERM_LOCKED_FLASH) { + int opt = (fp & FPERM_LOCKED_FLASH) ? 1 : 0; + + printc_dbg("%s locked flash access\n", + opt ? "Enabling" : "Disabling"); + if (dev->MSP430_Configure(LOCKED_FLASH_ACCESS, opt) < 0) { + report_error(dev, "MSP430_Configure " + "(LOCKED_FLASH_ACCESS)\n"); + return -1; + } + } + + if (delta & FPERM_BSL) { + int opt = (fp & FPERM_BSL) ? 1 : 0; + + printc_dbg("%s BSL access\n", + opt ? "Enabling" : "Disabling"); + if (dev->MSP430_Configure(UNLOCK_BSL_MODE, opt) < 0) { + report_error(dev, "MSP430_Configure " + "(UNLOCK_BSL_MODE)\n"); + return -1; + } + } + + dev->active_fperm = fp; + return 0; +} + static int tilib_readmem(device_t dev_base, address_t addr, uint8_t *mem, address_t len) { @@ -257,6 +292,8 @@ static int tilib_writemem(device_t dev_base, address_t addr, { struct tilib_device *dev = (struct tilib_device *)dev_base; + refresh_fperm(dev); + if (dev->MSP430_Memory(addr, (char *)mem, len, WRITE) < 0) { report_error(dev, "MSP430_Memory"); return -1; @@ -284,6 +321,8 @@ static int tilib_erase(device_t dev_base, device_erase_type_t type, if (type == DEVICE_ERASE_MAIN) address = 0xfffe; + refresh_fperm(dev); + /* We need to pass a non-zero length if we've selected segment * erase. */ diff --git a/mspdebug.man b/mspdebug.man index d64fd89..7e7437c 100644 --- a/mspdebug.man +++ b/mspdebug.man @@ -712,6 +712,13 @@ If true, MSPDebug will colorize debugging output. Change the size of the buffer used to transfer memory to and from the FET. Increasing the value from the default of 64 will improve transfer speed, but may cause problems with some chips. +.IP "\fBenable_bsl_access\fR (boolean)" +If set, some drivers will allow erase/program access to flash +BSL memory. If in doubt, do not enable this. +.IP "\fBenable_locked_flash_access\fR (boolean)" +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 "\fBgdb_loop\fR (boolean)" Automatically restart the GDB server after disconnection. If this option is set, then the GDB server keeps running until an error occurs, diff --git a/util/opdb.c b/util/opdb.c index 7ddf1bf..622727e 100644 --- a/util/opdb.c +++ b/util/opdb.c @@ -77,6 +77,23 @@ static const struct opdb_key keys[] = { .defval = { .numeric = 64 } + }, + { + .name = "enable_locked_flash_access", + .type = OPDB_TYPE_BOOLEAN, + .help = +"If set, some drivers will allow erase/program access to the info A\n" +"segment. If in doubt, do not enable this.\n", + .defval = { + .boolean = 0 + } + }, + { + .name = "enable_bsl_access", + .type = OPDB_TYPE_BOOLEAN, + .help = +"If set, some drivers will allow erase/program access to flash\n" +"BSL memory. If in doubt, do not enable this.\n" } }; @@ -186,3 +203,15 @@ address_t opdb_get_numeric(const char *name) return values[idx].numeric; } + +fperm_t opdb_read_fperm(void) +{ + fperm_t ret = 0; + + if (opdb_get_boolean("enable_locked_flash_access")) + ret |= FPERM_LOCKED_FLASH; + if (opdb_get_boolean("enable_bsl_access")) + ret |= FPERM_BSL; + + return ret; +} diff --git a/util/opdb.h b/util/opdb.h index f1e8f2f..e362988 100644 --- a/util/opdb.h +++ b/util/opdb.h @@ -62,4 +62,12 @@ const char *opdb_get_string(const char *name); int opdb_get_boolean(const char *name); address_t opdb_get_numeric(const char *name); +/* Check flash unlock bits, as configured by the user */ +typedef enum { + FPERM_LOCKED_FLASH = 0x01, + FPERM_BSL = 0x02 +} fperm_t; + +fperm_t opdb_read_fperm(void); + #endif