X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=c2f479add0fe6818c84d16eebfb3d34e14a8eedb;hp=5b75c34801bfa082fb90eec957cce86bde7663f8;hb=6f9aac189206328568866244f471b5f27bbb0c45;hpb=b6db182c0020051e0dc642ca0b1040ea7453dcd0 diff --git a/src/target/target.c b/src/target/target.c index 5b75c34801..c2f479add0 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -34,6 +34,7 @@ #endif #include "target.h" +#include "target_type.h" #include "target_request.h" #include "time_support.h" #include "register.h" @@ -41,8 +42,6 @@ #include "image.h" #include "jtag.h" -#include - static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -324,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) { @@ -336,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; } @@ -384,7 +381,7 @@ target_t* get_current_target(command_context_t *cmd_ctx) 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; @@ -435,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_continous_poll; + target_continous_poll = 0; + sprintf( buf, "ocd_process_reset %s", n->name ); retval = Jim_Eval( interp, buf ); + target_continous_poll = save_poll; + if(retval != JIM_OK) { Jim_PrintErrorMessage(interp); return ERROR_FAIL; @@ -463,10 +469,15 @@ 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); +} + /* Targets that correctly implement init+examine, i.e. * no communication with target during init: * @@ -475,19 +486,25 @@ 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) + if (!target->tap->enabled) + 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) { - if (!target->type->examined) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -497,7 +514,7 @@ static int target_write_memory_imp(struct target_s *target, u32 address, u32 siz static int target_read_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer) { - if (!target->type->examined) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -507,7 +524,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; @@ -517,7 +534,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; @@ -531,6 +548,79 @@ int target_read_memory(struct target_s *target, return target->type->read_memory(target, address, size, count, buffer); } +int target_write_memory(struct target_s *target, + u32 address, u32 size, u32 count, u8 *buffer) +{ + return target->type->write_memory(target, address, size, count, buffer); +} +int target_bulk_write_memory(struct target_s *target, + u32 address, u32 count, u8 *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; @@ -538,7 +628,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; @@ -546,7 +636,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; } @@ -729,46 +819,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; @@ -898,7 +998,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; } @@ -985,7 +1085,7 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff 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; @@ -1004,7 +1104,7 @@ 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 */ @@ -1015,7 +1115,7 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff 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; @@ -1036,7 +1136,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; } @@ -1048,7 +1148,7 @@ 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; } @@ -1064,7 +1164,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe 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; @@ -1131,7 +1231,7 @@ int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* int retval; u32 i; u32 checksum = 0; - if (!target->type->examined) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -1173,7 +1273,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; @@ -1190,7 +1290,7 @@ 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) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -1215,7 +1315,7 @@ 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) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -1240,7 +1340,7 @@ int target_read_u16(struct target_s *target, u32 address, u16 *value) int target_read_u8(struct target_s *target, u32 address, u8 *value) { int retval = target_read_memory(target, address, 1, 1, value); - if (!target->type->examined) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -1263,7 +1363,7 @@ int target_write_u32(struct target_s *target, u32 address, u32 value) { int retval; u8 value_buf[4]; - if (!target->type->examined) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -1272,7 +1372,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); } @@ -1284,7 +1384,7 @@ int target_write_u16(struct target_s *target, u32 address, u16 value) { int retval; u8 value_buf[2]; - if (!target->type->examined) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -1293,7 +1393,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); } @@ -1304,7 +1404,7 @@ int target_write_u16(struct target_s *target, u32 address, u16 value) int target_write_u8(struct target_s *target, u32 address, u8 value) { int retval; - if (!target->type->examined) + if (!target_was_examined(target)) { LOG_ERROR("Target not examined yet"); return ERROR_FAIL; @@ -1312,7 +1412,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); } @@ -1384,6 +1484,12 @@ static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0] ); goto DumpTargets; } + 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; @@ -1391,19 +1497,32 @@ static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, DumpTargets: target = all_targets; - command_print(cmd_ctx, " CmdName Type Endian AbsChainPos Name State "); - command_print(cmd_ctx, "-- ---------- ---------- ---------- ----------- ------------- ----------"); + 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 %10d %14s %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->tap->abs_chain_position, + target_get_name(target), + Jim_Nvp_value2name_simple(nvp_target_endian, + target->endianness)->name, target->tap->dotted_name, - Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); + state); target = target->next; } @@ -1585,16 +1704,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; @@ -1668,9 +1790,11 @@ static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, cha if (argc == 0) { - if((retval = target_poll(target)) != ERROR_OK) + command_print(cmd_ctx, "background polling: %s", + target_continous_poll ? "on" : "off"); + 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; } @@ -1698,21 +1822,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); } @@ -1763,23 +1889,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; } @@ -1799,11 +1922,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; @@ -1818,36 +1943,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, @@ -1862,9 +1997,9 @@ static void handle_md_output(struct command_context_s *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; + 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); @@ -1879,7 +2014,7 @@ static void handle_md_output(struct command_context_s *cmd_ctx, "0x%8.8x: ", address + (i*size)); } - u32 value; + u32 value=0; const u8 *value_ptr = buffer + i * size; switch (size) { case 4: value = target_buffer_get_u32(target, value_ptr); break; @@ -1911,16 +2046,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); @@ -1932,22 +2074,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': @@ -1965,9 +2115,9 @@ static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char default: return ERROR_COMMAND_SYNTAX_ERROR; } - for (i=0; itype->write_memory(target, + retval = target_write_memory(target, address + i * wordsize, wordsize, 1, value_buf); if (ERROR_OK != retval) return retval; @@ -2322,57 +2472,69 @@ 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 = strtoul(args[0], NULL, 0); + u32 length = strtoul(args[1], NULL, 0); + + 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) @@ -2449,44 +2611,42 @@ static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char 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)); + target_t *target = get_current_target(cmd_ctx); + watchpoint_remove(target, strtoul(args[0], NULL, 0)); 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); - retval = target->type->virt2phys(target, va, &pa); + target_t *target = get_current_target(cmd_ctx); + u32 va = strtoul(args[0], NULL, 0); + u32 pa; + + int 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)); } @@ -3034,7 +3194,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); @@ -3079,7 +3239,7 @@ void 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 ) ); @@ -3168,7 +3328,7 @@ static int target_configure( Jim_GetOptInfo *goi, target_t *target ) 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: @@ -3311,7 +3471,7 @@ static int target_configure( Jim_GetOptInfo *goi, target_t *target ) 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; @@ -3367,7 +3527,7 @@ static int target_configure( Jim_GetOptInfo *goi, target_t *target ) if( e != JIM_OK ){ return e; } - tap = jtag_TapByJimObj( goi->interp, o ); + tap = jtag_tap_by_jim_obj( goi->interp, o ); if( tap == NULL ){ return JIM_ERR; } @@ -3525,7 +3685,7 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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; @@ -3653,6 +3813,8 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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 ); @@ -3664,7 +3826,9 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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 ); @@ -3691,6 +3855,8 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) if( e != JIM_OK ){ return e; } + 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. */ @@ -3708,6 +3874,8 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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: @@ -3725,6 +3893,8 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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, @@ -3780,6 +3950,10 @@ static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) 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 )