jim tests: use installed
[openocd.git] / src / target / target.c
index 9a605f3dca81401c9f445425a47d3867d19bdb04..d200ebc98427b2a3a71c0ed466ab9453eca9b1f6 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);
+static int target_register_user_commands(struct command_context *cmd_ctx);
 
 /* targets */
 extern struct target_type arm7tdmi_target;
@@ -63,9 +68,11 @@ 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;
+extern struct target_type avr32_ap7k_target;
 
-struct target_type *target_types[] =
+static struct target_type *target_types[] =
 {
        &arm7tdmi_target,
        &arm9tdmi_target,
@@ -82,15 +89,18 @@ struct target_type *target_types[] =
        &arm11_target,
        &mips_m4k_target,
        &avr_target,
+       &dsp563xx_target,
        &testee_target,
+       &avr32_ap7k_target,
        NULL,
 };
 
 struct target *all_targets = NULL;
-struct target_event_callback *target_event_callbacks = NULL;
-struct target_timer_callback *target_timer_callbacks = NULL;
+static struct target_event_callback *target_event_callbacks = NULL;
+static struct target_timer_callback *target_timer_callbacks = NULL;
+static const int polling_interval = 100;
 
-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 +110,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" },
@@ -115,7 +125,7 @@ const Jim_Nvp nvp_error_target[] = {
        { .value = -1, .name = NULL }
 };
 
-const char *target_strerror_safe(int err)
+static const char *target_strerror_safe(int err)
 {
        const Jim_Nvp *n;
 
@@ -178,7 +188,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 +197,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 +208,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 +216,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 +224,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 )
 {
@@ -263,7 +286,7 @@ uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)
 }
 
 /* read a uint8_t from a buffer in target memory endianness */
-uint8_t target_buffer_get_u8(struct target *target, const uint8_t *buffer)
+static uint8_t target_buffer_get_u8(struct target *target, const uint8_t *buffer)
 {
        return *buffer & 0x0ff;
 }
@@ -287,7 +310,7 @@ void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t valu
 }
 
 /* write a uint8_t to a buffer in target memory endianness */
-void target_buffer_set_u8(struct target *target, uint8_t *buffer, uint8_t value)
+static void target_buffer_set_u8(struct target *target, uint8_t *buffer, uint8_t value)
 {
        *buffer = value;
 }
@@ -406,6 +429,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,9 +470,9 @@ 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;
@@ -427,7 +480,7 @@ int target_resume(struct target *target, int current, uint32_t address, int hand
        return retval;
 }
 
