Cleanup: nuke trailling whitespaces
[openocd.git] / src / target / target.c
index 67bbcfc137cdbb7ac996f630962acbd1b31e187a..7763b95644d65d3dfce0d86e39e65e43dbde5112 100644 (file)
@@ -2,7 +2,7 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
- *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
+ *   Copyright (C) 2007-2009 Øyvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   Copyright (C) 2008, Duane Ellis                                       *
@@ -84,6 +84,7 @@ extern target_type_t arm966e_target;
 extern target_type_t arm926ejs_target;
 extern target_type_t fa526_target;
 extern target_type_t feroceon_target;
+extern target_type_t dragonite_target;
 extern target_type_t xscale_target;
 extern target_type_t cortexm3_target;
 extern target_type_t cortexa8_target;
@@ -101,6 +102,7 @@ target_type_t *target_types[] =
        &arm926ejs_target,
        &fa526_target,
        &feroceon_target,
+       &dragonite_target,
        &xscale_target,
        &cortexm3_target,
        &cortexa8_target,
@@ -155,7 +157,7 @@ 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_GDB_HALT, .name = "gdb-halt" },
        { .value = TARGET_EVENT_HALTED, .name = "halted" },
        { .value = TARGET_EVENT_RESUMED, .name = "resumed" },
        { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
@@ -237,20 +239,16 @@ const Jim_Nvp nvp_reset_modes[] = {
        { .name = NULL     , .value = -1 },
 };
 
-static int max_target_number(void)
+const char *
+target_state_name( target_t *t )
 {
-       target_t *t;
-       int x;
-
-       x = -1;
-       t = all_targets;
-       while (t) {
-               if (x < t->target_number) {
-                       x = (t->target_number) + 1;
-               }
-               t = t->next;
+       const char *cp;
+       cp = Jim_Nvp_value2name_simple(nvp_target_state, t->state)->name;
+       if( !cp ){
+               LOG_ERROR("Invalid target state: %d", (int)(t->state));
+               cp = "(*BUG*unknown*BUG*)";
        }
-       return x;
+       return cp;
 }
 
 /* determine the number of the new target */
@@ -271,8 +269,6 @@ static int new_target_number(void)
        return x + 1;
 }
 
-static int target_continuous_poll = 1;
-
 /* read a uint32_t from a buffer in target memory endianness */
 uint32_t target_buffer_get_u32(target_t *target, const uint8_t *buffer)
 {
@@ -334,14 +330,19 @@ target_t *get_target(const char *id)
                        return target;
        }
 
+       /* It's OK to remove this fallback sometime after August 2010 or so */
+
        /* 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)
+               if (target->target_number == (int)num) {
+                       LOG_WARNING("use '%s' as target identifier, not '%u'",
+                                       target->cmd_name, num);
                        return target;
+               }
        }
 
        return NULL;
@@ -362,11 +363,6 @@ static target_t *get_target_by_num(int num)
        return NULL;
 }
 
-int get_num_by_target(target_t *query_target)
-{
-       return query_target->target_number;
-}
-
 target_t* get_current_target(command_context_t *cmd_ctx)
 {
        target_t *target = get_target_by_num(cmd_ctx->current_target);
@@ -382,24 +378,57 @@ target_t* get_current_target(command_context_t *cmd_ctx)
 
 int target_poll(struct target_s *target)
 {
+       int retval;
+
        /* We can't poll until after examine */
        if (!target_was_examined(target))
        {
                /* Fail silently lest we pollute the log */
                return ERROR_FAIL;
        }
-       return target->type->poll(target);
+
+       retval = target->type->poll(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (target->halt_issued)
+       {
+               if (target->state == TARGET_HALTED)
+               {
+                       target->halt_issued = false;
+               } else
+               {
+                       long long t = timeval_ms() - target->halt_issued_time;
+                       if (t>1000)
+                       {
+                               target->halt_issued = false;
+                               LOG_INFO("Halt timed out, wake up GDB.");
+                               target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
+                       }
+               }
+       }
+
+       return ERROR_OK;
 }
 
 int target_halt(struct target_s *target)
 {
+       int retval;
        /* We can't poll until after examine */
        if (!target_was_examined(target))
        {
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
-       return target->type->halt(target);
+
+       retval = target->type->halt(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       target->halt_issued = true;
+       target->halt_issued_time = timeval_ms();
+
+       return ERROR_OK;
 }
 
 int target_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
@@ -438,13 +467,14 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo
         * 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;
+       bool save_poll = jtag_poll_get_enabled();
+
+       jtag_poll_set_enabled(false);
 
        sprintf(buf, "ocd_process_reset %s", n->name);
        retval = Jim_Eval(interp, buf);
 
-       target_continuous_poll = save_poll;
+       jtag_poll_set_enabled(save_poll);
 
        if (retval != JIM_OK) {
                Jim_PrintErrorMessage(interp);
@@ -547,6 +577,11 @@ static int target_soft_reset_halt_imp(struct target_s *target)
                LOG_ERROR("Target not examined yet");
                return ERROR_FAIL;
        }
+       if (!target->type->soft_reset_halt_imp) {
+               LOG_ERROR("Target %s does not support soft_reset_halt",
+                               target->cmd_name);
+               return ERROR_FAIL;
+       }
        return target->type->soft_reset_halt_imp(target);
 }
 
@@ -663,7 +698,6 @@ int target_init(struct command_context_s *cmd_ctx)
                {
                        target->type->virt2phys = default_virt2phys;
                }
-               target->type->virt2phys = default_virt2phys;
                /* a non-invasive way(in terms of patches) to add some code that
                 * runs before the type->write/read_memory implementation
                 */
@@ -818,7 +852,7 @@ int target_call_event_callbacks(target_t *target, enum target_event event)
        if (event == TARGET_EVENT_HALTED)
        {
                /* execute early halted first */
-               target_call_event_callbacks(target, TARGET_EVENT_EARLY_HALTED);
+               target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
        }
 
        LOG_DEBUG("target event %i (%s)",
@@ -969,7 +1003,7 @@ int target_alloc_working_area(struct target_s *target, uint32_t size, working_ar
 
                if (free_size < size)
                {
-                       LOG_WARNING("not enough working area available(requested %u, free %u)", 
+                       LOG_WARNING("not enough working area available(requested %u, free %u)",
                                    (unsigned)(size), (unsigned)(free_size));
                        return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
@@ -1085,8 +1119,7 @@ int target_arch_state(struct target_s *target)
                return ERROR_OK;
        }
 
-       LOG_USER("target state: %s",
-                Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name);
+       LOG_USER("target state: %s", target_state_name( target ));
 
        if (target->state != TARGET_HALTED)
                return ERROR_OK;
@@ -1102,7 +1135,7 @@ int target_arch_state(struct target_s *target)
 int target_write_buffer(struct target_s *target, uint32_t address, uint32_t size, uint8_t *buffer)
 {
        int retval;
-       LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", 
+       LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
                  (int)size, (unsigned)address);
 
        if (!target_was_examined(target))
@@ -1118,8 +1151,8 @@ int target_write_buffer(struct target_s *target, uint32_t address, uint32_t size
        if ((address + size - 1) < address)
        {
                /* GDB can request this when e.g. PC is 0xfffffffc*/
-               LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)", 
-                                 (unsigned)address, 
+               LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
+                                 (unsigned)address,
                                  (unsigned)size);
                return ERROR_FAIL;
        }
@@ -1184,7 +1217,7 @@ int target_write_buffer(struct target_s *target, uint32_t address, uint32_t size
 int target_read_buffer(struct target_s *target, uint32_t address, uint32_t size, uint8_t *buffer)
 {
        int retval;
-       LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", 
+       LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
                          (int)size, (unsigned)address);
 
        if (!target_was_examined(target))
@@ -1200,8 +1233,8 @@ int target_read_buffer(struct target_s *target, uint32_t address, uint32_t size,
        if ((address + size - 1) < address)
        {
                /* GDB can request this when e.g. PC is 0xfffffffc*/
-               LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")", 
-                                 address, 
+               LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
+                                 address,
                                  size);
                return ERROR_FAIL;
        }
@@ -1240,6 +1273,18 @@ int target_read_buffer(struct target_s *target, uint32_t address, uint32_t size,
                size -= aligned;
        }
 
+       /*prevent byte access when possible (avoid AHB access limitations in some cases)*/
+       if(size >=2)
+       {
+               int aligned = size - (size%2);
+               retval = target_read_memory(target, address, 2, aligned / 2, buffer);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               buffer += aligned;
+               address += aligned;
+               size -= aligned;
+       }
        /* handle tail writes of less than 4 bytes */
        if (size > 0)
        {
@@ -1326,14 +1371,14 @@ int target_read_u32(struct target_s *target, uint32_t address, uint32_t *value)
        if (retval == ERROR_OK)
        {
                *value = target_buffer_get_u32(target, value_buf);
-               LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "", 
-                                 address, 
+               LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
+                                 address,
                                  *value);
        }
        else
        {
                *value = 0x0;
-               LOG_DEBUG("address: 0x%8.8" PRIx32 " failed", 
+               LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
                                  address);
        }
 
@@ -1354,14 +1399,14 @@ int target_read_u16(struct target_s *target, uint32_t address, uint16_t *value)
        if (retval == ERROR_OK)
        {
                *value = target_buffer_get_u16(target, value_buf);
-               LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x", 
-                                 address, 
+               LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
+                                 address,
                                  *value);
        }
        else
        {
                *value = 0x0;
-               LOG_DEBUG("address: 0x%8.8" PRIx32 " failed", 
+               LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
                                  address);
        }
 
@@ -1379,14 +1424,14 @@ int target_read_u8(struct target_s *target, uint32_t address, uint8_t *value)
 
        if (retval == ERROR_OK)
        {
-               LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x", 
-                                 address, 
+               LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
+                                 address,
                                  *value);
        }
        else
        {
                *value = 0x0;
-               LOG_DEBUG("address: 0x%8.8" PRIx32 " failed", 
+               LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
                                  address);
        }
 
@@ -1403,8 +1448,8 @@ int target_write_u32(struct target_s *target, uint32_t address, uint32_t value)
                return ERROR_FAIL;
        }
 
-       LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "", 
-                         address, 
+       LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
+                         address,
                          value);
 
        target_buffer_set_u32(target, value_buf, value);
@@ -1426,8 +1471,8 @@ int target_write_u16(struct target_s *target, uint32_t address, uint16_t value)
                return ERROR_FAIL;
        }
 
