Transform 'u8' to 'uint8_t' in src/target
[openocd.git] / src / target / target.c
index 66c80f4e7d96b6f603ae114f47a3b5afd09983e0..6795b179d07fad5664f4e02160504e77f3b123f6 100644 (file)
 #include "config.h"
 #endif
 
-#include "replacements.h"
 #include "target.h"
+#include "target_type.h"
 #include "target_request.h"
-
-#include "log.h"
-#include "configuration.h"
-#include "binarybuffer.h"
+#include "time_support.h"
+#include "register.h"
+#include "trace.h"
+#include "image.h"
 #include "jtag.h"
 
-#include <string.h>
-#include <stdlib.h>
-#include <inttypes.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/time.h>
-#include <time.h>
-
-#include <time_support.h>
-
-#include <fileio.h>
-#include <image.h>
-
-int cli_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv);
-
-
-int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-
-int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-
-int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
-int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
+static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
+static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
 static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
 static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
 static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv);
@@ -92,8 +75,6 @@ static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv);
 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
 
-
-
 /* targets */
 extern target_type_t arm7tdmi_target;
 extern target_type_t arm720t_target;
@@ -104,8 +85,10 @@ extern target_type_t arm926ejs_target;
 extern target_type_t feroceon_target;
 extern target_type_t xscale_target;
 extern target_type_t cortexm3_target;
+extern target_type_t cortexa8_target;
 extern target_type_t arm11_target;
 extern target_type_t mips_m4k_target;
+extern target_type_t avr_target;
 
 target_type_t *target_types[] =
 {
@@ -118,8 +101,10 @@ target_type_t *target_types[] =
        &feroceon_target,
        &xscale_target,
        &cortexm3_target,
+       &cortexa8_target,
        &arm11_target,
        &mips_m4k_target,
+       &avr_target,
        NULL,
 };
 
@@ -164,22 +149,19 @@ const char *target_strerror_safe( int err )
        }
 }
 