-int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode reset_mode)
+static int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode reset_mode)
 {
        char buf[100];
        int retval;
@@ -452,13 +505,19 @@ int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode
        jtag_poll_set_enabled(save_poll);
 
        if (retval != JIM_OK) {
-               Jim_PrintErrorMessage(cmd_ctx->interp);
+               Jim_MakeErrorMessage(cmd_ctx->interp);
+               command_print(NULL,"%s\n", Jim_GetString(Jim_GetResult(cmd_ctx->interp), NULL));
                return ERROR_FAIL;
        }
 
        /* 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 +540,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,23 +626,55 @@ 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;
+       }
+       if (!target->type->run_algorithm) {
+               LOG_ERROR("Target type '%s' does not support %s",
+                               target_type_name(target), __func__);
+               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);
+
+       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)
 {
        return target->type->read_memory(target, address, size, count, buffer);
 }
 
-int target_read_phys_memory(struct target *target,
+static int target_read_phys_memory(struct target *target,
                uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
        return target->type->read_phys_memory(target, address, size, count, buffer);
@@ -589,7 +686,7 @@ int target_write_memory(struct target *target,
        return target->type->write_memory(target, address, size, count, buffer);
 }
 
-int target_write_phys_memory(struct target *target,
+static int target_write_phys_memory(struct target *target,
                uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
        return target->type->write_phys_memory(target, address, size, count, buffer);
@@ -643,17 +740,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.
@@ -690,6 +776,9 @@ static int target_init_one(struct command_context *cmd_ctx,
        if (type->examine == NULL)
                type->examine = default_examine;
 
+       if (type->check_reset== NULL)
+               type->check_reset = default_check_reset;
+
        int retval = type->init_target(cmd_ctx, target);
        if (ERROR_OK != retval)
        {
@@ -714,9 +803,6 @@ static int target_init_one(struct command_context *cmd_ctx,
        type->soft_reset_halt_imp = target->type->soft_reset_halt;
        type->soft_reset_halt = target_soft_reset_halt_imp;
 
-       type->run_algorithm_imp = target->type->run_algorithm;
-       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.
         */
@@ -760,7 +846,7 @@ static int target_init_one(struct command_context *cmd_ctx,
        return ERROR_OK;
 }
 
-int target_init(struct command_context *cmd_ctx)
+static int target_init(struct command_context *cmd_ctx)
 {
        struct target *target;
        int retval;
@@ -780,7 +866,7 @@ int target_init(struct command_context *cmd_ctx)
                return retval;
 
        retval = target_register_timer_callback(&handle_target,
-                       100, 1, cmd_ctx->interp);
+                       polling_interval, 1, cmd_ctx->interp);
        if (ERROR_OK != retval)
                return retval;
 
@@ -893,7 +979,7 @@ int target_unregister_event_callback(int (*callback)(struct target *target, enum
        return ERROR_OK;
 }
 
-int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
+static int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
 {
        struct target_timer_callback **p = &target_timer_callbacks;
        struct target_timer_callback *c = target_timer_callbacks;
@@ -1016,7 +1102,7 @@ int target_call_timer_callbacks_now(void)
        return target_call_timer_callbacks_check_time(0);
 }
 
-int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
+int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
 {
        struct working_area *c = target->working_areas;
        struct working_area *new_wa = NULL;
@@ -1094,8 +1180,6 @@ int target_alloc_working_area(struct target *target, uint32_t size, struct worki
 
                if (free_size < size)
                {
-                       LOG_WARNING("not enough working area available(requested %u, free %u)",
-                                   (unsigned)(size), (unsigned)(free_size));
                        return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
 
@@ -1136,7 +1220,20 @@ int target_alloc_working_area(struct target *target, uint32_t size, struct worki
        return ERROR_OK;
 }
 
-int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
+int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
+{
+       int retval;
+
+       retval = target_alloc_working_area_try(target, size, area);
+       if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+       {
+               LOG_WARNING("not enough working area available(requested %u)", (unsigned)(size));
+       }
+       return retval;
+
+}
+
+static int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
 {
        if (area->free)
                return ERROR_OK;
@@ -1165,7 +1262,7 @@ int target_free_working_area(struct target *target, struct working_area *area)
 /* free resources and restore memory, if restoring memory fails,
  * free up resources anyway
  */
-void target_free_all_working_areas_restore(struct target *target, int restore)
+static void target_free_all_working_areas_restore(struct target *target, int restore)
 {
        struct working_area *c = target->working_areas;
 
@@ -1707,14 +1804,8 @@ 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;
-       }
-}
+static int backoff_times = 0;
+static int backoff_count = 0;
 
 /* process target state changes */
 static int handle_target(void *priv)
@@ -1722,6 +1813,12 @@ 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)
@@ -1735,7 +1832,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;
                }
@@ -1746,7 +1843,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;
                }
@@ -1772,6 +1869,14 @@ static int handle_target(void *priv)
                recursive = 0;
        }
 
+       if (backoff_times > backoff_count)
+       {
+               /* do not poll this time as we failed previously */
+               backoff_count++;
+               return ERROR_OK;
+       }
+       backoff_count = 0;
+
        /* Poll targets for state changes unless that's globally disabled.
         * Skip targets that are currently disabled.
         */
@@ -1788,9 +1893,26 @@ static int handle_target(void *priv)
                        /* polling may fail silently until the target has been examined */
                        if ((retval = target_poll(target)) != ERROR_OK)
                        {
+                               /* 100ms polling interval. Increase interval between polling up to 5000ms */
+                               if (backoff_times * polling_interval < 5000)
+                               {
+                                       backoff_times *= 2;
+                                       backoff_times++;
+                               }
+                               LOG_USER("Polling target failed, GDB will be halted. Polling again in %dms", backoff_times * polling_interval);
+
+                               /* Tell GDB to halt the debugger. This allows the user to
+                                * run monitor commands to handle the situation.
+                                */
                                target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
                                return retval;
                        }
+                       /* Since we succeeded, we reset backoff count */
+                       if (backoff_times > 0)
+                       {
+                               LOG_USER("Polling succeeded again");
+                       }
+                       backoff_times = 0;
                }
        }
 