-       LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x", 
-                         address, 
+       LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x",
+                         address,
                          value);
 
        target_buffer_set_u16(target, value_buf, value);
@@ -1448,7 +1493,7 @@ int target_write_u8(struct target_s *target, uint32_t address, uint8_t value)
                return ERROR_FAIL;
        }
 
-       LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x", 
+       LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
                          address, value);
 
        if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
@@ -1494,10 +1539,19 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx,  NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value> [count]");
        register_command(cmd_ctx,  NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value> [count]");
 
-       register_command(cmd_ctx,  NULL, "bp", handle_bp_command, COMMAND_EXEC, "set breakpoint <address> <length> [hw]");
-       register_command(cmd_ctx,  NULL, "rbp", handle_rbp_command, COMMAND_EXEC, "remove breakpoint <adress>");
-       register_command(cmd_ctx,  NULL, "wp", handle_wp_command, COMMAND_EXEC, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
-       register_command(cmd_ctx,  NULL, "rwp", handle_rwp_command, COMMAND_EXEC, "remove watchpoint <adress>");
+       register_command(cmd_ctx,  NULL, "bp",
+                       handle_bp_command, COMMAND_EXEC,
+                       "list or set breakpoint [<address> <length> [hw]]");
+       register_command(cmd_ctx,  NULL, "rbp",
+                       handle_rbp_command, COMMAND_EXEC,
+                       "remove breakpoint <address>");
+       register_command(cmd_ctx,  NULL, "wp",
+                       handle_wp_command, COMMAND_EXEC,
+                       "list or set watchpoint "
+                               "[<address> <length> <r/w/a> [value] [mask]]");
+       register_command(cmd_ctx,  NULL, "rwp",
+                       handle_rwp_command, COMMAND_EXEC,
+                       "remove watchpoint <address>");
 
        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>");
@@ -1544,8 +1598,7 @@ DumpTargets:
                char marker = ' ';
 
                if (target->tap->enabled)
-                       state = Jim_Nvp_value2name_simple(nvp_target_state,
-                                       target->state)->name;
+                       state = target_state_name( target );
                else
                        state = "tap-disabled";
 
@@ -1636,6 +1689,15 @@ static int sense_handler(void)
        return ERROR_OK;
 }
 
+static void target_call_event_callbacks_all(enum target_event e) {
+       target_t *target;
+       target = all_targets;
+       while (target) {
+               target_call_event_callbacks(target, e);
+               target = target->next;
+       }
+}
+
 /* process target state changes */
 int handle_target(void *priv)
 {
@@ -1654,6 +1716,7 @@ int handle_target(void *priv)
                int did_something = 0;
                if (runSrstAsserted)
                {
+                       target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
                        Jim_Eval(interp, "srst_asserted");
                        did_something = 1;
                }
@@ -1664,6 +1727,7 @@ int handle_target(void *priv)
                }
                if (runPowerDropout)
                {
+                       target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
                        Jim_Eval(interp, "power_dropout");
                        did_something = 1;
                }
@@ -1693,7 +1757,7 @@ int handle_target(void *priv)
         * Skip targets that are currently disabled.
         */
        for (target_t *target = all_targets;
-                       target_continuous_poll && target;
+                       is_jtag_poll_safe() && target;
                        target = target->next)
        {
                if (!target->tap->enabled)
@@ -1704,7 +1768,10 @@ int handle_target(void *priv)
                {
                        /* polling may fail silently until the target has been examined */
                        if ((retval = target_poll(target)) != ERROR_OK)
+                       {
+                               target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
                                return retval;
+                       }
                }
        }
 
@@ -1731,17 +1798,28 @@ static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char
                while (cache)
                {
                        int i;
-                       for (i = 0; i < cache->num_regs; i++)
+
+                       for (i = 0, reg = cache->reg_list;
+                                       i < cache->num_regs;
+                                       i++, reg++, count++)
                        {
-                               value = buf_to_str(cache->reg_list[i].value, cache->reg_list[i].size, 16);
-                               command_print(cmd_ctx, "(%i) %s (/%i): 0x%s (dirty: %i, valid: %i)", 
-                                                         count++, 
-                                                         cache->reg_list[i].name, 
-                                                         (int)(cache->reg_list[i].size),
-                                                         value, 
-                                                         cache->reg_list[i].dirty, 
-                                                         cache->reg_list[i].valid);
-                               free(value);
+                               /* only print cached values if they are valid */
+                               if (reg->valid) {
+                                       value = buf_to_str(reg->value,
+                                                       reg->size, 16);
+                                       command_print(cmd_ctx,
+                                                       "(%i) %s (/%" PRIu32 "): 0x%s%s",
+                                                       count, reg->name,
+                                                       reg->size, value,
+                                                       reg->dirty
+                                                               ? " (dirty)"
+                                                               : "");
+                                       free(value);
+                               } else {
+                                       command_print(cmd_ctx, "(%i) %s (/%" PRIu32 ")",
+                                                         count, reg->name,
+                                                         reg->size) ;
+                               }
                        }
                        cache = cache->next;
                }
@@ -1839,7 +1917,7 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha
        if (argc == 0)
        {
                command_print(cmd_ctx, "background polling: %s",
-                               target_continuous_poll ?  "on" : "off");
+                               jtag_poll_get_enabled() ? "on" : "off");
                command_print(cmd_ctx, "TAP: %s (%s)",
                                target->tap->dotted_name,
                                target->tap->enabled ? "enabled" : "disabled");
@@ -1855,11 +1933,11 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha
        {
                if (strcmp(args[0], "on") == 0)
                {
-                       target_continuous_poll = 1;
+                       jtag_poll_set_enabled(true);
                }
                else if (strcmp(args[0], "off") == 0)
                {
-                       target_continuous_poll = 0;
+                       jtag_poll_set_enabled(false);
                }
                else
                {
@@ -2029,15 +2107,18 @@ static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, cha
         * with one argument addr = args[0],
         * handle breakpoints, debugging */
        uint32_t addr = 0;
+       int current_pc = 1;
        if (argc == 1)
        {
                int retval = parse_u32(args[0], &addr);
                if (ERROR_OK != retval)
                        return retval;
+               current_pc = 0;
        }
 
        target_t *target = get_current_target(cmd_ctx);
-       return target->type->step(target, 0, addr, 1);
+
+       return target->type->step(target, current_pc, addr, 1);
 }
 
 static void handle_md_output(struct command_context_s *cmd_ctx,
@@ -2066,7 +2147,7 @@ static void handle_md_output(struct command_context_s *cmd_ctx,
                {
                        output_len += snprintf(output + output_len,
                                        sizeof(output) - output_len,
-                                       "0x%8.8x: ", 
+                                       "0x%8.8x: ",
                                        (unsigned)(address + (i*size)));
                }
 
@@ -2241,7 +2322,7 @@ static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cm
 
        duration_t duration;
        char *duration_text;
-       
+
        int retval = parse_load_image_command_args(args, argc,
                        &image, &min_address, &max_address);
        if (ERROR_OK != retval)
@@ -2262,8 +2343,8 @@ static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cm
                buffer = malloc(image.sections[i].size);
                if (buffer == NULL)
                {
-                       command_print(cmd_ctx, 
-                                                 "error allocating buffer for section (%d bytes)", 
+                       command_print(cmd_ctx,
+                                                 "error allocating buffer for section (%d bytes)",
                                                  (int)(image.sections[i].size));
                        break;
                }
@@ -2300,8 +2381,8 @@ static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cm
                                break;
                        }
                        image_size += length;
-                       command_print(cmd_ctx, "%u byte written at address 0x%8.8" PRIx32 "", 
-                                                 (unsigned int)length, 
+                       command_print(cmd_ctx, "%u bytes written at address 0x%8.8" PRIx32 "",
+                                                 (unsigned int)length,
                                                  image.sections[i].base_address + offset);
                }
 
@@ -2316,8 +2397,8 @@ static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cm
 
        if (retval == ERROR_OK)
        {
-               command_print(cmd_ctx, "downloaded %u byte in %s", 
-                                         (unsigned int)image_size, 
+               command_print(cmd_ctx, "downloaded %u byte in %s",
+                                         (unsigned int)image_size,
                                          duration_text);
        }
        free(duration_text);
@@ -2459,8 +2540,8 @@ static int handle_verify_image_command_internal(struct command_context_s *cmd_ct
                buffer = malloc(image.sections[i].size);
                if (buffer == NULL)
                {
-                       command_print(cmd_ctx, 
-                                                 "error allocating buffer for section (%d bytes)", 
+                       command_print(cmd_ctx,
+                                                 "error allocating buffer for section (%d bytes)",
                                                  (int)(image.sections[i].size));
                        break;
                }
@@ -2507,10 +2588,10 @@ static int handle_verify_image_command_internal(struct command_context_s *cmd_ct
                                        {
                                                if (data[t] != buffer[t])
                                                {
-                                                       command_print(cmd_ctx, 
-                                                                                 "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n", 
-                                                                                 (unsigned)(t + image.sections[i].base_address), 
-                                                                                 data[t], 
+                                                       command_print(cmd_ctx,
+                                                                                 "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n",
+                                                                                 (unsigned)(t + image.sections[i].base_address),
+                                                                                 data[t],
                                                                                  buffer[t]);
                                                        free(data);
                                                        free(buffer);
@@ -2528,8 +2609,8 @@ static int handle_verify_image_command_internal(struct command_context_s *cmd_ct
                        }
                } else
                {
-                       command_print(cmd_ctx, "address 0x%08" PRIx32 " length 0x%08" PRIx32 "", 
-                                                 image.sections[i].base_address, 
+                       command_print(cmd_ctx, "address 0x%08" PRIx32 " length 0x%08" PRIx32 "",
+                                                 image.sections[i].base_address,
                                                  buf_cnt);
                }
 
@@ -2546,8 +2627,8 @@ done:
 
        if (retval == ERROR_OK)
        {
-               command_print(cmd_ctx, "verified %u bytes in %s", 
-                                         (unsigned int)image_size, 
+               command_print(cmd_ctx, "verified %u bytes in %s",
+                                         (unsigned int)image_size,
                                          duration_text);
        }
        free(duration_text);
@@ -2578,7 +2659,7 @@ static int handle_bp_command_list(struct command_context_s *cmd_ctx)
                        char* buf = buf_to_str(breakpoint->orig_instr,
                                        breakpoint->length, 16);
                        command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i, 0x%s",
-                                       breakpoint->address, 
+                                       breakpoint->address,
                                        breakpoint->length,
                                        breakpoint->set, buf);
                        free(buf);
@@ -2586,7 +2667,7 @@ static int handle_bp_command_list(struct command_context_s *cmd_ctx)
                else
                {
                        command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i",
-                                                 breakpoint->address, 
+                                                 breakpoint->address,
                                                  breakpoint->length, breakpoint->set);
                }
 
@@ -2667,9 +2748,9 @@ static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char
 
                while (watchpoint)
                {
-                       command_print(cmd_ctx, 
-                                                 "address: 0x%8.8" PRIx32 ", len: 0x%8.8x, r/w/a: %i, value: 0x%8.8" PRIx32 ", mask: 0x%8.8" PRIx32 "", 
-                                                 watchpoint->address, 
+                       command_print(cmd_ctx,
+                                                 "address: 0x%8.8" PRIx32 ", len: 0x%8.8x, r/w/a: %i, value: 0x%8.8" PRIx32 ", mask: 0x%8.8" PRIx32 "",
+                                                 watchpoint->address,
                                                  watchpoint->length,
                                                  (int)(watchpoint->rw),
                                                  watchpoint->value,
@@ -3111,8 +3192,8 @@ static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_
        } else {
                char buf[100];
                Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-               sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads", 
-                               addr, 
+               sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
+                               addr,
                                width);
                Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
                return JIM_ERR;
@@ -3135,9 +3216,9 @@ static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_
                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", 
-                                         (unsigned int)addr, 
-                                         (int)width, 
+                       LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed",
+                                         (unsigned int)addr,
+                                         (int)width,
                                          (int)count);
                        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
                        Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
@@ -3298,8 +3379,8 @@ static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_
        } else {
                char buf[100];
                Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-               sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", 
-                               (unsigned int)addr, 
+               sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads",
+                               (unsigned int)addr,
                                (int)width);
                Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
                return JIM_ERR;
@@ -3339,9 +3420,9 @@ static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_
                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", 
-                                         (unsigned int)addr, 
-                                         (int)width, 
+                       LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed",
+                                         (unsigned int)addr,
+                                         (int)width,
                                          (int)count);
                        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
                        Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL);
@@ -3370,18 +3451,17 @@ void target_all_handle_event(enum target_event e)
        }
 }
 
+
+/* FIX? should we propagate errors here rather than printing them
+ * and continuing?
+ */
 void target_handle_event(target_t *target, enum target_event e)
 {
        target_event_action_t *teap;
-       int done;
-
-       teap = target->event_action;
 
-       done = 0;
-       while (teap) {
+       for (teap = target->event_action; teap != NULL; teap = teap->next) {
                if (teap->event == e) {
-                       done = 1;
-                       LOG_DEBUG("target: (%d) %s (%s) event: %d (%s) action: %s\n",
+                       LOG_DEBUG("target: (%d) %s (%s) event: %d (%s) action: %s",
                                           target->target_number,
                                           target->cmd_name,
                                           target_get_name(target),
@@ -3393,12 +3473,6 @@ void target_handle_event(target_t *target, enum target_event e)
                                Jim_PrintErrorMessage(interp);
                        }
                }
-               teap = teap->next;
-       }
-       if (!done) {
-               LOG_DEBUG("event: %d %s - no action",
-                                  e,
-                                  Jim_Nvp_value2name_simple(nvp_target_event, e)->name);
        }
 }
 
@@ -3513,9 +3587,11 @@ static int target_configure(Jim_GetOptInfo *goi, target_t *target)
                                }
 
                                if (goi->isconfigure) {
+                                       bool replace = true;
                                        if (teap == NULL) {
                                                /* create new */
                                                teap = calloc(1, sizeof(*teap));
+                                               replace = false;
                                        }
                                        teap->event = n->value;
                                        Jim_GetOpt_Obj(goi, &o);
@@ -3535,9 +3611,12 @@ static int target_configure(Jim_GetOptInfo *goi, target_t *target)
                                         */
                                        Jim_IncrRefCount(teap->body);
 
-                                       /* add to head of event list */
-                                       teap->next = target->event_action;
-                                       target->event_action = teap;
+                                       if (!replace)
+                                       {
+                                               /* add to head of event list */
+                                               teap->next = target->event_action;
+                                               target->event_action = teap;
+                                       }
                                        Jim_SetEmptyResult(goi->interp);
                                } else {
                                        /* get */
@@ -3987,7 +4066,8 @@ static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                break;
        case TS_CMD_RESET:
                if (goi.argc != 2) {
-                       Jim_WrongNumArgs(interp, 2, argv, "t | f|assert | deassert BOOL");
+                       Jim_WrongNumArgs(interp, 2, argv,
+                                       "([tT]|[fF]|assert|deassert) BOOL");
                        return JIM_ERR;
                }
                e = Jim_GetOpt_Nvp(&goi, nvp_assert, &n);
@@ -4002,6 +4082,13 @@ static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                }
                if (!target->tap->enabled)
                        goto err_tap_disabled;
+               if (!target->type->assert_reset
+                               || !target->type->deassert_reset) {
+                       Jim_SetResult_sprintf(interp,
+                                       "No target-specific reset for %s",
+                                       target->cmd_name);
+                       return JIM_ERR;
+               }
                /* determine if we should halt or not. */
                target->reset_halt = !!a;
                /* When this happens - all workareas are invalid. */
@@ -4009,11 +4096,11 @@ static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 
                /* do the assert */
                if (n->value == NVP_ASSERT) {
-                       target->type->assert_reset(target);
+                       e = target->type->assert_reset(target);
                } else {
-                       target->type->deassert_reset(target);
+                       e = target->type->deassert_reset(target);
                }
-               return JIM_OK;
+               return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
        case TS_CMD_HALT:
                if (goi.argc) {
                        Jim_WrongNumArgs(goi.interp, 0, argv, "halt [no parameters]");
@@ -4021,8 +4108,8 @@ static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                }
                if (!target->tap->enabled)
                        goto err_tap_disabled;
-               target->type->halt(target);
-               return JIM_OK;
+               e = target->type->halt(target);
+               return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
        case TS_CMD_WAITSTATE:
                /* params:  <name>  statename timeoutmsecs */
                if (goi.argc != 2) {
@@ -4079,7 +4166,8 @@ static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                        return JIM_ERR;
                }
                Jim_SetResultString(goi.interp,
-                                                        Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name,-1);
+                                                       target_state_name( target ),
+                                                       -1);
                return JIM_OK;
        case TS_CMD_INVOKE_EVENT:
                if (goi.argc != 1) {
@@ -4184,6 +4272,8 @@ static int target_create(Jim_GetOptInfo *goi)
 
        target->display             = 1;
 
+       target->halt_issued                     = false;
+
        /* initialize trace information */
        target->trace_info = malloc(sizeof(trace_t));
        target->trace_info->num_trace_points         = 0;
@@ -4341,6 +4431,8 @@ static int jim_target(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                return target_create(&goi);
                break;
        case TG_CMD_NUMBER:
+               /* It's OK to remove this mechanism sometime after August 2010 or so */
+               LOG_WARNING("don't use numbers as target identifiers; use names");
                if (goi.argc != 1) {
                        Jim_SetResult_sprintf(goi.interp, "expected: target number ?NUMBER?");
                        return JIM_ERR;
@@ -4349,23 +4441,25 @@ static int jim_target(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                if (e != JIM_OK) {
                        return JIM_ERR;
                }
-               {
-                       target_t *t;
-                       t = get_target_by_num(w);
-                       if (t == NULL) {
-                               Jim_SetResult_sprintf(goi.interp,"Target: number %d does not exist", (int)(w));
-                               return JIM_ERR;
-                       }
-                       Jim_SetResultString(goi.interp, t->cmd_name, -1);
-                       return JIM_OK;
+               for (x = 0, target = all_targets; target; target = target->next, x++) {
+                       if (target->target_number == w)
+                               break;
                }
+               if (target == NULL) {
+                       Jim_SetResult_sprintf(goi.interp,
+                                       "Target: number %d does not exist", (int)(w));
+                       return JIM_ERR;
+               }
+               Jim_SetResultString(goi.interp, target->cmd_name, -1);
+               return JIM_OK;
        case TG_CMD_COUNT:
                if (goi.argc != 0) {
                        Jim_WrongNumArgs(goi.interp, 0, goi.argv, "<no parameters>");
                        return JIM_ERR;
                }
-               Jim_SetResult(goi.interp,
-                                          Jim_NewIntObj(goi.interp, max_target_number()));
+               for (x = 0, target = all_targets; target; target = target->next, x++)
+                       continue;
+               Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, x));
                return JIM_OK;
        }
 
@@ -4443,7 +4537,7 @@ static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, cha
                buffer = malloc(image.sections[i].size);
                if (buffer == NULL)
                {
-                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", 
+                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)",
                                                  (int)(image.sections[i].size));
                        break;
                }
@@ -4486,8 +4580,8 @@ static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, cha
                        fastload[i].length = length;
 
                        image_size += length;
-                       command_print(cmd_ctx, "%u byte written at address 0x%8.8x", 
-                                                 (unsigned int)length, 
+                       command_print(cmd_ctx, "%u bytes written at address 0x%8.8x",
+                                                 (unsigned int)length,
                                                  ((unsigned int)(image.sections[i].base_address + offset)));
                }
 
@@ -4528,8 +4622,8 @@ static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd
        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", 
-                                         (unsigned int)(fastload[i].address), 
+               command_print(cmd_ctx, "Write to 0x%08x, length 0x%08x",
+                                         (unsigned int)(fastload[i].address),
                                          (unsigned int)(fastload[i].length));
                if (retval == ERROR_OK)
                {
@@ -4544,7 +4638,7 @@ static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd
 
 
 /*
- * Local Variables: 
+ * Local Variables:
  * c-basic-offset: 4
  * tab-width: 4
  * End:

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)