X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=5184a80bd6c108a7391043c120885e5dd9668558;hp=1ac666e51e5cf1f7f473d4bfb87ae02bcba0cee1;hb=6ba0b46cec38942bfa04ce9fd6379761df38a841;hpb=bdb7dd5e0f6690faf5a4c1ef19b2f36af9a7cfaa diff --git a/src/target/target.c b/src/target/target.c index 1ac666e51e..5184a80bd6 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -269,7 +269,7 @@ static int 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, const u8 *buffer) @@ -323,8 +323,6 @@ void target_buffer_set_u8(target_t *target, u8 *buffer, u8 value) target_t *get_target(const char *id) { target_t *target; - char *endptr; - int num; /* try as tcltarget name */ for (target = all_targets; target; target = target->next) { @@ -335,12 +333,12 @@ target_t *get_target(const char *id) } /* no match, try as number */ - num = strtoul(id, &endptr, 0); - if (*endptr != 0) + unsigned num; + if (parse_uint(id, &num) != ERROR_OK) return NULL; for (target = all_targets; target; target = target->next) { - if (target->target_number == num) + if (target->target_number == (int)num) return target; } @@ -434,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; @@ -471,6 +478,18 @@ 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: * @@ -483,8 +502,12 @@ int target_examine(void) for (target = all_targets; target; target = target->next) { - if (!target->tap->enabled) + /* 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; } @@ -812,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; @@ -1633,20 +1666,23 @@ int handle_target(void *priv) recursive = 0; } - target_t *target = all_targets; - - while (target) + /* 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; @@ -1687,16 +1723,19 @@ static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char /* 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; @@ -1771,7 +1810,12 @@ 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_continous_poll ? "on" : "off"); + 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) @@ -1782,11 +1826,11 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha { 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 { @@ -1802,21 +1846,23 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha 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); } @@ -1867,23 +1913,20 @@ int target_wait_state(target_t *target, enum target_state state, int ms) 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) { - int wait; - char *end; - - wait = strtoul(args[0], &end, 0); - if (!*end && !wait) + unsigned wait; + retval = parse_uint(args[0], &wait); + if (ERROR_OK != retval) + return ERROR_COMMAND_SYNTAX_ERROR; + if (!wait) return ERROR_OK; } @@ -1903,11 +1946,13 @@ static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, cha 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; @@ -1922,36 +1967,46 @@ static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, ch 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); } 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); } static void handle_md_output(struct command_context_s *cmd_ctx, @@ -2015,16 +2070,23 @@ static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char default: return ERROR_COMMAND_SYNTAX_ERROR; } - u32 address = strtoul(args[0], NULL, 0); + u32 address; + int retval = parse_u32(args[0], &address); + if (ERROR_OK != retval) + return retval; unsigned count = 1; if (argc == 2) - count = strtoul(args[1], NULL, 0); + { + retval = parse_uint(args[1], &count); + if (ERROR_OK != retval) + return retval; + } u8 *buffer = calloc(count, size); target_t *target = get_current_target(cmd_ctx); - int retval = target_read_memory(target, + retval = target_read_memory(target, address, size, count, buffer); if (ERROR_OK == retval) handle_md_output(cmd_ctx, target, address, size, count, buffer); @@ -2036,22 +2098,30 @@ static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char 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; + u8 value_buf[4]; switch (cmd[2]) { case 'w': @@ -2069,9 +2139,9 @@ static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char default: return ERROR_COMMAND_SYNTAX_ERROR; } - for (i=0; i 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) +{ + u8 *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) @@ -2210,10 +2294,8 @@ static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cm { fileio_t fileio; - u32 address; - u32 size; u8 buffer[560]; - int retval=ERROR_OK, retvaltemp; + int retvaltemp; duration_t duration; char *duration_text; @@ -2226,8 +2308,15 @@ static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cm 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; + + 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) { @@ -2305,8 +2394,12 @@ static int handle_verify_image_command_internal(struct command_context_s *cmd_ct 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 { @@ -2426,65 +2519,90 @@ static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cm return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 0); } -static int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +static int handle_bp_command_list(struct command_context_s *cmd_ctx) { - int retval; target_t *target = get_current_target(cmd_ctx); - - if (argc == 0) + breakpoint_t *breakpoint = target->breakpoints; + while (breakpoint) { - breakpoint_t *breakpoint = target->breakpoints; - - while (breakpoint) + if (breakpoint->type == BKPT_SOFT) { - 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) - { - 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) - { - 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.8lx", - 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
['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); } 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; } @@ -2492,7 +2610,6 @@ static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char 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) { @@ -2503,94 +2620,113 @@ static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char 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 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
[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); - } + enum watchpoint_rw type = WPT_ACCESS; + u32 addr = 0; + u32 length = 0; + u32 data_value = 0x0; + u32 data_mask = 0xffffffff; + int retval; - if ((retval = watchpoint_add(target, strtoul(args[0], NULL, 0), - strtoul(args[1], NULL, 0), type, data_value, data_mask)) != ERROR_OK) + 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]) { - LOG_ERROR("Failure setting breakpoints"); + 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; } - } - else - { + // 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
[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; } 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; - if (argc > 0) - watchpoint_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); + watchpoint_remove(target, addr); return ERROR_OK; } -static 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, len, 1, f); + size_t written = fwrite(data, 1, len, f); if (written != len) LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno)); } @@ -2715,12 +2851,12 @@ static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, { 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..."); @@ -2730,7 +2866,6 @@ static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, 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. */ reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1); @@ -3588,7 +3723,7 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) * argv[3] = optional count. */ - if( (goi.argc == 3) || (goi.argc == 4) ){ + if( (goi.argc == 2) || (goi.argc == 3) ){ /* all is well */ } else { mwx_error: @@ -3605,7 +3740,7 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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; @@ -4209,45 +4344,16 @@ static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, cha u32 min_address=0; u32 max_address=0xffffffff; int i; - int retval; image_t image; duration_t duration; char *duration_text; - 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) */ - if (argc >= 2) - { - image.base_address_set = 1; - image.base_address = strtoul(args[1], NULL, 0); - } - else - { - image.base_address_set = 0; - } - - - image.start_address_set = 0; - - if (argc>=4) - { - min_address=strtoul(args[3], NULL, 0); - } - if (argc>=5) - { - max_address=strtoul(args[4], NULL, 0)+min_address; - } - - if (min_address>max_address) - { - return ERROR_COMMAND_SYNTAX_ERROR; - } + int retval = parse_load_image_command_args(args, argc, + &image, &min_address, &max_address); + if (ERROR_OK != retval) + return retval; duration_start_measure(&duration);