@@ -2037,11 +2159,11 @@ COMMAND_HANDLER(handle_halt_command)
 
        if (CMD_ARGC == 1)
        {
-               unsigned wait;
-               retval = parse_uint(CMD_ARGV[0], &wait);
+               unsigned wait_local;
+               retval = parse_uint(CMD_ARGV[0], &wait_local);
                if (ERROR_OK != retval)
                        return ERROR_COMMAND_SYNTAX_ERROR;
-               if (!wait)
+               if (!wait_local)
                        return ERROR_OK;
        }
 
@@ -2138,11 +2260,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++)
@@ -2223,6 +2346,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;
+               }
+               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)
@@ -2230,8 +2423,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--;
@@ -2239,7 +2431,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;
@@ -2256,35 +2448,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,
@@ -2405,7 +2584,7 @@ COMMAND_HANDLER(handle_load_image_command)
        if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
        {
                command_print(CMD_CTX, "downloaded %" PRIu32 " bytes "
-                               "in %fs (%0.3f kb/s)", image_size,
+                               "in %fs (%0.3f KiB/s)", image_size,
                                duration_elapsed(&bench), duration_kbps(&bench, image_size));
        }
 
@@ -2418,33 +2597,25 @@ COMMAND_HANDLER(handle_load_image_command)
 COMMAND_HANDLER(handle_dump_image_command)
 {
        struct fileio fileio;
-
        uint8_t buffer[560];
-       int retvaltemp;
-
-
+       int retval, retvaltemp;
+       uint32_t address, size;
+       struct duration bench;
        struct target *target = get_current_target(CMD_CTX);
 
        if (CMD_ARGC != 3)
-       {
-               command_print(CMD_CTX, "usage: dump_image <filename> <address> <size>");
-               return ERROR_OK;
-       }
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       uint32_t address;
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], address);
-       uint32_t size;
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], size);
 
-       if (fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
-       {
-               return ERROR_OK;
-       }
+       retval = fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY);
+       if (retval != ERROR_OK)
+               return retval;
 
-       struct duration bench;
        duration_start(&bench);
 
-       int retval = ERROR_OK;
+       retval = ERROR_OK;
        while (size > 0)
        {
                size_t size_written;
@@ -2465,16 +2636,20 @@ COMMAND_HANDLER(handle_dump_image_command)
                address += this_run_size;
        }
 
-       if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
-               return retvaltemp;
-
        if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
        {
+               int filesize;
+               retval = fileio_size(&fileio, &filesize);
+               if (retval != ERROR_OK)
+                       return retval;
                command_print(CMD_CTX,
-                               "dumped %zu bytes in %fs (%0.3f kb/s)", fileio.size,
-                               duration_elapsed(&bench), duration_kbps(&bench, fileio.size));
+                               "dumped %ld bytes in %fs (%0.3f KiB/s)", (long)filesize,
+                               duration_elapsed(&bench), duration_kbps(&bench, filesize));
        }
 
+       if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
+               return retvaltemp;
+
        return retval;
 }
 
@@ -2527,6 +2702,7 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify)
        }
 
        image_size = 0x0;
