X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=3c1a6338e915a561fb1d08f7f4ee79161753dc2c;hb=f8453ae52cf336c337b7f135f10ed4afecf35a7c;hp=a3230d2486fbccac84221cd2f6383669b9625400;hpb=17a052d6fe44fc265d48e94bdd3356d6f25ca064;p=openocd.git diff --git a/src/target/target.c b/src/target/target.c index a3230d2486..3c1a6338e9 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -72,8 +72,6 @@ static int target_get_gdb_fileio_info_default(struct target *target, struct gdb_fileio_info *fileio_info); static int target_gdb_fileio_end_default(struct target *target, int retcode, int fileio_errno, bool ctrl_c); -static int target_profiling_default(struct target *target, uint32_t *samples, - uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds); /* targets */ extern struct target_type arm7tdmi_target; @@ -94,6 +92,7 @@ extern struct target_type cortexr4_target; extern struct target_type arm11_target; extern struct target_type ls1_sap_target; extern struct target_type mips_m4k_target; +extern struct target_type mips_mips64_target; extern struct target_type avr_target; extern struct target_type dsp563xx_target; extern struct target_type dsp5680xx_target; @@ -110,6 +109,7 @@ extern struct target_type stm8_target; extern struct target_type riscv_target; extern struct target_type mem_ap_target; extern struct target_type esirisc_target; +extern struct target_type arcv2_target; static struct target_type *target_types[] = { &arm7tdmi_target, @@ -145,17 +145,17 @@ static struct target_type *target_types[] = { &riscv_target, &mem_ap_target, &esirisc_target, -#if BUILD_TARGET64 + &arcv2_target, &aarch64_target, -#endif + &mips_mips64_target, NULL, }; struct target *all_targets; static struct target_event_callback *target_event_callbacks; static struct target_timer_callback *target_timer_callbacks; -LIST_HEAD(target_reset_callback_list); -LIST_HEAD(target_trace_callback_list); +static LIST_HEAD(target_reset_callback_list); +static LIST_HEAD(target_trace_callback_list); static const int polling_interval = 100; static const Jim_Nvp nvp_assert[] = { @@ -174,10 +174,10 @@ static const Jim_Nvp nvp_error_target[] = { { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" }, { .value = ERROR_TARGET_NOT_HALTED, .name = "err-not-halted" }, { .value = ERROR_TARGET_FAILURE, .name = "err-failure" }, - { .value = ERROR_TARGET_UNALIGNED_ACCESS , .name = "err-unaligned-access" }, - { .value = ERROR_TARGET_DATA_ABORT , .name = "err-data-abort" }, - { .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE , .name = "err-resource-not-available" }, - { .value = ERROR_TARGET_TRANSLATION_FAULT , .name = "err-translation-fault" }, + { .value = ERROR_TARGET_UNALIGNED_ACCESS, .name = "err-unaligned-access" }, + { .value = ERROR_TARGET_DATA_ABORT, .name = "err-data-abort" }, + { .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE, .name = "err-resource-not-available" }, + { .value = ERROR_TARGET_TRANSLATION_FAULT, .name = "err-translation-fault" }, { .value = ERROR_TARGET_NOT_RUNNING, .name = "err-not-running" }, { .value = ERROR_TARGET_NOT_EXAMINED, .name = "err-not-examined" }, { .value = -1, .name = NULL } @@ -201,6 +201,8 @@ static const Jim_Nvp nvp_target_event[] = { { .value = TARGET_EVENT_RESUMED, .name = "resumed" }, { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" }, { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" }, + { .value = TARGET_EVENT_STEP_START, .name = "step-start" }, + { .value = TARGET_EVENT_STEP_END, .name = "step-end" }, { .name = "gdb-start", .value = TARGET_EVENT_GDB_START }, { .name = "gdb-end", .value = TARGET_EVENT_GDB_END }, @@ -215,6 +217,7 @@ static const Jim_Nvp nvp_target_event[] = { { .value = TARGET_EVENT_RESET_END, .name = "reset-end" }, { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" }, + { .value = TARGET_EVENT_EXAMINE_FAIL, .name = "examine-fail" }, { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" }, { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" }, @@ -224,10 +227,10 @@ static const Jim_Nvp nvp_target_event[] = { { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" }, { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" }, - { .value = TARGET_EVENT_GDB_FLASH_WRITE_END , .name = "gdb-flash-write-end" }, + { .value = TARGET_EVENT_GDB_FLASH_WRITE_END, .name = "gdb-flash-write-end" }, { .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = "gdb-flash-erase-start" }, - { .value = TARGET_EVENT_GDB_FLASH_ERASE_END , .name = "gdb-flash-erase-end" }, + { .value = TARGET_EVENT_GDB_FLASH_ERASE_END, .name = "gdb-flash-erase-end" }, { .value = TARGET_EVENT_TRACE_CONFIG, .name = "trace-config" }, @@ -244,14 +247,15 @@ static const Jim_Nvp nvp_target_state[] = { }; static const Jim_Nvp nvp_target_debug_reason[] = { - { .name = "debug-request" , .value = DBG_REASON_DBGRQ }, - { .name = "breakpoint" , .value = DBG_REASON_BREAKPOINT }, - { .name = "watchpoint" , .value = DBG_REASON_WATCHPOINT }, + { .name = "debug-request", .value = DBG_REASON_DBGRQ }, + { .name = "breakpoint", .value = DBG_REASON_BREAKPOINT }, + { .name = "watchpoint", .value = DBG_REASON_WATCHPOINT }, { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT }, - { .name = "single-step" , .value = DBG_REASON_SINGLESTEP }, - { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED }, - { .name = "program-exit" , .value = DBG_REASON_EXIT }, - { .name = "undefined" , .value = DBG_REASON_UNDEFINED }, + { .name = "single-step", .value = DBG_REASON_SINGLESTEP }, + { .name = "target-not-halted", .value = DBG_REASON_NOTHALTED }, + { .name = "program-exit", .value = DBG_REASON_EXIT }, + { .name = "exception-catch", .value = DBG_REASON_EXC_CATCH }, + { .name = "undefined", .value = DBG_REASON_UNDEFINED }, { .name = NULL, .value = -1 }, }; @@ -265,10 +269,10 @@ static const Jim_Nvp nvp_target_endian[] = { static const Jim_Nvp nvp_reset_modes[] = { { .name = "unknown", .value = RESET_UNKNOWN }, - { .name = "run" , .value = RESET_RUN }, - { .name = "halt" , .value = RESET_HALT }, - { .name = "init" , .value = RESET_INIT }, - { .name = NULL , .value = -1 }, + { .name = "run", .value = RESET_RUN }, + { .name = "halt", .value = RESET_HALT }, + { .name = "init", .value = RESET_INIT }, + { .name = NULL, .value = -1 }, }; const char *debug_reason_name(struct target *t) @@ -338,6 +342,15 @@ static int new_target_number(void) return x + 1; } +static void append_to_list_all_targets(struct target *target) +{ + struct target **t = &all_targets; + + while (*t) + t = &((*t)->next); + *t = target; +} + /* read a uint64_t from a buffer in target memory endianness */ uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer) { @@ -374,12 +387,6 @@ uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer) return be_to_h_u16(buffer); } -/* read a uint8_t from a buffer in target memory endianness */ -static uint8_t target_buffer_get_u8(struct target *target, const uint8_t *buffer) -{ - return *buffer & 0x0ff; -} - /* write a uint64_t to a buffer in target memory endianness */ void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value) { @@ -593,7 +600,7 @@ int target_halt(struct target *target) * @param address Optionally used as the program counter. * @param handle_breakpoints True iff breakpoints at the resumption PC * should be skipped. (For example, maybe execution was stopped by - * such a breakpoint, in which case it would be counterprodutive to + * such a breakpoint, in which case it would be counterproductive to * let it re-trigger. * @param debug_execution False if all working areas allocated by OpenOCD * should be released and/or restored to their original contents. @@ -639,7 +646,7 @@ int target_resume(struct target *target, int current, target_addr_t address, return retval; } -static int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode reset_mode) +static int target_process_reset(struct command_invocation *cmd, enum target_reset_mode reset_mode) { char buf[100]; int retval; @@ -663,13 +670,13 @@ static int target_process_reset(struct command_context *cmd_ctx, enum target_res jtag_poll_set_enabled(false); sprintf(buf, "ocd_process_reset %s", n->name); - retval = Jim_Eval(cmd_ctx->interp, buf); + retval = Jim_Eval(cmd->ctx->interp, buf); jtag_poll_set_enabled(save_poll); if (retval != JIM_OK) { - Jim_MakeErrorMessage(cmd_ctx->interp); - command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(cmd_ctx->interp), NULL)); + Jim_MakeErrorMessage(cmd->ctx->interp); + command_print(cmd, "%s", Jim_GetString(Jim_GetResult(cmd->ctx->interp), NULL)); return ERROR_FAIL; } @@ -709,13 +716,17 @@ static int default_check_reset(struct target *target) return ERROR_OK; } +/* Equivalent Tcl code arp_examine_one is in src/target/startup.tcl + * Keep in sync */ int target_examine_one(struct target *target) { target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_START); int retval = target->type->examine(target); - if (retval != ERROR_OK) + if (retval != ERROR_OK) { + target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_FAIL); return retval; + } target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END); @@ -755,9 +766,11 @@ int target_examine(void) if (target->defer_examine) continue; - retval = target_examine_one(target); - if (retval != ERROR_OK) - return retval; + int retval2 = target_examine_one(target); + if (retval2 != ERROR_OK) { + LOG_WARNING("target %s examination failed", target_name(target)); + retval = retval2; + } } return retval; } @@ -1018,11 +1031,11 @@ 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; } @@ -1036,6 +1049,10 @@ int target_run_flash_async_algorithm(struct target *target, 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) @@ -1085,6 +1102,156 @@ int target_run_flash_async_algorithm(struct target *target, 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) { @@ -1220,22 +1387,58 @@ int target_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class) { - return target->type->get_gdb_reg_list(target, reg_list, reg_list_size, reg_class); + int result = ERROR_FAIL; + + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + goto done; + } + + result = target->type->get_gdb_reg_list(target, reg_list, + reg_list_size, reg_class); + +done: + if (result != ERROR_OK) { + *reg_list = NULL; + *reg_list_size = 0; + } + return result; +} + +int target_get_gdb_reg_list_noread(struct target *target, + struct reg **reg_list[], int *reg_list_size, + enum target_register_class reg_class) +{ + if (target->type->get_gdb_reg_list_noread && + target->type->get_gdb_reg_list_noread(target, reg_list, + reg_list_size, reg_class) == ERROR_OK) + return ERROR_OK; + return target_get_gdb_reg_list(target, reg_list, reg_list_size, reg_class); } bool target_supports_gdb_connection(struct target *target) { /* - * based on current code, we can simply exclude all the targets that - * don't provide get_gdb_reg_list; this could change with new targets. + * exclude all the targets that don't provide get_gdb_reg_list + * or that have explicit gdb_max_connection == 0 */ - return !!target->type->get_gdb_reg_list; + return !!target->type->get_gdb_reg_list && !!target->gdb_max_connections; } int target_step(struct target *target, int current, target_addr_t address, int handle_breakpoints) { - return target->type->step(target, current, address, handle_breakpoints); + int retval; + + target_call_event_callbacks(target, TARGET_EVENT_STEP_START); + + retval = target->type->step(target, current, address, handle_breakpoints); + if (retval != ERROR_OK) + return retval; + + target_call_event_callbacks(target, TARGET_EVENT_STEP_END); + + return retval; } int target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info) @@ -1256,13 +1459,25 @@ int target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, return target->type->gdb_fileio_end(target, retcode, fileio_errno, ctrl_c); } -int target_profiling(struct target *target, uint32_t *samples, +target_addr_t target_address_max(struct target *target) +{ + unsigned bits = target_address_bits(target); + if (sizeof(target_addr_t) * 8 == bits) + return (target_addr_t) -1; + else + return (((target_addr_t) 1) << bits) - 1; +} + +unsigned target_address_bits(struct target *target) +{ + if (target->type->address_bits) + return target->type->address_bits(target); + return 32; +} + +static int target_profiling(struct target *target, uint32_t *samples, uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) { - if (target->state != TARGET_HALTED) { - LOG_WARNING("target %s is not halted (profiling)", target->cmd_name); - return ERROR_TARGET_NOT_HALTED; - } return target->type->profiling(target, samples, max_num_samples, num_samples, seconds); } @@ -1357,7 +1572,7 @@ static int target_init(struct command_context *cmd_ctx) return retval; retval = target_register_timer_callback(&handle_target, - polling_interval, 1, cmd_ctx->interp); + polling_interval, TARGET_TIMER_TYPE_PERIODIC, cmd_ctx->interp); if (ERROR_OK != retval) return retval; @@ -1576,8 +1791,9 @@ int target_call_event_callbacks(struct target *target, enum target_event event) target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); } - LOG_DEBUG("target event %i (%s)", event, - Jim_Nvp_value2name_simple(nvp_target_event, event)->name); + LOG_DEBUG("target event %i (%s) for core %s", event, + Jim_Nvp_value2name_simple(nvp_target_event, event)->name, + target_name(target)); target_handle_event(target, event); @@ -1651,7 +1867,7 @@ static int target_call_timer_callbacks_check_time(int checktime) * next item; initially, that's a standalone "root of the * list" variable. */ struct target_timer_callback **callback = &target_timer_callbacks; - while (*callback) { + while (callback && *callback) { if ((*callback)->removed) { struct target_timer_callback *p = *callback; *callback = (*callback)->next; @@ -1722,10 +1938,8 @@ static void target_split_working_area(struct working_area *area, uint32_t size) /* If backup memory was allocated to this area, it has the wrong size * now so free it and it will be reallocated if/when needed */ - if (area->backup) { - free(area->backup); - area->backup = NULL; - } + free(area->backup); + area->backup = NULL; } } @@ -1745,16 +1959,13 @@ static void target_merge_working_areas(struct target *target) /* Remove the last */ struct working_area *to_be_freed = c->next; c->next = c->next->next; - if (to_be_freed->backup) - free(to_be_freed->backup); + free(to_be_freed->backup); free(to_be_freed); /* If backup memory was allocated to the remaining area, it's has * the wrong size now */ - if (c->backup) { - free(c->backup); - c->backup = NULL; - } + free(c->backup); + c->backup = NULL; } else { c = c->next; } @@ -1984,8 +2195,7 @@ static void target_destroy(struct target *target) if (target->type->deinit_target) target->type->deinit_target(target); - if (target->semihosting) - free(target->semihosting); + free(target->semihosting); jtag_unregister_event_callback(jtag_enable_callback, target); @@ -2011,6 +2221,8 @@ static void target_destroy(struct target *target) target->smp = 0; } + rtos_destroy(target); + free(target->gdb_port_override); free(target->type); free(target->trace_info); @@ -2079,7 +2291,7 @@ static int target_gdb_fileio_end_default(struct target *target, return ERROR_OK; } -static int target_profiling_default(struct target *target, uint32_t *samples, +int target_profiling_default(struct target *target, uint32_t *samples, uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) { struct timeval timeout, now; @@ -2133,7 +2345,7 @@ static int target_profiling_default(struct target *target, uint32_t *samples, */ int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer) { - LOG_DEBUG("writing buffer of %" PRIi32 " byte at " TARGET_ADDR_FMT, + LOG_DEBUG("writing buffer of %" PRIu32 " byte at " TARGET_ADDR_FMT, size, address); if (!target_was_examined(target)) { @@ -2195,7 +2407,7 @@ static int target_write_buffer_default(struct target *target, */ int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer) { - LOG_DEBUG("reading buffer of %" PRIi32 " byte at " TARGET_ADDR_FMT, + LOG_DEBUG("reading buffer of %" PRIu32 " byte at " TARGET_ADDR_FMT, size, address); if (!target_was_examined(target)) { @@ -2250,7 +2462,7 @@ static int target_read_buffer_default(struct target *target, target_addr_t addre return ERROR_OK; } -int target_checksum_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t* crc) +int target_checksum_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t *crc) { uint8_t *buffer; int retval; @@ -2265,7 +2477,7 @@ int target_checksum_memory(struct target *target, target_addr_t address, uint32_ if (retval != ERROR_OK) { buffer = malloc(size); if (buffer == NULL) { - LOG_ERROR("error allocating buffer for section (%" PRId32 " bytes)", size); + LOG_ERROR("error allocating buffer for section (%" PRIu32 " bytes)", size); return ERROR_COMMAND_SYNTAX_ERROR; } retval = target_read_buffer(target, address, size, buffer); @@ -2561,23 +2773,23 @@ int target_write_phys_u8(struct target *target, target_addr_t address, uint8_t v return retval; } -static int find_target(struct command_context *cmd_ctx, const char *name) +static int find_target(struct command_invocation *cmd, const char *name) { struct target *target = get_target(name); if (target == NULL) { - LOG_ERROR("Target: %s is unknown, try one of:\n", name); + command_print(cmd, "Target: %s is unknown, try one of:\n", name); return ERROR_FAIL; } if (!target->tap->enabled) { - LOG_USER("Target: TAP %s is disabled, " + command_print(cmd, "Target: TAP %s is disabled, " "can't be the current target\n", target->tap->dotted_name); return ERROR_FAIL; } - cmd_ctx->current_target = target; - if (cmd_ctx->current_target_override) - cmd_ctx->current_target_override = target; + cmd->ctx->current_target = target; + if (cmd->ctx->current_target_override) + cmd->ctx->current_target_override = target; return ERROR_OK; } @@ -2587,7 +2799,7 @@ COMMAND_HANDLER(handle_targets_command) { int retval = ERROR_OK; if (CMD_ARGC == 1) { - retval = find_target(CMD_CTX, CMD_ARGV[0]); + retval = find_target(CMD, CMD_ARGV[0]); if (retval == ERROR_OK) { /* we're done! */ return retval; @@ -2595,8 +2807,8 @@ COMMAND_HANDLER(handle_targets_command) } struct target *target = all_targets; - command_print(CMD_CTX, " TargetName Type Endian TapName State "); - command_print(CMD_CTX, "-- ------------------ ---------- ------ ------------------ ------------"); + command_print(CMD, " TargetName Type Endian TapName State "); + command_print(CMD, "-- ------------------ ---------- ------ ------------------ ------------"); while (target) { const char *state; char marker = ' '; @@ -2610,7 +2822,7 @@ COMMAND_HANDLER(handle_targets_command) marker = '*'; /* keep columns lined up to match the headers above */ - command_print(CMD_CTX, + command_print(CMD, "%2d%c %-18s %-10s %-6s %-18s %s", target->target_number, marker, @@ -2820,18 +3032,18 @@ COMMAND_HANDLER(handle_reg_command) while (cache) { unsigned i; - command_print(CMD_CTX, "===== %s", cache->name); + command_print(CMD, "===== %s", cache->name); 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) { - value = buf_to_str(reg->value, - reg->size, 16); - command_print(CMD_CTX, + value = buf_to_hex_str(reg->value, + reg->size); + command_print(CMD, "(%i) %s (/%" PRIu32 "): 0x%s%s", count, reg->name, reg->size, value, @@ -2840,9 +3052,9 @@ COMMAND_HANDLER(handle_reg_command) : ""); free(value); } else { - command_print(CMD_CTX, "(%i) %s (/%" PRIu32 ")", + command_print(CMD, "(%i) %s (/%" PRIu32 ")", count, reg->name, - reg->size) ; + reg->size); } } cache = cache->next; @@ -2872,7 +3084,7 @@ COMMAND_HANDLER(handle_reg_command) } if (!reg) { - command_print(CMD_CTX, "%i is out of bounds, the current target " + command_print(CMD, "%i is out of bounds, the current target " "has only %i registers (0 - %i)", num, count, count - 1); return ERROR_OK; } @@ -2897,8 +3109,8 @@ COMMAND_HANDLER(handle_reg_command) if (reg->valid == 0) reg->type->get(reg); - value = buf_to_str(reg->value, reg->size, 16); - command_print(CMD_CTX, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value); + value = buf_to_hex_str(reg->value, reg->size); + command_print(CMD, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value); free(value); return ERROR_OK; } @@ -2912,8 +3124,8 @@ COMMAND_HANDLER(handle_reg_command) reg->type->set(reg, buf); - value = buf_to_str(reg->value, reg->size, 16); - command_print(CMD_CTX, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value); + value = buf_to_hex_str(reg->value, reg->size); + command_print(CMD, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value); free(value); free(buf); @@ -2924,7 +3136,7 @@ COMMAND_HANDLER(handle_reg_command) return ERROR_COMMAND_SYNTAX_ERROR; not_found: - command_print(CMD_CTX, "register %s not found in current target", CMD_ARGV[0]); + command_print(CMD, "register %s not found in current target", CMD_ARGV[0]); return ERROR_OK; } @@ -2934,9 +3146,9 @@ COMMAND_HANDLER(handle_poll_command) struct target *target = get_current_target(CMD_CTX); if (CMD_ARGC == 0) { - command_print(CMD_CTX, "background polling: %s", + command_print(CMD, "background polling: %s", jtag_poll_get_enabled() ? "on" : "off"); - command_print(CMD_CTX, "TAP: %s (%s)", + command_print(CMD, "TAP: %s (%s)", target->tap->dotted_name, target->tap->enabled ? "enabled" : "disabled"); if (!target->tap->enabled) @@ -3062,7 +3274,7 @@ COMMAND_HANDLER(handle_reset_command) } /* reset *all* targets */ - return target_process_reset(CMD_CTX, reset_mode); + return target_process_reset(CMD, reset_mode); } @@ -3105,10 +3317,10 @@ COMMAND_HANDLER(handle_step_command) struct target *target = get_current_target(CMD_CTX); - return target->type->step(target, current_pc, addr, 1); + return target_step(target, current_pc, addr, 1); } -static void handle_md_output(struct command_context *cmd_ctx, +void target_handle_md_output(struct command_invocation *cmd, struct target *target, target_addr_t address, unsigned size, unsigned count, const uint8_t *buffer) { @@ -3166,7 +3378,7 @@ static void handle_md_output(struct command_context *cmd_ctx, value_fmt, value); if ((i % line_modulo == line_modulo - 1) || (i == count - 1)) { - command_print(cmd_ctx, "%s", output); + command_print(cmd, "%s", output); output_len = 0; } } @@ -3223,7 +3435,7 @@ COMMAND_HANDLER(handle_md_command) struct target *target = get_current_target(CMD_CTX); int retval = fn(target, address, size, count, buffer); if (ERROR_OK == retval) - handle_md_output(CMD_CTX, target, address, size, count, buffer); + target_handle_md_output(CMD, target, address, size, count, buffer); free(buffer); @@ -3307,8 +3519,8 @@ COMMAND_HANDLER(handle_mw_command) target_addr_t address; COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address); - target_addr_t value; - COMMAND_PARSE_ADDRESS(CMD_ARGV[1], value); + uint64_t value; + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], value); unsigned count = 1; if (CMD_ARGC == 3) @@ -3348,11 +3560,11 @@ static COMMAND_HELPER(parse_load_image_command_CMD_ARGV, struct image *image, target_addr_t addr; COMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr); image->base_address = addr; - image->base_address_set = 1; + image->base_address_set = true; } else - image->base_address_set = 0; + image->base_address_set = false; - image->start_address_set = 0; + image->start_address_set = false; if (CMD_ARGC >= 4) COMMAND_PARSE_ADDRESS(CMD_ARGV[3], *min_address); @@ -3375,7 +3587,6 @@ COMMAND_HANDLER(handle_load_image_command) uint32_t image_size; target_addr_t min_address = 0; target_addr_t max_address = -1; - int i; struct image image; int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV, @@ -3393,10 +3604,10 @@ COMMAND_HANDLER(handle_load_image_command) image_size = 0x0; retval = ERROR_OK; - for (i = 0; i < image.num_sections; i++) { + for (unsigned int i = 0; i < image.num_sections; i++) { buffer = malloc(image.sections[i].size); if (buffer == NULL) { - command_print(CMD_CTX, + command_print(CMD, "error allocating buffer for section (%d bytes)", (int)(image.sections[i].size)); retval = ERROR_FAIL; @@ -3412,7 +3623,7 @@ COMMAND_HANDLER(handle_load_image_command) uint32_t offset = 0; uint32_t length = buf_cnt; - /* DANGER!!! beware of unsigned comparision here!!! */ + /* DANGER!!! beware of unsigned comparison here!!! */ if ((image.sections[i].base_address + buf_cnt >= min_address) && (image.sections[i].base_address < max_address)) { @@ -3433,7 +3644,7 @@ COMMAND_HANDLER(handle_load_image_command) break; } image_size += length; - command_print(CMD_CTX, "%u bytes written at address " TARGET_ADDR_FMT "", + command_print(CMD, "%u bytes written at address " TARGET_ADDR_FMT "", (unsigned int)length, image.sections[i].base_address + offset); } @@ -3442,7 +3653,7 @@ COMMAND_HANDLER(handle_load_image_command) } if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "downloaded %" PRIu32 " bytes " + command_print(CMD, "downloaded %" PRIu32 " bytes " "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); } @@ -3503,7 +3714,7 @@ COMMAND_HANDLER(handle_dump_image_command) retval = fileio_size(fileio, &filesize); if (retval != ERROR_OK) return retval; - command_print(CMD_CTX, + command_print(CMD, "dumped %zu bytes in %fs (%0.3f KiB/s)", filesize, duration_elapsed(&bench), duration_kbps(&bench, filesize)); } @@ -3526,7 +3737,6 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver uint8_t *buffer; size_t buf_cnt; uint32_t image_size; - int i; int retval; uint32_t checksum = 0; uint32_t mem_checksum = 0; @@ -3550,13 +3760,13 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver target_addr_t addr; COMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr); image.base_address = addr; - image.base_address_set = 1; + image.base_address_set = true; } else { - image.base_address_set = 0; + image.base_address_set = false; image.base_address = 0x0; } - image.start_address_set = 0; + image.start_address_set = false; retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL); if (retval != ERROR_OK) @@ -3565,12 +3775,12 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver image_size = 0x0; int diffs = 0; retval = ERROR_OK; - for (i = 0; i < image.num_sections; i++) { + for (unsigned int i = 0; i < image.num_sections; i++) { buffer = malloc(image.sections[i].size); if (buffer == NULL) { - command_print(CMD_CTX, - "error allocating buffer for section (%d bytes)", - (int)(image.sections[i].size)); + command_print(CMD, + "error allocating buffer for section (%" PRIu32 " bytes)", + image.sections[i].size); break; } retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt); @@ -3607,26 +3817,19 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver data = malloc(buf_cnt); - /* Can we use 32bit word accesses? */ - int size = 1; - int count = buf_cnt; - if ((count % 4) == 0) { - size *= 4; - count /= 4; - } - retval = target_read_memory(target, image.sections[i].base_address, size, count, data); + retval = target_read_buffer(target, image.sections[i].base_address, buf_cnt, data); if (retval == ERROR_OK) { uint32_t t; for (t = 0; t < buf_cnt; t++) { if (data[t] != buffer[t]) { - command_print(CMD_CTX, + command_print(CMD, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x", diffs, (unsigned)(t + image.sections[i].base_address), data[t], buffer[t]); if (diffs++ >= 127) { - command_print(CMD_CTX, "More than 128 errors, the rest are not printed."); + command_print(CMD, "More than 128 errors, the rest are not printed."); free(data); free(buffer); goto done; @@ -3638,7 +3841,7 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver free(data); } } else { - command_print(CMD_CTX, "address " TARGET_ADDR_FMT " length 0x%08zx", + command_print(CMD, "address " TARGET_ADDR_FMT " length 0x%08zx", image.sections[i].base_address, buf_cnt); } @@ -3647,12 +3850,12 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver image_size += buf_cnt; } if (diffs > 0) - command_print(CMD_CTX, "No more differences found."); + command_print(CMD, "No more differences found."); done: if (diffs > 0) retval = ERROR_FAIL; if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "verified %" PRIu32 " bytes " + command_print(CMD, "verified %" PRIu32 " bytes " "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); } @@ -3677,32 +3880,32 @@ COMMAND_HANDLER(handle_test_image_command) return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_TEST); } -static int handle_bp_command_list(struct command_context *cmd_ctx) +static int handle_bp_command_list(struct command_invocation *cmd) { - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(cmd->ctx); struct breakpoint *breakpoint = target->breakpoints; while (breakpoint) { if (breakpoint->type == BKPT_SOFT) { - char *buf = buf_to_str(breakpoint->orig_instr, - breakpoint->length, 16); - command_print(cmd_ctx, "IVA breakpoint: " TARGET_ADDR_FMT ", 0x%x, %i, 0x%s", + char *buf = buf_to_hex_str(breakpoint->orig_instr, + breakpoint->length); + command_print(cmd, "IVA breakpoint: " TARGET_ADDR_FMT ", 0x%x, %i, 0x%s", breakpoint->address, breakpoint->length, breakpoint->set, buf); free(buf); } else { if ((breakpoint->address == 0) && (breakpoint->asid != 0)) - command_print(cmd_ctx, "Context breakpoint: 0x%8.8" PRIx32 ", 0x%x, %i", + command_print(cmd, "Context breakpoint: 0x%8.8" PRIx32 ", 0x%x, %i", breakpoint->asid, breakpoint->length, breakpoint->set); else if ((breakpoint->address != 0) && (breakpoint->asid != 0)) { - command_print(cmd_ctx, "Hybrid breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i", + command_print(cmd, "Hybrid breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i", breakpoint->address, breakpoint->length, breakpoint->set); - command_print(cmd_ctx, "\t|--->linked with ContextID: 0x%8.8" PRIx32, + command_print(cmd, "\t|--->linked with ContextID: 0x%8.8" PRIx32, breakpoint->asid); } else - command_print(cmd_ctx, "Breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i", + command_print(cmd, "Breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i", breakpoint->address, breakpoint->length, breakpoint->set); } @@ -3712,17 +3915,17 @@ static int handle_bp_command_list(struct command_context *cmd_ctx) return ERROR_OK; } -static int handle_bp_command_set(struct command_context *cmd_ctx, +static int handle_bp_command_set(struct command_invocation *cmd, target_addr_t addr, uint32_t asid, uint32_t length, int hw) { - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(cmd->ctx); int retval; if (asid == 0) { retval = breakpoint_add(target, addr, length, hw); /* error is always logged in breakpoint_add(), do not print it again */ if (ERROR_OK == retval) - command_print(cmd_ctx, "breakpoint set at " TARGET_ADDR_FMT "", addr); + command_print(cmd, "breakpoint set at " TARGET_ADDR_FMT "", addr); } else if (addr == 0) { if (target->type->add_context_breakpoint == NULL) { @@ -3732,7 +3935,7 @@ static int handle_bp_command_set(struct command_context *cmd_ctx, retval = context_breakpoint_add(target, asid, length, hw); /* error is always logged in context_breakpoint_add(), do not print it again */ if (ERROR_OK == retval) - command_print(cmd_ctx, "Context breakpoint set at 0x%8.8" PRIx32 "", asid); + command_print(cmd, "Context breakpoint set at 0x%8.8" PRIx32 "", asid); } else { if (target->type->add_hybrid_breakpoint == NULL) { @@ -3742,7 +3945,7 @@ static int handle_bp_command_set(struct command_context *cmd_ctx, retval = hybrid_breakpoint_add(target, addr, asid, length, hw); /* error is always logged in hybrid_breakpoint_add(), do not print it again */ if (ERROR_OK == retval) - command_print(cmd_ctx, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid); + command_print(cmd, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid); } return retval; } @@ -3756,13 +3959,13 @@ COMMAND_HANDLER(handle_bp_command) switch (CMD_ARGC) { case 0: - return handle_bp_command_list(CMD_CTX); + return handle_bp_command_list(CMD); case 2: asid = 0; COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length); - return handle_bp_command_set(CMD_CTX, addr, asid, length, hw); + return handle_bp_command_set(CMD, addr, asid, length, hw); case 3: if (strcmp(CMD_ARGV[2], "hw") == 0) { @@ -3770,13 +3973,13 @@ COMMAND_HANDLER(handle_bp_command) COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length); asid = 0; - return handle_bp_command_set(CMD_CTX, addr, asid, length, hw); + return handle_bp_command_set(CMD, addr, asid, length, hw); } else if (strcmp(CMD_ARGV[2], "hw_ctx") == 0) { hw = BKPT_HARD; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], asid); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length); addr = 0; - return handle_bp_command_set(CMD_CTX, addr, asid, length, hw); + return handle_bp_command_set(CMD, addr, asid, length, hw); } /* fallthrough */ case 4: @@ -3784,7 +3987,7 @@ COMMAND_HANDLER(handle_bp_command) COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], asid); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], length); - return handle_bp_command_set(CMD_CTX, addr, asid, length, hw); + return handle_bp_command_set(CMD, addr, asid, length, hw); default: return ERROR_COMMAND_SYNTAX_ERROR; @@ -3796,11 +3999,16 @@ COMMAND_HANDLER(handle_rbp_command) if (CMD_ARGC != 1) return ERROR_COMMAND_SYNTAX_ERROR; - target_addr_t addr; - COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr); - struct target *target = get_current_target(CMD_CTX); - breakpoint_remove(target, addr); + + if (!strcmp(CMD_ARGV[0], "all")) { + breakpoint_remove_all(target); + } else { + target_addr_t addr; + COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr); + + breakpoint_remove(target, addr); + } return ERROR_OK; } @@ -3813,7 +4021,7 @@ COMMAND_HANDLER(handle_wp_command) struct watchpoint *watchpoint = target->watchpoints; while (watchpoint) { - command_print(CMD_CTX, "address: " TARGET_ADDR_FMT + command_print(CMD, "address: " TARGET_ADDR_FMT ", len: 0x%8.8" PRIx32 ", r/w/a: %i, value: 0x%8.8" PRIx32 ", mask: 0x%8.8" PRIx32, @@ -3905,7 +4113,7 @@ COMMAND_HANDLER(handle_virt2phys_command) struct target *target = get_current_target(CMD_CTX); int retval = target->type->virt2phys(target, va, &pa); if (retval == ERROR_OK) - command_print(CMD_CTX, "Physical address " TARGET_ADDR_FMT "", pa); + command_print(CMD, "Physical address " TARGET_ADDR_FMT "", pa); return retval; } @@ -4043,6 +4251,7 @@ COMMAND_HANDLER(handle_profile_command) uint32_t offset; uint32_t num_of_samples; int retval = ERROR_OK; + bool halted_before_profiling = target->state == TARGET_HALTED; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], offset); @@ -4073,12 +4282,23 @@ COMMAND_HANDLER(handle_profile_command) free(samples); return retval; } - if (target->state == TARGET_RUNNING) { + + if (target->state == TARGET_RUNNING && halted_before_profiling) { + /* The target was halted before we started and is running now. Halt it, + * for consistency. */ retval = target_halt(target); if (retval != ERROR_OK) { free(samples); return retval; } + } else if (target->state == TARGET_HALTED && !halted_before_profiling) { + /* The target was running before we started and is halted now. Resume + * it, for consistency. */ + retval = target_resume(target, 1, 0, 0, 0); + if (retval != ERROR_OK) { + free(samples); + return retval; + } } retval = target_poll(target); @@ -4098,7 +4318,7 @@ COMMAND_HANDLER(handle_profile_command) write_gmon(samples, num_of_samples, CMD_ARGV[1], with_range, start_address, end_address, target, duration_ms); - command_print(CMD_CTX, "Wrote %s", CMD_ARGV[1]); + command_print(CMD, "Wrote %s", CMD_ARGV[1]); free(samples); return retval; @@ -4235,7 +4455,7 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, } else { char buf[100]; Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads", + sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRIu32 " byte reads", addr, width); Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL); @@ -4267,7 +4487,7 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, retval = target_read_memory(target, addr, width, count, buffer); if (retval != ERROR_OK) { /* BOO !*/ - LOG_ERROR("mem2array: Read @ 0x%08" PRIx32 ", w=%" PRId32 ", cnt=%" PRId32 ", failed", + LOG_ERROR("mem2array: Read @ 0x%08" PRIx32 ", w=%" PRIu32 ", cnt=%" PRIu32 ", failed", addr, width, count); @@ -4441,7 +4661,7 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, } else { char buf[100]; Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - sprintf(buf, "array2mem address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads", + sprintf(buf, "array2mem address: 0x%08" PRIx32 " is not aligned for %" PRIu32 " byte reads", addr, width); Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL); @@ -4490,7 +4710,7 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, retval = target_write_memory(target, addr, width, count, buffer); if (retval != ERROR_OK) { /* BOO !*/ - LOG_ERROR("array2mem: Write @ 0x%08" PRIx32 ", w=%" PRId32 ", cnt=%" PRId32 ", failed", + LOG_ERROR("array2mem: Write @ 0x%08" PRIx32 ", w=%" PRIu32 ", cnt=%" PRIu32 ", failed", addr, width, count); @@ -4515,6 +4735,7 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, void target_handle_event(struct target *target, enum target_event e) { struct target_event_action *teap; + int retval; for (teap = target->event_action; teap != NULL; teap = teap->next) { if (teap->event == e) { @@ -4534,12 +4755,25 @@ void target_handle_event(struct target *target, enum target_event e) struct target *saved_target_override = cmd_ctx->current_target_override; cmd_ctx->current_target_override = target; - if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK) { - Jim_MakeErrorMessage(teap->interp); - command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(teap->interp), NULL)); - } + retval = Jim_EvalObj(teap->interp, teap->body); cmd_ctx->current_target_override = saved_target_override; + + if (retval == ERROR_COMMAND_CLOSE_CONNECTION) + return; + + if (retval == JIM_RETURN) + retval = teap->interp->returnCode; + + if (retval != JIM_OK) { + Jim_MakeErrorMessage(teap->interp); + LOG_USER("Error executing event %s on target %s:\n%s", + Jim_Nvp_value2name_simple(nvp_target_event, e)->name, + target_name(target), + Jim_GetString(Jim_GetResult(teap->interp), NULL)); + /* clean both error code and stacktrace before return */ + Jim_Eval(teap->interp, "error \"\" \"\""); + } } } } @@ -4572,6 +4806,7 @@ enum target_cfg_param { TCFG_RTOS, TCFG_DEFER_EXAMINE, TCFG_GDB_PORT, + TCFG_GDB_MAX_CONNECTIONS, }; static Jim_Nvp nvp_config_opts[] = { @@ -4581,13 +4816,14 @@ static Jim_Nvp nvp_config_opts[] = { { .name = "-work-area-phys", .value = TCFG_WORK_AREA_PHYS }, { .name = "-work-area-size", .value = TCFG_WORK_AREA_SIZE }, { .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP }, - { .name = "-endian" , .value = TCFG_ENDIAN }, + { .name = "-endian", .value = TCFG_ENDIAN }, { .name = "-coreid", .value = TCFG_COREID }, { .name = "-chain-position", .value = TCFG_CHAIN_POSITION }, { .name = "-dbgbase", .value = TCFG_DBGBASE }, { .name = "-rtos", .value = TCFG_RTOS }, { .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE }, { .name = "-gdb-port", .value = TCFG_GDB_PORT }, + { .name = "-gdb-max-connections", .value = TCFG_GDB_MAX_CONNECTIONS }, { .name = NULL, .value = -1 } }; @@ -4624,7 +4860,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) } switch (n->value) { case TCFG_TYPE: - /* not setable */ + /* not settable */ if (goi->isconfigure) { Jim_SetResultFormatted(goi->interp, "not settable: %s", n->name); @@ -4814,7 +5050,7 @@ no_params: if (goi->argc != 0) goto no_params; } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size)); + Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->coreid)); /* loop for more */ break; @@ -4877,6 +5113,12 @@ no_params: case TCFG_GDB_PORT: if (goi->isconfigure) { + struct command_context *cmd_ctx = current_command_context(goi->interp); + if (cmd_ctx->mode != COMMAND_CONFIG) { + Jim_SetResultString(goi->interp, "-gdb-port must be configured before 'init'", -1); + return JIM_ERR; + } + const char *s; e = Jim_GetOpt_String(goi, &s, NULL); if (e != JIM_OK) @@ -4889,6 +5131,25 @@ no_params: Jim_SetResultString(goi->interp, target->gdb_port_override ? : "undefined", -1); /* loop for more */ break; + + case TCFG_GDB_MAX_CONNECTIONS: + 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); + return JIM_ERR; + } + + e = Jim_GetOpt_Wide(goi, &w); + if (e != JIM_OK) + return e; + target->gdb_max_connections = (w < 0) ? CONNECTION_LIMIT_UNLIMITED : (int)w; + } else { + if (goi->argc != 0) + goto no_params; + } + Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->gdb_max_connections)); + break; } } /* while (goi->argc) */ @@ -4912,228 +5173,6 @@ static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *a return target_configure(&goi, target); } -static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - - if (goi.argc < 2 || goi.argc > 4) { - Jim_SetResultFormatted(goi.interp, - "usage: %s [phys]
[]", cmd_name); - return JIM_ERR; - } - - target_write_fn fn; - fn = target_write_memory; - - int e; - if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) { - /* consume it */ - struct Jim_Obj *obj; - e = Jim_GetOpt_Obj(&goi, &obj); - if (e != JIM_OK) - return e; - - fn = target_write_phys_memory; - } - - jim_wide a; - e = Jim_GetOpt_Wide(&goi, &a); - if (e != JIM_OK) - return e; - - jim_wide b; - e = Jim_GetOpt_Wide(&goi, &b); - if (e != JIM_OK) - return e; - - jim_wide c = 1; - if (goi.argc == 1) { - e = Jim_GetOpt_Wide(&goi, &c); - if (e != JIM_OK) - return e; - } - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - struct target *target = Jim_CmdPrivData(goi.interp); - unsigned data_size; - if (strcasecmp(cmd_name, "mww") == 0) - data_size = 4; - else if (strcasecmp(cmd_name, "mwh") == 0) - data_size = 2; - else if (strcasecmp(cmd_name, "mwb") == 0) - data_size = 1; - else { - LOG_ERROR("command '%s' unknown: ", cmd_name); - return JIM_ERR; - } - - return (target_fill_mem(target, a, fn, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR; -} - -/** -* @brief Reads an array of words/halfwords/bytes from target memory starting at specified address. -* -* Usage: mdw [phys]
[] - for 32 bit reads -* mdh [phys]
[] - for 16 bit reads -* mdb [phys]
[] - for 8 bit reads -* -* Count defaults to 1. -* -* Calls target_read_memory or target_read_phys_memory depending on -* the presence of the "phys" argument -* Reads the target memory in blocks of max. 32 bytes, and returns an array of ints formatted -* to int representation in base16. -* Also outputs read data in a human readable form using command_print -* -* @param phys if present target_read_phys_memory will be used instead of target_read_memory -* @param address address where to start the read. May be specified in decimal or hex using the standard "0x" prefix -* @param count optional count parameter to read an array of values. If not specified, defaults to 1. -* @returns: JIM_ERR on error or JIM_OK on success and sets the result string to an array of ascii formatted numbers -* on success, with [] number of elements. -* -* In case of little endian target: -* Example1: "mdw 0x00000000" returns "10123456" -* Exmaple2: "mdh 0x00000000 1" returns "3456" -* Example3: "mdb 0x00000000" returns "56" -* Example4: "mdh 0x00000000 2" returns "3456 1012" -* Example5: "mdb 0x00000000 3" returns "56 34 12" -**/ -static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - const char *cmd_name = Jim_GetString(argv[0], NULL); - - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - - if ((goi.argc < 1) || (goi.argc > 3)) { - Jim_SetResultFormatted(goi.interp, - "usage: %s [phys]
[]", cmd_name); - return JIM_ERR; - } - - int (*fn)(struct target *target, - target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); - fn = target_read_memory; - - int e; - if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) { - /* consume it */ - struct Jim_Obj *obj; - e = Jim_GetOpt_Obj(&goi, &obj); - if (e != JIM_OK) - return e; - - fn = target_read_phys_memory; - } - - /* Read address parameter */ - jim_wide addr; - e = Jim_GetOpt_Wide(&goi, &addr); - if (e != JIM_OK) - return JIM_ERR; - - /* If next parameter exists, read it out as the count parameter, if not, set it to 1 (default) */ - jim_wide count; - if (goi.argc == 1) { - e = Jim_GetOpt_Wide(&goi, &count); - if (e != JIM_OK) - return JIM_ERR; - } else - count = 1; - - /* all args must be consumed */ - if (goi.argc != 0) - return JIM_ERR; - - jim_wide dwidth = 1; /* shut up gcc */ - if (strcasecmp(cmd_name, "mdw") == 0) - dwidth = 4; - else if (strcasecmp(cmd_name, "mdh") == 0) - dwidth = 2; - else if (strcasecmp(cmd_name, "mdb") == 0) - dwidth = 1; - else { - LOG_ERROR("command '%s' unknown: ", cmd_name); - return JIM_ERR; - } - - /* convert count to "bytes" */ - int bytes = count * dwidth; - - struct target *target = Jim_CmdPrivData(goi.interp); - uint8_t target_buf[32]; - jim_wide x, y, z; - while (bytes > 0) { - y = (bytes < 16) ? bytes : 16; /* y = min(bytes, 16); */ - - /* Try to read out next block */ - e = fn(target, addr, dwidth, y / dwidth, target_buf); - - if (e != ERROR_OK) { - Jim_SetResultFormatted(interp, "error reading target @ 0x%08lx", (long)addr); - return JIM_ERR; - } - - command_print_sameline(NULL, "0x%08x ", (int)(addr)); - switch (dwidth) { - case 4: - for (x = 0; x < 16 && x < y; x += 4) { - z = target_buffer_get_u32(target, &(target_buf[x])); - command_print_sameline(NULL, "%08x ", (int)(z)); - } - for (; (x < 16) ; x += 4) - command_print_sameline(NULL, " "); - break; - case 2: - for (x = 0; x < 16 && x < y; x += 2) { - z = target_buffer_get_u16(target, &(target_buf[x])); - command_print_sameline(NULL, "%04x ", (int)(z)); - } - for (; (x < 16) ; x += 2) - command_print_sameline(NULL, " "); - break; - case 1: - default: - for (x = 0 ; (x < 16) && (x < y) ; x += 1) { - z = target_buffer_get_u8(target, &(target_buf[x])); - command_print_sameline(NULL, "%02x ", (int)(z)); - } - for (; (x < 16) ; x += 1) - command_print_sameline(NULL, " "); - break; - } - /* ascii-ify the bytes */ - for (x = 0 ; x < y ; x++) { - if ((target_buf[x] >= 0x20) && - (target_buf[x] <= 0x7e)) { - /* good */ - } else { - /* smack it */ - target_buf[x] = '.'; - } - } - /* space pad */ - while (x < 16) { - target_buf[x] = ' '; - x++; - } - /* terminate */ - target_buf[16] = 0; - /* print - with a newline */ - command_print_sameline(NULL, "%s\n", target_buf); - /* NEXT... */ - bytes -= 16; - addr += 16; - } - return JIM_OK; -} - static int jim_target_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -5169,7 +5208,7 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv if (goi.argc > 0 && strcmp(Jim_GetString(argv[1], NULL), "allow-defer") == 0) { /* consume it */ - struct Jim_Obj *obj; + Jim_Obj *obj; int e = Jim_GetOpt_Obj(&goi, &obj); if (e != JIM_OK) return e; @@ -5339,7 +5378,6 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a "target: %s wait %s fails (%#s) %s", target_name(target), n->name, eObj, target_strerror_safe(e)); - Jim_FreeNewObj(interp, eObj); return JIM_ERR; } return JIM_OK; @@ -5347,27 +5385,25 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a /* List for human, Events defined for this target. * scripts/programs should use 'name cget -event NAME' */ -static int jim_target_event_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_event_list) { - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx != NULL); - - struct target *target = Jim_CmdPrivData(interp); + struct target *target = get_current_target(CMD_CTX); struct target_event_action *teap = target->event_action; - command_print(cmd_ctx, "Event actions for target (%d) %s\n", + + command_print(CMD, "Event actions for target (%d) %s\n", target->target_number, target_name(target)); - command_print(cmd_ctx, "%-25s | Body", "Event"); - command_print(cmd_ctx, "------------------------- | " + command_print(CMD, "%-25s | Body", "Event"); + command_print(CMD, "------------------------- | " "----------------------------------------"); while (teap) { Jim_Nvp *opt = Jim_Nvp_value2name_simple(nvp_target_event, teap->event); - command_print(cmd_ctx, "%-25s | %s", + command_print(CMD, "%-25s | %s", opt->name, Jim_GetString(teap->body, NULL)); teap = teap->next; } - command_print(cmd_ctx, "***END***"); - return JIM_OK; + command_print(CMD, "***END***"); + return ERROR_OK; } static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -5402,7 +5438,7 @@ static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const static const struct command_registration target_instance_command_handlers[] = { { .name = "configure", - .mode = COMMAND_CONFIG, + .mode = COMMAND_ANY, .jim_handler = jim_target_configure, .help = "configure a new target for use", .usage = "[target_attribute ...]", @@ -5414,45 +5450,59 @@ static const struct command_registration target_instance_command_handlers[] = { .help = "returns the specified target attribute", .usage = "target_attribute", }, + { + .name = "mwd", + .handler = handle_mw_command, + .mode = COMMAND_EXEC, + .help = "Write 64-bit word(s) to target memory", + .usage = "address data [count]", + }, { .name = "mww", + .handler = handle_mw_command, .mode = COMMAND_EXEC, - .jim_handler = jim_target_mw, .help = "Write 32-bit word(s) to target memory", .usage = "address data [count]", }, { .name = "mwh", + .handler = handle_mw_command, .mode = COMMAND_EXEC, - .jim_handler = jim_target_mw, .help = "Write 16-bit half-word(s) to target memory", .usage = "address data [count]", }, { .name = "mwb", + .handler = handle_mw_command, .mode = COMMAND_EXEC, - .jim_handler = jim_target_mw, .help = "Write byte(s) to target memory", .usage = "address data [count]", }, + { + .name = "mdd", + .handler = handle_md_command, + .mode = COMMAND_EXEC, + .help = "Display target memory as 64-bit words", + .usage = "address [count]", + }, { .name = "mdw", + .handler = handle_md_command, .mode = COMMAND_EXEC, - .jim_handler = jim_target_md, .help = "Display target memory as 32-bit words", .usage = "address [count]", }, { .name = "mdh", + .handler = handle_md_command, .mode = COMMAND_EXEC, - .jim_handler = jim_target_md, .help = "Display target memory as 16-bit half-words", .usage = "address [count]", }, { .name = "mdb", + .handler = handle_md_command, .mode = COMMAND_EXEC, - .jim_handler = jim_target_md, .help = "Display target memory as 8-bit bytes", .usage = "address [count]", }, @@ -5474,9 +5524,10 @@ static const struct command_registration target_instance_command_handlers[] = { }, { .name = "eventlist", + .handler = handle_target_event_list, .mode = COMMAND_EXEC, - .jim_handler = jim_target_event_list, .help = "displays a table of events defined for this target", + .usage = "", }, { .name = "curstate", @@ -5620,12 +5671,21 @@ static int target_create(Jim_GetOptInfo *goi) /* Create it */ target = calloc(1, sizeof(struct target)); + if (!target) { + LOG_ERROR("Out of memory"); + return JIM_ERR; + } + /* set target number */ target->target_number = new_target_number(); - cmd_ctx->current_target = target; /* allocate memory for each unique target type */ - target->type = calloc(1, sizeof(struct target_type)); + target->type = malloc(sizeof(struct target_type)); + if (!target->type) { + LOG_ERROR("Out of memory"); + free(target); + return JIM_ERR; + } memcpy(target->type, target_types[x], sizeof(struct target_type)); @@ -5654,6 +5714,12 @@ static int target_create(Jim_GetOptInfo *goi) /* initialize trace information */ target->trace_info = calloc(1, sizeof(struct trace)); + if (!target->trace_info) { + LOG_ERROR("Out of memory"); + free(target->type); + free(target); + return JIM_ERR; + } target->dbgmsg = NULL; target->dbg_msg_enabled = 0; @@ -5664,6 +5730,7 @@ static int target_create(Jim_GetOptInfo *goi) target->rtos_auto_detect = false; target->gdb_port_override = NULL; + target->gdb_max_connections = 1; /* Do the rest as "configure" options */ goi->isconfigure = 1; @@ -5687,7 +5754,9 @@ static int target_create(Jim_GetOptInfo *goi) } if (e != JIM_OK) { + rtos_destroy(target); free(target->gdb_port_override); + free(target->trace_info); free(target->type); free(target); return e; @@ -5700,14 +5769,25 @@ static int target_create(Jim_GetOptInfo *goi) cp = Jim_GetString(new_cmd, NULL); target->cmd_name = strdup(cp); + if (!target->cmd_name) { + LOG_ERROR("Out of memory"); + rtos_destroy(target); + free(target->gdb_port_override); + free(target->trace_info); + free(target->type); + free(target); + return JIM_ERR; + } if (target->type->target_create) { e = (*(target->type->target_create))(target, goi->interp); if (e != ERROR_OK) { LOG_DEBUG("target_create failed"); + free(target->cmd_name); + rtos_destroy(target); free(target->gdb_port_override); + free(target->trace_info); free(target->type); - free(target->cmd_name); free(target); return JIM_ERR; } @@ -5720,15 +5800,6 @@ static int target_create(Jim_GetOptInfo *goi) LOG_ERROR("unable to register '%s' commands", cp); } - /* append to end of list */ - { - struct target **tpp; - tpp = &(all_targets); - while (*tpp) - tpp = &((*tpp)->next); - *tpp = target; - } - /* now - create the new target name command */ const struct command_registration target_subcommands[] = { { @@ -5750,14 +5821,27 @@ static int target_create(Jim_GetOptInfo *goi) COMMAND_REGISTRATION_DONE }; e = register_commands(cmd_ctx, NULL, target_commands); - if (ERROR_OK != e) + if (e != ERROR_OK) { + if (target->type->deinit_target) + target->type->deinit_target(target); + free(target->cmd_name); + rtos_destroy(target); + free(target->gdb_port_override); + free(target->trace_info); + free(target->type); + free(target); return JIM_ERR; + } struct command *c = command_find_in_context(cmd_ctx, cp); assert(c); command_set_handler_data(c, target); - return (ERROR_OK == e) ? JIM_OK : JIM_ERR; + /* append to end of list */ + append_to_list_all_targets(target); + + cmd_ctx->current_target = target; + return JIM_OK; } static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -5769,7 +5853,9 @@ static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv struct command_context *cmd_ctx = current_command_context(interp); assert(cmd_ctx != NULL); - Jim_SetResultString(interp, target_name(get_current_target(cmd_ctx)), -1); + struct target *target = get_current_target_or_null(cmd_ctx); + if (target) + Jim_SetResultString(interp, target_name(target), -1); return JIM_OK; } @@ -5816,7 +5902,7 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) retval = 0; LOG_DEBUG("%d", argc); /* argv[1] = target to associate in smp - * argv[2] = target to assoicate in smp + * argv[2] = target to associate in smp * argv[3] ... */ @@ -5873,6 +5959,7 @@ static const struct command_registration target_subcommand_handlers[] = { .mode = COMMAND_CONFIG, .handler = handle_target_init_command, .help = "initialize targets", + .usage = "", }, { .name = "create", @@ -5924,11 +6011,8 @@ static struct FastLoad *fastload; static void free_fastload(void) { if (fastload != NULL) { - int i; - for (i = 0; i < fastload_num; i++) { - if (fastload[i].data) - free(fastload[i].data); - } + for (int i = 0; i < fastload_num; i++) + free(fastload[i].data); free(fastload); fastload = NULL; } @@ -5941,7 +6025,6 @@ COMMAND_HANDLER(handle_fast_load_image_command) uint32_t image_size; target_addr_t min_address = 0; target_addr_t max_address = -1; - int i; struct image image; @@ -5962,15 +6045,15 @@ COMMAND_HANDLER(handle_fast_load_image_command) fastload_num = image.num_sections; fastload = malloc(sizeof(struct FastLoad)*image.num_sections); if (fastload == NULL) { - command_print(CMD_CTX, "out of memory"); + command_print(CMD, "out of memory"); image_close(&image); return ERROR_FAIL; } memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections); - for (i = 0; i < image.num_sections; i++) { + for (unsigned int i = 0; i < image.num_sections; i++) { buffer = malloc(image.sections[i].size); if (buffer == NULL) { - command_print(CMD_CTX, "error allocating buffer for section (%d bytes)", + command_print(CMD, "error allocating buffer for section (%d bytes)", (int)(image.sections[i].size)); retval = ERROR_FAIL; break; @@ -5985,7 +6068,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) uint32_t offset = 0; uint32_t length = buf_cnt; - /* DANGER!!! beware of unsigned comparision here!!! */ + /* DANGER!!! beware of unsigned comparison here!!! */ if ((image.sections[i].base_address + buf_cnt >= min_address) && (image.sections[i].base_address < max_address)) { @@ -6002,7 +6085,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) fastload[i].data = malloc(length); if (fastload[i].data == NULL) { free(buffer); - command_print(CMD_CTX, "error allocating buffer for section (%" PRIu32 " bytes)", + command_print(CMD, "error allocating buffer for section (%" PRIu32 " bytes)", length); retval = ERROR_FAIL; break; @@ -6011,7 +6094,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) fastload[i].length = length; image_size += length; - command_print(CMD_CTX, "%u bytes written at address 0x%8.8x", + command_print(CMD, "%u bytes written at address 0x%8.8x", (unsigned int)length, ((unsigned int)(image.sections[i].base_address + offset))); } @@ -6020,11 +6103,11 @@ COMMAND_HANDLER(handle_fast_load_image_command) } if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { - command_print(CMD_CTX, "Loaded %" PRIu32 " bytes " + command_print(CMD, "Loaded %" PRIu32 " bytes " "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); - command_print(CMD_CTX, + command_print(CMD, "WARNING: image has not been loaded to target!" "You can issue a 'fast_load' to finish loading."); } @@ -6051,7 +6134,7 @@ COMMAND_HANDLER(handle_fast_load_command) int retval = ERROR_OK; for (i = 0; i < fastload_num; i++) { struct target *target = get_current_target(CMD_CTX); - command_print(CMD_CTX, "Write to 0x%08x, length 0x%08x", + command_print(CMD, "Write to 0x%08x, length 0x%08x", (unsigned int)(fastload[i].address), (unsigned int)(fastload[i].length)); retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data); @@ -6061,7 +6144,7 @@ COMMAND_HANDLER(handle_fast_load_command) } if (retval == ERROR_OK) { int64_t after = timeval_ms(); - command_print(CMD_CTX, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0)); + command_print(CMD, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0)); } return retval; } @@ -6079,8 +6162,8 @@ static const struct command_registration target_command_handlers[] = { .name = "target", .mode = COMMAND_CONFIG, .help = "configure target", - .chain = target_subcommand_handlers, + .usage = "", }, COMMAND_REGISTRATION_DONE }; @@ -6116,7 +6199,7 @@ COMMAND_HANDLER(handle_ps_command) if ((target->rtos) && (target->rtos->type) && (target->rtos->type->ps_command)) { display = target->rtos->type->ps_command(target); - command_print(CMD_CTX, "%s", display); + command_print(CMD, "%s", display); free(display); return ERROR_OK; } else { @@ -6125,13 +6208,13 @@ COMMAND_HANDLER(handle_ps_command) } } -static void binprint(struct command_context *cmd_ctx, const char *text, const uint8_t *buf, int size) +static void binprint(struct command_invocation *cmd, const char *text, const uint8_t *buf, int size) { if (text != NULL) - command_print_sameline(cmd_ctx, "%s", text); + command_print_sameline(cmd, "%s", text); for (int i = 0; i < size; i++) - command_print_sameline(cmd_ctx, " %02x", buf[i]); - command_print(cmd_ctx, " "); + command_print_sameline(cmd, " %02x", buf[i]); + command_print(cmd, " "); } COMMAND_HANDLER(handle_test_mem_access_command) @@ -6183,7 +6266,7 @@ COMMAND_HANDLER(handle_test_mem_access_command) read_ref[i] = rand(); read_buf[i] = read_ref[i]; } - command_print_sameline(CMD_CTX, + command_print_sameline(CMD, "Test read %" PRIu32 " x %d @ %d to %saligned buffer: ", count, size, offset, host_offset ? "un" : ""); @@ -6196,10 +6279,10 @@ COMMAND_HANDLER(handle_test_mem_access_command) duration_measure(&bench); if (retval == ERROR_TARGET_UNALIGNED_ACCESS) { - command_print(CMD_CTX, "Unsupported alignment"); + command_print(CMD, "Unsupported alignment"); goto next; } else if (retval != ERROR_OK) { - command_print(CMD_CTX, "Memory read failed"); + command_print(CMD, "Memory read failed"); goto next; } @@ -6209,13 +6292,13 @@ COMMAND_HANDLER(handle_test_mem_access_command) /* check result */ int result = memcmp(read_ref, read_buf, host_bufsiz); if (result == 0) { - command_print(CMD_CTX, "Pass in %fs (%0.3f KiB/s)", + command_print(CMD, "Pass in %fs (%0.3f KiB/s)", duration_elapsed(&bench), duration_kbps(&bench, count * size)); } else { - command_print(CMD_CTX, "Compare failed"); - binprint(CMD_CTX, "ref:", read_ref, host_bufsiz); - binprint(CMD_CTX, "buf:", read_buf, host_bufsiz); + command_print(CMD, "Compare failed"); + binprint(CMD, "ref:", read_ref, host_bufsiz); + binprint(CMD, "buf:", read_buf, host_bufsiz); } next: free(read_ref); @@ -6255,13 +6338,13 @@ out: for (size_t i = 0; i < host_bufsiz; i++) write_buf[i] = rand(); - command_print_sameline(CMD_CTX, + command_print_sameline(CMD, "Test write %" PRIu32 " x %d @ %d from %saligned buffer: ", count, size, offset, host_offset ? "un" : ""); retval = target_write_memory(target, wa->address, 1, num_bytes, test_pattern); if (retval != ERROR_OK) { - command_print(CMD_CTX, "Test pattern write failed"); + command_print(CMD, "Test pattern write failed"); goto nextw; } @@ -6278,30 +6361,30 @@ out: duration_measure(&bench); if (retval == ERROR_TARGET_UNALIGNED_ACCESS) { - command_print(CMD_CTX, "Unsupported alignment"); + command_print(CMD, "Unsupported alignment"); goto nextw; } else if (retval != ERROR_OK) { - command_print(CMD_CTX, "Memory write failed"); + command_print(CMD, "Memory write failed"); goto nextw; } /* read back */ retval = target_read_memory(target, wa->address, 1, num_bytes, read_buf); if (retval != ERROR_OK) { - command_print(CMD_CTX, "Test pattern write failed"); + command_print(CMD, "Test pattern write failed"); goto nextw; } /* check result */ int result = memcmp(read_ref, read_buf, num_bytes); if (result == 0) { - command_print(CMD_CTX, "Pass in %fs (%0.3f KiB/s)", + command_print(CMD, "Pass in %fs (%0.3f KiB/s)", duration_elapsed(&bench), duration_kbps(&bench, count * size)); } else { - command_print(CMD_CTX, "Compare failed"); - binprint(CMD_CTX, "ref:", read_ref, num_bytes); - binprint(CMD_CTX, "buf:", read_buf, num_bytes); + command_print(CMD, "Compare failed"); + binprint(CMD, "ref:", read_ref, num_bytes); + binprint(CMD, "buf:", read_buf, num_bytes); } nextw: free(read_ref); @@ -6377,7 +6460,7 @@ static const struct command_registration target_exec_command_handlers[] = { .name = "halt", .handler = handle_halt_command, .mode = COMMAND_EXEC, - .help = "request target to halt, then wait up to the specified" + .help = "request target to halt, then wait up to the specified " "number of milliseconds (default 5000) for it to complete", .usage = "[milliseconds]", }, @@ -6393,7 +6476,7 @@ static const struct command_registration target_exec_command_handlers[] = { .handler = handle_reset_command, .mode = COMMAND_EXEC, .usage = "[run|halt|init]", - .help = "Reset all targets into the specified mode." + .help = "Reset all targets into the specified mode. " "Default reset mode is run, if not given.", }, { @@ -6414,7 +6497,7 @@ static const struct command_registration target_exec_command_handlers[] = { .name = "mdd", .handler = handle_md_command, .mode = COMMAND_EXEC, - .help = "display memory words", + .help = "display memory double-words", .usage = "['phys'] address [count]", }, { @@ -6442,7 +6525,7 @@ static const struct command_registration target_exec_command_handlers[] = { .name = "mwd", .handler = handle_mw_command, .mode = COMMAND_EXEC, - .help = "write memory word", + .help = "write memory double-word", .usage = "['phys'] address value [count]", }, { @@ -6471,14 +6554,14 @@ static const struct command_registration target_exec_command_handlers[] = { .handler = handle_bp_command, .mode = COMMAND_EXEC, .help = "list or set hardware or software breakpoint", - .usage = "
[] ['hw'|'hw_ctx']", + .usage = "[
[] ['hw'|'hw_ctx']]", }, { .name = "rbp", .handler = handle_rbp_command, .mode = COMMAND_EXEC, .help = "remove breakpoint", - .usage = "address", + .usage = "'all' | address", }, { .name = "wp",