From f7e0f3c285e9b1578184da886792e02d253ea687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Wed, 5 May 2010 09:32:43 +0200 Subject: [PATCH] flash: erase_address now has an unlock option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quite useful to be able to unlock the flash, just like in the flash write_image cmd. Signed-off-by: Øyvind Harboe --- doc/openocd.texi | 6 ++++-- src/flash/nor/core.c | 2 +- src/flash/nor/core.h | 3 +++ src/flash/nor/tcl.c | 47 +++++++++++++++++++++++++++++++------------- 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 49df1590c..d311c8eee 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -21,7 +21,7 @@ of the Open On-Chip Debugger (OpenOCD). @itemize @bullet @item Copyright @copyright{} 2008 The OpenOCD Project @item Copyright @copyright{} 2007-2008 Spencer Oliver @email{spen@@spen-soft.co.uk} -@item Copyright @copyright{} 2008 Oyvind Harboe @email{oyvind.harboe@@zylin.com} +@item Copyright @copyright{} 2008-2010 Oyvind Harboe @email{oyvind.harboe@@zylin.com} @item Copyright @copyright{} 2008 Duane Ellis @email{openocd@@duaneellis.com} @item Copyright @copyright{} 2009-2010 David Brownell @end itemize @@ -4043,7 +4043,7 @@ specifies "to the end of the flash bank". The @var{num} parameter is a value shown by @command{flash banks}. @end deffn -@deffn Command {flash erase_address} [@option{pad}] address length +@deffn Command {flash erase_address} [@option{pad}] [@option{unlock}] address length Erase sectors starting at @var{address} for @var{length} bytes. Unless @option{pad} is specified, @math{address} must begin a flash sector, and @math{address + length - 1} must end a sector. @@ -4053,6 +4053,8 @@ The flash bank to use is inferred from the @var{address}, and the specified length must stay within that bank. As a special case, when @var{length} is zero and @var{address} is the start of the bank, the whole flash is erased. +If @option{unlock} is specified, then the flash is unprotected +before erase starts. @end deffn @deffn Command {flash fillw} address word length diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index 232d50371..e07ca1f64 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -502,7 +502,7 @@ static int flash_driver_unprotect(struct flash_bank *bank, int first, int last) return flash_driver_protect(bank, 0, first, last); } -static int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length) +int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length) { /* By default, pad to sector boundaries ... the real issue here * is that our (only) caller *permanently* removes protection, diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index 797cf6868..b15267744 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -108,6 +108,9 @@ int flash_register_commands(struct command_context *cmd_ctx); int flash_erase_address_range(struct target *target, bool pad, uint32_t addr, uint32_t length); +int flash_unlock_address_range(struct target *target, uint32_t addr, + uint32_t length); + /** * Writes @a image into the @a target flash. The @a written parameter * will contain the diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 66b8ac340..947fd046b 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -194,32 +194,40 @@ COMMAND_HANDLER(handle_flash_erase_check_command) COMMAND_HANDLER(handle_flash_erase_address_command) { struct flash_bank *p; - int retval; + int retval = ERROR_OK; int address; int length; bool do_pad = false; + bool do_unlock = false; struct target *target = get_current_target(CMD_CTX); - switch (CMD_ARGC) { - case 3: + while (CMD_ARGC >= 3) + { /* Optionally pad out the address range to block/sector * boundaries. We can't know if there's data in that part * of the flash; only do padding if we're told to. */ - if (strcmp("pad", CMD_ARGV[0]) != 0) + if (strcmp("pad", CMD_ARGV[0]) == 0) + { + do_pad = true; + } else if (strcmp("unlock", CMD_ARGV[0]) == 0) + { + do_unlock = true; + } else + { return ERROR_COMMAND_SYNTAX_ERROR; - do_pad = true; + } CMD_ARGC--; CMD_ARGV++; - /* FALL THROUGH */ - case 2: - COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], address); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], length); - break; - default: + } + if (CMD_ARGC != 2) + { return ERROR_COMMAND_SYNTAX_ERROR; } + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], address); + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], length); + if (length <= 0) { command_print(CMD_CTX, "Length must be >0"); @@ -238,7 +246,15 @@ COMMAND_HANDLER(handle_flash_erase_address_command) struct duration bench; duration_start(&bench); - retval = flash_erase_address_range(target, do_pad, address, length); + if (do_unlock) + { + retval = flash_unlock_address_range(target, address, length); + } + + if (retval == ERROR_OK) + { + retval = flash_erase_address_range(target, do_pad, address, length); + } if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { @@ -709,12 +725,15 @@ static const struct command_registration flash_exec_command_handlers[] = { .name = "erase_address", .handler = handle_flash_erase_address_command, .mode = COMMAND_EXEC, - .usage = "['pad'] address length", + .usage = "['pad'] ['unlock'] address length", .help = "Erase flash sectors starting at address and " "continuing for length bytes. If 'pad' is specified, " "data outside that range may also be erased: the start " "address may be decreased, and length increased, so " - "that all of the first and last sectors are erased.", + "that all of the first and last sectors are erased. " + "If 'unlock' is specified, then the flash is unprotected " + "before erasing.", + }, { .name = "fillw",