]> git.sur5r.net Git - openocd/blobdiff - src/target/target.c
target: are we running algorithm code?
[openocd] / src / target / target.c
index 88931b5badfb922ecafae90193e97cc8ea23703b..286933f45458e7e19a6fe842fa578641d729f72a 100644 (file)
@@ -2,7 +2,7 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
- *   Copyright (C) 2007-2009 Øyvind Harboe                                 *
+ *   Copyright (C) 2007-2010 Øyvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   Copyright (C) 2008, Duane Ellis                                       *
 #include "config.h"
 #endif
 
+#include <helper/time_support.h>
+#include <jtag/jtag.h>
+#include <flash/nor/core.h>
+
 #include "target.h"
 #include "target_type.h"
 #include "target_request.h"
 #include "breakpoints.h"
-#include "time_support.h"
 #include "register.h"
 #include "trace.h"
 #include "image.h"
-#include "jtag.h"
 
 
-static int target_array2mem(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv);
-static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv);
+static int target_array2mem(Jim_Interp *interp, struct target *target,
+               int argc, Jim_Obj *const *argv);
+static int target_mem2array(Jim_Interp *interp, struct target *target,
+               int argc, Jim_Obj *const *argv);
 
 /* targets */
 extern struct target_type arm7tdmi_target;
@@ -63,6 +67,7 @@ extern struct target_type cortexa8_target;
 extern struct target_type arm11_target;
 extern struct target_type mips_m4k_target;
 extern struct target_type avr_target;
+extern struct target_type dsp563xx_target;
 extern struct target_type testee_target;
 
 struct target_type *target_types[] =
@@ -82,6 +87,7 @@ struct target_type *target_types[] =
        &arm11_target,
        &mips_m4k_target,
        &avr_target,
+       &dsp563xx_target,
        &testee_target,
        NULL,
 };
@@ -90,7 +96,7 @@ struct target *all_targets = NULL;
 struct target_event_callback *target_event_callbacks = NULL;
 struct target_timer_callback *target_timer_callbacks = NULL;
 