+       int diffs = 0;
        retval = ERROR_OK;
        for (i = 0; i < image.num_sections; i++)
        {
@@ -2547,7 +2723,12 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify)
                if (verify)
                {
                        /* calculate checksum of image */
-                       image_calculate_checksum(buffer, buf_cnt, &checksum);
+                       retval = image_calculate_checksum(buffer, buf_cnt, &checksum);
+                       if (retval != ERROR_OK)
+                       {
+                               free(buffer);
+                               break;
+                       }
 
                        retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
                        if (retval != ERROR_OK)
@@ -2561,7 +2742,10 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify)
                                /* failed crc checksum, fall back to a binary compare */
                                uint8_t *data;
 
-                               command_print(CMD_CTX, "checksum mismatch - attempting binary compare");
+                               if (diffs == 0)
+                               {
+                                       LOG_ERROR("checksum mismatch - attempting binary compare");
+                               }
 
                                data = (uint8_t*)malloc(buf_cnt);
 
@@ -2582,22 +2766,22 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify)
                                                if (data[t] != buffer[t])
                                                {
                                                        command_print(CMD_CTX,
-                                                                                 "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n",
+                                                                                 "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
+                                                                                 diffs,
                                                                                  (unsigned)(t + image.sections[i].base_address),
                                                                                  data[t],
                                                                                  buffer[t]);
-                                                       free(data);
-                                                       free(buffer);
-                                                       retval = ERROR_FAIL;
-                                                       goto done;
-                                               }
-                                               if ((t%16384) == 0)
-                                               {
-                                                       keep_alive();
+                                                       if (diffs++ >= 127)
+                                                       {
+                                                               command_print(CMD_CTX, "More than 128 errors, the rest are not printed.");
+                                                               free(data);
+                                                               free(buffer);
+                                                               goto done;
+                                                       }
                                                }
+                                               keep_alive();
                                        }
                                }
-
                                free(data);
                        }
                } else
@@ -2610,11 +2794,19 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify)
                free(buffer);
                image_size += buf_cnt;
        }
+       if (diffs > 0)
+       {
+               command_print(CMD_CTX, "No more differences found.");
+       }
 done:
+       if (diffs > 0)
+       {
+               retval = ERROR_FAIL;
+       }
        if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
        {
                command_print(CMD_CTX, "verified %" PRIu32 " bytes "
-                               "in %fs (%0.3f kb/s)", image_size,
+                               "in %fs (%0.3f KiB/s)", image_size,
                                duration_elapsed(&bench), duration_kbps(&bench, image_size));
        }
 
@@ -2902,8 +3094,8 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
                long long a = address-min;
                long long b = length-1;
                long long c = addressSpace-1;
-               int index = (a*b)/c; /* danger!!!! int32 overflows */
-               buckets[index]++;
+               int index_t = (a*b)/c; /* danger!!!! int32 overflows */
+               buckets[index_t]++;
        }
 
        /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
@@ -2943,7 +3135,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);
@@ -2959,6 +3152,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;
@@ -3061,12 +3260,9 @@ static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        struct command_context *context;
        struct target *target;
 
