flash: erase_address now has an unlock option
authorØyvind Harboe <oyvind.harboe@zylin.com>
Wed, 5 May 2010 07:32:43 +0000 (09:32 +0200)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Wed, 5 May 2010 13:24:25 +0000 (15:24 +0200)
Quite useful to be able to unlock the flash, just like in
the flash write_image cmd.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
doc/openocd.texi
src/flash/nor/core.c
src/flash/nor/core.h
src/flash/nor/tcl.c

index 49df1590ce3f26d5f3b10dad7003268038ed53f9..d311c8eee4c9589175dd9450313356df807ea90d 100644 (file)
@@ -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
index 232d503714fb8ffb38c5dbe28279a9132584c684..e07ca1f649d9f3ed3a73f2d7ac9e8c1f97c42e9b 100644 (file)
@@ -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,
index 797cf68681aea87890f570a1aeb46f0e67fe02e7..b152677447912006f83b0b2f8896e2d8f8c49ae8 100644 (file)
@@ -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
index 66b8ac3402634a6574308da71839bd1d1dbe550c..947fd046bc012aba7e3e03ccb055e21d2adf1f7e 100644 (file)
@@ -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",