X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=e1341a0a3e8ae42bb0ca2dfec515742a8bb5e3fe;hb=06d501a192e36986ba0f81c7ddff9298dd0a389e;hp=589f626f0902f61a6f551cca298eeada31614b03;hpb=679592d42e5db7e8a2485b66aabc4c5ec76307e4;p=openocd.git diff --git a/src/target/target.c b/src/target/target.c index 589f626f09..e1341a0a3e 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -274,20 +274,22 @@ int target_resume(struct target_s *target, int current, u32 address, int handle_ return ERROR_FAIL; } + /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can + * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?) + * the application. + */ if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK) return retval; return retval; } -int target_process_reset(struct command_context_s *cmd_ctx) +int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode) { int retval = ERROR_OK; target_t *target; struct timeval timeout, now; - jtag->speed(jtag_speed); - target = targets; while (target) { @@ -298,6 +300,8 @@ int target_process_reset(struct command_context_s *cmd_ctx) if ((retval = jtag_init_reset(cmd_ctx)) != ERROR_OK) return retval; + keep_alive(); /* we might be running on a very slow JTAG clk */ + /* First time this is executed after launching OpenOCD, it will read out * the type of CPU, etc. and init Embedded ICE registers in host * memory. @@ -311,29 +315,8 @@ int target_process_reset(struct command_context_s *cmd_ctx) if ((retval = target_examine(cmd_ctx)) != ERROR_OK) return retval; - /* prepare reset_halt where necessary */ - target = targets; - while (target) - { - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - { - switch (target->reset_mode) - { - case RESET_HALT: - command_print(cmd_ctx, "nSRST pulls nTRST, falling back to \"reset run_and_halt\""); - target->reset_mode = RESET_RUN_AND_HALT; - break; - case RESET_INIT: - command_print(cmd_ctx, "nSRST pulls nTRST, falling back to \"reset run_and_init\""); - target->reset_mode = RESET_RUN_AND_INIT; - break; - default: - break; - } - } - target = target->next; - } - + keep_alive(); /* we might be running on a very slow JTAG clk */ + target = targets; while (target) { @@ -341,6 +324,7 @@ int target_process_reset(struct command_context_s *cmd_ctx) * have to drop working areas */ target_free_all_working_areas_restore(target, 0); + target->reset_halt=((reset_mode==RESET_HALT)||(reset_mode==RESET_INIT)); target->type->assert_reset(target); target = target->next; } @@ -354,7 +338,7 @@ int target_process_reset(struct command_context_s *cmd_ctx) target = targets; while (target) { - switch (target->reset_mode) + switch (reset_mode) { case RESET_RUN: /* nothing to do if target just wants to be run */ @@ -369,10 +353,12 @@ int target_process_reset(struct command_context_s *cmd_ctx) target_register_event_callback(target_init_handler, cmd_ctx); break; case RESET_HALT: - target_halt(target); + if ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0) + target_halt(target); break; case RESET_INIT: - target_halt(target); + if ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0) + target_halt(target); target_register_event_callback(target_init_handler, cmd_ctx); break; default: @@ -391,6 +377,14 @@ int target_process_reset(struct command_context_s *cmd_ctx) while (target) { target->type->deassert_reset(target); + /* We can fail to bring the target into the halted state */ + target_poll(target); + if (target->reset_halt&&((target->state != TARGET_HALTED))) + { + LOG_WARNING("Failed to reset target into halted mode - issuing halt"); + target->type->halt(target); + } + target = target->next; } @@ -407,8 +401,7 @@ int target_process_reset(struct command_context_s *cmd_ctx) return retval; } - - LOG_DEBUG("Waiting for halted stated as approperiate"); + LOG_DEBUG("Waiting for halted stated as appropriate"); /* Wait for reset to complete, maximum 5 seconds. */ gettimeofday(&timeout, NULL); @@ -424,10 +417,10 @@ int target_process_reset(struct command_context_s *cmd_ctx) { LOG_DEBUG("Polling target"); target_poll(target); - if ((target->reset_mode == RESET_RUN_AND_INIT) || - (target->reset_mode == RESET_RUN_AND_HALT) || - (target->reset_mode == RESET_HALT) || - (target->reset_mode == RESET_INIT)) + if ((reset_mode == RESET_RUN_AND_INIT) || + (reset_mode == RESET_RUN_AND_HALT) || + (reset_mode == RESET_HALT) || + (reset_mode == RESET_INIT)) { if (target->state != TARGET_HALTED) { @@ -464,8 +457,6 @@ int target_process_reset(struct command_context_s *cmd_ctx) } target_unregister_event_callback(target_init_handler, cmd_ctx); - jtag->speed(jtag_speed_post_reset); - return retval; } @@ -738,6 +729,8 @@ static int target_call_timer_callbacks_check_time(int checktime) target_timer_callback_t *next_callback; struct timeval now; + keep_alive(); + gettimeofday(&now, NULL); while (callback) @@ -941,8 +934,8 @@ int target_register_commands(struct command_context_s *cmd_ctx) /* script procedures */ - register_jim(cmd_ctx, "openocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing"); - register_jim(cmd_ctx, "openocd_array2mem", jim_mem2array, "convert a TCL array to memory locations and write the values"); + register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing"); + register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values"); return ERROR_OK; } @@ -1404,18 +1397,31 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a return ERROR_COMMAND_SYNTAX_ERROR; } - /* what to do on a target reset */ - (*last_target_p)->reset_mode = RESET_INIT; /* default */ if (strcmp(args[2], "reset_halt") == 0) - (*last_target_p)->reset_mode = RESET_HALT; + { + LOG_WARNING("reset_mode argument is obsolete."); + return ERROR_COMMAND_SYNTAX_ERROR; + } else if (strcmp(args[2], "reset_run") == 0) - (*last_target_p)->reset_mode = RESET_RUN; + { + LOG_WARNING("reset_mode argument is obsolete."); + return ERROR_COMMAND_SYNTAX_ERROR; + } else if (strcmp(args[2], "reset_init") == 0) - (*last_target_p)->reset_mode = RESET_INIT; + { + LOG_WARNING("reset_mode argument is obsolete."); + return ERROR_COMMAND_SYNTAX_ERROR; + } else if (strcmp(args[2], "run_and_halt") == 0) - (*last_target_p)->reset_mode = RESET_RUN_AND_HALT; + { + LOG_WARNING("reset_mode argument is obsolete."); + return ERROR_COMMAND_SYNTAX_ERROR; + } else if (strcmp(args[2], "run_and_init") == 0) - (*last_target_p)->reset_mode = RESET_RUN_AND_INIT; + { + LOG_WARNING("reset_mode argument is obsolete."); + return ERROR_COMMAND_SYNTAX_ERROR; + } else { /* Kludge! we want to make this reset arg optional while remaining compatible! */ @@ -1470,9 +1476,9 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a int target_invoke_script(struct command_context_s *cmd_ctx, target_t *target, char *name) { - return command_run_linef(cmd_ctx, " if {[catch {info body target_%s_%d} t]==0} {target_%s_%d}", - name, get_num_by_target(target), - name, get_num_by_target(target)); + return command_run_linef(cmd_ctx, " if {[catch {info body target_%d_%s} t]==0} {target_%d_%s}", + get_num_by_target(target), name, + get_num_by_target(target), name); } int handle_run_and_halt_time_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) @@ -1677,7 +1683,6 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args return ERROR_OK; } -static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms); int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { @@ -1723,11 +1728,12 @@ int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_OK; } } + target_t *target = get_current_target(cmd_ctx); - return wait_state(cmd_ctx, cmd, TARGET_HALTED, ms); + return target_wait_state(target, TARGET_HALTED, ms); } -static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms) +int target_wait_state(target_t *target, enum target_state state, int ms) { int retval; struct timeval timeout, now; @@ -1735,7 +1741,6 @@ static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_ gettimeofday(&timeout, NULL); timeval_add_time(&timeout, 0, ms * 1000); - target_t *target = get_current_target(cmd_ctx); for (;;) { if ((retval=target_poll(target))!=ERROR_OK) @@ -1748,7 +1753,7 @@ static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_ if (once) { once=0; - command_print(cmd_ctx, "waiting for target %s...", target_state_strings[state]); + LOG_USER("waiting for target %s...", target_state_strings[state]); } gettimeofday(&now, NULL); @@ -1791,8 +1796,7 @@ int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); - enum target_reset_mode reset_mode = target->reset_mode; - enum target_reset_mode save = target->reset_mode; + enum target_reset_mode reset_mode = RESET_RUN; LOG_DEBUG("-"); @@ -1827,14 +1831,8 @@ int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **ar } } - /* temporarily modify mode of current reset target */ - target->reset_mode = reset_mode; - /* reset *all* targets */ - target_process_reset(cmd_ctx); - - /* Restore default reset mode for this target */ - target->reset_mode = save; + target_process_reset(cmd_ctx, reset_mode); return ERROR_OK; }