-       context = Jim_GetAssocData(interp, "context");
-       if (context == NULL)
-       {
-               LOG_ERROR("mem2array: no command context");
-               return JIM_ERR;
-       }
+       context = current_command_context(interp);
+       assert (context != NULL);
+
        target = get_current_target(context);
        if (target == NULL)
        {
@@ -3257,11 +3453,9 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        struct command_context *context;
        struct target *target;
 
-       context = Jim_GetAssocData(interp, "context");
-       if (context == NULL) {
-               LOG_ERROR("array2mem: no command context");
-               return JIM_ERR;
-       }
+       context = current_command_context(interp);
+       assert (context != NULL);
+
        target = get_current_target(context);
        if (target == NULL) {
                LOG_ERROR("array2mem: no current target");
@@ -3270,7 +3464,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;
@@ -3414,22 +3610,6 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, int argc,
        return JIM_OK;
 }
 
-void target_all_handle_event(enum target_event e)
-{
-       struct target *target;
-
-       LOG_DEBUG("**all*targets: event: %d, %s",
-                          (int)e,
-                          Jim_Nvp_value2name_simple(nvp_target_event, e)->name);
-
-       target = all_targets;
-       while (target) {
-               target_handle_event(target, e);
-               target = target->next;
-       }
-}
-
-
 /* FIX? should we propagate errors here rather than printing them
  * and continuing?
  */
@@ -3448,7 +3628,8 @@ void target_handle_event(struct target *target, enum target_event e)
                                           Jim_GetString(teap->body, NULL));
                        if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK)
                        {
-                               Jim_PrintErrorMessage(teap->interp);
+                               Jim_MakeErrorMessage(teap->interp);
+                               command_print(NULL,"%s\n", Jim_GetString(Jim_GetResult(teap->interp), NULL));
                        }
                }
        }
