X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=ed6f655eac68607285030188b894db34141a4979;hp=39a07ad6ce00dc8df1a20ebfa722cd0124751a2b;hb=8457a1be10d1463b40c020867ad4dc2513c93a4b;hpb=c4dd883c9a919b0b0a36bc538157820225b85610 diff --git a/src/target/target.c b/src/target/target.c index 39a07ad6ce..ed6f655eac 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -41,6 +41,7 @@ #include "config.h" #endif +#include #include #include #include @@ -154,9 +155,10 @@ static struct target_type *target_types[] = { struct target *all_targets; static struct target_event_callback *target_event_callbacks; static struct target_timer_callback *target_timer_callbacks; +static int64_t target_timer_next_event_value; static LIST_HEAD(target_reset_callback_list); static LIST_HEAD(target_trace_callback_list); -static const int polling_interval = 100; +static const int polling_interval = TARGET_DEFAULT_POLLING_INTERVAL; static const struct jim_nvp nvp_assert[] = { { .name = "assert", NVP_ASSERT }, @@ -188,7 +190,7 @@ static const char *target_strerror_safe(int err) const struct jim_nvp *n; n = jim_nvp_value2name_simple(nvp_error_target, err); - if (n->name == NULL) + if (!n->name) return "unknown"; else return n->name; @@ -484,7 +486,7 @@ struct target *get_target(const char *id) /* try as tcltarget name */ for (target = all_targets; target; target = target->next) { - if (target_name(target) == NULL) + if (!target_name(target)) continue; if (strcmp(id, target_name(target)) == 0) return target; @@ -526,7 +528,7 @@ struct target *get_current_target(struct command_context *cmd_ctx) { struct target *target = get_current_target_or_null(cmd_ctx); - if (target == NULL) { + if (!target) { LOG_ERROR("BUG: current_target out of bounds"); exit(-1); } @@ -663,7 +665,7 @@ static int target_process_reset(struct command_invocation *cmd, enum target_rese int retval; struct jim_nvp *n; n = jim_nvp_value2name_simple(nvp_reset_modes, reset_mode); - if (n->name == NULL) { + if (!n->name) { LOG_ERROR("invalid reset mode"); return ERROR_FAIL; } @@ -715,6 +717,15 @@ static int no_mmu(struct target *target, int *enabled) return ERROR_OK; } +/** + * Reset the @c examined flag for the given target. + * Pure paranoia -- targets are zeroed on allocation. + */ +static inline void target_reset_examined(struct target *target) +{ + target->examined = false; +} + static int default_examine(struct target *target) { target_set_examined(target); @@ -735,10 +746,12 @@ int target_examine_one(struct target *target) int retval = target->type->examine(target); if (retval != ERROR_OK) { + target_reset_examined(target); target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_FAIL); return retval; } + target_set_examined(target); target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END); return ERROR_OK; @@ -826,7 +839,7 @@ static int target_soft_reset_halt(struct target *target) int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, - uint32_t entry_point, uint32_t exit_point, + target_addr_t entry_point, target_addr_t exit_point, int timeout_ms, void *arch_info) { int retval = ERROR_FAIL; @@ -867,7 +880,7 @@ done: int target_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - uint32_t entry_point, uint32_t exit_point, + target_addr_t entry_point, target_addr_t exit_point, void *arch_info) { int retval = ERROR_FAIL; @@ -911,7 +924,7 @@ done: int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - uint32_t exit_point, int timeout_ms, + target_addr_t exit_point, int timeout_ms, void *arch_info) { int retval = ERROR_FAIL; @@ -1003,7 +1016,7 @@ int target_run_flash_async_algorithm(struct target *target, uint32_t rp = fifo_start_addr; /* validate block_size is 2^n */ - assert(!block_size || !(block_size & (block_size - 1))); + assert(IS_PWR_OF_2(block_size)); retval = target_write_u32(target, wp_addr, wp); if (retval != ERROR_OK) @@ -1041,7 +1054,7 @@ int target_run_flash_async_algorithm(struct target *target, break; } - if (((rp - fifo_start_addr) & (block_size - 1)) || rp < fifo_start_addr || rp >= fifo_end_addr) { + if (!IS_ALIGNED(rp - fifo_start_addr, block_size) || rp < fifo_start_addr || rp >= fifo_end_addr) { LOG_ERROR("corrupted fifo read pointer 0x%" PRIx32, rp); break; } @@ -1156,7 +1169,7 @@ int target_run_read_async_algorithm(struct target *target, uint32_t rp = fifo_start_addr; /* validate block_size is 2^n */ - assert(!block_size || !(block_size & (block_size - 1))); + assert(IS_PWR_OF_2(block_size)); retval = target_write_u32(target, wp_addr, wp); if (retval != ERROR_OK) @@ -1193,7 +1206,7 @@ int target_run_read_async_algorithm(struct target *target, break; } - if (((wp - fifo_start_addr) & (block_size - 1)) || wp < fifo_start_addr || wp >= fifo_end_addr) { + if (!IS_ALIGNED(wp - fifo_start_addr, block_size) || wp < fifo_start_addr || wp >= fifo_end_addr) { LOG_ERROR("corrupted fifo write pointer 0x%" PRIx32, wp); break; } @@ -1397,7 +1410,7 @@ int target_hit_watchpoint(struct target *target, return ERROR_TARGET_NOT_HALTED; } - if (target->type->hit_watchpoint == NULL) { + if (!target->type->hit_watchpoint) { /* For backward compatible, if hit_watchpoint is not implemented, * return ERROR_FAIL such that gdb_server will not take the nonsense * information. */ @@ -1409,7 +1422,7 @@ int target_hit_watchpoint(struct target *target, const char *target_get_gdb_arch(struct target *target) { - if (target->type->get_gdb_arch == NULL) + if (!target->type->get_gdb_arch) return NULL; return target->type->get_gdb_arch(target); } @@ -1506,6 +1519,13 @@ unsigned target_address_bits(struct target *target) return 32; } +unsigned int target_data_bits(struct target *target) +{ + if (target->type->data_bits) + return target->type->data_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) { @@ -1513,15 +1533,6 @@ static int target_profiling(struct target *target, uint32_t *samples, num_samples, seconds); } -/** - * Reset the @c examined flag for the given target. - * Pure paranoia -- targets are zeroed on allocation. - */ -static void target_reset_examined(struct target *target) -{ - target->examined = false; -} - static int handle_target(void *priv); static int target_init_one(struct command_context *cmd_ctx, @@ -1530,16 +1541,16 @@ static int target_init_one(struct command_context *cmd_ctx, target_reset_examined(target); struct target_type *type = target->type; - if (type->examine == NULL) + if (!type->examine) type->examine = default_examine; - if (type->check_reset == NULL) + if (!type->check_reset) type->check_reset = default_check_reset; - assert(type->init_target != NULL); + assert(type->init_target); int retval = type->init_target(cmd_ctx, target); - if (ERROR_OK != retval) { + if (retval != ERROR_OK) { LOG_ERROR("target '%s' init failed", target_name(target)); return retval; } @@ -1548,7 +1559,7 @@ static int target_init_one(struct command_context *cmd_ctx, * implement it in stages, but warn if we need to do so. */ if (type->mmu) { - if (type->virt2phys == NULL) { + if (!type->virt2phys) { LOG_ERROR("type '%s' is missing virt2phys", type->name); type->virt2phys = identity_virt2phys; } @@ -1566,19 +1577,19 @@ static int target_init_one(struct command_context *cmd_ctx, type->virt2phys = identity_virt2phys; } - if (target->type->read_buffer == NULL) + if (!target->type->read_buffer) target->type->read_buffer = target_read_buffer_default; - if (target->type->write_buffer == NULL) + if (!target->type->write_buffer) target->type->write_buffer = target_write_buffer_default; - if (target->type->get_gdb_fileio_info == NULL) + if (!target->type->get_gdb_fileio_info) target->type->get_gdb_fileio_info = target_get_gdb_fileio_info_default; - if (target->type->gdb_fileio_end == NULL) + if (!target->type->gdb_fileio_end) target->type->gdb_fileio_end = target_gdb_fileio_end_default; - if (target->type->profiling == NULL) + if (!target->type->profiling) target->type->profiling = target_profiling_default; return ERROR_OK; @@ -1591,7 +1602,7 @@ static int target_init(struct command_context *cmd_ctx) for (target = all_targets; target; target = target->next) { retval = target_init_one(cmd_ctx, target); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; } @@ -1599,12 +1610,12 @@ static int target_init(struct command_context *cmd_ctx) return ERROR_OK; retval = target_register_user_commands(cmd_ctx); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; retval = target_register_timer_callback(&handle_target, polling_interval, TARGET_TIMER_TYPE_PERIODIC, cmd_ctx->interp); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; return ERROR_OK; @@ -1625,15 +1636,15 @@ COMMAND_HANDLER(handle_target_init_command) target_initialized = true; retval = command_run_line(CMD_CTX, "init_targets"); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; retval = command_run_line(CMD_CTX, "init_target_events"); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; retval = command_run_line(CMD_CTX, "init_board"); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; LOG_DEBUG("Initializing targets..."); @@ -1645,7 +1656,7 @@ int target_register_event_callback(int (*callback)(struct target *target, { struct target_event_callback **callbacks_p = &target_event_callbacks; - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; if (*callbacks_p) { @@ -1667,11 +1678,11 @@ int target_register_reset_callback(int (*callback)(struct target *target, { struct target_reset_callback *entry; - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; entry = malloc(sizeof(struct target_reset_callback)); - if (entry == NULL) { + if (!entry) { LOG_ERROR("error allocating buffer for reset callback entry"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1689,11 +1700,11 @@ int target_register_trace_callback(int (*callback)(struct target *target, { struct target_trace_callback *entry; - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; entry = malloc(sizeof(struct target_trace_callback)); - if (entry == NULL) { + if (!entry) { LOG_ERROR("error allocating buffer for trace callback entry"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1711,7 +1722,7 @@ int target_register_timer_callback(int (*callback)(void *priv), { struct target_timer_callback **callbacks_p = &target_timer_callbacks; - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; if (*callbacks_p) { @@ -1726,8 +1737,8 @@ int target_register_timer_callback(int (*callback)(void *priv), (*callbacks_p)->time_ms = time_ms; (*callbacks_p)->removed = false; - gettimeofday(&(*callbacks_p)->when, NULL); - timeval_add_time(&(*callbacks_p)->when, 0, time_ms * 1000); + (*callbacks_p)->when = timeval_ms() + time_ms; + target_timer_next_event_value = MIN(target_timer_next_event_value, (*callbacks_p)->when); (*callbacks_p)->priv = priv; (*callbacks_p)->next = NULL; @@ -1741,7 +1752,7 @@ int target_unregister_event_callback(int (*callback)(struct target *target, struct target_event_callback **p = &target_event_callbacks; struct target_event_callback *c = target_event_callbacks; - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; while (c) { @@ -1763,7 +1774,7 @@ int target_unregister_reset_callback(int (*callback)(struct target *target, { struct target_reset_callback *entry; - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; list_for_each_entry(entry, &target_reset_callback_list, list) { @@ -1782,7 +1793,7 @@ int target_unregister_trace_callback(int (*callback)(struct target *target, { struct target_trace_callback *entry; - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; list_for_each_entry(entry, &target_trace_callback_list, list) { @@ -1798,7 +1809,7 @@ int target_unregister_trace_callback(int (*callback)(struct target *target, int target_unregister_timer_callback(int (*callback)(void *priv), void *priv) { - if (callback == NULL) + if (!callback) return ERROR_COMMAND_SYNTAX_ERROR; for (struct target_timer_callback *c = target_timer_callbacks; @@ -1861,15 +1872,14 @@ int target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data } static int target_timer_callback_periodic_restart( - struct target_timer_callback *cb, struct timeval *now) + struct target_timer_callback *cb, int64_t *now) { - cb->when = *now; - timeval_add_time(&cb->when, 0, cb->time_ms * 1000L); + cb->when = *now + cb->time_ms; return ERROR_OK; } static int target_call_timer_callback(struct target_timer_callback *cb, - struct timeval *now) + int64_t *now) { cb->callback(cb->priv); @@ -1891,8 +1901,12 @@ static int target_call_timer_callbacks_check_time(int checktime) keep_alive(); - struct timeval now; - gettimeofday(&now, NULL); + int64_t now = timeval_ms(); + + /* Initialize to a default value that's a ways into the future. + * The loop below will make it closer to now if there are + * callbacks that want to be called sooner. */ + target_timer_next_event_value = now + 1000; /* Store an address of the place containing a pointer to the * next item; initially, that's a standalone "root of the @@ -1908,11 +1922,14 @@ static int target_call_timer_callbacks_check_time(int checktime) bool call_it = (*callback)->callback && ((!checktime && (*callback)->type == TARGET_TIMER_TYPE_PERIODIC) || - timeval_compare(&now, &(*callback)->when) >= 0); + now >= (*callback)->when); if (call_it) target_call_timer_callback(*callback, &now); + if (!(*callback)->removed && (*callback)->when < target_timer_next_event_value) + target_timer_next_event_value = (*callback)->when; + callback = &(*callback)->next; } @@ -1920,17 +1937,22 @@ static int target_call_timer_callbacks_check_time(int checktime) return ERROR_OK; } -int target_call_timer_callbacks(void) +int target_call_timer_callbacks() { return target_call_timer_callbacks_check_time(1); } /* invoke periodic callbacks immediately */ -int target_call_timer_callbacks_now(void) +int target_call_timer_callbacks_now() { return target_call_timer_callbacks_check_time(0); } +int64_t target_timer_next_event(void) +{ + return target_timer_next_event_value; +} + /* Prints the working area layout for debug purposes */ static void print_wa_layout(struct target *target) { @@ -1954,7 +1976,7 @@ static void target_split_working_area(struct working_area *area, uint32_t size) if (size < area->size) { struct working_area *new_wa = malloc(sizeof(*new_wa)); - if (new_wa == NULL) + if (!new_wa) return; new_wa->next = area->next; @@ -2006,7 +2028,7 @@ static void target_merge_working_areas(struct target *target) int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area) { /* Reevaluate working area address based on MMU state*/ - if (target->working_areas == NULL) { + if (!target->working_areas) { int retval; int enabled; @@ -2065,7 +2087,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w c = c->next; } - if (c == NULL) + if (!c) return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; /* Split the working area into the requested size */ @@ -2075,9 +2097,9 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w size, c->address); if (target->backup_working_area) { - if (c->backup == NULL) { + if (!c->backup) { c->backup = malloc(c->size); - if (c->backup == NULL) + if (!c->backup) return ERROR_FAIL; } @@ -2113,7 +2135,7 @@ static int target_restore_working_area(struct target *target, struct working_are { int retval = ERROR_OK; - if (target->backup_working_area && area->backup != NULL) { + if (target->backup_working_area && area->backup) { retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup); if (retval != ERROR_OK) LOG_ERROR("failed to restore %" PRIu32 " bytes of working area at address " TARGET_ADDR_FMT, @@ -2208,7 +2230,7 @@ uint32_t target_get_working_area_avail(struct target *target) struct working_area *c = target->working_areas; uint32_t max_size = 0; - if (c == NULL) + if (!c) return target->working_area_size; while (c) { @@ -2243,7 +2265,7 @@ static void target_destroy(struct target *target) /* release the targets SMP list */ if (target->smp) { struct target_list *head = target->head; - while (head != NULL) { + while (head) { struct target_list *pos = head->next; head->target->smp = 0; free(head); @@ -2294,7 +2316,7 @@ void target_quit(void) int target_arch_state(struct target *target) { int retval; - if (target == NULL) { + if (!target) { LOG_WARNING("No target has been configured"); return ERROR_OK; } @@ -2335,7 +2357,7 @@ int target_profiling_default(struct target *target, uint32_t *samples, uint32_t sample_count = 0; /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */ - struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1); + struct reg *reg = register_get_by_name(target->reg_cache, "pc", true); int retval = ERROR_OK; for (;;) { @@ -2402,10 +2424,13 @@ static int target_write_buffer_default(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer) { uint32_t size; + unsigned int data_bytes = target_data_bits(target) / 8; - /* Align up to maximum 4 bytes. The loop condition makes sure the next pass + /* Align up to maximum bytes. The loop condition makes sure the next pass * will have something to do with the size we leave to it. */ - for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) { + for (size = 1; + size < data_bytes && count >= size * 2 + (address & size); + size *= 2) { if (address & size) { int retval = target_write_memory(target, address, size, 1, buffer); if (retval != ERROR_OK) @@ -2463,10 +2488,13 @@ int target_read_buffer(struct target *target, target_addr_t address, uint32_t si static int target_read_buffer_default(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer) { uint32_t size; + unsigned int data_bytes = target_data_bits(target) / 8; - /* Align up to maximum 4 bytes. The loop condition makes sure the next pass + /* Align up to maximum bytes. The loop condition makes sure the next pass * will have something to do with the size we leave to it. */ - for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) { + for (size = 1; + size < data_bytes && count >= size * 2 + (address & size); + size *= 2) { if (address & size) { int retval = target_read_memory(target, address, size, 1, buffer); if (retval != ERROR_OK) @@ -2507,7 +2535,7 @@ int target_checksum_memory(struct target *target, target_addr_t address, uint32_ retval = target->type->checksum_memory(target, address, size, &checksum); if (retval != ERROR_OK) { buffer = malloc(size); - if (buffer == NULL) { + if (!buffer) { LOG_ERROR("error allocating buffer for section (%" PRIu32 " bytes)", size); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -2542,7 +2570,7 @@ int target_blank_check_memory(struct target *target, return ERROR_FAIL; } - if (target->type->blank_check_memory == NULL) + if (!target->type->blank_check_memory) return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; return target->type->blank_check_memory(target, blocks, num_blocks, erased_value); @@ -2807,7 +2835,7 @@ int target_write_phys_u8(struct target *target, target_addr_t address, uint8_t v static int find_target(struct command_invocation *cmd, const char *name) { struct target *target = get_target(name); - if (target == NULL) { + if (!target) { command_print(cmd, "Target: %s is unknown, try one of:\n", name); return ERROR_FAIL; } @@ -2871,57 +2899,57 @@ COMMAND_HANDLER(handle_targets_command) /* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */ -static int powerDropout; -static int srstAsserted; +static int power_dropout; +static int srst_asserted; -static int runPowerRestore; -static int runPowerDropout; -static int runSrstAsserted; -static int runSrstDeasserted; +static int run_power_restore; +static int run_power_dropout; +static int run_srst_asserted; +static int run_srst_deasserted; static int sense_handler(void) { - static int prevSrstAsserted; - static int prevPowerdropout; + static int prev_srst_asserted; + static int prev_power_dropout; - int retval = jtag_power_dropout(&powerDropout); + int retval = jtag_power_dropout(&power_dropout); if (retval != ERROR_OK) return retval; - int powerRestored; - powerRestored = prevPowerdropout && !powerDropout; - if (powerRestored) - runPowerRestore = 1; + int power_restored; + power_restored = prev_power_dropout && !power_dropout; + if (power_restored) + run_power_restore = 1; int64_t current = timeval_ms(); - static int64_t lastPower; - bool waitMore = lastPower + 2000 > current; - if (powerDropout && !waitMore) { - runPowerDropout = 1; - lastPower = current; + static int64_t last_power; + bool wait_more = last_power + 2000 > current; + if (power_dropout && !wait_more) { + run_power_dropout = 1; + last_power = current; } - retval = jtag_srst_asserted(&srstAsserted); + retval = jtag_srst_asserted(&srst_asserted); if (retval != ERROR_OK) return retval; - int srstDeasserted; - srstDeasserted = prevSrstAsserted && !srstAsserted; + int srst_deasserted; + srst_deasserted = prev_srst_asserted && !srst_asserted; - static int64_t lastSrst; - waitMore = lastSrst + 2000 > current; - if (srstDeasserted && !waitMore) { - runSrstDeasserted = 1; - lastSrst = current; + static int64_t last_srst; + wait_more = last_srst + 2000 > current; + if (srst_deasserted && !wait_more) { + run_srst_deasserted = 1; + last_srst = current; } - if (!prevSrstAsserted && srstAsserted) - runSrstAsserted = 1; + if (!prev_srst_asserted && srst_asserted) + run_srst_asserted = 1; - prevSrstAsserted = srstAsserted; - prevPowerdropout = powerDropout; + prev_srst_asserted = srst_asserted; + prev_power_dropout = power_dropout; - if (srstDeasserted || powerRestored) { + if (srst_deasserted || power_restored) { /* Other than logging the event we can't do anything here. * Issuing a reset is a particularly bad idea as we might * be inside a reset already. @@ -2952,21 +2980,21 @@ static int handle_target(void *priv) * clearing the flags after running these events. */ int did_something = 0; - if (runSrstAsserted) { + if (run_srst_asserted) { LOG_INFO("srst asserted detected, running srst_asserted proc."); Jim_Eval(interp, "srst_asserted"); did_something = 1; } - if (runSrstDeasserted) { + if (run_srst_deasserted) { Jim_Eval(interp, "srst_deasserted"); did_something = 1; } - if (runPowerDropout) { + if (run_power_dropout) { LOG_INFO("Power dropout detected, running power_dropout proc."); Jim_Eval(interp, "power_dropout"); did_something = 1; } - if (runPowerRestore) { + if (run_power_restore) { Jim_Eval(interp, "power_restore"); did_something = 1; } @@ -2978,10 +3006,10 @@ static int handle_target(void *priv) /* clear action flags */ - runSrstAsserted = 0; - runSrstDeasserted = 0; - runPowerRestore = 0; - runPowerDropout = 0; + run_srst_asserted = 0; + run_srst_deasserted = 0; + run_power_restore = 0; + run_power_dropout = 0; recursive = 0; } @@ -3007,7 +3035,7 @@ static int handle_target(void *priv) target->backoff.count = 0; /* only poll target if we've got power and srst isn't asserted */ - if (!powerDropout && !srstAsserted) { + if (!power_dropout && !srst_asserted) { /* polling may fail silently until the target has been examined */ retval = target_poll(target); if (retval != ERROR_OK) { @@ -3029,7 +3057,7 @@ static int handle_target(void *priv) /* Target examination could have failed due to unstable connection, * but we set the examined flag anyway to repoll it later */ if (retval != ERROR_OK) { - target->examined = true; + target_set_examined(target); LOG_USER("Examination failed, GDB will be halted. Polling again in %dms", target->backoff.times * polling_interval); return retval; @@ -3046,20 +3074,16 @@ static int handle_target(void *priv) COMMAND_HANDLER(handle_reg_command) { - struct target *target; - struct reg *reg = NULL; - unsigned count = 0; - char *value; - LOG_DEBUG("-"); - target = get_current_target(CMD_CTX); + struct target *target = get_current_target(CMD_CTX); + struct reg *reg = NULL; /* list all available registers for the current target */ if (CMD_ARGC == 0) { struct reg_cache *cache = target->reg_cache; - count = 0; + unsigned int count = 0; while (cache) { unsigned i; @@ -3072,7 +3096,7 @@ COMMAND_HANDLER(handle_reg_command) continue; /* only print cached values if they are valid */ if (reg->valid) { - value = buf_to_hex_str(reg->value, + char *value = buf_to_hex_str(reg->value, reg->size); command_print(CMD, "(%i) %s (/%" PRIu32 "): 0x%s%s", @@ -3100,7 +3124,7 @@ COMMAND_HANDLER(handle_reg_command) COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); struct reg_cache *cache = target->reg_cache; - count = 0; + unsigned int count = 0; while (cache) { unsigned i; for (i = 0; i < cache->num_regs; i++) { @@ -3121,13 +3145,13 @@ COMMAND_HANDLER(handle_reg_command) } } else { /* access a single register by its name */ - reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], 1); + reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], true); if (!reg) goto not_found; } - assert(reg != NULL); /* give clang a hint that we *know* reg is != NULL here */ + assert(reg); /* give clang a hint that we *know* reg is != NULL here */ if (!reg->exist) goto not_found; @@ -3138,9 +3162,14 @@ COMMAND_HANDLER(handle_reg_command) if ((CMD_ARGC == 2) && (strcmp(CMD_ARGV[1], "force") == 0)) reg->valid = 0; - if (reg->valid == 0) - reg->type->get(reg); - value = buf_to_hex_str(reg->value, reg->size); + if (reg->valid == 0) { + int retval = reg->type->get(reg); + if (retval != ERROR_OK) { + LOG_ERROR("Could not read register '%s'", reg->name); + return retval; + } + } + char *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; @@ -3149,19 +3178,22 @@ COMMAND_HANDLER(handle_reg_command) /* set register value */ if (CMD_ARGC == 2) { uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8)); - if (buf == NULL) + if (!buf) return ERROR_FAIL; str_to_buf(CMD_ARGV[1], strlen(CMD_ARGV[1]), buf, reg->size, 0); - reg->type->set(reg, buf); - - value = buf_to_hex_str(reg->value, reg->size); - command_print(CMD, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value); - free(value); + int retval = reg->type->set(reg, buf); + if (retval != ERROR_OK) { + LOG_ERROR("Could not write to register '%s'", reg->name); + } else { + char *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); - return ERROR_OK; + return retval; } return ERROR_COMMAND_SYNTAX_ERROR; @@ -3208,7 +3240,7 @@ COMMAND_HANDLER(handle_wait_halt_command) unsigned ms = DEFAULT_HALT_TIMEOUT; if (1 == CMD_ARGC) { int retval = parse_uint(CMD_ARGV[0], &ms); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return ERROR_COMMAND_SYNTAX_ERROR; } @@ -3264,13 +3296,13 @@ COMMAND_HANDLER(handle_halt_command) target->verbose_halt_msg = true; int retval = target_halt(target); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; if (CMD_ARGC == 1) { unsigned wait_local; retval = parse_uint(CMD_ARGV[0], &wait_local); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return ERROR_COMMAND_SYNTAX_ERROR; if (!wait_local) return ERROR_OK; @@ -3299,7 +3331,7 @@ COMMAND_HANDLER(handle_reset_command) if (CMD_ARGC == 1) { const struct jim_nvp *n; n = jim_nvp_name2value_simple(nvp_reset_modes, CMD_ARGV[0]); - if ((n->name == NULL) || (n->value == RESET_UNKNOWN)) + if ((!n->name) || (n->value == RESET_UNKNOWN)) return ERROR_COMMAND_SYNTAX_ERROR; reset_mode = n->value; } @@ -3458,14 +3490,14 @@ COMMAND_HANDLER(handle_md_command) COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], count); uint8_t *buffer = calloc(count, size); - if (buffer == NULL) { + if (!buffer) { LOG_ERROR("Failed to allocate md read buffer"); return ERROR_FAIL; } struct target *target = get_current_target(CMD_CTX); int retval = fn(target, address, size, count, buffer); - if (ERROR_OK == retval) + if (retval == ERROR_OK) target_handle_md_output(CMD, target, address, size, count, buffer); free(buffer); @@ -3489,7 +3521,7 @@ static int target_fill_mem(struct target *target, * to fill large memory areas with any sane speed */ const unsigned chunk_size = 16384; uint8_t *target_buf = malloc(chunk_size * data_size); - if (target_buf == NULL) { + if (!target_buf) { LOG_ERROR("Out of memory"); return ERROR_FAIL; } @@ -3579,7 +3611,7 @@ COMMAND_HANDLER(handle_mw_command) return target_fill_mem(target, address, fn, wordsize, value, count); } -static COMMAND_HELPER(parse_load_image_command_CMD_ARGV, struct image *image, +static COMMAND_HELPER(parse_load_image_command, struct image *image, target_addr_t *min_address, target_addr_t *max_address) { if (CMD_ARGC < 1 || CMD_ARGC > 5) @@ -3620,9 +3652,9 @@ COMMAND_HANDLER(handle_load_image_command) target_addr_t max_address = -1; struct image image; - int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV, + int retval = CALL_COMMAND_HANDLER(parse_load_image_command, &image, &min_address, &max_address); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; struct target *target = get_current_target(CMD_CTX); @@ -3637,7 +3669,7 @@ COMMAND_HANDLER(handle_load_image_command) retval = ERROR_OK; for (unsigned int i = 0; i < image.num_sections; i++) { buffer = malloc(image.sections[i].size); - if (buffer == NULL) { + if (!buffer) { command_print(CMD, "error allocating buffer for section (%d bytes)", (int)(image.sections[i].size)); @@ -3683,7 +3715,7 @@ COMMAND_HANDLER(handle_load_image_command) free(buffer); } - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { + if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) { command_print(CMD, "downloaded %" PRIu32 " bytes " "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); @@ -3740,7 +3772,7 @@ COMMAND_HANDLER(handle_dump_image_command) free(buffer); - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { + if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) { size_t filesize; retval = fileio_size(fileio, &filesize); if (retval != ERROR_OK) @@ -3808,7 +3840,7 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver retval = ERROR_OK; for (unsigned int i = 0; i < image.num_sections; i++) { buffer = malloc(image.sections[i].size); - if (buffer == NULL) { + if (!buffer) { command_print(CMD, "error allocating buffer for section (%" PRIu32 " bytes)", image.sections[i].size); @@ -3885,7 +3917,7 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver done: if (diffs > 0) retval = ERROR_FAIL; - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { + if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) { command_print(CMD, "verified %" PRIu32 " bytes " "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); @@ -3955,27 +3987,27 @@ static int handle_bp_command_set(struct command_invocation *cmd, 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) + if (retval == ERROR_OK) command_print(cmd, "breakpoint set at " TARGET_ADDR_FMT "", addr); } else if (addr == 0) { - if (target->type->add_context_breakpoint == NULL) { + if (!target->type->add_context_breakpoint) { LOG_ERROR("Context breakpoint not available"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } 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) + if (retval == ERROR_OK) command_print(cmd, "Context breakpoint set at 0x%8.8" PRIx32 "", asid); } else { - if (target->type->add_hybrid_breakpoint == NULL) { + if (!target->type->add_hybrid_breakpoint) { LOG_ERROR("Hybrid breakpoint not available"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } 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) + if (retval == ERROR_OK) command_print(cmd, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid); } return retval; @@ -4106,7 +4138,7 @@ COMMAND_HANDLER(handle_wp_command) int retval = watchpoint_add(target, addr, length, type, data_value, data_mask); - if (ERROR_OK != retval) + if (retval != ERROR_OK) LOG_ERROR("Failure setting watchpoints"); return retval; @@ -4149,44 +4181,44 @@ COMMAND_HANDLER(handle_virt2phys_command) return retval; } -static void writeData(FILE *f, const void *data, size_t len) +static void write_data(FILE *f, const void *data, size_t len) { size_t written = fwrite(data, 1, len, f); if (written != len) LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno)); } -static void writeLong(FILE *f, int l, struct target *target) +static void write_long(FILE *f, int l, struct target *target) { uint8_t val[4]; target_buffer_set_u32(target, val, l); - writeData(f, val, 4); + write_data(f, val, 4); } -static void writeString(FILE *f, char *s) +static void write_string(FILE *f, char *s) { - writeData(f, s, strlen(s)); + write_data(f, s, strlen(s)); } typedef unsigned char UNIT[2]; /* unit of profiling */ /* Dump a gmon.out histogram file. */ -static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filename, bool with_range, +static void write_gmon(uint32_t *samples, uint32_t sample_num, const char *filename, bool with_range, uint32_t start_address, uint32_t end_address, struct target *target, uint32_t duration_ms) { uint32_t i; FILE *f = fopen(filename, "w"); - if (f == NULL) + if (!f) return; - writeString(f, "gmon"); - writeLong(f, 0x00000001, target); /* Version */ - writeLong(f, 0, target); /* padding */ - writeLong(f, 0, target); /* padding */ - writeLong(f, 0, target); /* padding */ + write_string(f, "gmon"); + write_long(f, 0x00000001, target); /* Version */ + write_long(f, 0, target); /* padding */ + write_long(f, 0, target); /* padding */ + write_long(f, 0, target); /* padding */ uint8_t zero = 0; /* GMON_TAG_TIME_HIST */ - writeData(f, &zero, 1); + write_data(f, &zero, 1); /* figure out bucket size */ uint32_t min; @@ -4197,7 +4229,7 @@ static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filena } else { min = samples[0]; max = samples[0]; - for (i = 0; i < sampleNum; i++) { + for (i = 0; i < sample_num; i++) { if (min > samples[i]) min = samples[i]; if (max < samples[i]) @@ -4209,50 +4241,50 @@ static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filena max++; } - int addressSpace = max - min; - assert(addressSpace >= 2); + int address_space = max - min; + assert(address_space >= 2); /* FIXME: What is the reasonable number of buckets? * The profiling result will be more accurate if there are enough buckets. */ - static const uint32_t maxBuckets = 128 * 1024; /* maximum buckets. */ - uint32_t numBuckets = addressSpace / sizeof(UNIT); - if (numBuckets > maxBuckets) - numBuckets = maxBuckets; - int *buckets = malloc(sizeof(int) * numBuckets); - if (buckets == NULL) { + static const uint32_t max_buckets = 128 * 1024; /* maximum buckets. */ + uint32_t num_buckets = address_space / sizeof(UNIT); + if (num_buckets > max_buckets) + num_buckets = max_buckets; + int *buckets = malloc(sizeof(int) * num_buckets); + if (!buckets) { fclose(f); return; } - memset(buckets, 0, sizeof(int) * numBuckets); - for (i = 0; i < sampleNum; i++) { + memset(buckets, 0, sizeof(int) * num_buckets); + for (i = 0; i < sample_num; i++) { uint32_t address = samples[i]; if ((address < min) || (max <= address)) continue; long long a = address - min; - long long b = numBuckets; - long long c = addressSpace; + long long b = num_buckets; + long long c = address_space; int index_t = (a * b) / c; /* danger!!!! int32 overflows */ buckets[index_t]++; } /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */ - writeLong(f, min, target); /* low_pc */ - writeLong(f, max, target); /* high_pc */ - writeLong(f, numBuckets, target); /* # of buckets */ - float sample_rate = sampleNum / (duration_ms / 1000.0); - writeLong(f, sample_rate, target); - writeString(f, "seconds"); + write_long(f, min, target); /* low_pc */ + write_long(f, max, target); /* high_pc */ + write_long(f, num_buckets, target); /* # of buckets */ + float sample_rate = sample_num / (duration_ms / 1000.0); + write_long(f, sample_rate, target); + write_string(f, "seconds"); for (i = 0; i < (15-strlen("seconds")); i++) - writeData(f, &zero, 1); - writeString(f, "s"); + write_data(f, &zero, 1); + write_string(f, "s"); /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */ - char *data = malloc(2 * numBuckets); - if (data != NULL) { - for (i = 0; i < numBuckets; i++) { + char *data = malloc(2 * num_buckets); + if (data) { + for (i = 0; i < num_buckets; i++) { int val; val = buckets[i]; if (val > 65535) @@ -4261,7 +4293,7 @@ static void write_gmon(uint32_t *samples, uint32_t sampleNum, const char *filena data[i * 2 + 1] = (val >> 8) & 0xff; } free(buckets); - writeData(f, data, numBuckets * 2); + write_data(f, data, num_buckets * 2); free(data); } else free(buckets); @@ -4287,7 +4319,7 @@ COMMAND_HANDLER(handle_profile_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], offset); uint32_t *samples = malloc(sizeof(uint32_t) * MAX_PROFILE_SAMPLE_NUM); - if (samples == NULL) { + if (!samples) { LOG_ERROR("No memory to store samples."); return ERROR_FAIL; } @@ -4355,28 +4387,29 @@ COMMAND_HANDLER(handle_profile_command) return retval; } -static int new_int_array_element(Jim_Interp *interp, const char *varname, int idx, uint32_t val) +static int new_u64_array_element(Jim_Interp *interp, const char *varname, int idx, uint64_t val) { char *namebuf; - Jim_Obj *nameObjPtr, *valObjPtr; + Jim_Obj *obj_name, *obj_val; int result; namebuf = alloc_printf("%s(%d)", varname, idx); if (!namebuf) return JIM_ERR; - nameObjPtr = Jim_NewStringObj(interp, namebuf, -1); - valObjPtr = Jim_NewIntObj(interp, val); - if (!nameObjPtr || !valObjPtr) { + obj_name = Jim_NewStringObj(interp, namebuf, -1); + jim_wide wide_val = val; + obj_val = Jim_NewWideObj(interp, wide_val); + if (!obj_name || !obj_val) { free(namebuf); return JIM_ERR; } - Jim_IncrRefCount(nameObjPtr); - Jim_IncrRefCount(valObjPtr); - result = Jim_SetVariable(interp, nameObjPtr, valObjPtr); - Jim_DecrRefCount(interp, nameObjPtr); - Jim_DecrRefCount(interp, valObjPtr); + Jim_IncrRefCount(obj_name); + Jim_IncrRefCount(obj_val); + result = Jim_SetVariable(interp, obj_name, obj_val); + Jim_DecrRefCount(interp, obj_name); + Jim_DecrRefCount(interp, obj_val); free(namebuf); /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */ return result; @@ -4388,10 +4421,10 @@ static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv) struct target *target; context = current_command_context(interp); - assert(context != NULL); + assert(context); target = get_current_target(context); - if (target == NULL) { + if (!target) { LOG_ERROR("mem2array: no current target"); return JIM_ERR; } @@ -4401,67 +4434,65 @@ static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv) { - long l; - uint32_t width; - int len; - uint32_t addr; - uint32_t count; - uint32_t v; - const char *varname; - const char *phys; - bool is_phys; - int n, e, retval; - uint32_t i; + int e; - /* argv[1] = name of array to receive the data - * argv[2] = desired width - * argv[3] = memory address - * argv[4] = count of times to read + /* argv[0] = name of array to receive the data + * argv[1] = desired element width in bits + * argv[2] = memory address + * argv[3] = count of times to read + * argv[4] = optional "phys" */ - if (argc < 4 || argc > 5) { Jim_WrongNumArgs(interp, 0, argv, "varname width addr nelems [phys]"); return JIM_ERR; } - varname = Jim_GetString(argv[0], &len); - /* given "foo" get space for worse case "foo(%d)" .. add 20 */ + /* Arg 0: Name of the array variable */ + const char *varname = Jim_GetString(argv[0], NULL); + + /* Arg 1: Bit width of one element */ + long l; e = Jim_GetLong(interp, argv[1], &l); - width = l; if (e != JIM_OK) return e; + const unsigned int width_bits = l; + + if (width_bits != 8 && + width_bits != 16 && + width_bits != 32 && + width_bits != 64) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), + "Invalid width param. Must be one of: 8, 16, 32 or 64.", NULL); + return JIM_ERR; + } + const unsigned int width = width_bits / 8; - e = Jim_GetLong(interp, argv[2], &l); - addr = l; + /* Arg 2: Memory address */ + jim_wide wide_addr; + e = Jim_GetWide(interp, argv[2], &wide_addr); if (e != JIM_OK) return e; + target_addr_t addr = (target_addr_t)wide_addr; + + /* Arg 3: Number of elements to read */ e = Jim_GetLong(interp, argv[3], &l); - len = l; if (e != JIM_OK) return e; - is_phys = false; + size_t len = l; + + /* Arg 4: phys */ + bool is_phys = false; if (argc > 4) { - phys = Jim_GetString(argv[4], &n); - if (!strncmp(phys, "phys", n)) + int str_len = 0; + const char *phys = Jim_GetString(argv[4], &str_len); + if (!strncmp(phys, "phys", str_len)) is_phys = true; else return JIM_ERR; } - switch (width) { - case 8: - width = 1; - break; - case 16: - width = 2; - break; - case 32: - width = 4; - break; - default: - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL); - return JIM_ERR; - } + + /* Argument checks */ if (len == 0) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL); @@ -4472,21 +4503,22 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL); return JIM_ERR; } - /* absurd transfer size? */ if (len > 65536) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL); + Jim_AppendStrings(interp, Jim_GetResult(interp), + "mem2array: too large read request, exceeds 64K items", NULL); return JIM_ERR; } if ((width == 1) || ((width == 2) && ((addr & 1) == 0)) || - ((width == 4) && ((addr & 3) == 0))) { - /* all is well */ + ((width == 4) && ((addr & 3) == 0)) || + ((width == 8) && ((addr & 7) == 0))) { + /* alignment correct */ } else { char buf[100]; Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRIu32 " byte reads", + sprintf(buf, "mem2array address: " TARGET_ADDR_FMT " is not aligned for %" PRIu32 " byte reads", addr, width); Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL); @@ -4496,40 +4528,42 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, /* Transfer loop */ /* index counter */ - n = 0; + size_t idx = 0; - size_t buffersize = 4096; + const size_t buffersize = 4096; uint8_t *buffer = malloc(buffersize); - if (buffer == NULL) + if (!buffer) return JIM_ERR; /* assume ok */ e = JIM_OK; while (len) { /* Slurp... in buffer size chunks */ + const unsigned int max_chunk_len = buffersize / width; + const size_t chunk_len = MIN(len, max_chunk_len); /* in elements.. */ - count = len; /* in objects.. */ - if (count > (buffersize / width)) - count = (buffersize / width); - + int retval; if (is_phys) - retval = target_read_phys_memory(target, addr, width, count, buffer); + retval = target_read_phys_memory(target, addr, width, chunk_len, buffer); else - retval = target_read_memory(target, addr, width, count, buffer); + retval = target_read_memory(target, addr, width, chunk_len, buffer); if (retval != ERROR_OK) { /* BOO !*/ - LOG_ERROR("mem2array: Read @ 0x%08" PRIx32 ", w=%" PRIu32 ", cnt=%" PRIu32 ", failed", + LOG_ERROR("mem2array: Read @ " TARGET_ADDR_FMT ", w=%u, cnt=%zu, failed", addr, width, - count); + chunk_len); Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL); e = JIM_ERR; break; } else { - v = 0; /* shut up gcc */ - for (i = 0; i < count ; i++, n++) { + for (size_t i = 0; i < chunk_len ; i++, idx++) { + uint64_t v = 0; switch (width) { + case 8: + v = target_buffer_get_u64(target, &buffer[i*width]); + break; case 4: v = target_buffer_get_u32(target, &buffer[i*width]); break; @@ -4540,10 +4574,10 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, v = buffer[i] & 0x0ff; break; } - new_int_array_element(interp, varname, n, v); + new_u64_array_element(interp, varname, idx, v); } - len -= count; - addr += count * width; + len -= chunk_len; + addr += chunk_len * width; } } @@ -4554,33 +4588,28 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, return e; } -static int get_int_array_element(Jim_Interp *interp, const char *varname, int idx, uint32_t *val) +static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val) { - char *namebuf; - Jim_Obj *nameObjPtr, *valObjPtr; - int result; - long l; - - namebuf = alloc_printf("%s(%d)", varname, idx); + char *namebuf = alloc_printf("%s(%zu)", varname, idx); if (!namebuf) return JIM_ERR; - nameObjPtr = Jim_NewStringObj(interp, namebuf, -1); - if (!nameObjPtr) { + Jim_Obj *obj_name = Jim_NewStringObj(interp, namebuf, -1); + if (!obj_name) { free(namebuf); return JIM_ERR; } - Jim_IncrRefCount(nameObjPtr); - valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG); - Jim_DecrRefCount(interp, nameObjPtr); + Jim_IncrRefCount(obj_name); + Jim_Obj *obj_val = Jim_GetVariable(interp, obj_name, JIM_ERRMSG); + Jim_DecrRefCount(interp, obj_name); free(namebuf); - if (valObjPtr == NULL) + if (!obj_val) return JIM_ERR; - result = Jim_GetLong(interp, valObjPtr, &l); - /* printf("%s(%d) => 0%08x\n", varname, idx, val); */ - *val = l; + jim_wide wide_val; + int result = Jim_GetWide(interp, obj_val, &wide_val); + *val = wide_val; return result; } @@ -4590,10 +4619,10 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv) struct target *target; context = current_command_context(interp); - assert(context != NULL); + assert(context); target = get_current_target(context); - if (target == NULL) { + if (!target) { LOG_ERROR("array2mem: no current target"); return JIM_ERR; } @@ -4604,95 +4633,95 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int target_array2mem(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv) { - long l; - uint32_t width; - int len; - uint32_t addr; - uint32_t count; - uint32_t v; - const char *varname; - const char *phys; - bool is_phys; - int n, e, retval; - uint32_t i; + int e; - /* argv[1] = name of array to get the data - * argv[2] = desired width - * argv[3] = memory address - * argv[4] = count to write + /* argv[0] = name of array from which to read the data + * argv[1] = desired element width in bits + * argv[2] = memory address + * argv[3] = number of elements to write + * argv[4] = optional "phys" */ if (argc < 4 || argc > 5) { Jim_WrongNumArgs(interp, 0, argv, "varname width addr nelems [phys]"); return JIM_ERR; } - varname = Jim_GetString(argv[0], &len); - /* given "foo" get space for worse case "foo(%d)" .. add 20 */ + /* Arg 0: Name of the array variable */ + const char *varname = Jim_GetString(argv[0], NULL); + + /* Arg 1: Bit width of one element */ + long l; e = Jim_GetLong(interp, argv[1], &l); - width = l; if (e != JIM_OK) return e; + const unsigned int width_bits = l; + + if (width_bits != 8 && + width_bits != 16 && + width_bits != 32 && + width_bits != 64) { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), + "Invalid width param. Must be one of: 8, 16, 32 or 64.", NULL); + return JIM_ERR; + } + const unsigned int width = width_bits / 8; - e = Jim_GetLong(interp, argv[2], &l); - addr = l; + /* Arg 2: Memory address */ + jim_wide wide_addr; + e = Jim_GetWide(interp, argv[2], &wide_addr); if (e != JIM_OK) return e; + target_addr_t addr = (target_addr_t)wide_addr; + + /* Arg 3: Number of elements to write */ e = Jim_GetLong(interp, argv[3], &l); - len = l; if (e != JIM_OK) return e; - is_phys = false; + size_t len = l; + + /* Arg 4: Phys */ + bool is_phys = false; if (argc > 4) { - phys = Jim_GetString(argv[4], &n); - if (!strncmp(phys, "phys", n)) + int str_len = 0; + const char *phys = Jim_GetString(argv[4], &str_len); + if (!strncmp(phys, "phys", str_len)) is_phys = true; else return JIM_ERR; } - switch (width) { - case 8: - width = 1; - break; - case 16: - width = 2; - break; - case 32: - width = 4; - break; - default: - Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), - "Invalid width param, must be 8/16/32", NULL); - return JIM_ERR; - } + + /* Argument checks */ if (len == 0) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL); return JIM_ERR; } + if ((addr + (len * width)) < addr) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL); return JIM_ERR; } - /* absurd transfer size? */ + if (len > 65536) { Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), - "array2mem: absurd > 64K item request", NULL); + "array2mem: too large memory write request, exceeds 64K items", NULL); return JIM_ERR; } if ((width == 1) || ((width == 2) && ((addr & 1) == 0)) || - ((width == 4) && ((addr & 3) == 0))) { - /* all is well */ + ((width == 4) && ((addr & 3) == 0)) || + ((width == 8) && ((addr & 7) == 0))) { + /* alignment correct */ } else { char buf[100]; Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - sprintf(buf, "array2mem address: 0x%08" PRIx32 " is not aligned for %" PRIu32 " byte reads", + sprintf(buf, "array2mem address: " TARGET_ADDR_FMT " is not aligned for %" PRIu32 " byte reads", addr, width); Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL); @@ -4701,27 +4730,34 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, /* Transfer loop */ - /* index counter */ - n = 0; /* assume ok */ e = JIM_OK; - size_t buffersize = 4096; + const size_t buffersize = 4096; uint8_t *buffer = malloc(buffersize); - if (buffer == NULL) + if (!buffer) return JIM_ERR; + /* index counter */ + size_t idx = 0; + while (len) { /* Slurp... in buffer size chunks */ + const unsigned int max_chunk_len = buffersize / width; - count = len; /* in objects.. */ - if (count > (buffersize / width)) - count = (buffersize / width); + const size_t chunk_len = MIN(len, max_chunk_len); /* in elements.. */ - v = 0; /* shut up gcc */ - for (i = 0; i < count; i++, n++) { - get_int_array_element(interp, varname, n, &v); + /* Fill the buffer */ + for (size_t i = 0; i < chunk_len; i++, idx++) { + uint64_t v = 0; + if (get_u64_array_element(interp, varname, idx, &v) != JIM_OK) { + free(buffer); + return JIM_ERR; + } switch (width) { + case 8: + target_buffer_set_u64(target, &buffer[i * width], v); + break; case 4: target_buffer_set_u32(target, &buffer[i * width], v); break; @@ -4733,24 +4769,26 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, break; } } - len -= count; + len -= chunk_len; + /* Write the buffer to memory */ + int retval; if (is_phys) - retval = target_write_phys_memory(target, addr, width, count, buffer); + retval = target_write_phys_memory(target, addr, width, chunk_len, buffer); else - retval = target_write_memory(target, addr, width, count, buffer); + retval = target_write_memory(target, addr, width, chunk_len, buffer); if (retval != ERROR_OK) { /* BOO !*/ - LOG_ERROR("array2mem: Write @ 0x%08" PRIx32 ", w=%" PRIu32 ", cnt=%" PRIu32 ", failed", + LOG_ERROR("array2mem: Write @ " TARGET_ADDR_FMT ", w=%u, cnt=%zu, failed", addr, width, - count); + chunk_len); Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL); e = JIM_ERR; break; } - addr += count * width; + addr += chunk_len * width; } free(buffer); @@ -4768,7 +4806,7 @@ 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) { + for (teap = target->event_action; teap; teap = teap->next) { if (teap->event == e) { LOG_DEBUG("target(%d): %s (%s) event: %d (%s) action: %s", target->target_number, @@ -4816,7 +4854,7 @@ bool target_has_event_action(struct target *target, enum target_event event) { struct target_event_action *teap; - for (teap = target->event_action; teap != NULL; teap = teap->next) { + for (teap = target->event_action; teap; teap = teap->next) { if (teap->event == event) return true; } @@ -4947,11 +4985,11 @@ no_params: if (goi->isconfigure) { /* START_DEPRECATED_TPIU */ if (n->value == TARGET_EVENT_TRACE_CONFIG) - LOG_INFO("DEPRECATED target event %s", n->name); + LOG_INFO("DEPRECATED target event %s; use TPIU events {pre,post}-{enable,disable}", n->name); /* END_DEPRECATED_TPIU */ bool replace = true; - if (teap == NULL) { + if (!teap) { /* create new */ teap = calloc(1, sizeof(*teap)); replace = false; @@ -4982,7 +5020,7 @@ no_params: Jim_SetEmptyResult(goi->interp); } else { /* get */ - if (teap == NULL) + if (!teap) Jim_SetEmptyResult(goi->interp); else Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, teap->body)); @@ -5068,7 +5106,7 @@ no_params: goto no_params; } n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness); - if (n->name == NULL) { + if (!n->name) { target->endianness = TARGET_LITTLE_ENDIAN; n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness); } @@ -5106,7 +5144,7 @@ no_params: if (e != JIM_OK) return e; tap = jtag_tap_by_jim_obj(goi->interp, o_t); - if (tap == NULL) + if (!tap) return JIM_ERR; target->tap = tap; target->tap_configured = true; @@ -5165,7 +5203,7 @@ no_params: if (goi->argc != 0) goto no_params; } - Jim_SetResultString(goi->interp, target->gdb_port_override ? : "undefined", -1); + Jim_SetResultString(goi->interp, target->gdb_port_override ? target->gdb_port_override : "undefined", -1); /* loop for more */ break; @@ -5272,8 +5310,13 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv } int e = target->type->examine(target); - if (e != ERROR_OK) + if (e != ERROR_OK) { + target_reset_examined(target); return JIM_ERR; + } + + target_set_examined(target); + return JIM_OK; } @@ -5433,11 +5476,11 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a e = target_wait_state(target, n->value, a); if (e != ERROR_OK) { - Jim_Obj *eObj = Jim_NewIntObj(interp, e); + Jim_Obj *obj = Jim_NewIntObj(interp, e); Jim_SetResultFormatted(goi.interp, "target: %s wait %s fails (%#s) %s", target_name(target), n->name, - eObj, target_strerror_safe(e)); + obj, target_strerror_safe(e)); return JIM_ERR; } return JIM_OK; @@ -5669,7 +5712,7 @@ static int target_create(struct jim_getopt_info *goi) struct command_context *cmd_ctx; cmd_ctx = current_command_context(goi->interp); - assert(cmd_ctx != NULL); + assert(cmd_ctx); if (goi->argc < 3) { Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ?type? ..options..."); @@ -5679,7 +5722,7 @@ static int target_create(struct jim_getopt_info *goi) /* COMMAND */ jim_getopt_obj(goi, &new_cmd); /* does this command exist? */ - cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG); + cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_NONE); if (cmd) { cp = Jim_GetString(new_cmd, NULL); Jim_SetResultFormatted(goi->interp, "Command/target: %s Exists", cp); @@ -5701,12 +5744,12 @@ static int target_create(struct jim_getopt_info *goi) } /* now does target type exist */ for (x = 0 ; target_types[x] ; x++) { - if (0 == strcmp(cp, target_types[x]->name)) { + if (strcmp(cp, target_types[x]->name) == 0) { /* found */ break; } } - if (target_types[x] == NULL) { + if (!target_types[x]) { Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp); for (x = 0 ; target_types[x] ; x++) { if (target_types[x + 1]) { @@ -5801,7 +5844,7 @@ static int target_create(struct jim_getopt_info *goi) } } /* tap must be set after target was configured */ - if (target->tap == NULL) + if (!target->tap) e = JIM_ERR; } @@ -5848,7 +5891,7 @@ static int target_create(struct jim_getopt_info *goi) /* create the target specific commands */ if (target->type->commands) { e = register_commands(cmd_ctx, NULL, target->type->commands); - if (ERROR_OK != e) + if (e != ERROR_OK) LOG_ERROR("unable to register '%s' commands", cp); } @@ -5899,7 +5942,7 @@ static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv return JIM_ERR; } struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx != NULL); + assert(cmd_ctx); struct target *target = get_current_target_or_null(cmd_ctx); if (target) @@ -5914,7 +5957,7 @@ static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - for (unsigned x = 0; NULL != target_types[x]; x++) { + for (unsigned x = 0; target_types[x]; x++) { Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, target_types[x]->name, -1)); } @@ -5942,10 +5985,10 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int i; const char *targetname; int retval, len; - struct target *target = (struct target *) NULL; + struct target *target = NULL; struct target_list *head, *curr, *new; - curr = (struct target_list *) NULL; - head = (struct target_list *) NULL; + curr = NULL; + head = NULL; retval = 0; LOG_DEBUG("%d", argc); @@ -5962,8 +6005,8 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (target) { new = malloc(sizeof(struct target_list)); new->target = target; - new->next = (struct target_list *)NULL; - if (head == (struct target_list *)NULL) { + new->next = NULL; + if (!head) { head = new; curr = head; } else { @@ -5975,7 +6018,7 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) /* now parse the list of cpu and put the target in smp mode*/ curr = head; - while (curr != (struct target_list *)NULL) { + while (curr) { target = curr->target; target->smp = 1; target->head = head; @@ -6046,7 +6089,7 @@ static const struct command_registration target_subcommand_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct FastLoad { +struct fast_load { target_addr_t address; uint8_t *data; int length; @@ -6054,11 +6097,11 @@ struct FastLoad { }; static int fastload_num; -static struct FastLoad *fastload; +static struct fast_load *fastload; static void free_fastload(void) { - if (fastload != NULL) { + if (fastload) { for (int i = 0; i < fastload_num; i++) free(fastload[i].data); free(fastload); @@ -6076,9 +6119,9 @@ COMMAND_HANDLER(handle_fast_load_image_command) struct image image; - int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV, + int retval = CALL_COMMAND_HANDLER(parse_load_image_command, &image, &min_address, &max_address); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; struct duration bench; @@ -6091,16 +6134,16 @@ COMMAND_HANDLER(handle_fast_load_image_command) image_size = 0x0; retval = ERROR_OK; fastload_num = image.num_sections; - fastload = malloc(sizeof(struct FastLoad)*image.num_sections); - if (fastload == NULL) { + fastload = malloc(sizeof(struct fast_load)*image.num_sections); + if (!fastload) { command_print(CMD, "out of memory"); image_close(&image); return ERROR_FAIL; } - memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections); + memset(fastload, 0, sizeof(struct fast_load)*image.num_sections); for (unsigned int i = 0; i < image.num_sections; i++) { buffer = malloc(image.sections[i].size); - if (buffer == NULL) { + if (!buffer) { command_print(CMD, "error allocating buffer for section (%d bytes)", (int)(image.sections[i].size)); retval = ERROR_FAIL; @@ -6131,7 +6174,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) fastload[i].address = image.sections[i].base_address + offset; fastload[i].data = malloc(length); - if (fastload[i].data == NULL) { + if (!fastload[i].data) { free(buffer); command_print(CMD, "error allocating buffer for section (%" PRIu32 " bytes)", length); @@ -6150,7 +6193,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) free(buffer); } - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { + if ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) { command_print(CMD, "Loaded %" PRIu32 " bytes " "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); @@ -6172,7 +6215,7 @@ COMMAND_HANDLER(handle_fast_load_command) { if (CMD_ARGC > 0) return ERROR_COMMAND_SYNTAX_ERROR; - if (fastload == NULL) { + if (!fastload) { LOG_ERROR("No image in memory"); return ERROR_FAIL; } @@ -6258,7 +6301,7 @@ COMMAND_HANDLER(handle_ps_command) static void binprint(struct command_invocation *cmd, const char *text, const uint8_t *buf, int size) { - if (text != NULL) + if (text) command_print_sameline(cmd, "%s", text); for (int i = 0; i < size; i++) command_print_sameline(cmd, " %02x", buf[i]); @@ -6358,7 +6401,7 @@ next: out: free(test_pattern); - if (wa != NULL) + if (wa) target_free_working_area(target, wa); /* Test writes */ @@ -6443,7 +6486,7 @@ nextw: free(test_pattern); - if (wa != NULL) + if (wa) target_free_working_area(target, wa); return retval; }