* 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.
*/
+ /*
+ * resume() triggers the event 'resumed'. The execution of TCL commands
+ * in the event handler causes the polling of targets. If the target has
+ * already halted for a breakpoint, polling will run the 'halted' event
+ * handler before the pending 'resumed' handler.
+ * Disable polling during resume() to guarantee the execution of handlers
+ * in the correct order.
+ */
+ bool save_poll = jtag_poll_get_enabled();
+ jtag_poll_set_enabled(false);
retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution);
+ jtag_poll_set_enabled(save_poll);
if (retval != ERROR_OK)
return retval;
* algorithm.
*
* @param target used to run the algorithm
+ * @param num_mem_params
+ * @param mem_params
+ * @param num_reg_params
+ * @param reg_param
+ * @param entry_point
+ * @param exit_point
+ * @param timeout_ms
* @param arch_info target-specific description of the algorithm.
*/
int target_run_algorithm(struct target *target,
* Executes a target-specific native code algorithm and leaves it running.
*
* @param target used to run the algorithm
+ * @param num_mem_params
+ * @param mem_params
+ * @param num_reg_params
+ * @param reg_params
+ * @param entry_point
+ * @param exit_point
* @param arch_info target-specific description of the algorithm.
*/
int target_start_algorithm(struct target *target,
* Waits for an algorithm started with target_start_algorithm() to complete.
*
* @param target used to run the algorithm
+ * @param num_mem_params
+ * @param mem_params
+ * @param num_reg_params
+ * @param reg_params
+ * @param exit_point
+ * @param timeout_ms
* @param arch_info target-specific description of the algorithm.
*/
int target_wait_algorithm(struct target *target,
* @param entry_point address on the target to execute to start the algorithm
* @param exit_point address at which to set a breakpoint to catch the
* end of the algorithm; can be 0 if target triggers a breakpoint itself
+ * @param arch_info
*/
int target_run_flash_async_algorithm(struct target *target,
* programming. The exact delay shouldn't matter as long as it's
* less than buffer size / flash speed. This is very unlikely to
* run when using high latency connections such as USB. */
- alive_sleep(10);
+ alive_sleep(2);
/* to stop an infinite loop on some targets check and increment a timeout
* this issue was observed on a stellaris using the new ICDI interface */
- if (timeout++ >= 500) {
+ if (timeout++ >= 2500) {
LOG_ERROR("timeout waiting for algorithm, a target reset is recommended");
return ERROR_FLASH_OPERATION_FAILED;
}
if (thisrun_bytes > count * block_size)
thisrun_bytes = count * block_size;
+ /* Force end of large blocks to be word aligned */
+ if (thisrun_bytes >= 16)
+ thisrun_bytes -= (rp + thisrun_bytes) & 0x03;
+
/* Write data to fifo */
retval = target_write_buffer(target, wp, thisrun_bytes, buffer);
if (retval != ERROR_OK)
return retval;
}
+int target_run_read_async_algorithm(struct target *target,
+ uint8_t *buffer, uint32_t count, int block_size,
+ int num_mem_params, struct mem_param *mem_params,
+ int num_reg_params, struct reg_param *reg_params,
+ uint32_t buffer_start, uint32_t buffer_size,
+ uint32_t entry_point, uint32_t exit_point, void *arch_info)
+{
+ int retval;
+ int timeout = 0;
+
+ const uint8_t *buffer_orig = buffer;
+
+ /* Set up working area. First word is write pointer, second word is read pointer,
+ * rest is fifo data area. */
+ uint32_t wp_addr = buffer_start;
+ uint32_t rp_addr = buffer_start + 4;
+ uint32_t fifo_start_addr = buffer_start + 8;
+ uint32_t fifo_end_addr = buffer_start + buffer_size;
+
+ uint32_t wp = fifo_start_addr;
+ uint32_t rp = fifo_start_addr;
+
+ /* validate block_size is 2^n */
+ assert(!block_size || !(block_size & (block_size - 1)));
+
+ retval = target_write_u32(target, wp_addr, wp);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_write_u32(target, rp_addr, rp);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* Start up algorithm on target */
+ retval = target_start_algorithm(target, num_mem_params, mem_params,
+ num_reg_params, reg_params,
+ entry_point,
+ exit_point,
+ arch_info);
+
+ if (retval != ERROR_OK) {
+ LOG_ERROR("error starting target flash read algorithm");
+ return retval;
+ }
+
+ while (count > 0) {
+ retval = target_read_u32(target, wp_addr, &wp);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("failed to get write pointer");
+ break;
+ }
+
+ LOG_DEBUG("offs 0x%zx count 0x%" PRIx32 " wp 0x%" PRIx32 " rp 0x%" PRIx32,
+ (size_t)(buffer - buffer_orig), count, wp, rp);
+
+ if (wp == 0) {
+ LOG_ERROR("flash read algorithm aborted by target");
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ break;
+ }
+
+ if (((wp - fifo_start_addr) & (block_size - 1)) || wp < fifo_start_addr || wp >= fifo_end_addr) {
+ LOG_ERROR("corrupted fifo write pointer 0x%" PRIx32, wp);
+ break;
+ }
+
+ /* Count the number of bytes available in the fifo without
+ * crossing the wrap around. */
+ uint32_t thisrun_bytes;
+ if (wp >= rp)
+ thisrun_bytes = wp - rp;
+ else
+ thisrun_bytes = fifo_end_addr - rp;
+
+ if (thisrun_bytes == 0) {
+ /* Throttle polling a bit if transfer is (much) faster than flash
+ * reading. The exact delay shouldn't matter as long as it's
+ * less than buffer size / flash speed. This is very unlikely to
+ * run when using high latency connections such as USB. */
+ alive_sleep(2);
+
+ /* to stop an infinite loop on some targets check and increment a timeout
+ * this issue was observed on a stellaris using the new ICDI interface */
+ if (timeout++ >= 2500) {
+ LOG_ERROR("timeout waiting for algorithm, a target reset is recommended");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+ continue;
+ }
+
+ /* Reset our timeout */
+ timeout = 0;
+
+ /* Limit to the amount of data we actually want to read */
+ if (thisrun_bytes > count * block_size)
+ thisrun_bytes = count * block_size;
+
+ /* Force end of large blocks to be word aligned */
+ if (thisrun_bytes >= 16)
+ thisrun_bytes -= (rp + thisrun_bytes) & 0x03;
+
+ /* Read data from fifo */
+ retval = target_read_buffer(target, rp, thisrun_bytes, buffer);
+ if (retval != ERROR_OK)
+ break;
+
+ /* Update counters and wrap write pointer */
+ buffer += thisrun_bytes;
+ count -= thisrun_bytes / block_size;
+ rp += thisrun_bytes;
+ if (rp >= fifo_end_addr)
+ rp = fifo_start_addr;
+
+ /* Store updated write pointer to target */
+ retval = target_write_u32(target, rp_addr, rp);
+ if (retval != ERROR_OK)
+ break;
+
+ /* Avoid GDB timeouts */
+ keep_alive();
+
+ }
+
+ if (retval != ERROR_OK) {
+ /* abort flash write algorithm on target */
+ target_write_u32(target, rp_addr, 0);
+ }
+
+ int retval2 = target_wait_algorithm(target, num_mem_params, mem_params,
+ num_reg_params, reg_params,
+ exit_point,
+ 10000,
+ arch_info);
+
+ if (retval2 != ERROR_OK) {
+ LOG_ERROR("error waiting for target flash write algorithm");
+ retval = retval2;
+ }
+
+ if (retval == ERROR_OK) {
+ /* check if algorithm set wp = 0 after fifo writer loop finished */
+ retval = target_read_u32(target, wp_addr, &wp);
+ if (retval == ERROR_OK && wp == 0) {
+ LOG_ERROR("flash read algorithm aborted by target");
+ retval = ERROR_FLASH_OPERATION_FAILED;
+ }
+ }
+
+ return retval;
+}
+
int target_read_memory(struct target *target,
target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
{
for (i = 0, reg = cache->reg_list;
i < cache->num_regs;
i++, reg++, count++) {
- if (reg->exist == false)
+ if (reg->exist == false || reg->hidden)
continue;
/* only print cached values if they are valid */
if (reg->valid) {
}
enum watchpoint_rw type = WPT_ACCESS;
- uint32_t addr = 0;
+ target_addr_t addr = 0;
uint32_t length = 0;
uint32_t data_value = 0x0;
uint32_t data_mask = 0xffffffff;
/* fall through */
case 2:
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
break;
default:
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- uint32_t addr;
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
+ target_addr_t addr;
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
struct target *target = get_current_target(CMD_CTX);
watchpoint_remove(target, addr);
}
if (goi->isconfigure) {
+ /* START_DEPRECATED_TPIU */
+ if (n->value == TARGET_EVENT_TRACE_CONFIG)
+ LOG_INFO("DEPRECATED target event %s", n->name);
+ /* END_DEPRECATED_TPIU */
+
bool replace = true;
if (teap == NULL) {
/* create new */
e = Jim_GetOpt_String(goi, &s, NULL);
if (e != JIM_OK)
return e;
+ free(target->gdb_port_override);
target->gdb_port_override = strdup(s);
} else {
if (goi->argc != 0)
if (goi->isconfigure) {
struct command_context *cmd_ctx = current_command_context(goi->interp);
if (cmd_ctx->mode != COMMAND_CONFIG) {
- Jim_SetResultString(goi->interp, "-gdb-max-conenctions must be configured before 'init'", -1);
+ Jim_SetResultString(goi->interp, "-gdb-max-connections must be configured before 'init'", -1);
return JIM_ERR;
}
static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
+ struct command *c = jim_to_command(interp);
Jim_GetOptInfo goi;
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- goi.isconfigure = !strcmp(Jim_GetString(argv[0], NULL), "configure");
+ goi.isconfigure = !strcmp(c->name, "configure");
if (goi.argc < 1) {
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
"missing: -option ...");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
return target_configure(&goi, target);
}
static int jim_target_mem2array(Jim_Interp *interp,
int argc, Jim_Obj *const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
return target_mem2array(interp, target, argc - 1, argv + 1);
}
static int jim_target_array2mem(Jim_Interp *interp,
int argc, Jim_Obj *const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
return target_array2mem(interp, target, argc - 1, argv + 1);
}
allow_defer = true;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
Jim_SetResultBool(interp, target_was_examined(target));
return JIM_OK;
static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
Jim_SetResultBool(interp, target->defer_examine);
return JIM_OK;
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK)
return JIM_ERR;
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
if (e != JIM_OK)
return e;
- struct target *target = Jim_CmdPrivData(goi.interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
int e = target->type->halt(target);
e = Jim_GetOpt_Wide(&goi, &a);
if (e != JIM_OK)
return e;
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
if (!target->tap->enabled)
return jim_target_tap_disabled(interp);
Jim_WrongNumArgs(interp, 1, argv, "[no parameters]");
return JIM_ERR;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
Jim_SetResultString(interp, target_state_name(target), -1);
return JIM_OK;
}
Jim_GetOpt_NvpUnknown(&goi, nvp_target_event, 1);
return e;
}
- struct target *target = Jim_CmdPrivData(interp);
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ struct target *target = get_current_target(cmd_ctx);
target_handle_event(target, n->value);
return JIM_OK;
}
/* found */
break;
}
-
- /* check for deprecated name */
- if (target_types[x]->deprecated_name) {
- if (0 == strcmp(cp, target_types[x]->deprecated_name)) {
- /* found */
- LOG_WARNING("target name is deprecated use: \'%s\'", target_types[x]->name);
- break;
- }
- }
}
if (target_types[x] == NULL) {
Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp);
memcpy(target->type, target_types[x], sizeof(struct target_type));
- /* will be set by "-endian" */
- target->endianness = TARGET_ENDIAN_UNKNOWN;
-
/* default to first core, override with -coreid */
target->coreid = 0;
},
COMMAND_REGISTRATION_DONE
};
- e = register_commands(cmd_ctx, NULL, target_commands);
+ e = register_commands_override_target(cmd_ctx, NULL, target_commands, target);
if (e != ERROR_OK) {
if (target->type->deinit_target)
target->type->deinit_target(target);
return JIM_ERR;
}
- struct command *c = command_find_in_context(cmd_ctx, cp);
- assert(c);
- command_set_handler_data(c, target);
-
/* append to end of list */
append_to_list_all_targets(target);