@@ -3530,7 +3711,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                case TCFG_TYPE:
                        /* not setable */
                        if (goi->isconfigure) {
-                               Jim_SetResult_sprintf(goi->interp,
+                               Jim_SetResultFormatted(goi->interp,
                                                "not settable: %s", n->name);
                                return JIM_ERR;
                        } else {
@@ -3723,7 +3904,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                case TCFG_VARIANT:
                        if (goi->isconfigure) {
                                if (goi->argc < 1) {
-                                       Jim_SetResult_sprintf(goi->interp,
+                                       Jim_SetResultFormatted(goi->interp,
                                                                                   "%s ?STRING?",
                                                                                   n->name);
                                        return JIM_ERR;
@@ -3743,14 +3924,14 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                        break;
                case TCFG_CHAIN_POSITION:
                        if (goi->isconfigure) {
-                               Jim_Obj *o;
+                               Jim_Obj *o_t;
                                struct jtag_tap *tap;
                                target_free_all_working_areas(target);
-                               e = Jim_GetOpt_Obj(goi, &o);
+                               e = Jim_GetOpt_Obj(goi, &o_t);
                                if (e != JIM_OK) {
                                        return e;
                                }
-                               tap = jtag_tap_by_jim_obj(goi->interp, o);
+                               tap = jtag_tap_by_jim_obj(goi->interp, o_t);
                                if (tap == NULL) {
                                        return JIM_ERR;
                                }
@@ -3772,11 +3953,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)
        {
@@ -3797,15 +3980,30 @@ 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)
+       if (goi.argc < 2 || goi.argc > 4)
        {
-               Jim_SetResult_sprintf(goi.interp,
-                               "usage: %s <address> <data> [<count>]", cmd_name);
+               Jim_SetResultFormatted(goi.interp,
+                               "usage: %s [phys] <address> <data> [<count>]", cmd_name);
                return JIM_ERR;
        }
 
+       target_write_fn fn;
+       fn = target_write_memory_fast;
+
+       int e;
+       if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0)
+       {
+               /* consume it */
+               struct Jim_Obj *obj;
+               e = Jim_GetOpt_Obj(&goi, &obj);
+               if (e != JIM_OK)
+                       return e;
+
+               fn = target_write_phys_memory;
+       }
+
        jim_wide a;
-       int e = Jim_GetOpt_Wide(&goi, &a);
+       e = Jim_GetOpt_Wide(&goi, &a);
        if (e != JIM_OK)
                return e;
 
@@ -3815,44 +4013,35 @@ 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 (goi.argc == 1)
        {
                e = Jim_GetOpt_Wide(&goi, &c);
                if (e != JIM_OK)
                        return e;
        }
 
+       /* all args must be consumed */
+       if (goi.argc != 0)
+       {
+               return JIM_ERR;
+       }
+
        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, fn, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR;
 }
 
 static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -3862,20 +4051,36 @@ 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))
+       if ((goi.argc < 1) || (goi.argc > 3))
        {
-               Jim_SetResult_sprintf(goi.interp,
-                               "usage: %s <address> [<count>]", cmd_name);
+               Jim_SetResultFormatted(goi.interp,
+                               "usage: %s [phys] <address> [<count>]", cmd_name);
                return JIM_ERR;
        }
 
+       int (*fn)(struct target *target,
+                       uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+       fn=target_read_memory;
+
+       int e;
+       if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0)
+       {
+               /* consume it */
+               struct Jim_Obj *obj;
+               e = Jim_GetOpt_Obj(&goi, &obj);
+               if (e != JIM_OK)
+                       return e;
+
+               fn=target_read_phys_memory;
+       }
+
        jim_wide a;
-       int e = Jim_GetOpt_Wide(&goi, &a);
+       e = Jim_GetOpt_Wide(&goi, &a);
        if (e != JIM_OK) {
                return JIM_ERR;
        }
        jim_wide c;
-       if (goi.argc) {
+       if (goi.argc == 1) {
                e = Jim_GetOpt_Wide(&goi, &c);
                if (e != JIM_OK) {
                        return JIM_ERR;
@@ -3883,6 +4088,13 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        } else {
                c = 1;
        }
+
+       /* all args must be consumed */
+       if (goi.argc != 0)
+       {
+               return JIM_ERR;
+       }
+
        jim_wide b = 1; /* shut up gcc */
        if (strcasecmp(cmd_name, "mdw") == 0)
                b = 4;
@@ -3906,42 +4118,44 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                if (y > 16) {
                        y = 16;
                }
-               e = target_read_memory(target, a, b, y / b, target_buf);
+               e = fn(target, a, b, y / b, target_buf);
                if (e != ERROR_OK) {
-                       Jim_SetResult_sprintf(interp, "error reading target @ 0x%08lx", (int)(a));
+                       char tmp[10];
+                       snprintf(tmp, sizeof(tmp), "%08lx", (long)a);
+                       Jim_SetResultFormatted(interp, "error reading target @ 0x%s", tmp);
                        return JIM_ERR;
                }
 
-               Jim_fprintf(interp, interp->cookie_stdout, "0x%08x ", (int)(a));
+               command_print(NULL, "0x%08x ", (int)(a));
                switch (b) {
                case 4:
                        for (x = 0; x < 16 && x < y; x += 4)
                        {
-                               z = target_buffer_get_u32(target, &(target_buf[ x * 4 ]));
-                               Jim_fprintf(interp, interp->cookie_stdout, "%08x ", (int)(z));
+                               z = target_buffer_get_u32(target, &(target_buf[ x ]));
+                               command_print(NULL, "%08x ", (int)(z));
                        }
                        for (; (x < 16) ; x += 4) {
-                               Jim_fprintf(interp, interp->cookie_stdout, "         ");
+                               command_print(NULL, "         ");
                        }
                        break;
                case 2:
                        for (x = 0; x < 16 && x < y; x += 2)
                        {
-                               z = target_buffer_get_u16(target, &(target_buf[ x * 2 ]));
-                               Jim_fprintf(interp, interp->cookie_stdout, "%04x ", (int)(z));
+                               z = target_buffer_get_u16(target, &(target_buf[ x ]));
+                               command_print(NULL, "%04x ", (int)(z));
                        }
                        for (; (x < 16) ; x += 2) {
-                               Jim_fprintf(interp, interp->cookie_stdout, "     ");
+                               command_print(NULL, "     ");
                        }
                        break;
                case 1:
                default:
                        for (x = 0 ; (x < 16) && (x < y) ; x += 1) {
-                               z = target_buffer_get_u8(target, &(target_buf[ x * 4 ]));
-                               Jim_fprintf(interp, interp->cookie_stdout, "%02x ", (int)(z));
+                               z = target_buffer_get_u8(target, &(target_buf[ x ]));
+                               command_print(NULL, "%02x ", (int)(z));
                        }
                        for (; (x < 16) ; x += 1) {
-                               Jim_fprintf(interp, interp->cookie_stdout, "   ");
+                               command_print(NULL, "   ");
                        }
                        break;
                }
@@ -3963,7 +4177,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                /* terminate */
                target_buf[16] = 0;
                /* print - with a newline */
-               Jim_fprintf(interp, interp->cookie_stdout, "%s\n", target_buf);
+               command_print(NULL, "%s\n", target_buf);
                /* NEXT... */
                c -= 16;
                a += 16;
@@ -3971,13 +4185,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);
@@ -3985,7 +4201,7 @@ static int jim_target_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *ar
 
 static int jim_target_tap_disabled(Jim_Interp *interp)
 {
-       Jim_SetResult_sprintf(interp, "[TAP is disabled]");
+       Jim_SetResultFormatted(interp, "[TAP is disabled]");
        return JIM_ERR;
 }
 
@@ -4003,9 +4219,26 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv
        int e = target->type->examine(target);
        if (e != ERROR_OK)
        {
-               Jim_SetResult_sprintf(interp, "examine-fails: %d", e);
+               Jim_Obj *eObj = Jim_NewIntObj(interp, e);
+               Jim_SetResultFormatted(interp, "examine-fails: %#s", eObj);
+               Jim_FreeNewObj(interp, eObj);
+               return JIM_ERR;
+       }
+       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;
 }
 
@@ -4028,7 +4261,9 @@ static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        }
        if (e != ERROR_OK)
        {
-               Jim_SetResult_sprintf(interp, "poll-fails: %d", e);
+               Jim_Obj *eObj = Jim_NewIntObj(interp, e);
+               Jim_SetResultFormatted(interp, "poll-fails: %#s", eObj);
+               Jim_FreeNewObj(interp, eObj);
                return JIM_ERR;
        }
        return JIM_OK;
