diff options
-rw-r--r-- | src/jtag/jtag.c | 13 | ||||
-rw-r--r-- | src/jtag/jtag.h | 4 | ||||
-rw-r--r-- | src/server/gdb_server.c | 10 | ||||
-rw-r--r-- | src/target/arm720t.c | 2 | ||||
-rw-r--r-- | src/target/arm7_9_common.c | 14 | ||||
-rw-r--r-- | src/target/arm920t.c | 2 | ||||
-rw-r--r-- | src/target/arm926ejs.c | 2 | ||||
-rw-r--r-- | src/target/armv4_5.c | 10 | ||||
-rw-r--r-- | src/target/armv7m.c | 10 | ||||
-rw-r--r-- | src/target/feroceon.c | 4 | ||||
-rw-r--r-- | src/target/target.c | 79 | ||||
-rw-r--r-- | src/target/target.h | 3 |
12 files changed, 93 insertions, 60 deletions
diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 8ebd92b..fa439ec 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -1482,6 +1482,9 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) int jtag_interface_init(struct command_context_s *cmd_ctx) { + if (jtag) + return ERROR_OK; + if (!jtag_interface) { /* nothing was previously specified by "interface" command */ @@ -1511,11 +1514,12 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) { int validate_tries = 0; jtag_device_t *device; + int retval; LOG_DEBUG("-"); - if (!jtag && jtag_interface_init(cmd_ctx) != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; + if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK) + return retval; device = jtag_devices; jtag_ir_scan_size = 0; @@ -1528,7 +1532,8 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) } jtag_add_tlr(); - jtag_execute_queue(); + if ((retval=jtag_execute_queue())==ERROR_OK) + return retval; /* examine chain first, as this could discover the real chain layout */ if (jtag_examine_chain() != ERROR_OK) @@ -1930,7 +1935,7 @@ int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_COMMAND_SYNTAX_ERROR; } - if (!jtag && jtag_interface_init(cmd_ctx) != ERROR_OK) + if (jtag_interface_init(cmd_ctx) != ERROR_OK) return ERROR_JTAG_INIT_FAILED; jtag_add_reset(trst, srst); diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index b7ce094..27ffbf8 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -241,6 +241,10 @@ enum reset_types extern enum reset_types jtag_reset_config; +/* initialize interface upon startup. A successful no-op + * upon subsequent invocations + */ +extern int jtag_interface_init(struct command_context_s *cmd_ctx); /* initialize JTAG chain using only a TLR reset. If init fails, * try reset + init. */ diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 9a5b81a..3e4ba82 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -690,7 +690,7 @@ int gdb_new_connection(connection_t *connection) * instantaneous and thus avoiding annoying timeout problems during * connect. */ - gdb_service->target->type->halt(gdb_service->target); + target_halt(gdb_service->target); /* remove the initial ACK from the incoming buffer */ if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK) @@ -1231,7 +1231,7 @@ void gdb_step_continue_packet(connection_t *connection, target_t *target, char * if (packet[0] == 'c') { LOG_DEBUG("continue"); - target->type->resume(target, current, address, 0, 0); /* resume at current address, don't handle breakpoints, not debugging */ + target_resume(target, current, address, 0, 0); /* resume at current address, don't handle breakpoints, not debugging */ } else if (packet[0] == 's') { @@ -1755,7 +1755,7 @@ int gdb_detach(connection_t *connection, target_t *target) switch( detach_mode ) { case GDB_DETACH_RESUME: - target->type->resume(target, 1, 0, 1, 0); + target_resume(target, 1, 0, 1, 0); break; case GDB_DETACH_RESET: @@ -1763,7 +1763,7 @@ int gdb_detach(connection_t *connection, target_t *target) break; case GDB_DETACH_HALT: - target->type->halt(target); + target_halt(target); break; case GDB_DETACH_NOTHING: @@ -1904,7 +1904,7 @@ int gdb_input_inner(connection_t *connection) { if (target->state == TARGET_RUNNING) { - target->type->halt(target); + target_halt(target); gdb_con->ctrl_c = 0; } } diff --git a/src/target/arm720t.c b/src/target/arm720t.c index 24885d2..9645db8 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -368,7 +368,7 @@ int arm720t_soft_reset_halt(struct target_s *target) int i; reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - target->type->halt(target); + target_halt(target); for (i=0; i<10; i++) { diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 106b95d..14d0314 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -755,14 +755,6 @@ int arm7_9_assert_reset(target_t *target) if ((target->reset_mode == RESET_HALT) || (target->reset_mode == RESET_INIT)) { - reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - - /* program EmbeddedICE Debug Control Register to deassert DBGRQ - * i.e. resume. - */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0); - embeddedice_store_reg(dbg_ctrl); - /* * Some targets do not support communication while SRST is asserted. We need to * set up the reset vector catch here. @@ -867,7 +859,7 @@ int arm7_9_soft_reset_halt(struct target_s *target) int i; int retval; - if ((retval=target->type->halt(target))!=ERROR_OK) + if ((retval=target_halt(target))!=ERROR_OK) return retval; for (i=0; i<10; i++) @@ -2176,11 +2168,11 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe } } - target->type->halt(target); + target_halt(target); for (i=0; i<100; i++) { - target->type->poll(target); + target_poll(target); if (target->state == TARGET_HALTED) break; usleep(1000); /* sleep 1ms */ diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 93ddb4c..2dff6b9 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -624,7 +624,7 @@ int arm920t_soft_reset_halt(struct target_s *target) reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; int i; - target->type->halt(target); + target_halt(target); for (i=0; i<10; i++) { diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index 50abd46..f46760e 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -580,7 +580,7 @@ int arm926ejs_soft_reset_halt(struct target_s *target) reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; int i; - target->type->halt(target); + target_halt(target); for (i=0; i<10; i++) { diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 0b6b345..07033bf 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -574,22 +574,22 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param return ERROR_TARGET_FAILURE; } - target->type->resume(target, 0, entry_point, 1, 1); - target->type->poll(target); + target_resume(target, 0, entry_point, 1, 1); + target_poll(target); while (target->state != TARGET_HALTED) { usleep(10000); - target->type->poll(target); + target_poll(target); if ((timeout_ms -= 10) <= 0) { LOG_ERROR("timeout waiting for algorithm to complete, trying to halt target"); - target->type->halt(target); + target_halt(target); timeout_ms = 1000; while (target->state != TARGET_HALTED) { usleep(10000); - target->type->poll(target); + target_poll(target); if ((timeout_ms -= 10) <= 0) { LOG_ERROR("target didn't reenter debug state, exiting"); diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 81b477a..eaf1eb9 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -349,22 +349,22 @@ int armv7m_run_algorithm(struct target_s *target, int num_mem_params, mem_param_ /* This code relies on the target specific resume() and poll()->debug_entry() sequence to write register values to the processor and the read them back */ - target->type->resume(target, 0, entry_point, 1, 1); - target->type->poll(target); + target_resume(target, 0, entry_point, 1, 1); + target_poll(target); while (target->state != TARGET_HALTED) { usleep(5000); - target->type->poll(target); + target_poll(target); if ((timeout_ms -= 5) <= 0) { LOG_ERROR("timeout waiting for algorithm to complete, trying to halt target"); - target->type->halt(target); + target_halt(target); timeout_ms = 1000; while (target->state != TARGET_HALTED) { usleep(10000); - target->type->poll(target); + target_poll(target); if ((timeout_ms -= 10) <= 0) { LOG_ERROR("target didn't reenter debug state, exiting"); diff --git a/src/target/feroceon.c b/src/target/feroceon.c index c6edc42..0cd632b 100644 --- a/src/target/feroceon.c +++ b/src/target/feroceon.c @@ -547,9 +547,9 @@ int feroceon_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buf buffer += 4; } - target->type->halt(target); + target_halt(target); while (target->state != TARGET_HALTED) - target->type->poll(target); + target_poll(target); /* restore target state */ for (i = 0; i <= 5; i++) diff --git a/src/target/target.c b/src/target/target.c index 28639a7..ee387db 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -248,11 +248,45 @@ int target_run_and_halt_handler(void *priv) { target_t *target = priv; - target->type->halt(target); + target_halt(target); return ERROR_OK; } +int target_poll(struct target_s *target) +{ + /* We can't poll until after examine */ + if (!target->type->examined) + { + /* Fail silently lest we pollute the log */ + return ERROR_FAIL; + } + return target->type->poll(target); +} + +int target_halt(struct target_s *target) +{ + /* We can't poll until after examine */ + if (!target->type->examined) + { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + return target->type->halt(target); +} + +int target_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution) +{ + /* We can't poll until after examine */ + if (!target->type->examined) + { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + return target->type->resume(target, current, address, handle_breakpoints, debug_execution); +} + + int target_process_reset(struct command_context_s *cmd_ctx) { int retval = ERROR_OK; @@ -325,10 +359,10 @@ int target_process_reset(struct command_context_s *cmd_ctx) target_register_event_callback(target_init_handler, cmd_ctx); break; case RESET_HALT: - target->type->halt(target); + target_halt(target); break; case RESET_INIT: - target->type->halt(target); + target_halt(target); target_register_event_callback(target_init_handler, cmd_ctx); break; default: @@ -371,7 +405,7 @@ int target_process_reset(struct command_context_s *cmd_ctx) while (target) { LOG_DEBUG("Polling target"); - target->type->poll(target); + target_poll(target); if ((target->reset_mode == RESET_RUN_AND_INIT) || (target->reset_mode == RESET_RUN_AND_HALT) || (target->reset_mode == RESET_HALT) || @@ -1414,19 +1448,14 @@ int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, ch /* process target state changes */ int handle_target(void *priv) { - int retval; target_t *target = targets; while (target) { - /* only poll if target isn't already halted */ - if (target->state != TARGET_HALTED) + if (target_continous_poll) { - if (target_continous_poll) - if ((retval = target->type->poll(target)) != ERROR_OK) - { - LOG_ERROR("couldn't poll target(%d). It's due for a reset.", retval); - } + /* polling may fail silently until the target has been examined */ + target_poll(target); } target = target->next; @@ -1565,7 +1594,7 @@ int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **arg if (argc == 0) { - target->type->poll(target); + target_poll(target); target_arch_state(target); } else @@ -1610,7 +1639,7 @@ int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char static void target_process_events(struct command_context_s *cmd_ctx) { target_t *target = get_current_target(cmd_ctx); - target->type->poll(target); + target_poll(target); target_call_timer_callbacks_now(); } @@ -1625,7 +1654,7 @@ static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_ target_t *target = get_current_target(cmd_ctx); for (;;) { - if ((retval=target->type->poll(target))!=ERROR_OK) + if ((retval=target_poll(target))!=ERROR_OK) return retval; target_call_timer_callbacks_now(); if (target->state == state) @@ -1656,7 +1685,7 @@ int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **arg LOG_DEBUG("-"); - if ((retval = target->type->halt(target)) != ERROR_OK) + if ((retval = target_halt(target)) != ERROR_OK) { return retval; } @@ -1733,9 +1762,9 @@ int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **a target_t *target = get_current_target(cmd_ctx); if (argc == 0) - retval = target->type->resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */ + retval = target_resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */ else if (argc == 1) - retval = target->type->resume(target, 0, strtoul(args[0], NULL, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */ + retval = target_resume(target, 0, strtoul(args[0], NULL, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */ else { return ERROR_COMMAND_SYNTAX_ERROR; @@ -2485,18 +2514,18 @@ int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char ** for (;;) { - target->type->poll(target); + target_poll(target); if (target->state == TARGET_HALTED) { u32 t=*((u32 *)reg->value); samples[numSamples++]=t; - retval = target->type->resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */ - target->type->poll(target); + retval = target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */ + target_poll(target); usleep(10*1000); // sleep 10ms, i.e. <100 samples/second. } else if (target->state == TARGET_RUNNING) { // We want to quickly sample the PC. - target->type->halt(target); + target_halt(target); } else { command_print(cmd_ctx, "Target not halted or running"); @@ -2512,12 +2541,12 @@ int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char ** if ((numSamples>=maxSample) || ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec))) { command_print(cmd_ctx, "Profiling completed. %d samples.", numSamples); - target->type->poll(target); + target_poll(target); if (target->state == TARGET_HALTED) { - target->type->resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */ + target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */ } - target->type->poll(target); + target_poll(target); writeGmon(samples, numSamples, args[1]); command_print(cmd_ctx, "Wrote %s", args[1]); break; diff --git a/src/target/target.h b/src/target/target.h index 6480bc5..8f53d89 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -256,6 +256,9 @@ extern int target_process_reset(struct command_context_s *cmd_ctx); extern int target_register_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv); extern int target_unregister_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv); +extern int target_poll(target_t *target); +extern int target_resume(target_t *target, int current, u32 address, int handle_breakpoints, int debug_execution); +extern int target_halt(target_t *target); extern int target_call_event_callbacks(target_t *target, enum target_event event); /* The period is very approximate, the callback can happen much more often |