-const Jim_Nvp nvp_target_event[] = {
+static const Jim_Nvp nvp_target_event[] = {
        { .value = TARGET_EVENT_OLD_gdb_program_config , .name = "old-gdb_program_config" },
        { .value = TARGET_EVENT_OLD_pre_resume         , .name = "old-pre_resume" },
 
-
        { .value = TARGET_EVENT_EARLY_HALTED, .name = "early-halted" },
        { .value = TARGET_EVENT_HALTED, .name = "halted" },
        { .value = TARGET_EVENT_RESUMED, .name = "resumed" },
        { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
        { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" },
 
-
        { .name = "gdb-start", .value = TARGET_EVENT_GDB_START },
        { .name = "gdb-end", .value = TARGET_EVENT_GDB_END },
 
-
        /* historical name */
 
        { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
@@ -195,13 +177,8 @@ const Jim_Nvp nvp_target_event[] = {
        { .value = TARGET_EVENT_RESET_INIT , .name = "reset-init" },
        { .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
 
-
-
-
-
        { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
-       { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-end" },
-
+       { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" },
 
        { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" },
        { .value = TARGET_EVENT_DEBUG_RESUMED, .name = "debug-resumed" },
@@ -209,7 +186,6 @@ const Jim_Nvp nvp_target_event[] = {
        { .value = TARGET_EVENT_GDB_ATTACH, .name = "gdb-attach" },
        { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" },
 
-
        { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" },
        { .value = TARGET_EVENT_GDB_FLASH_WRITE_END  , .name = "gdb-flash-write-end"   },
 
@@ -232,7 +208,6 @@ const Jim_Nvp nvp_target_state[] = {
        { .name = NULL, .value = -1 },
 };
 
-
 const Jim_Nvp nvp_target_debug_reason [] = {
        { .name = "debug-request"            , .value = DBG_REASON_DBGRQ },
        { .name = "breakpoint"               , .value = DBG_REASON_BREAKPOINT },
@@ -244,12 +219,11 @@ const Jim_Nvp nvp_target_debug_reason [] = {
        { .name = NULL, .value = -1 },
 };
 
-
 const Jim_Nvp nvp_target_endian[] = {
        { .name = "big",    .value = TARGET_BIG_ENDIAN },
        { .name = "little", .value = TARGET_LITTLE_ENDIAN },
        { .name = "be",     .value = TARGET_BIG_ENDIAN },
-        { .name = "le",     .value = TARGET_LITTLE_ENDIAN },
+       { .name = "le",     .value = TARGET_LITTLE_ENDIAN },
        { .name = NULL,     .value = -1 },
 };
 
@@ -261,8 +235,7 @@ const Jim_Nvp nvp_reset_modes[] = {
        { .name = NULL     , .value = -1 },
 };
 
-static int
-max_target_number( void )
+static int max_target_number(void)
 {
        target_t *t;
        int x;
@@ -279,8 +252,7 @@ max_target_number( void )
 }
 
 /* determine the number of the new target */
-static int
-new_target_number( void )
+static int new_target_number(void)
 {
        target_t *t;
        int x;
@@ -297,10 +269,10 @@ new_target_number( void )
        return x+1;
 }
 
-static int target_continous_poll = 1;
+static int target_continuous_poll = 1;
 
 /* read a u32 from a buffer in target memory endianness */
-u32 target_buffer_get_u32(target_t *target, u8 *buffer)
+u32 target_buffer_get_u32(target_t *target, const uint8_t *buffer)
 {
        if (target->endianness == TARGET_LITTLE_ENDIAN)
                return le_to_h_u32(buffer);
@@ -309,7 +281,7 @@ u32 target_buffer_get_u32(target_t *target, u8 *buffer)
 }
 
 /* read a u16 from a buffer in target memory endianness */
-u16 target_buffer_get_u16(target_t *target, u8 *buffer)
+u16 target_buffer_get_u16(target_t *target, const uint8_t *buffer)
 {
        if (target->endianness == TARGET_LITTLE_ENDIAN)
                return le_to_h_u16(buffer);
@@ -317,14 +289,14 @@ u16 target_buffer_get_u16(target_t *target, u8 *buffer)
                return be_to_h_u16(buffer);
 }
 
-/* read a u8 from a buffer in target memory endianness */
-u8 target_buffer_get_u8(target_t *target, u8 *buffer)
+/* read a uint8_t from a buffer in target memory endianness */
+uint8_t target_buffer_get_u8(target_t *target, const uint8_t *buffer)
 {
        return *buffer & 0x0ff;
 }
 
 /* write a u32 to a buffer in target memory endianness */
-void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value)
+void target_buffer_set_u32(target_t *target, uint8_t *buffer, u32 value)
 {
        if (target->endianness == TARGET_LITTLE_ENDIAN)
                h_u32_to_le(buffer, value);
@@ -333,7 +305,7 @@ void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value)
 }
 
 /* write a u16 to a buffer in target memory endianness */
-void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value)
+void target_buffer_set_u16(target_t *target, uint8_t *buffer, u16 value)
 {
        if (target->endianness == TARGET_LITTLE_ENDIAN)
                h_u16_to_le(buffer, value);
@@ -341,14 +313,40 @@ void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value)
                h_u16_to_be(buffer, value);
 }
 
-/* write a u8 to a buffer in target memory endianness */
-void target_buffer_set_u8(target_t *target, u8 *buffer, u8 value)
+/* write a uint8_t to a buffer in target memory endianness */
+void target_buffer_set_u8(target_t *target, uint8_t *buffer, uint8_t value)
 {
        *buffer = value;
 }
 
+/* return a pointer to a configured target; id is name or number */
+target_t *get_target(const char *id)
+{
+       target_t *target;
+
+       /* try as tcltarget name */
+       for (target = all_targets; target; target = target->next) {
+               if (target->cmd_name == NULL)
+                       continue;
+               if (strcmp(id, target->cmd_name) == 0)
+                       return target;
+       }
+
+       /* no match, try as number */
+       unsigned num;
+       if (parse_uint(id, &num) != ERROR_OK)
+               return NULL;
+
+       for (target = all_targets; target; target = target->next) {
+               if (target->target_number == (int)num)
+                       return target;
+       }
+
+       return NULL;
+}
+
 /* returns a pointer to the n-th configured target */
-target_t* get_target_by_num(int num)
+static target_t *get_target_by_num(int num)
 {
        target_t *target = all_targets;
 
@@ -380,11 +378,10 @@ target_t* get_current_target(command_context_t *cmd_ctx)
        return target;
 }
 
-
 int target_poll(struct target_s *target)
 {
        /* We can't poll until after examine */
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                /* Fail silently lest we pollute the log */
                return ERROR_FAIL;
@@ -395,7 +392,7 @@ int target_poll(struct target_s *target)
 int target_halt(struct target_s *target)
 {
        /* We can't poll until after examine */
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -408,7 +405,7 @@ int target_resume(struct target_s *target, int current, u32 address, int handle_
        int retval;
 
        /* We can't poll until after examine */
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -424,7 +421,6 @@ int target_resume(struct target_s *target, int current, u32 address, int handle_
        return retval;
 }
 
-
 int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
 {
        char buf[100];
@@ -436,9 +432,18 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
                return ERROR_FAIL;
        }
 
+       /* disable polling during reset to make reset event scripts
+        * more predictable, i.e. dr/irscan & pathmove in events will
+        * not have JTAG operations injected into the middle of a sequence.
+        */
+       int save_poll = target_continuous_poll;
+       target_continuous_poll = 0;
+
        sprintf( buf, "ocd_process_reset %s", n->name );
        retval = Jim_Eval( interp, buf );
 
+       target_continuous_poll = save_poll;
+
        if(retval != JIM_OK) {
                Jim_PrintErrorMessage(interp);
                return ERROR_FAIL;
@@ -450,7 +455,6 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
        return retval;
 }
 
-
 static int default_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
 {
        *physical = virtual;
@@ -465,10 +469,26 @@ static int default_mmu(struct target_s *target, int *enabled)
 
 static int default_examine(struct target_s *target)
 {
-       target->type->examined = 1;
+       target_set_examined(target);
        return ERROR_OK;
 }
 
+int target_examine_one(struct target_s *target)
+{
+       return target->type->examine(target);
+}
+
+static int jtag_enable_callback(enum jtag_event event, void *priv)
+{
+       target_t *target = priv;
+
+       if (event != JTAG_TAP_EVENT_ENABLE || !target->tap->enabled)
+               return ERROR_OK;
+
+       jtag_unregister_event_callback(jtag_enable_callback, target);
+       return target_examine_one(target);
+}
+
 
 /* Targets that correctly implement init+examine, i.e.
  * no communication with target during init:
@@ -478,19 +498,29 @@ static int default_examine(struct target_s *target)
 int target_examine(void)
 {
        int retval = ERROR_OK;
-       target_t *target = all_targets;
-       while (target)
+       target_t *target;
+
+       for (target = all_targets; target; target = target->next)
        {
-               if ((retval = target->type->examine(target))!=ERROR_OK)
+               /* defer examination, but don't skip it */
+               if (!target->tap->enabled) {
+                       jtag_register_event_callback(jtag_enable_callback,
+                                       target);
+                       continue;
+               }
+               if ((retval = target_examine_one(target)) != ERROR_OK)
                        return retval;
-               target = target->next;
        }
        return retval;
 }
+const char *target_get_name(struct target_s *target)
+{
+       return target->type->name;
+}
 
-static int target_write_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
+static int target_write_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, uint8_t *buffer)
 {
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -498,9 +528,9 @@ static int target_write_memory_imp(struct target_s *target, u32 address, u32 siz
        return target->type->write_memory_imp(target, address, size, count, buffer);
 }
 
-static int target_read_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
+static int target_read_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, uint8_t *buffer)
 {
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -510,7 +540,7 @@ static int target_read_memory_imp(struct target_s *target, u32 address, u32 size
 
 static int target_soft_reset_halt_imp(struct target_s *target)
 {
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -520,7 +550,7 @@ static int target_soft_reset_halt_imp(struct target_s *target)
 
 static int target_run_algorithm_imp(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_param, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info)
 {
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -528,6 +558,85 @@ static int target_run_algorithm_imp(struct target_s *target, int num_mem_params,
        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);
 }
 
+int target_read_memory(struct target_s *target,
+               u32 address, u32 size, u32 count, uint8_t *buffer)
+{
+       return target->type->read_memory(target, address, size, count, buffer);
+}
+
+int target_write_memory(struct target_s *target,
+               u32 address, u32 size, u32 count, uint8_t *buffer)
+{
+       return target->type->write_memory(target, address, size, count, buffer);
+}
+int target_bulk_write_memory(struct target_s *target,
+               u32 address, u32 count, uint8_t *buffer)
+{
+       return target->type->bulk_write_memory(target, address, count, buffer);
+}
+
+int target_add_breakpoint(struct target_s *target,
+               struct breakpoint_s *breakpoint)
+{
+       return target->type->add_breakpoint(target, breakpoint);
+}
+int target_remove_breakpoint(struct target_s *target,
+               struct breakpoint_s *breakpoint)
+{
+       return target->type->remove_breakpoint(target, breakpoint);
+}
+
+int target_add_watchpoint(struct target_s *target,
+               struct watchpoint_s *watchpoint)
+{
+       return target->type->add_watchpoint(target, watchpoint);
+}
+int target_remove_watchpoint(struct target_s *target,
+               struct watchpoint_s *watchpoint)
+{
+       return target->type->remove_watchpoint(target, watchpoint);
+}
+
+int target_get_gdb_reg_list(struct target_s *target,
+               struct reg_s **reg_list[], int *reg_list_size)
+{
+       return target->type->get_gdb_reg_list(target, reg_list, reg_list_size);
+}
+int target_step(struct target_s *target,
+               int current, u32 address, int handle_breakpoints)
+{
+       return target->type->step(target, current, address, handle_breakpoints);
+}
+
+
+int target_run_algorithm(struct target_s *target,
+               int num_mem_params, mem_param_t *mem_params,
+               int num_reg_params, reg_param_t *reg_param,
+               u32 entry_point, u32 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);
+}
+
+/// @returns @c true if the target has been examined.
+bool target_was_examined(struct target_s *target)
+{
+       return target->type->examined;
+}
+/// Sets the @c examined flag for the given target.
+void target_set_examined(struct target_s *target)
+{
+       target->type->examined = true;
+}
+// Reset the @c examined flag for the given target.
+void target_reset_examined(struct target_s *target)
+{
+       target->type->examined = false;
+}
+
+
 int target_init(struct command_context_s *cmd_ctx)
 {
        target_t *target = all_targets;
@@ -535,7 +644,7 @@ int target_init(struct command_context_s *cmd_ctx)
 
        while (target)
        {
-               target->type->examined = 0;
+               target_reset_examined(target);
                if (target->type->examine == NULL)
                {
                        target->type->examine = default_examine;
@@ -543,7 +652,7 @@ int target_init(struct command_context_s *cmd_ctx)
 
                if ((retval = target->type->init_target(cmd_ctx, target)) != ERROR_OK)
                {
-                       LOG_ERROR("target '%s' init failed", target->type->name);
+                       LOG_ERROR("target '%s' init failed", target_get_name(target));
                        return retval;
                }
 
@@ -565,7 +674,6 @@ int target_init(struct command_context_s *cmd_ctx)
                target->type->run_algorithm_imp = target->type->run_algorithm;
                target->type->run_algorithm = target_run_algorithm_imp;
 
-
                if (target->type->mmu == NULL)
                {
                        target->type->mmu = default_mmu;
@@ -711,7 +819,6 @@ int target_call_event_callbacks(target_t *target, enum target_event event)
                target_call_event_callbacks(target, TARGET_EVENT_EARLY_HALTED);
        }
 
-
        LOG_DEBUG("target event %i (%s)",
                          event,
                          Jim_Nvp_value2name_simple( nvp_target_event, event )->name );
@@ -728,46 +835,56 @@ int target_call_event_callbacks(target_t *target, enum target_event event)
        return ERROR_OK;
 }
 
-static int target_call_timer_callbacks_check_time(int checktime)
+static int target_timer_callback_periodic_restart(
+               target_timer_callback_t *cb, struct timeval *now)
 {
-       target_timer_callback_t *callback = target_timer_callbacks;
-       target_timer_callback_t *next_callback;
-       struct timeval now;
+       int time_ms = cb->time_ms;
+       cb->when.tv_usec = now->tv_usec + (time_ms % 1000) * 1000;
+       time_ms -= (time_ms % 1000);
+       cb->when.tv_sec = now->tv_sec + time_ms / 1000;
+       if (cb->when.tv_usec > 1000000)
+       {
+               cb->when.tv_usec = cb->when.tv_usec - 1000000;
+               cb->when.tv_sec += 1;
+       }
+       return ERROR_OK;
+}
+
+static int target_call_timer_callback(target_timer_callback_t *cb,
+               struct timeval *now)
+{
+       cb->callback(cb->priv);
+
+       if (cb->periodic)
+               return target_timer_callback_periodic_restart(cb, now);
+
+       return target_unregister_timer_callback(cb->callback, cb->priv);
+}
 
+static int target_call_timer_callbacks_check_time(int checktime)
+{
        keep_alive();
 
+       struct timeval now;
        gettimeofday(&now, NULL);
 
+       target_timer_callback_t *callback = target_timer_callbacks;
        while (callback)
        {
-               next_callback = callback->next;
+               // cleaning up may unregister and free this callback
+               target_timer_callback_t *next_callback = callback->next;
 
-               if ((!checktime&&callback->periodic)||
-                               (((now.tv_sec >= callback->when.tv_sec) && (now.tv_usec >= callback->when.tv_usec))
-                                               || (now.tv_sec > callback->when.tv_sec)))
+               bool call_it = callback->callback &&
+                       ((!checktime && callback->periodic) ||
+                         now.tv_sec > callback->when.tv_sec ||
+                        (now.tv_sec == callback->when.tv_sec &&
+                         now.tv_usec >= callback->when.tv_usec));
+
+               if (call_it)
                {
-                       if(callback->callback != NULL)
-                       {
-                               callback->callback(callback->priv);
-                               if (callback->periodic)
-                               {
-                                       int time_ms = callback->time_ms;
-                                       callback->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
-                                       time_ms -= (time_ms % 1000);
-                                       callback->when.tv_sec = now.tv_sec + time_ms / 1000;
-                                       if (callback->when.tv_usec > 1000000)
-                                       {
-                                               callback->when.tv_usec = callback->when.tv_usec - 1000000;
-                                               callback->when.tv_sec += 1;
-                                       }
-                               }
-                               else
-                               {
-                                       int retval;
-                                       if((retval = target_unregister_timer_callback(callback->callback, callback->priv)) != ERROR_OK)
-                                               return retval;
-                               }
-                       }
+                       int retval = target_call_timer_callback(callback, &now);
+                       if (retval != ERROR_OK)
+                               return retval;
                }
 
                callback = next_callback;
@@ -863,7 +980,7 @@ int target_alloc_working_area(struct target_s *target, u32 size, working_area_t
                {
                        int retval;
                        new_wa->backup = malloc(new_wa->size);
-                       if((retval = target->type->read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
+                       if((retval = target_read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
                        {
                                free(new_wa->backup);
                                free(new_wa);
@@ -897,7 +1014,7 @@ int target_free_working_area_restore(struct target_s *target, working_area_t *ar
        if (restore&&target->backup_working_area)
        {
                int retval;
-               if((retval = target->type->write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
+               if((retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
                        return retval;
        }
 
@@ -947,16 +1064,12 @@ int target_register_commands(struct command_context_s *cmd_ctx)
 {
 
        register_command(cmd_ctx, NULL, "targets", handle_targets_command, COMMAND_EXEC, "change the current command line target (one parameter) or lists targets (with no parameter)");
-       register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, "set a new working space");
-       register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
-       register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
 
-       register_jim(cmd_ctx, "target", jim_target, "configure target" );
 
 
-       /* script procedures */
-       register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing");
-       register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values");
+
+       register_jim(cmd_ctx, "target", jim_target, "configure target" );
+
        return ERROR_OK;
 }
 
@@ -983,17 +1096,21 @@ int target_arch_state(struct target_s *target)
  * mode respectively, otherwise data is handled as quickly as
  * possible
  */
-int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
+int target_write_buffer(struct target_s *target, u32 address, u32 size, uint8_t *buffer)
 {
        int retval;
        LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
 
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
 
+       if (size == 0) {
+               return ERROR_OK;
+       }
+
        if ((address + size - 1) < address)
        {
                /* GDB can request this when e.g. PC is 0xfffffffc*/
@@ -1003,18 +1120,18 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff
 
        if (((address % 2) == 0) && (size == 2))
        {
-               return target->type->write_memory(target, address, 2, 1, buffer);
+               return target_write_memory(target, address, 2, 1, buffer);
        }
 
        /* handle unaligned head bytes */
        if (address % 4)
        {
-               int unaligned = 4 - (address % 4);
+               u32 unaligned = 4 - (address % 4);
 
                if (unaligned > size)
                        unaligned = size;
 
-               if ((retval = target->type->write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
+               if ((retval = target_write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
                        return retval;
 
                buffer += unaligned;
@@ -1035,7 +1152,7 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff
                }
                else
                {
-                       if ((retval = target->type->write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
+                       if ((retval = target_write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
                                return retval;
                }
 
@@ -1047,29 +1164,32 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff
        /* handle tail writes of less than 4 bytes */
        if (size > 0)
        {
-               if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)
+               if ((retval = target_write_memory(target, address, 1, size, buffer)) != ERROR_OK)
                        return retval;
        }
 
        return ERROR_OK;
 }
 
-
 /* Single aligned words are guaranteed to use 16 or 32 bit access
  * mode respectively, otherwise data is handled as quickly as
  * possible
  */
-int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
+int target_read_buffer(struct target_s *target, u32 address, u32 size, uint8_t *buffer)
 {
        int retval;
        LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
 
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
 
+       if (size == 0) {
+               return ERROR_OK;
+       }
+
        if ((address + size - 1) < address)
        {
                /* GDB can request this when e.g. PC is 0xfffffffc*/
@@ -1079,18 +1199,18 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
 
        if (((address % 2) == 0) && (size == 2))
        {
-               return target->type->read_memory(target, address, 2, 1, buffer);
+               return target_read_memory(target, address, 2, 1, buffer);
        }
 
        /* handle unaligned head bytes */
        if (address % 4)
        {
-               int unaligned = 4 - (address % 4);
+               u32 unaligned = 4 - (address % 4);
 
                if (unaligned > size)
                        unaligned = size;
 
-               if ((retval = target->type->read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
+               if ((retval = target_read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
                        return retval;
 
                buffer += unaligned;
@@ -1103,7 +1223,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
        {
                int aligned = size - (size % 4);
 
-               if ((retval = target->type->read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
+               if ((retval = target_read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
                        return retval;
 
                buffer += aligned;
@@ -1114,7 +1234,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
        /* handle tail writes of less than 4 bytes */
        if (size > 0)
        {
-               if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)
+               if ((retval = target_read_memory(target, address, 1, size, buffer)) != ERROR_OK)
                        return retval;
        }
 
@@ -1123,11 +1243,11 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
 
 int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc)
 {
-       u8 *buffer;
+       uint8_t *buffer;
        int retval;
-       int i;
+       u32 i;
        u32 checksum = 0;
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -1169,7 +1289,7 @@ int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32*
 int target_blank_check_memory(struct target_s *target, u32 address, u32 size, u32* blank)
 {
        int retval;
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -1185,14 +1305,14 @@ int target_blank_check_memory(struct target_s *target, u32 address, u32 size, u3
 
 int target_read_u32(struct target_s *target, u32 address, u32 *value)
 {
-       u8 value_buf[4];
-       if (!target->type->examined)
+       uint8_t value_buf[4];
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
 
-       int retval = target->type->read_memory(target, address, 4, 1, value_buf);
+       int retval = target_read_memory(target, address, 4, 1, value_buf);
 
        if (retval == ERROR_OK)
        {
@@ -1210,14 +1330,14 @@ int target_read_u32(struct target_s *target, u32 address, u32 *value)
 
 int target_read_u16(struct target_s *target, u32 address, u16 *value)
 {
-       u8 value_buf[2];
-       if (!target->type->examined)
+       uint8_t value_buf[2];
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
 
-       int retval = target->type->read_memory(target, address, 2, 1, value_buf);
+       int retval = target_read_memory(target, address, 2, 1, value_buf);
 
        if (retval == ERROR_OK)
        {
@@ -1233,10 +1353,10 @@ int target_read_u16(struct target_s *target, u32 address, u16 *value)
        return retval;
 }
 
-int target_read_u8(struct target_s *target, u32 address, u8 *value)
+int target_read_u8(struct target_s *target, u32 address, uint8_t *value)
 {
-       int retval = target->type->read_memory(target, address, 1, 1, value);
-       if (!target->type->examined)
+       int retval = target_read_memory(target, address, 1, 1, value);
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -1258,8 +1378,8 @@ int target_read_u8(struct target_s *target, u32 address, u8 *value)
 int target_write_u32(struct target_s *target, u32 address, u32 value)
 {
        int retval;
-       u8 value_buf[4];
-       if (!target->type->examined)
+       uint8_t value_buf[4];
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -1268,7 +1388,7 @@ int target_write_u32(struct target_s *target, u32 address, u32 value)
        LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
 
        target_buffer_set_u32(target, value_buf, value);
-       if ((retval = target->type->write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
+       if ((retval = target_write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
        {
                LOG_DEBUG("failed: %i", retval);
        }
@@ -1279,8 +1399,8 @@ int target_write_u32(struct target_s *target, u32 address, u32 value)
 int target_write_u16(struct target_s *target, u32 address, u16 value)
 {
        int retval;
-       u8 value_buf[2];
-       if (!target->type->examined)
+       uint8_t value_buf[2];
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -1289,7 +1409,7 @@ int target_write_u16(struct target_s *target, u32 address, u16 value)
        LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
 
        target_buffer_set_u16(target, value_buf, value);
-       if ((retval = target->type->write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
+       if ((retval = target_write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
        {
                LOG_DEBUG("failed: %i", retval);
        }
@@ -1297,10 +1417,10 @@ int target_write_u16(struct target_s *target, u32 address, u16 value)
        return retval;
 }
 
-int target_write_u8(struct target_s *target, u32 address, u8 value)
+int target_write_u8(struct target_s *target, u32 address, uint8_t value)
 {
        int retval;
-       if (!target->type->examined)
+       if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
@@ -1308,7 +1428,7 @@ int target_write_u8(struct target_s *target, u32 address, u8 value)
 
        LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, value);
 
-       if ((retval = target->type->write_memory(target, address, 1, 1, &value)) != ERROR_OK)
+       if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
        {
                LOG_DEBUG("failed: %i", retval);
        }
@@ -1319,6 +1439,21 @@ int target_write_u8(struct target_s *target, u32 address, u8 value)
 int target_register_user_commands(struct command_context_s *cmd_ctx)
 {
        int retval = ERROR_OK;
+
+
+       /* script procedures */
+       register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
+       register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
+       register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values  <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
+
+       register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
+                       "same args as load_image, image stored in memory - mainly for profiling purposes");
+
+       register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
+                       "loads active fast load image to current target - mainly for profiling purposes");
+
+
+       register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
        register_command(cmd_ctx,  NULL, "reg", handle_reg_command, COMMAND_EXEC, "display or set a register");
        register_command(cmd_ctx,  NULL, "poll", handle_poll_command, COMMAND_EXEC, "poll target state");
        register_command(cmd_ctx,  NULL, "wait_halt", handle_wait_halt_command, COMMAND_EXEC, "wait for target halt [time (s)]");
@@ -1344,121 +1479,83 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx,  NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf'|'s19'] [min_address] [max_length]");
        register_command(cmd_ctx,  NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
        register_command(cmd_ctx,  NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");
+       register_command(cmd_ctx,  NULL, "test_image", handle_test_image_command, COMMAND_EXEC, "test_image <file> [offset] [type]");
 
        if((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)
                return retval;
        if((retval = trace_register_commands(cmd_ctx)) != ERROR_OK)
                return retval;
 
-
        return retval;
 }
 
-int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       char *cp;
        target_t *target = all_targets;
 
        if (argc == 1)
        {
-               /* try as tcltarget name */
-               for( target = all_targets ; target ; target++ ){
-                 if( target->cmd_name ){
-                       if( 0 == strcmp( args[0], target->cmd_name ) ){
-                               /* MATCH */
-                               goto Match;
-                       }
-                 }
-               }
-               /* no match, try as number */
-
-               int num = strtoul(args[0], &cp, 0 );
-               if( *cp != 0 ){
-                       /* then it was not a number */
-                       command_print( cmd_ctx, "Target: %s unknown, try one of:\n", args[0] );
-                       goto DumpTargets;
-               }
-
-               target = get_target_by_num( num );
-               if( target == NULL ){
+               target = get_target(args[0]);
+               if (target == NULL) {
                        command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0] );
                        goto DumpTargets;
                }
-       Match:
+               if (!target->tap->enabled) {
+                       command_print(cmd_ctx,"Target: TAP %s is disabled, "
+                                       "can't be the current target\n",
+                                       target->tap->dotted_name);
+                       return ERROR_FAIL;
+               }
+
                cmd_ctx->current_target = target->target_number;
                return ERROR_OK;
        }
- DumpTargets:
+DumpTargets:
 
-       command_print(cmd_ctx, "    CmdName    Type       Endian     ChainPos State     ");
-       command_print(cmd_ctx, "--  ---------- ---------- ---------- -------- ----------");
+       target = all_targets;
+       command_print(cmd_ctx, "    TargetName         Type       Endian TapName            State       ");
+       command_print(cmd_ctx, "--  ------------------ ---------- ------ ------------------ ------------");
        while (target)
        {
-               /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
-               command_print(cmd_ctx, "%2d: %-10s %-10s %-10s %8d %s",
+               const char *state;
+               char marker = ' ';
+
+               if (target->tap->enabled)
+                       state = Jim_Nvp_value2name_simple(nvp_target_state,
+                                       target->state)->name;
+               else
+                       state = "tap-disabled";
+
+               if (cmd_ctx->current_target == target->target_number)
+                       marker = '*';
+
+               /* keep columns lined up to match the headers above */
+               command_print(cmd_ctx, "%2d%c %-18s %-10s %-6s %-18s %s",
                                          target->target_number,
+                                         marker,
                                          target->cmd_name,
-                                         target->type->name,
-                                         Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness )->name,
-                                         target->chain_position,
-                                         Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
+                                         target_get_name(target),
+                                         Jim_Nvp_value2name_simple(nvp_target_endian,
+                                                               target->endianness)->name,
+                                         target->tap->dotted_name,
+                                         state);
                target = target->next;
        }
 
        return ERROR_OK;
 }
 
-
-
-int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int retval = ERROR_OK;
-       target_t *target = NULL;
-
-       if ((argc < 4) || (argc > 5))
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-
-       target = get_target_by_num(strtoul(args[0], NULL, 0));
-       if (!target)
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-       target_free_all_working_areas(target);
-
-       target->working_area_phys = target->working_area_virt = strtoul(args[1], NULL, 0);
-       if (argc == 5)
-       {
-               target->working_area_virt = strtoul(args[4], NULL, 0);
-       }
-       target->working_area_size = strtoul(args[2], NULL, 0);
-
-       if (strcmp(args[3], "backup") == 0)
-       {
-               target->backup_working_area = 1;
-       }
-       else if (strcmp(args[3], "nobackup") == 0)
-       {
-               target->backup_working_area = 0;
-       }
-       else
-       {
-               LOG_ERROR("unrecognized <backup|nobackup> argument (%s)", args[3]);
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-
-       return retval;
-}
-
-
-// every 300ms we check for reset & powerdropout and issue a "reset halt" if
-// so.
+/* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
 
 static int powerDropout;
 static int srstAsserted;
 
-static int sense_handler()
+static int runPowerRestore;
+static int runPowerDropout;
+static int runSrstAsserted;
+static int runSrstDeasserted;
+
+static int sense_handler(void)
 {
        static int prevSrstAsserted = 0;
        static int prevPowerdropout = 0;
@@ -1471,7 +1568,7 @@ static int sense_handler()
        powerRestored = prevPowerdropout && !powerDropout;
        if (powerRestored)
        {
-               LOG_USER("Sensed power restore.");
+               runPowerRestore = 1;
        }
 
        long long current = timeval_ms();
@@ -1479,7 +1576,7 @@ static int sense_handler()
        int waitMore = lastPower + 2000 > current;
        if (powerDropout && !waitMore)
        {
-               LOG_USER("Sensed power dropout.");
+               runPowerDropout = 1;
                lastPower = current;
        }
 
@@ -1493,13 +1590,13 @@ static int sense_handler()
        waitMore = lastSrst + 2000 > current;
        if (srstDeasserted && !waitMore)
        {
-               LOG_USER("Sensed nSRST deasserted");
+               runSrstDeasserted = 1;
                lastSrst = current;
        }
 
        if (!prevSrstAsserted && srstAsserted)
        {
-               LOG_USER("Sensed nSRST asserted");
+               runSrstAsserted = 1;
        }
 
        prevSrstAsserted = srstAsserted;
@@ -1516,32 +1613,82 @@ static int sense_handler()
        return ERROR_OK;
 }
 
-
 /* process target state changes */
 int handle_target(void *priv)
 {
        int retval = ERROR_OK;
-       target_t *target = all_targets;
 
-       while (target)
+       /* we do not want to recurse here... */
+       static int recursive = 0;
+       if (! recursive)
        {
+               recursive = 1;
                sense_handler();
+               /* danger! running these procedures can trigger srst assertions and power dropouts.
+                * We need to avoid an infinite loop/recursion here and we do that by
+                * clearing the flags after running these events.
+                */
+               int did_something = 0;
+               if (runSrstAsserted)
+               {
+                       Jim_Eval( interp, "srst_asserted");
+                       did_something = 1;
+               }
+               if (runSrstDeasserted)
+               {
+                       Jim_Eval( interp, "srst_deasserted");
+                       did_something = 1;
+               }
+               if (runPowerDropout)
+               {
+                       Jim_Eval( interp, "power_dropout");
+                       did_something = 1;
+               }
+               if (runPowerRestore)
+               {
+                       Jim_Eval( interp, "power_restore");
+                       did_something = 1;
+               }
+
+               if (did_something)
+               {
+                       /* clear detect flags */
+                       sense_handler();
+               }
+
+               /* clear action flags */
+
+               runSrstAsserted=0;
+               runSrstDeasserted=0;
+               runPowerRestore=0;
+               runPowerDropout=0;
+
+               recursive = 0;
+       }
+
+       /* Poll targets for state changes unless that's globally disabled.
+        * Skip targets that are currently disabled.
+        */
+       for (target_t *target = all_targets;
+                       target_continuous_poll && target;
+                       target = target->next)
+       {
+               if (!target->tap->enabled)
+                       continue;
 
                /* only poll target if we've got power and srst isn't asserted */
-               if (target_continous_poll&&!powerDropout&&!srstAsserted)
+               if (!powerDropout && !srstAsserted)
                {
                        /* polling may fail silently until the target has been examined */
                        if((retval = target_poll(target)) != ERROR_OK)
                                return retval;
                }
-
-               target = target->next;
        }
 
        return retval;
 }
 
-int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        target_t *target;
        reg_t *reg = NULL;
@@ -1576,16 +1723,19 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
        /* access a single register by its ordinal number */
        if ((args[0][0] >= '0') && (args[0][0] <= '9'))
        {
-               int num = strtoul(args[0], NULL, 0);
-               reg_cache_t *cache = target->reg_cache;
+               unsigned num;
+               int retval = parse_uint(args[0], &num);
+               if (ERROR_OK != retval)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
 
+               reg_cache_t *cache = target->reg_cache;
                count = 0;
                while(cache)
                {
                        int i;
                        for (i = 0; i < cache->num_regs; i++)
                        {
-                               if (count++ == num)
+                               if (count++ == (int)num)
                                {
                                        reg = &cache->reg_list[i];
                                        break;
@@ -1632,7 +1782,7 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
        /* set register value */
        if (argc == 2)
        {
-               u8 *buf = malloc(CEIL(reg->size, 8));
+               uint8_t *buf = malloc(CEIL(reg->size, 8));
                str_to_buf(args[1], strlen(args[1]), buf, reg->size, 0);
 
                reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
@@ -1652,17 +1802,23 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
        return ERROR_OK;
 }
 
-
-int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        int retval = ERROR_OK;
        target_t *target = get_current_target(cmd_ctx);
 
        if (argc == 0)
        {
-               if((retval = target_poll(target)) != ERROR_OK)
+               command_print(cmd_ctx, "background polling: %s",
+                               target_continuous_poll ?  "on" : "off");
+               command_print(cmd_ctx, "TAP: %s (%s)",
+                               target->tap->dotted_name,
+                               target->tap->enabled ? "enabled" : "disabled");
+               if (!target->tap->enabled)
+                       return ERROR_OK;
+               if ((retval = target_poll(target)) != ERROR_OK)
                        return retval;
-               if((retval = target_arch_state(target)) != ERROR_OK)
+               if ((retval = target_arch_state(target)) != ERROR_OK)
                        return retval;
 
        }
@@ -1670,11 +1826,11 @@ int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
        {
                if (strcmp(args[0], "on") == 0)
                {
-                       target_continous_poll = 1;
+                       target_continuous_poll = 1;
                }
                else if (strcmp(args[0], "off") == 0)
                {
-                       target_continous_poll = 0;
+                       target_continuous_poll = 0;
                }
                else
                {
@@ -1685,59 +1841,69 @@ int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-
        return retval;
 }
 
-int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       int ms = 5000;
+       if (argc > 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if (argc > 0)
+       unsigned ms = 5000;
+       if (1 == argc)
        {
-               char *end;
-
-               ms = strtoul(args[0], &end, 0) * 1000;
-               if (*end)
+               int retval = parse_uint(args[0], &ms);
+               if (ERROR_OK != retval)
                {
                        command_print(cmd_ctx, "usage: %s [seconds]", cmd);
-                       return ERROR_OK;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
                }
+               // convert seconds (given) to milliseconds (needed)
+               ms *= 1000;
        }
-       target_t *target = get_current_target(cmd_ctx);
 
+       target_t *target = get_current_target(cmd_ctx);
        return target_wait_state(target, TARGET_HALTED, ms);
 }
 
+/* wait for target state to change. The trick here is to have a low
+ * latency for short waits and not to suck up all the CPU time
+ * on longer waits.
+ *
+ * After 500ms, keep_alive() is invoked
+ */
 int target_wait_state(target_t *target, enum target_state state, int ms)
 {
        int retval;
-       struct timeval timeout, now;
+       long long then=0, cur;
        int once=1;
-       gettimeofday(&timeout, NULL);
-       timeval_add_time(&timeout, 0, ms * 1000);
 
        for (;;)
        {
                if ((retval=target_poll(target))!=ERROR_OK)
                        return retval;
-               keep_alive();
                if (target->state == state)
                {
                        break;
                }
+               cur = timeval_ms();
                if (once)
                {
                        once=0;
+                       then = timeval_ms();
                        LOG_DEBUG("waiting for target %s...",
-                             Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
+                               Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
                }
 
-               gettimeofday(&now, NULL);
-               if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
+               if (cur-then>500)
+               {
+                       keep_alive();
+               }
+
+               if ((cur-then)>ms)
                {
                        LOG_ERROR("timed out while waiting for target %s",
-                             Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
+                               Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
                        return ERROR_FAIL;
                }
        }
@@ -1745,22 +1911,29 @@ int target_wait_state(target_t *target, enum target_state state, int ms)
        return ERROR_OK;
 }
 
-int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
-
        LOG_DEBUG("-");
 
-       if ((retval = target_halt(target)) != ERROR_OK)
-       {
+       target_t *target = get_current_target(cmd_ctx);
+       int retval = target_halt(target);
+       if (ERROR_OK != retval)
                return retval;
+
+       if (argc == 1)
+       {
+               unsigned wait;
+               retval = parse_uint(args[0], &wait);
+               if (ERROR_OK != retval)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               if (!wait)
+                       return ERROR_OK;
        }
 
        return handle_wait_halt_command(cmd_ctx, cmd, args, argc);
 }
 
-int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        target_t *target = get_current_target(cmd_ctx);
 
@@ -1771,13 +1944,15 @@ int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd,
        return ERROR_OK;
 }
 
-int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       const Jim_Nvp *n;
-       enum target_reset_mode reset_mode = RESET_RUN;
+       if (argc > 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if (argc >= 1)
+       enum target_reset_mode reset_mode = RESET_RUN;
+       if (argc == 1)
        {
+               const Jim_Nvp *n;
                n = Jim_Nvp_name2value_simple( nvp_reset_modes, args[0] );
                if( (n->name == NULL) || (n->value == RESET_UNKNOWN) ){
                        return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1790,136 +1965,163 @@ int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **ar
 }
 
 
-int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
+       if (argc > 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       target_handle_event( target, TARGET_EVENT_OLD_pre_resume );
+       target_t *target = get_current_target(cmd_ctx);
+       target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
 
-       if (argc == 0)
-               retval = target_resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
-       else if (argc == 1)
-               retval = target_resume(target, 0, strtoul(args[0], NULL, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
-       else
+       /* with no args, resume from current pc, addr = 0,
+        * with one arguments, addr = args[0],
+        * handle breakpoints, not debugging */
+       u32 addr = 0;
+       if (argc == 1)
        {
-               retval = ERROR_COMMAND_SYNTAX_ERROR;
+               int retval = parse_u32(args[0], &addr);
+               if (ERROR_OK != retval)
+                       return retval;
        }
 
-       return retval;
+       return target_resume(target, 0, addr, 1, 0);
 }
 
-int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       target_t *target = get_current_target(cmd_ctx);
+       if (argc > 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        LOG_DEBUG("-");
 
-       if (argc == 0)
-               return target->type->step(target, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
-
+       /* with no args, step from current pc, addr = 0,
+        * with one argument addr = args[0],
+        * handle breakpoints, debugging */
+       u32 addr = 0;
        if (argc == 1)
-               return target->type->step(target, 0, strtoul(args[0], NULL, 0), 1); /* addr = args[0], handle breakpoints */
+       {
+               int retval = parse_u32(args[0], &addr);
+               if (ERROR_OK != retval)
+                       return retval;
+       }
 
-       return ERROR_OK;
+       target_t *target = get_current_target(cmd_ctx);
+       return target->type->step(target, 0, addr, 1);
 }
 
-int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static void handle_md_output(struct command_context_s *cmd_ctx,
+               struct target_s *target, u32 address, unsigned size,
+               unsigned count, const uint8_t *buffer)
 {
-       const int line_bytecnt = 32;
-       int count = 1;
-       int size = 4;
-       u32 address = 0;
-       int line_modulo;
-       int i;
+       const unsigned line_bytecnt = 32;
+       unsigned line_modulo = line_bytecnt / size;
 
-       char output[128];
-       int output_len;
+       char output[line_bytecnt * 4 + 1];
+       unsigned output_len = 0;
 
-       int retval;
-
-       u8 *buffer;
-       target_t *target = get_current_target(cmd_ctx);
+       const char *value_fmt;
+       switch (size) {
+       case 4: value_fmt = "%8.8x "; break;
+       case 2: value_fmt = "%4.2x "; break;
+       case 1: value_fmt = "%2.2x "; break;
+       default:
+               LOG_ERROR("invalid memory read size: %u", size);
+               exit(-1);
+       }
 
-       if (argc < 1)
-               return ERROR_OK;
+       for (unsigned i = 0; i < count; i++)
+       {
+               if (i % line_modulo == 0)
+               {
+                       output_len += snprintf(output + output_len,
+                                       sizeof(output) - output_len,
+                                       "0x%8.8x: ", address + (i*size));
+               }
 
-       if (argc == 2)
-               count = strtoul(args[1], NULL, 0);
+               u32 value=0;
+               const uint8_t *value_ptr = buffer + i * size;
+               switch (size) {
+               case 4: value = target_buffer_get_u32(target, value_ptr); break;
+               case 2: value = target_buffer_get_u16(target, value_ptr); break;
+               case 1: value = *value_ptr;
+               }
+               output_len += snprintf(output + output_len,
+                               sizeof(output) - output_len,
+                               value_fmt, value);
 
-       address = strtoul(args[0], NULL, 0);
+               if ((i % line_modulo == line_modulo - 1) || (i == count - 1))
+               {
+                       command_print(cmd_ctx, "%s", output);
+                       output_len = 0;
+               }
+       }
+}
 
+static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc < 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       switch (cmd[2])
-       {
-               case 'w':
-                       size = 4; line_modulo = line_bytecnt / 4;
-                       break;
-               case 'h':
-                       size = 2; line_modulo = line_bytecnt / 2;
-                       break;
-               case 'b':
-                       size = 1; line_modulo = line_bytecnt / 1;
-                       break;
-               default:
-                       return ERROR_OK;
+       unsigned size = 0;
+       switch (cmd[2]) {
+       case 'w': size = 4; break;
+       case 'h': size = 2; break;
+       case 'b': size = 1; break;
+       default: return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       buffer = calloc(count, size);
-       retval  = target->type->read_memory(target, address, size, count, buffer);
-       if (retval == ERROR_OK)
-       {
-               output_len = 0;
+       u32 address;
+       int retval = parse_u32(args[0], &address);
+       if (ERROR_OK != retval)
+               return retval;
 
-               for (i = 0; i < count; i++)
-               {
-                       if (i%line_modulo == 0)
-                               output_len += snprintf(output + output_len, 128 - output_len, "0x%8.8x: ", address + (i*size));
+       unsigned count = 1;
+       if (argc == 2)
+       {
+               retval = parse_uint(args[1], &count);
+               if (ERROR_OK != retval)
+                       return retval;
+       }
 
-                       switch (size)
-                       {
-                               case 4:
-                                       output_len += snprintf(output + output_len, 128 - output_len, "%8.8x ", target_buffer_get_u32(target, &buffer[i*4]));
-                                       break;
-                               case 2:
-                                       output_len += snprintf(output + output_len, 128 - output_len, "%4.4x ", target_buffer_get_u16(target, &buffer[i*2]));
-                                       break;
-                               case 1:
-                                       output_len += snprintf(output + output_len, 128 - output_len, "%2.2x ", buffer[i*1]);
-                                       break;
-                       }
+       uint8_t *buffer = calloc(count, size);
 
-                       if ((i%line_modulo == line_modulo-1) || (i == count - 1))
-                       {
-                               command_print(cmd_ctx, output);
-                               output_len = 0;
-                       }
-               }
-       }
+       target_t *target = get_current_target(cmd_ctx);
+       retval = target_read_memory(target,
+                               address, size, count, buffer);
+       if (ERROR_OK == retval)
+               handle_md_output(cmd_ctx, target, address, size, count, buffer);
 
        free(buffer);
 
        return retval;
 }
 
-int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       u32 address = 0;
-       u32 value = 0;
-       int count = 1;
-       int i;
-       int wordsize;
-       target_t *target = get_current_target(cmd_ctx);
-       u8 value_buf[4];
-
         if ((argc < 2) || (argc > 3))
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       address = strtoul(args[0], NULL, 0);
-       value = strtoul(args[1], NULL, 0);
+       u32 address;
+       int retval = parse_u32(args[0], &address);
+       if (ERROR_OK != retval)
+               return retval;
+
+       u32 value;
+       retval = parse_u32(args[1], &value);
+       if (ERROR_OK != retval)
+               return retval;
+
+       unsigned count = 1;
        if (argc == 3)
-               count = strtoul(args[2], NULL, 0);
+       {
+               retval = parse_uint(args[2], &count);
+               if (ERROR_OK != retval)
+                       return retval;
+       }
 
+       target_t *target = get_current_target(cmd_ctx);
+       unsigned wordsize;
+       uint8_t value_buf[4];
        switch (cmd[2])
        {
                case 'w':
@@ -1937,86 +2139,83 @@ int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
                default:
                        return ERROR_COMMAND_SYNTAX_ERROR;
        }
-       for (i=0; i<count; i++)
+       for (unsigned i = 0; i < count; i++)
        {
-               int retval;
-               switch (wordsize)
-               {
-                       case 4:
-                               retval = target->type->write_memory(target, address + i*wordsize, 4, 1, value_buf);
-                               break;
-                       case 2:
-                               retval = target->type->write_memory(target, address + i*wordsize, 2, 1, value_buf);
-                               break;
-                       case 1:
-                               retval = target->type->write_memory(target, address + i*wordsize, 1, 1, value_buf);
-                       break;
-                       default:
-                       return ERROR_OK;
-               }
-               keep_alive();
-
-               if (retval!=ERROR_OK)
-               {
+               retval = target_write_memory(target,
+                               address + i * wordsize, wordsize, 1, value_buf);
+               if (ERROR_OK != retval)
                        return retval;
-               }
+               keep_alive();
        }
 
        return ERROR_OK;
 
 }
 
-int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int parse_load_image_command_args(char **args, int argc,
+               image_t *image, u32 *min_address, u32 *max_address)
 {
-       u8 *buffer;
-       u32 buf_cnt;
-       u32 image_size;
-       u32 min_address=0;
-       u32 max_address=0xffffffff;
-       int i;
-       int retval, retvaltemp;
-
-       image_t image;
-
-       duration_t duration;
-       char *duration_text;
-
-       target_t *target = get_current_target(cmd_ctx);
-
-       if ((argc < 1)||(argc > 5))
-       {
+       if (argc < 1 || argc > 5)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
-       /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
+       /* a base address isn't always necessary,
+        * default to 0x0 (i.e. don't relocate) */
        if (argc >= 2)
        {
-               image.base_address_set = 1;
-               image.base_address = strtoul(args[1], NULL, 0);
+               u32 addr;
+               int retval = parse_u32(args[1], &addr);
+               if (ERROR_OK != retval)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               image->base_address = addr;
+               image->base_address_set = 1;
        }
        else
-       {
-               image.base_address_set = 0;
-       }
+               image->base_address_set = 0;
 
+       image->start_address_set = 0;
 
-       image.start_address_set = 0;
-
-       if (argc>=4)
+       if (argc >= 4)
        {
-               min_address=strtoul(args[3], NULL, 0);
+               int retval = parse_u32(args[3], min_address);
+               if (ERROR_OK != retval)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
        }
-       if (argc>=5)
+       if (argc == 5)
        {
-               max_address=strtoul(args[4], NULL, 0)+min_address;
+               int retval = parse_u32(args[4], max_address);
+               if (ERROR_OK != retval)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               // use size (given) to find max (required)
+               *max_address += *min_address;
        }
 
-       if (min_address>max_address)
-       {
+       if (*min_address > *max_address)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
+       return ERROR_OK;
+}
+
+static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       uint8_t *buffer;
+       u32 buf_cnt;
+       u32 image_size;
+       u32 min_address = 0;
+       u32 max_address = 0xffffffff;
+       int i;
+       int retvaltemp;
+
+       image_t image;
+
+       duration_t duration;
+       char *duration_text;
+       
+       int retval = parse_load_image_command_args(args, argc,
+                       &image, &min_address, &max_address);
+       if (ERROR_OK != retval)
+               return retval;
 
+       target_t *target = get_current_target(cmd_ctx);
        duration_start_measure(&duration);
 
        if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
@@ -2044,7 +2243,6 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
                u32 offset=0;
                u32 length=buf_cnt;
 
-
                /* DANGER!!! beware of unsigned comparision here!!! */
 
                if ((image.sections[i].base_address+buf_cnt>=min_address)&&
@@ -2092,14 +2290,12 @@ int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char
 
 }
 
-int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        fileio_t fileio;
 
-       u32 address;
-       u32 size;
-       u8 buffer[560];
-       int retval=ERROR_OK, retvaltemp;
+       uint8_t buffer[560];
+       int retvaltemp;
 
        duration_t duration;
        char *duration_text;
@@ -2112,14 +2308,15 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
                return ERROR_OK;
        }
 
-       address = strtoul(args[1], NULL, 0);
-       size = strtoul(args[2], NULL, 0);
+       u32 address;
+       int retval = parse_u32(args[1], &address);
+       if (ERROR_OK != retval)
+               return retval;
 
-       if ((address & 3) || (size & 3))
-       {
-               command_print(cmd_ctx, "only 32-bit aligned address and size are supported");
-               return ERROR_OK;
-       }
+       u32 size;
+       retval = parse_u32(args[2], &size);
+       if (ERROR_OK != retval)
+               return retval;
 
        if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
        {
@@ -2133,7 +2330,7 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
                u32 size_written;
                u32 this_run_size = (size > 560) ? 560 : size;
 
-               retval = target->type->read_memory(target, address, 4, this_run_size / 4, buffer);
+               retval = target_read_buffer(target, address, this_run_size, buffer);
                if (retval != ERROR_OK)
                {
                        break;
@@ -2157,16 +2354,17 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
 
        if (retval==ERROR_OK)
        {
-               command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);
+               command_print(cmd_ctx, "dumped %lld byte in %s",
+                               fileio.size, duration_text);
+               free(duration_text);
        }
-       free(duration_text);
 
-       return ERROR_OK;
+       return retval;
 }
 
-int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_verify_image_command_internal(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, int verify)
 {
-       u8 *buffer;
+       uint8_t *buffer;
        u32 buf_cnt;
        u32 image_size;
        int i;
@@ -2196,8 +2394,12 @@ int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, ch
 
        if (argc >= 2)
        {
+               u32 addr;
+               retval = parse_u32(args[1], &addr);
+               if (ERROR_OK != retval)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               image.base_address = addr;
                image.base_address_set = 1;
-               image.base_address = strtoul(args[1], NULL, 0);
        }
        else
        {
@@ -2228,55 +2430,61 @@ int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        break;
                }
 
-               /* calculate checksum of image */
-               image_calculate_checksum( buffer, buf_cnt, &checksum );
-
-               retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
-               if( retval != ERROR_OK )
-               {
-                       free(buffer);
-                       break;
-               }
-
-               if( checksum != mem_checksum )
+               if (verify)
                {
-                       /* failed crc checksum, fall back to a binary compare */
-                       u8 *data;
-
-                       command_print(cmd_ctx, "checksum mismatch - attempting binary compare");
+                       /* calculate checksum of image */
+                       image_calculate_checksum( buffer, buf_cnt, &checksum );
 
-                       data = (u8*)malloc(buf_cnt);
-
-                       /* Can we use 32bit word accesses? */
-                       int size = 1;
-                       int count = buf_cnt;
-                       if ((count % 4) == 0)
+                       retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
+                       if( retval != ERROR_OK )
                        {
-                               size *= 4;
-                               count /= 4;
+                               free(buffer);
+                               break;
                        }
-                       retval = target->type->read_memory(target, image.sections[i].base_address, size, count, data);
-                       if (retval == ERROR_OK)
+
+                       if( checksum != mem_checksum )
                        {
-                               int t;
-                               for (t = 0; t < buf_cnt; t++)
+                               /* failed crc checksum, fall back to a binary compare */
+                               uint8_t *data;
+
+                               command_print(cmd_ctx, "checksum mismatch - attempting binary compare");
+
+                               data = (uint8_t*)malloc(buf_cnt);
+
+                               /* Can we use 32bit word accesses? */
+                               int size = 1;
+                               int count = buf_cnt;
+                               if ((count % 4) == 0)
                                {
-                                       if (data[t] != buffer[t])
-                                       {
-                                               command_print(cmd_ctx, "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n", t + image.sections[i].base_address, data[t], buffer[t]);
-                                               free(data);
-                                               free(buffer);
-                                               retval=ERROR_FAIL;
-                                               goto done;
-                                       }
-                                       if ((t%16384)==0)
+                                       size *= 4;
+                                       count /= 4;
+                               }
+                               retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
+                               if (retval == ERROR_OK)
+                               {
+                                       u32 t;
+                                       for (t = 0; t < buf_cnt; t++)
                                        {
-                                               keep_alive();
+                                               if (data[t] != buffer[t])
+                                               {
+                                                       command_print(cmd_ctx, "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n", 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();
+                                               }
                                        }
                                }
-                       }
 
-                       free(data);
+                               free(data);
+                       }
+               } else
+               {
+                       command_print(cmd_ctx, "address 0x%08x length 0x%08x", image.sections[i].base_address, buf_cnt);
                }
 
                free(buffer);
@@ -2301,72 +2509,107 @@ done:
        return retval;
 }
 
-int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
+       return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 1);
+}
 
-       if (argc == 0)
-       {
-               breakpoint_t *breakpoint = target->breakpoints;
+static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 0);
+}
 
-               while (breakpoint)
-               {
-                       if (breakpoint->type == BKPT_SOFT)
-                       {
-                               char* buf = buf_to_str(breakpoint->orig_instr, breakpoint->length, 16);
-                               command_print(cmd_ctx, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint->address, breakpoint->length, breakpoint->set, buf);
-                               free(buf);
-                       }
-                       else
-                       {
-                               command_print(cmd_ctx, "0x%8.8x, 0x%x, %i", breakpoint->address, breakpoint->length, breakpoint->set);
-                       }
-                       breakpoint = breakpoint->next;
-               }
-       }
-       else if (argc >= 2)
+static int handle_bp_command_list(struct command_context_s *cmd_ctx)
+{
+       target_t *target = get_current_target(cmd_ctx);
+       breakpoint_t *breakpoint = target->breakpoints;
+       while (breakpoint)
        {
-               int hw = BKPT_SOFT;
-               u32 length = 0;
-
-               length = strtoul(args[1], NULL, 0);
-
-               if (argc >= 3)
-                       if (strcmp(args[2], "hw") == 0)
-                               hw = BKPT_HARD;
-
-               if ((retval = breakpoint_add(target, strtoul(args[0], NULL, 0), length, hw)) != ERROR_OK)
+               if (breakpoint->type == BKPT_SOFT)
                {
-                       LOG_ERROR("Failure setting breakpoints");
+                       char* buf = buf_to_str(breakpoint->orig_instr,
+                                       breakpoint->length, 16);
+                       command_print(cmd_ctx, "0x%8.8x, 0x%x, %i, 0x%s",
+                                       breakpoint->address, breakpoint->length,
+                                       breakpoint->set, buf);
+                       free(buf);
                }
                else
                {
-                       command_print(cmd_ctx, "breakpoint added at address 0x%8.8x", strtoul(args[0], NULL, 0));
+                       command_print(cmd_ctx, "0x%8.8x, 0x%x, %i",
+                                       breakpoint->address, breakpoint->length, breakpoint->set);
                }
+
+               breakpoint = breakpoint->next;
        }
+       return ERROR_OK;
+}
+
+static int handle_bp_command_set(struct command_context_s *cmd_ctx,
+               u32 addr, u32 length, int hw)
+{
+       target_t *target = get_current_target(cmd_ctx);
+       int retval = breakpoint_add(target, addr, length, hw);
+       if (ERROR_OK == retval)
+               command_print(cmd_ctx, "breakpoint set at 0x%8.8x", addr);
        else
+               LOG_ERROR("Failure setting breakpoint");
+       return retval;
+}
+
+static int handle_bp_command(struct command_context_s *cmd_ctx,
+               char *cmd, char **args, int argc)
+{
+       if (argc == 0)
+               return handle_bp_command_list(cmd_ctx);
+
+       if (argc < 2 || argc > 3)
        {
                command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       return ERROR_OK;
+       u32 addr;
+       int retval = parse_u32(args[0], &addr);
+       if (ERROR_OK != retval)
+               return retval;
+
+       u32 length;
+       retval = parse_u32(args[1], &length);
+       if (ERROR_OK != retval)
+               return retval;
+
+       int hw = BKPT_SOFT;
+       if (argc == 3)
+       {
+               if (strcmp(args[2], "hw") == 0)
+                       hw = BKPT_HARD;
+               else
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       return handle_bp_command_set(cmd_ctx, addr, length, hw);
 }
 
-int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       target_t *target = get_current_target(cmd_ctx);
+       if (argc != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if (argc > 0)
-               breakpoint_remove(target, strtoul(args[0], NULL, 0));
+       u32 addr;
+       int retval = parse_u32(args[0], &addr);
+       if (ERROR_OK != retval)
+               return retval;
+
+       target_t *target = get_current_target(cmd_ctx);
+       breakpoint_remove(target, addr);
 
        return ERROR_OK;
 }
 
-int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        target_t *target = get_current_target(cmd_ctx);
-       int retval;
 
        if (argc == 0)
        {
@@ -2374,126 +2617,153 @@ int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
 
                while (watchpoint)
                {
-                       command_print(cmd_ctx, "address: 0x%8.8x, len: 0x%8.8x, r/w/a: %i, value: 0x%8.8x, mask: 0x%8.8x", watchpoint->address, watchpoint->length, watchpoint->rw, watchpoint->value, watchpoint->mask);
-                       watchpoint = watchpoint->next;
-               }
-       }
-       else if (argc >= 2)
-       {
-               enum watchpoint_rw type = WPT_ACCESS;
-               u32 data_value = 0x0;
-               u32 data_mask = 0xffffffff;
-
-               if (argc >= 3)
-               {
-                       switch(args[2][0])
-                       {
-                               case 'r':
-                                       type = WPT_READ;
-                                       break;
-                               case 'w':
-                                       type = WPT_WRITE;
-                                       break;
-                               case 'a':
-                                       type = WPT_ACCESS;
-                                       break;
-                               default:
-                                       command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
-                                       return ERROR_OK;
-                       }
-               }
-               if (argc >= 4)
-               {
-                       data_value = strtoul(args[3], NULL, 0);
-               }
-               if (argc >= 5)
-               {
-                       data_mask = strtoul(args[4], NULL, 0);
-               }
-
-               if ((retval = watchpoint_add(target, strtoul(args[0], NULL, 0),
-                               strtoul(args[1], NULL, 0), type, data_value, data_mask)) != ERROR_OK)
-               {
-                       LOG_ERROR("Failure setting breakpoints");
+                       command_print(cmd_ctx, "address: 0x%8.8x, len: 0x%8.8x, r/w/a: %i, value: 0x%8.8x, mask: 0x%8.8x", watchpoint->address, watchpoint->length, watchpoint->rw, watchpoint->value, watchpoint->mask);
+                       watchpoint = watchpoint->next;
                }
+               return ERROR_OK;
        }
-       else
+
+       enum watchpoint_rw type = WPT_ACCESS;
+       u32 addr = 0;
+       u32 length = 0;
+       u32 data_value = 0x0;
+       u32 data_mask = 0xffffffff;
+       int retval;
+
+       switch (argc)
        {
+       case 5:
+               retval = parse_u32(args[4], &data_mask);
+               if (ERROR_OK != retval)
+                       return retval;
+               // fall through
+       case 4:
+               retval = parse_u32(args[3], &data_value);
+               if (ERROR_OK != retval)
+                       return retval;
+               // fall through
+       case 3:
+               switch(args[2][0])
+               {
+               case 'r':
+                       type = WPT_READ;
+                       break;
+               case 'w':
+                       type = WPT_WRITE;
+                       break;
+               case 'a':
+                       type = WPT_ACCESS;
+                       break;
+               default:
+                       LOG_ERROR("invalid watchpoint mode ('%c')", args[2][0]);
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               }
+               // fall through
+       case 2:
+               retval = parse_u32(args[1], &length);
+               if (ERROR_OK != retval)
+                       return retval;
+               retval = parse_u32(args[0], &addr);
+               if (ERROR_OK != retval)
+                       return retval;
+               break;
+
+       default:
                command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       return ERROR_OK;
+       retval = watchpoint_add(target, addr, length, type,
+                       data_value, data_mask);
+       if (ERROR_OK != retval)
+               LOG_ERROR("Failure setting watchpoints");
+
+       return retval;
 }
 
-int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       target_t *target = get_current_target(cmd_ctx);
+       if (argc != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       u32 addr;
+       int retval = parse_u32(args[0], &addr);
+       if (ERROR_OK != retval)
+               return retval;
 
-       if (argc > 0)
-               watchpoint_remove(target, strtoul(args[0], NULL, 0));
+       target_t *target = get_current_target(cmd_ctx);
+       watchpoint_remove(target, addr);
 
        return ERROR_OK;
 }
 
-int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
-       u32 va;
-       u32 pa;
 
+/**
+ * Translate a virtual address to a physical address.
+ *
+ * The low-level target implementation must have logged a detailed error
+ * which is forwarded to telnet/GDB session.
+ */
+static int handle_virt2phys_command(command_context_t *cmd_ctx,
+               char *cmd, char **args, int argc)
+{
        if (argc != 1)
-       {
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-       va = strtoul(args[0], NULL, 0);
 
+       u32 va;
+       int retval = parse_u32(args[0], &va);
+       if (ERROR_OK != retval)
+               return retval;
+       u32 pa;
+
+       target_t *target = get_current_target(cmd_ctx);
        retval = target->type->virt2phys(target, va, &pa);
        if (retval == ERROR_OK)
-       {
                command_print(cmd_ctx, "Physical address 0x%08x", pa);
-       }
-       else
-       {
-               /* lower levels will have logged a detailed error which is
-                * forwarded to telnet/GDB session.
-                */
-       }
+
        return retval;
 }
+
+static void writeData(FILE *f, const void *data, size_t len)
+{
+       size_t written = fwrite(data, 1, len, f);
+       if (written != len)
+               LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno));
+}
+
 static void writeLong(FILE *f, int l)
 {
        int i;
        for (i=0; i<4; i++)
        {
                char c=(l>>(i*8))&0xff;
-               fwrite(&c, 1, 1, f);
+               writeData(f, &c, 1);
        }
 
 }
+
 static void writeString(FILE *f, char *s)
 {
-       fwrite(s, 1, strlen(s), f);
+       writeData(f, s, strlen(s));
 }
 
-
-
-// Dump a gmon.out histogram file.
-static void writeGmon(u32 *samples, int sampleNum, char *filename)
+/* Dump a gmon.out histogram file. */
+static void writeGmon(u32 *samples, u32 sampleNum, char *filename)
 {
-       int i;
+       u32 i;
        FILE *f=fopen(filename, "w");
        if (f==NULL)
                return;
-       fwrite("gmon", 1, 4, f);
-       writeLong(f, 0x00000001); // Version
-       writeLong(f, 0); // padding
-       writeLong(f, 0); // padding
-       writeLong(f, 0); // padding
+       writeString(f, "gmon");
+       writeLong(f, 0x00000001); /* Version */
+       writeLong(f, 0); /* padding */
+       writeLong(f, 0); /* padding */
+       writeLong(f, 0); /* padding */
 
-       fwrite("", 1, 1, f);  // GMON_TAG_TIME_HIST
+       uint8_t zero = 0;  /* GMON_TAG_TIME_HIST */
+       writeData(f, &zero, 1);
 
-       // figure out bucket size
+       /* figure out bucket size */
        u32 min=samples[0];
        u32 max=samples[0];
        for (i=0; i<sampleNum; i++)
@@ -2510,8 +2780,8 @@ static void writeGmon(u32 *samples, int sampleNum, char *filename)
 
        int addressSpace=(max-min+1);
 
-       static int const maxBuckets=256*1024; // maximum buckets.
-       int length=addressSpace;
+       static const u32 maxBuckets = 256 * 1024; /* maximum buckets. */
+       u32 length = addressSpace;
        if (length > maxBuckets)
        {
                length=maxBuckets;
@@ -2529,23 +2799,21 @@ static void writeGmon(u32 *samples, int sampleNum, char *filename)
                long long a=address-min;
                long long b=length-1;
                long long c=addressSpace-1;
-               int index=(a*b)/c; // danger!!!! int32 overflows
+               int index=(a*b)/c; /* danger!!!! int32 overflows */
                buckets[index]++;
        }
 
-       //                         append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr))
-       writeLong(f, min);                                      // low_pc
-       writeLong(f, max);              // high_pc
-       writeLong(f, length);           // # of samples
-       writeLong(f, 64000000);                         // 64MHz
+       /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
+       writeLong(f, min);                      /* low_pc */
+       writeLong(f, max);                      /* high_pc */
+       writeLong(f, length);           /* # of samples */
+       writeLong(f, 64000000);         /* 64MHz */
        writeString(f, "seconds");
        for (i=0; i<(15-strlen("seconds")); i++)
-       {
-               fwrite("", 1, 1, f);  // padding
-       }
+               writeData(f, &zero, 1);
        writeString(f, "s");
 
-//                        append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size)
+       /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
 
        char *data=malloc(2*length);
        if (data!=NULL)
@@ -2562,7 +2830,7 @@ static void writeGmon(u32 *samples, int sampleNum, char *filename)
                        data[i*2+1]=(val>>8)&0xff;
                }
                free(buckets);
-               fwrite(data, 1, length*2, f);
+               writeData(f, data, length * 2);
                free(data);
        } else
        {
@@ -2573,7 +2841,7 @@ static void writeGmon(u32 *samples, int sampleNum, char *filename)
 }
 
 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
-int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        target_t *target = get_current_target(cmd_ctx);
        struct timeval timeout, now;
@@ -2583,12 +2851,12 @@ int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
-       char *end;
-       timeval_add_time(&timeout, strtoul(args[0], &end, 0), 0);
-       if (*end)
-       {
-               return ERROR_OK;
-       }
+       unsigned offset;
+       int retval = parse_uint(args[0], &offset);
+       if (ERROR_OK != retval)
+               return retval;
+
+       timeval_add_time(&timeout, offset, 0);
 
        command_print(cmd_ctx, "Starting profiling. Halting and resuming the target as often as we can...");
 
@@ -2598,8 +2866,7 @@ int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **
                return ERROR_OK;
 
        int numSamples=0;
-       int retval=ERROR_OK;
-       // hopefully it is safe to cache! We want to stop/restart as quickly as possible.
+       /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
        reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1);
 
        for (;;)
@@ -2611,10 +2878,10 @@ int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **
                        samples[numSamples++]=t;
                        retval = target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
                        target_poll(target);
-                       alive_sleep(10); // sleep 10ms, i.e. <100 samples/second.
+                       alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
                } else if (target->state == TARGET_RUNNING)
                {
-                       // We want to quickly sample the PC.
+                       /* We want to quickly sample the PC. */
                        if((retval = target_halt(target)) != ERROR_OK)
                        {
                                free(samples);
@@ -2705,7 +2972,7 @@ static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                return JIM_ERR;
        }
 
-       return  target_mem2array(interp, target, argc,argv);
+       return  target_mem2array(interp, target, argc-1, argv+1);
 }
 
 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
@@ -2717,33 +2984,34 @@ static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_
        u32 count;
        u32 v;
        const char *varname;
-       u8 buffer[4096];
-       int  i, n, e, retval;
+       uint8_t buffer[4096];
+       int  n, e, retval;
+       u32 i;
 
        /* argv[1] = name of array to receive the data
         * argv[2] = desired width
         * argv[3] = memory address
         * argv[4] = count of times to read
         */
-       if (argc != 5) {
+       if (argc != 4) {
                Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
                return JIM_ERR;
        }
-       varname = Jim_GetString(argv[1], &len);
+       varname = Jim_GetString(argv[0], &len);
        /* given "foo" get space for worse case "foo(%d)" .. add 20 */
 
-       e = Jim_GetLong(interp, argv[2], &l);
+       e = Jim_GetLong(interp, argv[1], &l);
        width = l;
        if (e != JIM_OK) {
                return e;
        }
 
-       e = Jim_GetLong(interp, argv[3], &l);
+       e = Jim_GetLong(interp, argv[2], &l);
        addr = l;
        if (e != JIM_OK) {
                return e;
        }
-       e = Jim_GetLong(interp, argv[4], &l);
+       e = Jim_GetLong(interp, argv[3], &l);
        len = l;
        if (e != JIM_OK) {
                return e;
@@ -2806,7 +3074,7 @@ static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_
                        count = (sizeof(buffer)/width);
                }
 
-               retval = target->type->read_memory( target, addr, width, count, buffer );
+               retval = target_read_memory( target, addr, width, count, buffer );
                if (retval != ERROR_OK) {
                        /* BOO !*/
                        LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
@@ -2886,10 +3154,9 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                return JIM_ERR;
        }
 
-       return target_array2mem( interp,target, argc, argv );
+       return target_array2mem( interp,target, argc-1, argv+1 );
 }
 
-
 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
 {
        long l;
@@ -2899,33 +3166,34 @@ static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_
        u32 count;
        u32 v;
        const char *varname;
-       u8 buffer[4096];
-       int  i, n, e, retval;
+       uint8_t buffer[4096];
+       int  n, e, retval;
+       u32 i;
 
        /* argv[1] = name of array to get the data
         * argv[2] = desired width
         * argv[3] = memory address
         * argv[4] = count to write
         */
-       if (argc != 5) {
+       if (argc != 4) {
                Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
                return JIM_ERR;
        }
-       varname = Jim_GetString(argv[1], &len);
+       varname = Jim_GetString(argv[0], &len);
        /* given "foo" get space for worse case "foo(%d)" .. add 20 */
 
-       e = Jim_GetLong(interp, argv[2], &l);
+       e = Jim_GetLong(interp, argv[1], &l);
        width = l;
        if (e != JIM_OK) {
                return e;
        }
 
-       e = Jim_GetLong(interp, argv[3], &l);
+       e = Jim_GetLong(interp, argv[2], &l);
        addr = l;
        if (e != JIM_OK) {
                return e;
        }
-       e = Jim_GetLong(interp, argv[4], &l);
+       e = Jim_GetLong(interp, argv[3], &l);
        len = l;
        if (e != JIM_OK) {
                return e;
@@ -2974,7 +3242,6 @@ static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_
                return JIM_ERR;
        }
 
-
        /* Transfer loop */
 
        /* index counter */
@@ -3006,7 +3273,7 @@ static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_
                }
                len -= count;
 
-               retval = target->type->write_memory(target, addr, width, count, buffer);
+               retval = target_write_memory(target, addr, width, count, buffer);
                if (retval != ERROR_OK) {
                        /* BOO !*/
                        LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
@@ -3022,15 +3289,13 @@ static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_
        return JIM_OK;
 }
 
-void
-target_all_handle_event( enum target_event e )
+void target_all_handle_event( enum target_event e )
 {
        target_t *target;
 
-
        LOG_DEBUG( "**all*targets: event: %d, %s",
-                  e,
-                  Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
+                       e,
+                       Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
 
        target = all_targets;
        while (target){
@@ -3039,8 +3304,7 @@ target_all_handle_event( enum target_event e )
        }
 }
 
-void
-target_handle_event( target_t *target, enum target_event e )
+void target_handle_event( target_t *target, enum target_event e )
 {
        target_event_action_t *teap;
        int done;
@@ -3054,7 +3318,7 @@ target_handle_event( target_t *target, enum target_event e )
                        LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
                                           target->target_number,
                                           target->cmd_name,
-                                          target->type->name,
+                                          target_get_name(target),
                                           e,
                                           Jim_Nvp_value2name_simple( nvp_target_event, e )->name,
                                           Jim_GetString( teap->body, NULL ) );
@@ -3084,7 +3348,6 @@ enum target_cfg_param {
        TCFG_CHAIN_POSITION,
 };
 
-
 static Jim_Nvp nvp_config_opts[] = {
        { .name = "-type",             .value = TCFG_TYPE },
        { .name = "-event",            .value = TCFG_EVENT },
@@ -3099,10 +3362,7 @@ static Jim_Nvp nvp_config_opts[] = {
        { .name = NULL, .value = -1 }
 };
 
-
-static int
-target_configure( Jim_GetOptInfo *goi,
-                                 target_t *target )
+static int target_configure( Jim_GetOptInfo *goi, target_t *target )
 {
        Jim_Nvp *n;
        Jim_Obj *o;
@@ -3110,11 +3370,10 @@ target_configure( Jim_GetOptInfo *goi,
        char *cp;
        int e;
 
-
        /* parse config or cget options ... */
        while( goi->argc > 0 ){
                Jim_SetEmptyResult( goi->interp );
-               //Jim_GetOpt_Debug( goi );
+               /* Jim_GetOpt_Debug( goi ); */
 
                if( target->type->target_jim_configure ){
                        /* target defines a configure function */
@@ -3148,7 +3407,7 @@ target_configure( Jim_GetOptInfo *goi,
                                        return JIM_ERR;
                                }
                        }
-                       Jim_SetResultString( goi->interp, target->type->name, -1 );
+                       Jim_SetResultString( goi->interp, target_get_name(target), -1 );
                        /* loop for more */
                        break;
                case TCFG_EVENT:
@@ -3175,14 +3434,13 @@ target_configure( Jim_GetOptInfo *goi,
                                }
                        }
 
-
                        {
                                target_event_action_t *teap;
 
                                teap = target->event_action;
                                /* replace existing? */
                                while( teap ){
-                                       if( teap->event == n->value ){
+                                       if( teap->event == (enum target_event)n->value ){
                                                break;
                                        }
                                        teap = teap->next;
@@ -3292,7 +3550,7 @@ target_configure( Jim_GetOptInfo *goi,
                                        goto no_params;
                                }
                        }
-                       Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_size ) );
+                       Jim_SetResult(interp, Jim_NewIntObj(goi->interp, target->backup_working_area));
                        /* loop for more e*/
                        break;
 
@@ -3341,44 +3599,47 @@ target_configure( Jim_GetOptInfo *goi,
                        break;
                case TCFG_CHAIN_POSITION:
                        if( goi->isconfigure ){
+                               Jim_Obj *o;
+                               jtag_tap_t *tap;
                                target_free_all_working_areas(target);
-                               e = Jim_GetOpt_Wide( goi, &w );
+                               e = Jim_GetOpt_Obj( goi, &o );
                                if( e != JIM_OK ){
                                        return e;
                                }
+                               tap = jtag_tap_by_jim_obj( goi->interp, o );
+                               if( tap == NULL ){
+                                       return JIM_ERR;
+                               }
                                /* make this exactly 1 or 0 */
-                               target->chain_position = w;
+                               target->tap = tap;
                        } else {
                                if( goi->argc != 0 ){
                                        goto no_params;
                                }
                        }
-                       Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->chain_position ) );
+                       Jim_SetResultString( interp, target->tap->dotted_name, -1 );
                        /* loop for more e*/
                        break;
                }
        } /* while( goi->argc ) */
+
+
                /* done - we return */
        return JIM_OK;
 }
 
-
 /** this is the 'tcl' handler for the target specific command */
-static int
-tcl_target_func( Jim_Interp *interp,
-                                int argc,
-                                Jim_Obj *const *argv )
+static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
 {
        Jim_GetOptInfo goi;
        jim_wide a,b,c;
        int x,y,z;
-       u8  target_buf[32];
+       uint8_t  target_buf[32];
        Jim_Nvp *n;
        target_t *target;
        struct command_context_s *cmd_ctx;
        int e;
 
-
        enum {
                TS_CMD_CONFIGURE,
                TS_CMD_CGET,
@@ -3421,7 +3682,6 @@ tcl_target_func( Jim_Interp *interp,
                { .name = NULL, .value = -1 },
        };
 
-
        /* go past the "command" */
        Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
 
@@ -3434,7 +3694,7 @@ tcl_target_func( Jim_Interp *interp,
                Jim_GetOpt_NvpUnknown( &goi, target_options, 0 );
                return e;
        }
-       // Assume blank result
+       /* Assume blank result */
        Jim_SetEmptyResult( goi.interp );
 
        switch( n->value ){
@@ -3463,7 +3723,7 @@ tcl_target_func( Jim_Interp *interp,
                 * argv[3] = optional count.
                 */
 
-               if( (goi.argc == 3) || (goi.argc == 4) ){
+               if( (goi.argc == 2) || (goi.argc == 3) ){
                        /* all is well */
                } else {
                mwx_error:
@@ -3480,7 +3740,7 @@ tcl_target_func( Jim_Interp *interp,
                if( e != JIM_OK ){
                        goto mwx_error;
                }
-               if( goi.argc ){
+               if (goi.argc == 3) {
                        e = Jim_GetOpt_Wide( &goi, &c );
                        if( e != JIM_OK ){
                                goto mwx_error;
@@ -3504,7 +3764,7 @@ tcl_target_func( Jim_Interp *interp,
                        break;
                }
                for( x = 0 ; x < c ; x++ ){
-                       e = target->type->write_memory( target, a, b, 1, target_buf );
+                       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;
@@ -3560,7 +3820,7 @@ tcl_target_func( Jim_Interp *interp,
                        if( y > 16 ){
                                y = 16;
                        }
-                       e = target->type->read_memory( target, a, b, y / b, target_buf );
+                       e = target_read_memory( target, a, b, y / b, target_buf );
                        if( e != ERROR_OK ){
                                Jim_SetResult_sprintf( interp, "error reading target @ 0x%08lx", (int)(a) );
                                return JIM_ERR;
@@ -3632,6 +3892,8 @@ tcl_target_func( Jim_Interp *interp,
                        Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
                        return JIM_ERR;
                }
+               if (!target->tap->enabled)
+                       goto err_tap_disabled;
                e = target->type->examine( target );
                if( e != ERROR_OK ){
                        Jim_SetResult_sprintf( interp, "examine-fails: %d", e );
@@ -3643,7 +3905,9 @@ tcl_target_func( Jim_Interp *interp,
                        Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
                        return JIM_ERR;
                }
-               if( !(target->type->examined) ){
+               if (!target->tap->enabled)
+                       goto err_tap_disabled;
+               if( !(target_was_examined(target)) ){
                        e = ERROR_TARGET_NOT_EXAMINED;
                } else {
                        e = target->type->poll( target );
@@ -3665,17 +3929,19 @@ tcl_target_func( Jim_Interp *interp,
                        Jim_GetOpt_NvpUnknown( &goi, nvp_assert, 1 );
                        return e;
                }
-               // the halt or not param
+               /* the halt or not param */
                e = Jim_GetOpt_Wide( &goi, &a);
                if( e != JIM_OK ){
                        return e;
                }
-               // determine if we should halt or not.
+               if (!target->tap->enabled)
+                       goto err_tap_disabled;
+               /* determine if we should halt or not. */
                target->reset_halt = !!a;
-               // When this happens - all workareas are invalid.
+               /* When this happens - all workareas are invalid. */
                target_free_all_working_areas_restore(target, 0);
 
-               // do the assert
+               /* do the assert */
                if( n->value == NVP_ASSERT ){
                        target->type->assert_reset( target );
                } else {
@@ -3687,10 +3953,12 @@ tcl_target_func( Jim_Interp *interp,
                        Jim_WrongNumArgs( goi.interp, 0, argv, "halt [no parameters]");
                        return JIM_ERR;
                }
+               if (!target->tap->enabled)
+                       goto err_tap_disabled;
                target->type->halt( target );
                return JIM_OK;
        case TS_CMD_WAITSTATE:
-               // params:  <name>  statename timeoutmsecs
+               /* params:  <name>  statename timeoutmsecs */
                if( goi.argc != 2 ){
                        Jim_SetResult_sprintf( goi.interp, "%s STATENAME TIMEOUTMSECS", n->name );
                        return JIM_ERR;
@@ -3704,13 +3972,15 @@ tcl_target_func( Jim_Interp *interp,
                if( e != JIM_OK ){
                        return e;
                }
+               if (!target->tap->enabled)
+                       goto err_tap_disabled;
                e = target_wait_state( target, n->value, a );
                if( e != ERROR_OK ){
                        Jim_SetResult_sprintf( goi.interp,
                                                                   "target: %s wait %s fails (%d) %s",
                                                                   target->cmd_name,
                                                                   n->name,
-                                              e, target_strerror_safe(e) );
+                                                                  e, target_strerror_safe(e) );
                        return JIM_ERR;
                } else {
                        return JIM_OK;
@@ -3759,13 +4029,14 @@ tcl_target_func( Jim_Interp *interp,
                return JIM_OK;
        }
        return JIM_ERR;
-}
 
+err_tap_disabled:
+       Jim_SetResult_sprintf(interp, "[TAP is disabled]");
+       return JIM_ERR;
+}
 
-static int
-target_create( Jim_GetOptInfo *goi )
+static int target_create( Jim_GetOptInfo *goi )
 {
-
        Jim_Obj *new_cmd;
        Jim_Cmd *cmd;
        const char *cp;
@@ -3819,7 +4090,6 @@ target_create( Jim_GetOptInfo *goi )
                return JIM_ERR;
        }
 
-
        /* Create it */
        target = calloc(1,sizeof(target_t));
        /* set target number */
@@ -3866,6 +4136,13 @@ target_create( Jim_GetOptInfo *goi )
        /* Do the rest as "configure" options */
        goi->isconfigure = 1;
        e = target_configure( goi, target);
+
+       if (target->tap == NULL)
+       {
+               Jim_SetResultString( interp, "-chain-position required when creating target", -1);
+               e=JIM_ERR;
+       }
+
        if( e != JIM_OK ){
                free( target->type );
                free( target );
@@ -3877,6 +4154,10 @@ target_create( Jim_GetOptInfo *goi )
                target->endianness = TARGET_LITTLE_ENDIAN;
        }
 
+       /* incase variant is not set */
+       if (!target->variant)
+               target->variant = strdup("");
+
        /* create the target specific commands */
        if( target->type->register_commands ){
                (*(target->type->register_commands))( cmd_ctx );
@@ -3909,13 +4190,11 @@ target_create( Jim_GetOptInfo *goi )
        return e;
 }
 
-static int
-jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
+static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
 {
        int x,r,e;
        jim_wide w;
        struct command_context_s *cmd_ctx;
-       const char *cp;
        target_t *target;
        Jim_GetOptInfo goi;
        enum tcmd {
@@ -3930,11 +4209,11 @@ jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
        const char *target_cmds[] = {
                "create", "types", "names", "current", "number",
                "count",
-               NULL // terminate
+               NULL /* terminate */
        };
 
        LOG_DEBUG("Target command params:");
-       LOG_DEBUG(Jim_Debug_ArgvString( interp, argc, argv) );
+       LOG_DEBUG("%s", Jim_Debug_ArgvString(interp, argc, argv));
 
        cmd_ctx = Jim_GetAssocData( interp, "context" );
 
@@ -3945,104 +4224,7 @@ jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
                return JIM_ERR;
        }
 
-       /* is this old syntax? */
-       /* To determine: We have to peek at argv[0]*/
-       cp = Jim_GetString( goi.argv[0], NULL );
-       for( x = 0 ; target_types[x] ; x++ ){
-               if( 0 == strcmp(cp,target_types[x]->name) ){
-                       break;
-               }
-       }
-       if( target_types[x] ){
-               /* YES IT IS OLD SYNTAX */
-               Jim_Obj *new_argv[10];
-               int      new_argc;
-
-               /* target_old_syntax
-                *
-                * It appears that there are 2 old syntaxes:
-                *
-                * target <typename> <endian> <chain position> <variant>
-                *
-                * and
-                *
-                * target <typename> <endian> <reset mode> <chain position> <variant>
-                *
-                */
-
-               /* The minimum number of arguments is 4 */
-               if( argc < 4 ){
-                       Jim_WrongNumArgs( interp, 1, argv, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?CHAIN-POSITION? ?VARIANT?");
-                       return JIM_ERR;
-               }
-
-               /* the command */
-               new_argv[0] = argv[0];
-               new_argv[1] = Jim_NewStringObj( interp, "create", -1 );
-               {
-                       char buf[ 30 ];
-                       sprintf( buf, "target%d", new_target_number() );
-                       new_argv[2] = Jim_NewStringObj( interp, buf , -1 );
-               }
-               new_argv[3] = goi.argv[0]; /* typename */
-               new_argv[4] = Jim_NewStringObj( interp, "-endian", -1 );
-               new_argv[5] = goi.argv[1];
-               new_argv[6] = Jim_NewStringObj( interp, "-chain-position", -1 );
-
-               /* If goi.argv[2] is not a number, we need to skip it since it is the reset mode. */
-               jim_wide w;
-               int chain_position_argv = 2;
-               if (JIM_ERR == Jim_GetWide(interp, goi.argv[chain_position_argv], &w)) {
-                       if (chain_position_argv + 1 < goi.argc) {
-                               chain_position_argv += 1;
-                       } else {
-                               Jim_WrongNumArgs( interp, 1, argv, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?RESET? ?CHAIN-POSITION? ?VARIANT?");
-                               return JIM_ERR;
-                       }
-               }
-
-               new_argv[7] = goi.argv[chain_position_argv];
-
-               /* Only provide a variant configure option if there was a variant specified */
-               if (chain_position_argv + 1 < goi.argc) {
-                       new_argv[8] = Jim_NewStringObj( interp, "-variant", -1 );
-                       new_argv[9] = goi.argv[chain_position_argv + 1];
-                       new_argc = 10;
-               } else {
-                       new_argc = 8;
-               }
-
-               /*
-                * new arg syntax:
-                *   argv[0] = command
-                *   argv[1] = create
-                *   argv[2] = cmdname
-                *   argv[3] = typename
-                *   argv[4] = -endian
-                *   argv[5] = little
-                *   argv[6] = -position
-                *   argv[7] = NUMBER
-                *   argv[8] = -variant
-                *   argv[9] = "somestring"
-                */
-
-               /* don't let these be released */
-               for( x = 0 ; x < new_argc ; x++ ){
-                       Jim_IncrRefCount( new_argv[x]);
-               }
-               /* call our self */
-               LOG_DEBUG("Target OLD SYNTAX - converted to new syntax");
-
-               r = jim_target( goi.interp, new_argc, new_argv );
-
-               /* release? these items */
-               for( x = 0 ; x < new_argc ; x++ ){
-                       Jim_DecrRefCount( interp, new_argv[x] );
-               }
-               return r;
-       }
-
-       //Jim_GetOpt_Debug( &goi );
+       /* Jim_GetOpt_Debug( &goi ); */
        r = Jim_GetOpt_Enum( &goi, target_cmds, &x   );
        if( r != JIM_OK ){
                return r;
@@ -4123,3 +4305,168 @@ jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
 
        return JIM_ERR;
 }
+
+
+struct FastLoad
+{
+       u32 address;
+       uint8_t *data;
+       int length;
+
+};
+
+static int fastload_num;
+static struct FastLoad *fastload;
+
+static void free_fastload(void)
+{
+       if (fastload!=NULL)
+       {
+               int i;
+               for (i=0; i<fastload_num; i++)
+               {
+                       if (fastload[i].data)
+                               free(fastload[i].data);
+               }
+               free(fastload);
+               fastload=NULL;
+       }
+}
+
+
+
+
+static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       uint8_t *buffer;
+       u32 buf_cnt;
+       u32 image_size;
+       u32 min_address=0;
+       u32 max_address=0xffffffff;
+       int i;
+
+       image_t image;
+
+       duration_t duration;
+       char *duration_text;
+
+       int retval = parse_load_image_command_args(args, argc,
+                       &image, &min_address, &max_address);
+       if (ERROR_OK != retval)
+               return retval;
+
+       duration_start_measure(&duration);
+
+       if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
+       {
+               return ERROR_OK;
+       }
+
+       image_size = 0x0;
+       retval = ERROR_OK;
+       fastload_num=image.num_sections;
+       fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
+       if (fastload==NULL)
+       {
+               image_close(&image);
+               return ERROR_FAIL;
+       }
+       memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
+       for (i = 0; i < image.num_sections; i++)
+       {
+               buffer = malloc(image.sections[i].size);
+               if (buffer == NULL)
+               {
+                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
+                       break;
+               }
+
+               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
+               {
+                       free(buffer);
+                       break;
+               }
+
+               u32 offset=0;
+               u32 length=buf_cnt;
+
+
+               /* DANGER!!! beware of unsigned comparision here!!! */
+
+               if ((image.sections[i].base_address+buf_cnt>=min_address)&&
+                               (image.sections[i].base_address<max_address))
+               {
+                       if (image.sections[i].base_address<min_address)
+                       {
+                               /* clip addresses below */
+                               offset+=min_address-image.sections[i].base_address;
+                               length-=offset;
+                       }
+
+                       if (image.sections[i].base_address+buf_cnt>max_address)
+                       {
+                               length-=(image.sections[i].base_address+buf_cnt)-max_address;
+                       }
+
+                       fastload[i].address=image.sections[i].base_address+offset;
+                       fastload[i].data=malloc(length);
+                       if (fastload[i].data==NULL)
+                       {
+                               free(buffer);
+                               break;
+                       }
+                       memcpy(fastload[i].data, buffer+offset, length);
+                       fastload[i].length=length;
+
+                       image_size += length;
+                       command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
+               }
+
+               free(buffer);
+       }
+
+       duration_stop_measure(&duration, &duration_text);
+       if (retval==ERROR_OK)
+       {
+               command_print(cmd_ctx, "Loaded %u bytes in %s", image_size, duration_text);
+               command_print(cmd_ctx, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
+       }
+       free(duration_text);
+
+       image_close(&image);
+
+       if (retval!=ERROR_OK)
+       {
+               free_fastload();
+       }
+
+       return retval;
+}
+
+static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc>0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       if (fastload==NULL)
+       {
+               LOG_ERROR("No image in memory");
+               return ERROR_FAIL;
+       }
+       int i;
+       int ms=timeval_ms();
+       int size=0;
+       int retval=ERROR_OK;
+       for (i=0; i<fastload_num;i++)
+       {
+               target_t *target = get_current_target(cmd_ctx);
+               command_print(cmd_ctx, "Write to 0x%08x, length 0x%08x", fastload[i].address, fastload[i].length);
+               if (retval==ERROR_OK)
+               {
+                       retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
+               }
+               size+=fastload[i].length;
+       }
+       int after=timeval_ms();
+       command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
+       return retval;
+}

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)