@@ -4062,9 +4297,14 @@ 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,
+               Jim_SetResultFormatted(interp,
                                "No target-specific reset for %s",
                                target_name(target));
                return JIM_ERR;
@@ -4105,7 +4345,7 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a
        if (goi.argc != 2)
        {
                const char *cmd_name = Jim_GetString(argv[0], NULL);
-               Jim_SetResult_sprintf(goi.interp,
+               Jim_SetResultFormatted(goi.interp,
                                "%s <state_name> <timeout_in_msec>", cmd_name);
                return JIM_ERR;
        }
@@ -4128,10 +4368,12 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a
        e = target_wait_state(target, n->value, a);
        if (e != ERROR_OK)
        {
-               Jim_SetResult_sprintf(goi.interp,
-                               "target: %s wait %s fails (%d) %s",
+               Jim_Obj *eObj = Jim_NewIntObj(interp, e);
+               Jim_SetResultFormatted(goi.interp,
+                               "target: %s wait %s fails (%#s) %s",
                                target_name(target), n->name,
-                               e, target_strerror_safe(e));
+                               eObj, target_strerror_safe(e));
+               Jim_FreeNewObj(interp, eObj);
                return JIM_ERR;
        }
        return JIM_OK;
@@ -4141,7 +4383,9 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a
  */
 static int jim_target_event_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
-       struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context");
+       struct command_context *cmd_ctx = current_command_context(interp);
+       assert (cmd_ctx != NULL);
+
        struct target *target = Jim_CmdPrivData(interp);
        struct target_event_action *teap = target->event_action;
        command_print(cmd_ctx, "Event actions for target (%d) %s\n",
@@ -4178,7 +4422,7 @@ static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const
        if (goi.argc != 1)
        {
                const char *cmd_name = Jim_GetString(argv[0], NULL);
-               Jim_SetResult_sprintf(goi.interp, "%s <eventname>", cmd_name);
+               Jim_SetResultFormatted(goi.interp, "%s <eventname>", cmd_name);
                return JIM_ERR;
        }
        Jim_Nvp *n;
@@ -4197,108 +4441,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
 };
@@ -4314,7 +4579,9 @@ static int target_create(Jim_GetOptInfo *goi)
        struct target *target;
        struct command_context *cmd_ctx;
 
-       cmd_ctx = Jim_GetAssocData(goi->interp, "context");
+       cmd_ctx = current_command_context(goi->interp);
+       assert (cmd_ctx != NULL);
+
        if (goi->argc < 3) {
                Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ?type? ..options...");
                return JIM_ERR;
@@ -4326,7 +4593,7 @@ static int target_create(Jim_GetOptInfo *goi)
        cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
        if (cmd) {
                cp = Jim_GetString(new_cmd, NULL);
-               Jim_SetResult_sprintf(goi->interp, "Command/target: %s Exists", cp);
+               Jim_SetResultFormatted(goi->interp, "Command/target: %s Exists", cp);
                return JIM_ERR;
        }
 
@@ -4341,7 +4608,7 @@ static int target_create(Jim_GetOptInfo *goi)
                }
        }
        if (target_types[x] == NULL) {
-               Jim_SetResult_sprintf(goi->interp, "Unknown target type %s, try one of ", cp);
+               Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp);
                for (x = 0 ; target_types[x] ; x++) {
                        if (target_types[x + 1]) {
                                Jim_AppendStrings(goi->interp,
@@ -4450,7 +4717,7 @@ static int target_create(Jim_GetOptInfo *goi)
                }
                *tpp = target;
        }
-       
+
        /* now - create the new target name command */
        const const struct command_registration target_subcommands[] = {
                {
@@ -4488,7 +4755,9 @@ static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv
                Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
                return JIM_ERR;
        }
-       struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context");
+       struct command_context *cmd_ctx = current_command_context(interp);
+       assert (cmd_ctx != NULL);
+
        Jim_SetResultString(interp, get_current_target(cmd_ctx)->cmd_name, -1);
        return JIM_OK;
 }
@@ -4549,7 +4818,7 @@ static int jim_target_number(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
        LOG_WARNING("don't use numbers as target identifiers; use names");
        if (goi.argc != 1)
        {
-               Jim_SetResult_sprintf(goi.interp, "usage: target number <number>");
+               Jim_SetResultFormatted(goi.interp, "usage: target number <number>");
                return JIM_ERR;
        }
        jim_wide w;
@@ -4566,8 +4835,12 @@ static int jim_target_number(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                Jim_SetResultString(goi.interp, target_name(target), -1);
                return JIM_OK;
        }
-       Jim_SetResult_sprintf(goi.interp,
-                       "Target: number %d does not exist", (int)(w));
+       {
+               Jim_Obj *wObj = Jim_NewIntObj(goi.interp, w);
+               Jim_SetResultFormatted(goi.interp,
+                       "Target: number %#s does not exist", wObj);
+               Jim_FreeNewObj(interp, wObj);
+       }
        return JIM_ERR;
 }
 
@@ -4593,51 +4866,54 @@ static const struct command_registration target_subcommand_handlers[] = {
        {
                .name = "init",
                .mode = COMMAND_CONFIG,
-               .handler = &handle_target_init_command,
+               .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;
@@ -4760,7 +5036,7 @@ COMMAND_HANDLER(handle_fast_load_image_command)
        if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
        {
                command_print(CMD_CTX, "Loaded %" PRIu32 " bytes "
-                               "in %fs (%0.3f kb/s)", image_size, 
+                               "in %fs (%0.3f KiB/s)", image_size,
                                duration_elapsed(&bench), duration_kbps(&bench, image_size));
 
                command_print(CMD_CTX,
@@ -4811,11 +5087,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",
@@ -4832,72 +5108,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."
@@ -4905,137 +5201,139 @@ 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",
+               .name = "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",
+               .name = "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
 };
-int target_register_user_commands(struct command_context *cmd_ctx)
+static int target_register_user_commands(struct command_context *cmd_ctx)
 {
        int retval = ERROR_OK;
        if ((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)