-const Jim_Nvp nvp_assert[] = {
+static const Jim_Nvp nvp_assert[] = {
        { .name = "assert", NVP_ASSERT },
        { .name = "deassert", NVP_DEASSERT },
        { .name = "T", NVP_ASSERT },
@@ -100,7 +106,7 @@ const Jim_Nvp nvp_assert[] = {
        { .name = NULL, .value = -1 }
 };
 
-const Jim_Nvp nvp_error_target[] = {
+static const Jim_Nvp nvp_error_target[] = {
        { .value = ERROR_TARGET_INVALID, .name = "err-invalid" },
        { .value = ERROR_TARGET_INIT_FAILED, .name = "err-init-failed" },
        { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" },
@@ -178,7 +184,7 @@ static const Jim_Nvp nvp_target_event[] = {
        { .name = NULL, .value = -1 }
 };
 
-const Jim_Nvp nvp_target_state[] = {
+static const Jim_Nvp nvp_target_state[] = {
        { .name = "unknown", .value = TARGET_UNKNOWN },
        { .name = "running", .value = TARGET_RUNNING },
        { .name = "halted",  .value = TARGET_HALTED },
@@ -187,7 +193,7 @@ const Jim_Nvp nvp_target_state[] = {
        { .name = NULL, .value = -1 },
 };
 
-const Jim_Nvp nvp_target_debug_reason [] = {
+static const Jim_Nvp nvp_target_debug_reason [] = {
        { .name = "debug-request"            , .value = DBG_REASON_DBGRQ },
        { .name = "breakpoint"               , .value = DBG_REASON_BREAKPOINT },
        { .name = "watchpoint"               , .value = DBG_REASON_WATCHPOINT },
@@ -198,7 +204,7 @@ const Jim_Nvp nvp_target_debug_reason [] = {
        { .name = NULL, .value = -1 },
 };
 
-const Jim_Nvp nvp_target_endian[] = {
+static const Jim_Nvp nvp_target_endian[] = {
        { .name = "big",    .value = TARGET_BIG_ENDIAN },
        { .name = "little", .value = TARGET_LITTLE_ENDIAN },
        { .name = "be",     .value = TARGET_BIG_ENDIAN },
@@ -206,7 +212,7 @@ const Jim_Nvp nvp_target_endian[] = {
        { .name = NULL,     .value = -1 },
 };
 
-const Jim_Nvp nvp_reset_modes[] = {
+static const Jim_Nvp nvp_reset_modes[] = {
        { .name = "unknown", .value = RESET_UNKNOWN },
        { .name = "run"    , .value = RESET_RUN },
        { .name = "halt"   , .value = RESET_HALT },
@@ -214,6 +220,19 @@ const Jim_Nvp nvp_reset_modes[] = {
        { .name = NULL     , .value = -1 },
 };
 
+const char *debug_reason_name(struct target *t)
+{
+       const char *cp;
+
+       cp = Jim_Nvp_value2name_simple(nvp_target_debug_reason,
+                       t->debug_reason)->name;
+       if (!cp) {
+               LOG_ERROR("Invalid debug reason: %d", (int)(t->debug_reason));
+               cp = "(*BUG*unknown*BUG*)";
+       }
+       return cp;
+}
+
 const char *
 target_state_name( struct target *t )
 {
@@ -406,6 +425,36 @@ int target_halt(struct target *target)
        return ERROR_OK;
 }
 
+/**
+ * Make the target (re)start executing using its saved execution
+ * context (possibly with some modifications).
+ *
+ * @param target Which target should start executing.
+ * @param current True to use the target's saved program counter instead
+ *     of the address parameter
+ * @param address Optionally used as the program counter.
+ * @param handle_breakpoints True iff breakpoints at the resumption PC
+ *     should be skipped.  (For example, maybe execution was stopped by
+ *     such a breakpoint, in which case it would be counterprodutive to
+ *     let it re-trigger.
+ * @param debug_execution False if all working areas allocated by OpenOCD
+ *     should be released and/or restored to their original contents.
+ *     (This would for example be true to run some downloaded "helper"
+ *     algorithm code, which resides in one such working buffer and uses
+ *     another for data storage.)
+ *
+ * @todo Resolve the ambiguity about what the "debug_execution" flag
+ * signifies.  For example, Target implementations don't agree on how
+ * it relates to invalidation of the register cache, or to whether
+ * breakpoints and watchpoints should be enabled.  (It would seem wrong
+ * to enable breakpoints when running downloaded "helper" algorithms
+ * (debug_execution true), since the breakpoints would be set to match
+ * target firmware being debugged, not the helper algorithm.... and
+ * enabling them could cause such helpers to malfunction (for example,
+ * by overwriting data with a breakpoint instruction.  On the other
+ * hand the infrastructure for running such helpers might use this
+ * procedure but rely on hardware breakpoint to detect termination.)
+ */
 int target_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
 {
        int retval;
@@ -417,13 +466,26 @@ int target_resume(struct target *target, int current, uint32_t address, int hand
                return ERROR_FAIL;
        }
 
-       /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
-        * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
-        * the application.
+       /* note that resume *must* be asynchronous. The CPU can halt before
+        * we poll. The CPU can even halt at the current PC as a result of
+        * a software breakpoint being inserted by (a bug?) the application.
         */
        if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK)
                return retval;
 
+       /* Invalidate any cached protect/erase/... flash status, since
+        * almost all targets will now be able modify the flash by
+        * themselves.  We want flash drivers and infrastructure to
+        * be able to rely on (non-invalidated) cached state.
+        *
+        * For now we require that algorithms provided by OpenOCD are
+        * used only by code which properly maintains that  cached state.
+        * state
+        *
+        * REVISIT do the same for NAND ; maybe other flash flavors too...
+        */
+               if (!target->running_alg)
+               nor_resume(target);
        return retval;
 }
 
@@ -459,6 +521,11 @@ int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode
        /* We want any events to be processed before the prompt */
        retval = target_call_timer_callbacks_now();
 
+       struct target *target;
+       for (target = all_targets; target; target = target->next) {
+               target->type->check_reset(target);
+       }
+
        return retval;
 }
 
@@ -481,6 +548,12 @@ static int default_examine(struct target *target)
        return ERROR_OK;
 }
 
+/* no check by default */
+static int default_check_reset(struct target *target)
+{
+       return ERROR_OK;
+}
+
 int target_examine_one(struct target *target)
 {
        return target->type->examine(target);
@@ -561,16 +634,48 @@ static int target_soft_reset_halt_imp(struct target *target)
        return target->type->soft_reset_halt_imp(target);
 }
 
-static int target_run_algorithm_imp(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info)
+/**
+ * Downloads a target-specific native code algorithm to the target,
+ * and executes it.  * Note that some targets may need to set up, enable,
+ * and tear down a breakpoint (hard or * soft) to detect algorithm
+ * termination, while others may support  lower overhead schemes where
+ * soft breakpoints embedded in the algorithm automatically terminate the
+ * algorithm.
+ *
+ * @param target used to run the algorithm
+ * @param arch_info target-specific description of the algorithm.
+ */
+int target_run_algorithm(struct target *target,
+               int num_mem_params, struct mem_param *mem_params,
+               int num_reg_params, struct reg_param *reg_param,
+               uint32_t entry_point, uint32_t exit_point,
+               int timeout_ms, void *arch_info)
 {
+       int retval = ERROR_FAIL;
+
        if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
-               return ERROR_FAIL;
+               goto done;
        }
-       return target->type->run_algorithm_imp(target, num_mem_params, mem_params, num_reg_params, reg_param, entry_point, exit_point, timeout_ms, arch_info);
+       if (target->type->run_algorithm) {
+               LOG_ERROR("Target type '%s' does not support %s",
+                               target_type_name(target), __func__);
+               goto done;
+       }
+
+       target->running_alg = true;
+       retval = target->type->run_algorithm(target,
+                       num_mem_params, mem_params,
+                       num_reg_params, reg_param,
+                       entry_point, exit_point, timeout_ms, arch_info);
+       target->running_alg = false;
+
+done:
+       return retval;
 }
 
+
 int target_read_memory(struct target *target,
                uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
@@ -643,17 +748,6 @@ int target_step(struct target *target,
 }
 
 
-int target_run_algorithm(struct target *target,
-               int num_mem_params, struct mem_param *mem_params,
-               int num_reg_params, struct reg_param *reg_param,
-               uint32_t entry_point, uint32_t exit_point,
-               int timeout_ms, void *arch_info)
-{
-       return target->type->run_algorithm(target,
-                       num_mem_params, mem_params, num_reg_params, reg_param,
-                       entry_point, exit_point, timeout_ms, arch_info);
-}
-
 /**
  * Reset the @c examined flag for the given target.
  * Pure paranoia -- targets are zeroed on allocation.
@@ -681,97 +775,129 @@ err_write_phys_memory(struct target *target, uint32_t address,
 
 static int handle_target(void *priv);
 
-int target_init(struct command_context *cmd_ctx)
+static int target_init_one(struct command_context *cmd_ctx,
+               struct target *target)
 {
-       struct target *target;
-       int retval;
+       target_reset_examined(target);
 
-       for (target = all_targets; target; target = target->next) {
-               struct target_type *type = target->type;
+       struct target_type *type = target->type;
+       if (type->examine == NULL)
+               type->examine = default_examine;
 
-               target_reset_examined(target);
-               if (target->type->examine == NULL)
-               {
-                       target->type->examine = default_examine;
-               }
+       if (type->check_reset== NULL)
+               type->check_reset = default_check_reset;
 
-               if ((retval = target->type->init_target(cmd_ctx, target)) != ERROR_OK)
-               {
-                       LOG_ERROR("target '%s' init failed", target_name(target));
-                       return retval;
-               }
+       int retval = type->init_target(cmd_ctx, target);
+       if (ERROR_OK != retval)
+       {
+               LOG_ERROR("target '%s' init failed", target_name(target));
+               return retval;
+       }
 
+       /**
+        * @todo get rid of those *memory_imp() methods, now that all
+        * callers are using target_*_memory() accessors ... and make
+        * sure the "physical" paths handle the same issues.
+        */
+       /* a non-invasive way(in terms of patches) to add some code that
+        * runs before the type->write/read_memory implementation
+        */
+       type->write_memory_imp = target->type->write_memory;
+       type->write_memory = target_write_memory_imp;
 
-               /**
-                * @todo get rid of those *memory_imp() methods, now that all
-                * callers are using target_*_memory() accessors ... and make
-                * sure the "physical" paths handle the same issues.
-                */
+       type->read_memory_imp = target->type->read_memory;
+       type->read_memory = target_read_memory_imp;
 
-               /* a non-invasive way(in terms of patches) to add some code that
-                * runs before the type->write/read_memory implementation
-                */
-               target->type->write_memory_imp = target->type->write_memory;
-               target->type->write_memory = target_write_memory_imp;
-               target->type->read_memory_imp = target->type->read_memory;
-               target->type->read_memory = target_read_memory_imp;
-               target->type->soft_reset_halt_imp = target->type->soft_reset_halt;
-               target->type->soft_reset_halt = target_soft_reset_halt_imp;
-               target->type->run_algorithm_imp = target->type->run_algorithm;
-               target->type->run_algorithm = target_run_algorithm_imp;
-
-               /* Sanity-check MMU support ... stub in what we must, to help
-                * implement it in stages, but warn if we need to do so.
-                */
-               if (type->mmu) {
-                       if (type->write_phys_memory == NULL) {
-                               LOG_ERROR("type '%s' is missing %s",
-                                               type->name,
-                                               "write_phys_memory");
-                               type->write_phys_memory = err_write_phys_memory;
-                       }
-                       if (type->read_phys_memory == NULL) {
-                               LOG_ERROR("type '%s' is missing %s",
-                                               type->name,
-                                               "read_phys_memory");
-                               type->read_phys_memory = err_read_phys_memory;
-                       }
-                       if (type->virt2phys == NULL) {
-                               LOG_ERROR("type '%s' is missing %s",
-                                               type->name,
-                                               "virt2phys");
-                               type->virt2phys = identity_virt2phys;
-                       }
+       type->soft_reset_halt_imp = target->type->soft_reset_halt;
+       type->soft_reset_halt = target_soft_reset_halt_imp;
 
+       /* Sanity-check MMU support ... stub in what we must, to help
+        * implement it in stages, but warn if we need to do so.
+        */
+       if (type->mmu)
+       {
+               if (type->write_phys_memory == NULL)
+               {
+                       LOG_ERROR("type '%s' is missing write_phys_memory",
+                                       type->name);
+                       type->write_phys_memory = err_write_phys_memory;
+               }
+               if (type->read_phys_memory == NULL)
+               {
+                       LOG_ERROR("type '%s' is missing read_phys_memory",
+                                       type->name);
+                       type->read_phys_memory = err_read_phys_memory;
+               }
+               if (type->virt2phys == NULL)
+               {
+                       LOG_ERROR("type '%s' is missing virt2phys", type->name);
+                       type->virt2phys = identity_virt2phys;
+               }
+       }
+       else
+       {
                /* Make sure no-MMU targets all behave the same:  make no
                 * distinction between physical and virtual addresses, and
                 * ensure that virt2phys() is always an identity mapping.
                 */
-               } else {
-                       if (type->write_phys_memory
-                                       || type->read_phys_memory
-                                       || type->virt2phys)
-                               LOG_WARNING("type '%s' has broken MMU hooks",
-                                               type->name);
-
-                       type->mmu = no_mmu;
-                       type->write_phys_memory = type->write_memory;
-                       type->read_phys_memory = type->read_memory;
-                       type->virt2phys = identity_virt2phys;
+               if (type->write_phys_memory || type->read_phys_memory
+                               || type->virt2phys)
+               {
+                       LOG_WARNING("type '%s' has bad MMU hooks", type->name);
                }
+
+               type->mmu = no_mmu;
+               type->write_phys_memory = type->write_memory;
+               type->read_phys_memory = type->read_memory;
+               type->virt2phys = identity_virt2phys;
        }
+       return ERROR_OK;
+}
+
+int target_init(struct command_context *cmd_ctx)
+{
+       struct target *target;
+       int retval;
 
-       if (all_targets)
+       for (target = all_targets; target; target = target->next)
        {
-               if ((retval = target_register_user_commands(cmd_ctx)) != ERROR_OK)
-                       return retval;
-               if ((retval = target_register_timer_callback(&handle_target, 100, 1, cmd_ctx->interp)) != ERROR_OK)
+               retval = target_init_one(cmd_ctx, target);
+               if (ERROR_OK != retval)
                        return retval;
        }
 
+       if (!all_targets)
+               return ERROR_OK;
+
+       retval = target_register_user_commands(cmd_ctx);
+       if (ERROR_OK != retval)
+               return retval;
+
+       retval = target_register_timer_callback(&handle_target,
+                       100, 1, cmd_ctx->interp);
+       if (ERROR_OK != retval)
+               return retval;
+
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_target_init_command)
+{
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       static bool target_initialized = false;
+       if (target_initialized)
+       {
+               LOG_INFO("'target init' has already been called");
+               return ERROR_OK;
+       }
+       target_initialized = true;
+
+       LOG_DEBUG("Initializing targets...");
+       return target_init(CMD_CTX);
+}
+
 int target_register_event_callback(int (*callback)(struct target *target, enum target_event event, void *priv), void *priv)
 {
        struct target_event_callback **callbacks_p = &target_event_callbacks;
@@ -1675,21 +1801,18 @@ static int sense_handler(void)
        return ERROR_OK;
 }
 
-static void target_call_event_callbacks_all(enum target_event e) {
-       struct target *target;
-       target = all_targets;
-       while (target) {
-               target_call_event_callbacks(target, e);
-               target = target->next;
-       }
-}
-
 /* process target state changes */
 static int handle_target(void *priv)
 {
        Jim_Interp *interp = (Jim_Interp *)priv;
        int retval = ERROR_OK;
 
+       if (!is_jtag_poll_safe())
+       {
+               /* polling is disabled currently */
+               return ERROR_OK;
+       }
+
        /* we do not want to recurse here... */
        static int recursive = 0;
        if (! recursive)
@@ -1703,7 +1826,7 @@ static int handle_target(void *priv)
                int did_something = 0;
                if (runSrstAsserted)
                {
-                       target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
+                       LOG_INFO("srst asserted detected, running srst_asserted proc.");
                        Jim_Eval(interp, "srst_asserted");
                        did_something = 1;
                }
@@ -1714,7 +1837,7 @@ static int handle_target(void *priv)
                }
                if (runPowerDropout)
                {
-                       target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
+                       LOG_INFO("Power dropout detected, running power_dropout proc.");
                        Jim_Eval(interp, "power_dropout");
                        did_something = 1;
                }
@@ -1756,6 +1879,14 @@ static int handle_target(void *priv)
                        /* polling may fail silently until the target has been examined */
                        if ((retval = target_poll(target)) != ERROR_OK)
                        {
+                               /* FIX!!!!! If we add a LOG_INFO() here to output a line in GDB
+                                * *why* we are aborting GDB, then we'll spam telnet when the
+                                * poll is failing persistently.
+                                *
+                                * If we could implement an event that detected the
+                                * target going from non-pollable to pollable, we could issue
+                                * an error only upon the transition.
+                                */
                                target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
                                return retval;
                        }
@@ -2106,11 +2237,12 @@ static void handle_md_output(struct command_context *cmd_ctx,
        const char *value_fmt;
        switch (size) {
        case 4: value_fmt = "%8.8x "; break;
-       case 2: value_fmt = "%4.2x "; break;
+       case 2: value_fmt = "%4.4x "; break;
        case 1: value_fmt = "%2.2x "; break;
        default:
+               /* "can't happen", caller checked */
                LOG_ERROR("invalid memory read size: %u", size);
-               exit(-1);
+               return;
        }
 
        for (unsigned i = 0; i < count; i++)
@@ -2191,6 +2323,76 @@ COMMAND_HANDLER(handle_md_command)
        return retval;
 }
 
+typedef int (*target_write_fn)(struct target *target,
+               uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+
+static int target_write_memory_fast(struct target *target,
+               uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+{
+       return target_write_buffer(target, address, size * count, buffer);
+}
+
+static int target_fill_mem(struct target *target,
+               uint32_t address,
+               target_write_fn fn,
+               unsigned data_size,
+               /* value */
+               uint32_t b,
+               /* count */
+               unsigned c)
+{
+       /* We have to write in reasonably large chunks to be able
+        * to fill large memory areas with any sane speed */
+       const unsigned chunk_size = 16384;
+       uint8_t *target_buf = malloc(chunk_size * data_size);
+       if (target_buf == NULL)
+       {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
+       for (unsigned i = 0; i < chunk_size; i ++)
+       {
+               switch (data_size)
+               {
+               case 4:
+                       target_buffer_set_u32(target, target_buf + i*data_size, b);
+                       break;
+               case 2:
+                       target_buffer_set_u16(target, target_buf + i*data_size, b);
+                       break;
+               case 1:
+                       target_buffer_set_u8(target, target_buf + i*data_size, b);
+                       break;
+               default:
+                       exit(-1);
+               }
+       }
+
+       int retval = ERROR_OK;
+
+       for (unsigned x = 0; x < c; x += chunk_size)
+       {
+               unsigned current;
+               current = c - x;
+               if (current > chunk_size)
+               {
+                       current = chunk_size;
+               }
+               int retval = fn(target, address + x * data_size, data_size, current, target_buf);
+               if (retval != ERROR_OK)
+               {
+                       break;
+               }
+               /* avoid GDB timeouts */
+               keep_alive();
+       }
+       free(target_buf);
+
+       return retval;
+}
+
+
 COMMAND_HANDLER(handle_mw_command)
 {
        if (CMD_ARGC < 2)
@@ -2198,8 +2400,7 @@ COMMAND_HANDLER(handle_mw_command)
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
        bool physical=strcmp(CMD_ARGV[0], "phys")==0;
-       int (*fn)(struct target *target,
-                       uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+       target_write_fn fn;
        if (physical)
        {
                CMD_ARGC--;
@@ -2207,7 +2408,7 @@ COMMAND_HANDLER(handle_mw_command)
                fn=target_write_phys_memory;
        } else
        {
-               fn=target_write_memory;
+               fn = target_write_memory_fast;
        }
        if ((CMD_ARGC < 2) || (CMD_ARGC > 3))
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -2224,35 +2425,22 @@ COMMAND_HANDLER(handle_mw_command)
 
        struct target *target = get_current_target(CMD_CTX);
        unsigned wordsize;
-       uint8_t value_buf[4];
        switch (CMD_NAME[2])
        {
                case 'w':
                        wordsize = 4;
-                       target_buffer_set_u32(target, value_buf, value);
                        break;
                case 'h':
                        wordsize = 2;
-                       target_buffer_set_u16(target, value_buf, value);
                        break;
                case 'b':
                        wordsize = 1;
-                       value_buf[0] = value;
                        break;
                default:
                        return ERROR_COMMAND_SYNTAX_ERROR;
        }
-       for (unsigned i = 0; i < count; i++)
-       {
-               int retval = fn(target,
-                               address + i * wordsize, wordsize, 1, value_buf);
-               if (ERROR_OK != retval)
-                       return retval;
-               keep_alive();
-       }
-
-       return ERROR_OK;
 
+       return target_fill_mem(target, address, fn, wordsize, value, count);
 }
 
 static COMMAND_HELPER(parse_load_image_command_CMD_ARGV, struct image *image,
@@ -2439,7 +2627,7 @@ COMMAND_HANDLER(handle_dump_image_command)
        if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
        {
                command_print(CMD_CTX,
-                               "dumped %zu bytes in %fs (%0.3f kb/s)", fileio.size,
+                               "dumped %ld bytes in %fs (%0.3f kb/s)", (long)fileio.size,
                                duration_elapsed(&bench), duration_kbps(&bench, fileio.size));
        }
 
@@ -2911,7 +3099,8 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
        fclose(f);
 }
 
-/* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
+/* profiling samples the CPU PC as quickly as OpenOCD is able,
+ * which will be used as a random sampling of PC */
 COMMAND_HANDLER(handle_profile_command)
 {
        struct target *target = get_current_target(CMD_CTX);
@@ -2927,6 +3116,12 @@ COMMAND_HANDLER(handle_profile_command)
 
        timeval_add_time(&timeout, offset, 0);
 
+       /**
+        * @todo: Some cores let us sample the PC without the
+        * annoying halt/resume step; for example, ARMv7 PCSR.
+        * Provide a way to use that more efficient mechanism.
+        */
+
        command_print(CMD_CTX, "Starting profiling. Halting and resuming the target as often as we can...");
 
        static const int maxSample = 10000;
@@ -3238,7 +3433,9 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 
        return target_array2mem(interp,target, argc-1, argv + 1);
 }
-static int target_array2mem(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv)
+
+static int target_array2mem(Jim_Interp *interp, struct target *target,
+               int argc, Jim_Obj *const *argv)
 {
        long l;
        uint32_t width;
@@ -3740,11 +3937,13 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
        return JIM_OK;
 }
 
-static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int
+jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
        Jim_GetOptInfo goi;
+
        Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-       goi.isconfigure = strcmp(Jim_GetString(argv[0], NULL), "configure") == 0;
+       goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
        int need_args = 1 + goi.isconfigure;
        if (goi.argc < need_args)
        {
@@ -3765,13 +3964,17 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        Jim_GetOptInfo goi;
        Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
 
-       if (goi.argc != 2 && goi.argc != 3)
+       /* danger! goi.argc will be modified below! */
+       argc = goi.argc;
+
+       if (argc != 2 && argc != 3)
        {
                Jim_SetResult_sprintf(goi.interp,
                                "usage: %s <address> <data> [<count>]", cmd_name);
                return JIM_ERR;
        }
 
+
        jim_wide a;
        int e = Jim_GetOpt_Wide(&goi, &a);
        if (e != JIM_OK)
@@ -3783,7 +3986,7 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                return e;
 
        jim_wide c = 1;
-       if (goi.argc == 3)
+       if (argc == 3)
        {
                e = Jim_GetOpt_Wide(&goi, &c);
                if (e != JIM_OK)
@@ -3791,36 +3994,21 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        }
 
        struct target *target = Jim_CmdPrivData(goi.interp);
-       uint8_t  target_buf[32];
+       unsigned data_size;
        if (strcasecmp(cmd_name, "mww") == 0) {
-               target_buffer_set_u32(target, target_buf, b);
-               b = 4;
+               data_size = 4;
        }
        else if (strcasecmp(cmd_name, "mwh") == 0) {
-               target_buffer_set_u16(target, target_buf, b);
-               b = 2;
+               data_size = 2;
        }
        else if (strcasecmp(cmd_name, "mwb") == 0) {
-               target_buffer_set_u8(target, target_buf, b);
-               b = 1;
+               data_size = 1;
        } else {
                LOG_ERROR("command '%s' unknown: ", cmd_name);
                return JIM_ERR;
        }
 
-       for (jim_wide x = 0; x < c; x++)
-       {
-               e = target_write_memory(target, a, b, 1, target_buf);
-               if (e != ERROR_OK)
-               {
-                       Jim_SetResult_sprintf(interp,
-                                       "Error writing @ 0x%08x: %d\n", (int)(a), e);
-                       return JIM_ERR;
-               }
-               /* b = width */
-               a = a + b;
-       }
-       return JIM_OK;
+       return (target_fill_mem(target, a, target_write_memory_fast, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR;
 }
 
 static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -3830,7 +4018,10 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        Jim_GetOptInfo goi;
        Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
 
-       if ((goi.argc == 2) || (goi.argc == 3))
+       /* danger! goi.argc will be modified below! */
+       argc = goi.argc;
+
+       if ((argc != 1) && (argc != 2))
        {
                Jim_SetResult_sprintf(goi.interp,
                                "usage: %s <address> [<count>]", cmd_name);
@@ -3843,7 +4034,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                return JIM_ERR;
        }
        jim_wide c;
-       if (goi.argc) {
+       if (argc == 2) {
                e = Jim_GetOpt_Wide(&goi, &c);
                if (e != JIM_OK) {
                        return JIM_ERR;
@@ -3885,7 +4076,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                case 4:
                        for (x = 0; x < 16 && x < y; x += 4)
                        {
-                               z = target_buffer_get_u32(target, &(target_buf[ x * 4 ]));
+                               z = target_buffer_get_u32(target, &(target_buf[ x ]));
                                Jim_fprintf(interp, interp->cookie_stdout, "%08x ", (int)(z));
                        }
                        for (; (x < 16) ; x += 4) {
@@ -3895,7 +4086,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                case 2:
                        for (x = 0; x < 16 && x < y; x += 2)
                        {
-                               z = target_buffer_get_u16(target, &(target_buf[ x * 2 ]));
+                               z = target_buffer_get_u16(target, &(target_buf[ x ]));
                                Jim_fprintf(interp, interp->cookie_stdout, "%04x ", (int)(z));
                        }
                        for (; (x < 16) ; x += 2) {
@@ -3905,7 +4096,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                case 1:
                default:
                        for (x = 0 ; (x < 16) && (x < y) ; x += 1) {
-                               z = target_buffer_get_u8(target, &(target_buf[ x * 4 ]));
+                               z = target_buffer_get_u8(target, &(target_buf[ x ]));
                                Jim_fprintf(interp, interp->cookie_stdout, "%02x ", (int)(z));
                        }
                        for (; (x < 16) ; x += 1) {
@@ -3939,13 +4130,15 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        return JIM_OK;
 }
 
-static int jim_target_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_target_mem2array(Jim_Interp *interp,
+               int argc, Jim_Obj *const *argv)
 {
        struct target *target = Jim_CmdPrivData(interp);
        return target_mem2array(interp, target, argc - 1, argv + 1);
 }
 
-static int jim_target_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_target_array2mem(Jim_Interp *interp,
+               int argc, Jim_Obj *const *argv)
 {
        struct target *target = Jim_CmdPrivData(interp);
        return target_array2mem(interp, target, argc - 1, argv + 1);
@@ -3977,6 +4170,21 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv
        return JIM_OK;
 }
 
+static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       if (argc != 1)
+       {
+               Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
+               return JIM_ERR;
+       }
+       struct target *target = Jim_CmdPrivData(interp);
+
+       if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK)
+               return JIM_ERR;
+
+       return JIM_OK;
+}
+
 static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
        if (argc != 1)
@@ -4030,6 +4238,11 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        struct target *target = Jim_CmdPrivData(goi.interp);
        if (!target->tap->enabled)
                return jim_target_tap_disabled(interp);
+       if (!(target_was_examined(target)))
+       {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_TARGET_NOT_EXAMINED;
+       }
        if (!target->type->assert_reset || !target->type->deassert_reset)
        {
                Jim_SetResult_sprintf(interp,
@@ -4165,108 +4378,129 @@ static const struct command_registration target_instance_command_handlers[] = {
        {
                .name = "configure",
                .mode = COMMAND_CONFIG,
-               .jim_handler = &jim_target_configure,
-               .usage = "[<target_options> ...]",
+               .jim_handler = jim_target_configure,
                .help  = "configure a new target for use",
+               .usage = "[target_attribute ...]",
        },
        {
                .name = "cget",
                .mode = COMMAND_ANY,
-               .jim_handler = &jim_target_configure,
-               .usage = "<target_type> [<target_options> ...]",
-               .help  = "configure a new target for use",
+               .jim_handler = jim_target_configure,
+               .help  = "returns the specified target attribute",
+               .usage = "target_attribute",
        },
        {
                .name = "mww",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_mw,
-               .usage = "<address> <data> [<count>]",
+               .jim_handler = jim_target_mw,
                .help = "Write 32-bit word(s) to target memory",
+               .usage = "address data [count]",
        },
        {
                .name = "mwh",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_mw,
-               .usage = "<address> <data> [<count>]",
+               .jim_handler = jim_target_mw,
                .help = "Write 16-bit half-word(s) to target memory",
+               .usage = "address data [count]",
        },
        {
                .name = "mwb",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_mw,
-               .usage = "<address> <data> [<count>]",
+               .jim_handler = jim_target_mw,
                .help = "Write byte(s) to target memory",
+               .usage = "address data [count]",
        },
        {
                .name = "mdw",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_md,
-               .usage = "<address> [<count>]",
+               .jim_handler = jim_target_md,
                .help = "Display target memory as 32-bit words",
+               .usage = "address [count]",
        },
        {
                .name = "mdh",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_md,
-               .usage = "<address> [<count>]",
+               .jim_handler = jim_target_md,
                .help = "Display target memory as 16-bit half-words",
+               .usage = "address [count]",
        },
        {
                .name = "mdb",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_md,
-               .usage = "<address> [<count>]",
+               .jim_handler = jim_target_md,
                .help = "Display target memory as 8-bit bytes",
+               .usage = "address [count]",
        },
        {
                .name = "array2mem",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_array2mem,
+               .jim_handler = jim_target_array2mem,
+               .help = "Writes Tcl array of 8/16/32 bit numbers "
+                       "to target memory",
+               .usage = "arrayname bitwidth address count",
        },
        {
                .name = "mem2array",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_mem2array,
+               .jim_handler = jim_target_mem2array,
+               .help = "Loads Tcl array of 8/16/32 bit numbers "
+                       "from target memory",
+               .usage = "arrayname bitwidth address count",
        },
        {
                .name = "eventlist",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_event_list,
+               .jim_handler = jim_target_event_list,
+               .help = "displays a table of events defined for this target",
        },
        {
                .name = "curstate",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_current_state,
+               .jim_handler = jim_target_current_state,
+               .help = "displays the current state of this target",
        },
        {
                .name = "arp_examine",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_examine,
+               .jim_handler = jim_target_examine,
+               .help = "used internally for reset processing",
+       },
+       {
+               .name = "arp_halt_gdb",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_target_halt_gdb,
+               .help = "used internally for reset processing to halt GDB",
        },
        {
                .name = "arp_poll",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_poll,
+               .jim_handler = jim_target_poll,
+               .help = "used internally for reset processing",
        },
        {
                .name = "arp_reset",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_reset,
+               .jim_handler = jim_target_reset,
+               .help = "used internally for reset processing",
        },
        {
                .name = "arp_halt",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_halt,
+               .jim_handler = jim_target_halt,
+               .help = "used internally for reset processing",
        },
        {
                .name = "arp_waitstate",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_wait_state,
+               .jim_handler = jim_target_wait_state,
+               .help = "used internally for reset processing",
        },
        {
                .name = "invoke-event",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_target_invoke_event,
+               .jim_handler = jim_target_invoke_event,
+               .help = "invoke handler for specified event",
+               .usage = "event_name",
        },
        COMMAND_REGISTRATION_DONE
 };
@@ -4418,7 +4652,7 @@ static int target_create(Jim_GetOptInfo *goi)
                }
                *tpp = target;
        }
-       
+
        /* now - create the new target name command */
        const const struct command_registration target_subcommands[] = {
                {
@@ -4558,48 +4792,57 @@ static int jim_target_count(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 }
 
 static const struct command_registration target_subcommand_handlers[] = {
+       {
+               .name = "init",
+               .mode = COMMAND_CONFIG,
+               .handler = handle_target_init_command,
+               .help = "initialize targets",
+       },
        {
                .name = "create",
+               /* REVISIT this should be COMMAND_CONFIG ... */
                .mode = COMMAND_ANY,
-               .jim_handler = &jim_target_create,
-               .usage = "<name> <type> ...",
-               .help = "Returns the currently selected target",
+               .jim_handler = jim_target_create,
+               .usage = "name type '-chain-position' name [options ...]",
+               .help = "Creates and selects a new target",
        },
        {
                .name = "current",
                .mode = COMMAND_ANY,
-               .jim_handler = &jim_target_current,
+               .jim_handler = jim_target_current,
                .help = "Returns the currently selected target",
        },
        {
                .name = "types",
                .mode = COMMAND_ANY,
-               .jim_handler = &jim_target_types,
-               .help = "Returns the available target types as a list of strings",
+               .jim_handler = jim_target_types,
+               .help = "Returns the available target types as "
+                               "a list of strings",
        },
        {
                .name = "names",
                .mode = COMMAND_ANY,
-               .jim_handler = &jim_target_names,
+               .jim_handler = jim_target_names,
                .help = "Returns the names of all targets as a list of strings",
        },
        {
                .name = "number",
                .mode = COMMAND_ANY,
-               .jim_handler = &jim_target_number,
-               .usage = "<number>",
-               .help = "Returns the name of target <n>",
+               .jim_handler = jim_target_number,
+               .usage = "number",
+               .help = "Returns the name of the numbered target "
+                       "(DEPRECATED)",
        },
        {
                .name = "count",
                .mode = COMMAND_ANY,
-               .jim_handler = &jim_target_count,
-               .help = "Returns the number of targets as an integer",
+               .jim_handler = jim_target_count,
+               .help = "Returns the number of targets as an integer "
+                       "(DEPRECATED)",
        },
        COMMAND_REGISTRATION_DONE
 };
 
-
 struct FastLoad
 {
        uint32_t address;
@@ -4773,11 +5016,11 @@ COMMAND_HANDLER(handle_fast_load_command)
 static const struct command_registration target_command_handlers[] = {
        {
                .name = "targets",
-               .handler = &handle_targets_command,
+               .handler = handle_targets_command,
                .mode = COMMAND_ANY,
-               .help = "change current command line target (one parameter) "
-                       "or list targets (no parameters)",
-               .usage = "[<new_current_target>]",
+               .help = "change current default target (one parameter) "
+                       "or prints table of all targets (no parameters)",
+               .usage = "[target]",
        },
        {
                .name = "target",
@@ -4794,72 +5037,92 @@ int target_register_commands(struct command_context *cmd_ctx)
        return register_commands(cmd_ctx, NULL, target_command_handlers);
 }
 
+static bool target_reset_nag = true;
+
+bool get_target_reset_nag(void)
+{
+       return target_reset_nag;
+}
+
+COMMAND_HANDLER(handle_target_reset_nag)
+{
+       return CALL_COMMAND_HANDLER(handle_command_parse_bool,
+                       &target_reset_nag, "Nag after each reset about options to improve "
+                       "performance");
+}
+
 static const struct command_registration target_exec_command_handlers[] = {
        {
                .name = "fast_load_image",
-               .handler = &handle_fast_load_image_command,
+               .handler = handle_fast_load_image_command,
                .mode = COMMAND_ANY,
-               .help = "Load image into memory, mainly for profiling purposes",
-               .usage = "<file> <address> ['bin'|'ihex'|'elf'|'s19'] "
-                       "[min_address] [max_length]",
+               .help = "Load image into server memory for later use by "
+                       "fast_load; primarily for profiling",
+               .usage = "filename address ['bin'|'ihex'|'elf'|'s19'] "
+                       "[min_address [max_length]]",
        },
        {
                .name = "fast_load",
-               .handler = &handle_fast_load_command,
-               .mode = COMMAND_ANY,
+               .handler = handle_fast_load_command,
+               .mode = COMMAND_EXEC,
                .help = "loads active fast load image to current target "
                        "- mainly for profiling purposes",
        },
        {
                .name = "profile",
-               .handler = &handle_profile_command,
+               .handler = handle_profile_command,
                .mode = COMMAND_EXEC,
                .help = "profiling samples the CPU PC",
        },
        /** @todo don't register virt2phys() unless target supports it */
        {
                .name = "virt2phys",
-               .handler = &handle_virt2phys_command,
+               .handler = handle_virt2phys_command,
                .mode = COMMAND_ANY,
                .help = "translate a virtual address into a physical address",
+               .usage = "virtual_address",
        },
-
        {
                .name = "reg",
-               .handler = &handle_reg_command,
+               .handler = handle_reg_command,
                .mode = COMMAND_EXEC,
-               .help = "display or set a register",
+               .help = "display or set a register; with no arguments, "
+                       "displays all registers and their values",
+               .usage = "[(register_name|register_number) [value]]",
        },
-
        {
                .name = "poll",
-               .handler = &handle_poll_command,
+               .handler = handle_poll_command,
                .mode = COMMAND_EXEC,
-               .help = "poll target state",
+               .help = "poll target state; or reconfigure background polling",
+               .usage = "['on'|'off']",
        },
        {
                .name = "wait_halt",
-               .handler = &handle_wait_halt_command,
+               .handler = handle_wait_halt_command,
                .mode = COMMAND_EXEC,
-               .help = "wait for target halt",
-               .usage = "[time (s)]",
+               .help = "wait up to the specified number of milliseconds "
+                       "(default 5) for a previously requested halt",
+               .usage = "[milliseconds]",
        },
        {
                .name = "halt",
-               .handler = &handle_halt_command,
+               .handler = handle_halt_command,
                .mode = COMMAND_EXEC,
-               .help = "halt target",
+               .help = "request target to halt, then wait up to the specified"
+                       "number of milliseconds (default 5) for it to complete",
+               .usage = "[milliseconds]",
        },
        {
                .name = "resume",
-               .handler = &handle_resume_command,
+               .handler = handle_resume_command,
                .mode = COMMAND_EXEC,
-               .help = "resume target",
-               .usage = "[<address>]",
+               .help = "resume target execution from current PC or address",
+               .usage = "[address]",
        },
        {
                .name = "reset",
-               .handler = &handle_reset_command,
+               .handler = handle_reset_command,
                .mode = COMMAND_EXEC,
                .usage = "[run|halt|init]",
                .help = "Reset all targets into the specified mode."
@@ -4867,133 +5130,135 @@ static const struct command_registration target_exec_command_handlers[] = {
        },
        {
                .name = "soft_reset_halt",
-               .handler = &handle_soft_reset_halt_command,
+               .handler = handle_soft_reset_halt_command,
                .mode = COMMAND_EXEC,
                .help = "halt the target and do a soft reset",
        },
        {
-
                .name = "step",
-               .handler = &handle_step_command,
+               .handler = handle_step_command,
                .mode = COMMAND_EXEC,
-               .help = "step one instruction from current PC or [addr]",
-               .usage = "[<address>]",
+               .help = "step one instruction from current PC or address",
+               .usage = "[address]",
        },
        {
-
                .name = "mdw",
-               .handler = &handle_md_command,
+               .handler = handle_md_command,
                .mode = COMMAND_EXEC,
                .help = "display memory words",
-               .usage = "[phys] <addr> [count]",
+               .usage = "['phys'] address [count]",
        },
        {
                .name = "mdh",
-               .handler = &handle_md_command,
+               .handler = handle_md_command,
                .mode = COMMAND_EXEC,
                .help = "display memory half-words",
-               .usage = "[phys] <addr> [count]",
+               .usage = "['phys'] address [count]",
        },
        {
                .name = "mdb",
-               .handler = &handle_md_command,
+               .handler = handle_md_command,
                .mode = COMMAND_EXEC,
                .help = "display memory bytes",
-               .usage = "[phys] <addr> [count]",
+               .usage = "['phys'] address [count]",
        },
        {
-
                .name = "mww",
-               .handler = &handle_mw_command,
+               .handler = handle_mw_command,
                .mode = COMMAND_EXEC,
                .help = "write memory word",
-               .usage = "[phys]  <addr> <value> [count]",
+               .usage = "['phys'] address value [count]",
        },
        {
                .name = "mwh",
-               .handler = &handle_mw_command,
+               .handler = handle_mw_command,
                .mode = COMMAND_EXEC,
                .help = "write memory half-word",
-               .usage = "[phys] <addr> <value> [count]",
+               .usage = "['phys'] address value [count]",
        },
        {
                .name = "mwb",
-               .handler = &handle_mw_command,
+               .handler = handle_mw_command,
                .mode = COMMAND_EXEC,
                .help = "write memory byte",
-               .usage = "[phys] <addr> <value> [count]",
+               .usage = "['phys'] address value [count]",
        },
        {
-
                .name = "bp",
-               .handler = &handle_bp_command,
+               .handler = handle_bp_command,
                .mode = COMMAND_EXEC,
-               .help = "list or set breakpoint",
-               .usage = "[<address> <length> [hw]]",
+               .help = "list or set hardware or software breakpoint",
+               .usage = "[address length ['hw']]",
        },
        {
                .name = "rbp",
-               .handler = &handle_rbp_command,
+               .handler = handle_rbp_command,
                .mode = COMMAND_EXEC,
                .help = "remove breakpoint",
-               .usage = "<address>",
+               .usage = "address",
        },
        {
-
                .name = "wp",
-               .handler = &handle_wp_command,
+               .handler = handle_wp_command,
                .mode = COMMAND_EXEC,
-               .help = "list or set watchpoint",
-               .usage = "[<address> <length> <r/w/a> [value] [mask]]",
+               .help = "list (no params) or create watchpoints",
+               .usage = "[address length [('r'|'w'|'a') value [mask]]]",
        },
        {
                .name = "rwp",
-               .handler = &handle_rwp_command,
+               .handler = handle_rwp_command,
                .mode = COMMAND_EXEC,
                .help = "remove watchpoint",
-               .usage = "<address>",
-
+               .usage = "address",
        },
        {
                .name = "load_image",
-               .handler = &handle_load_image_command,
+               .handler = handle_load_image_command,
                .mode = COMMAND_EXEC,
-               .usage = "<file> <address> ['bin'|'ihex'|'elf'|'s19'] "
+               .usage = "filename address ['bin'|'ihex'|'elf'|'s19'] "
                        "[min_address] [max_length]",
        },
        {
                .name = "dump_image",
-               .handler = &handle_dump_image_command,
+               .handler = handle_dump_image_command,
                .mode = COMMAND_EXEC,
-               .usage = "<file> <address> <size>",
+               .usage = "filename address size",
        },
        {
                .name = "verify_image",
-               .handler = &handle_verify_image_command,
+               .handler = handle_verify_image_command,
                .mode = COMMAND_EXEC,
-               .usage = "<file> [offset] [type]",
+               .usage = "filename [offset [type]]",
        },
        {
                .name = "test_image",
-               .handler = &handle_test_image_command,
+               .handler = handle_test_image_command,
                .mode = COMMAND_EXEC,
-               .usage = "<file> [offset] [type]",
+               .usage = "filename [offset [type]]",
        },
        {
                .name = "ocd_mem2array",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_mem2array,
-               .help = "read memory and return as a TCL array "
+               .jim_handler = jim_mem2array,
+               .help = "read 8/16/32 bit memory and return as a TCL array "
                        "for script processing",
-               .usage = "<arrayname> <width=32|16|8> <address> <count>",
+               .usage = "arrayname bitwidth address count",
        },
        {
                .name = "ocd_array2mem",
                .mode = COMMAND_EXEC,
-               .jim_handler = &jim_array2mem,
+               .jim_handler = jim_array2mem,
                .help = "convert a TCL array to memory locations "
-                       "and write the values",
-               .usage = "<arrayname> <width=32|16|8> <address> <count>",
+                       "and write the 8/16/32 bit values",
+               .usage = "arrayname bitwidth address count",
+       },
+       {
+               .name = "reset_nag",
+               .handler = handle_target_reset_nag,
+               .mode = COMMAND_ANY,
+               .help = "Nag after each reset about options that could have been "
+                               "enabled to improve performance. ",
+               .usage = "['enable'|'disable']",
        },
        COMMAND_REGISTRATION_DONE
 };