X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=6a60b4ea471181640e662fa79e5d535ff9543d7d;hp=d17bb7445fa119b579a28ee15e9bedfbb2f35a38;hb=3f6ef7a40bcff5e1278b662248902c45a1dc8f81;hpb=91b9f3de0b8e3277ab5c584c6076ddfe491ffc86 diff --git a/src/target/target.c b/src/target/target.c index d17bb7445f..6a60b4ea47 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -14,6 +14,12 @@ * Copyright (C) 2008 by Rick Altherr * * kc8apf@kc8apf.net> * * * + * Copyright (C) 2011 by Broadcom Corporation * + * Evan Hunter - ehunter@broadcom.com * + * * + * Copyright (C) ST-Ericsson SA 2011 * + * michel.jaouen@stericsson.com : smp minimum support * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -44,8 +50,13 @@ #include "register.h" #include "trace.h" #include "image.h" +#include "rtos/rtos.h" +static int target_read_buffer_default(struct target *target, uint32_t address, + uint32_t size, uint8_t *buffer); +static int target_write_buffer_default(struct target *target, uint32_t address, + uint32_t size, const uint8_t *buffer); static int target_array2mem(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv); static int target_mem2array(Jim_Interp *interp, struct target *target, @@ -58,6 +69,7 @@ extern struct target_type arm720t_target; extern struct target_type arm9tdmi_target; extern struct target_type arm920t_target; extern struct target_type arm966e_target; +extern struct target_type arm946e_target; extern struct target_type arm926ejs_target; extern struct target_type fa526_target; extern struct target_type feroceon_target; @@ -69,7 +81,9 @@ extern struct target_type arm11_target; extern struct target_type mips_m4k_target; extern struct target_type avr_target; extern struct target_type dsp563xx_target; +extern struct target_type dsp5680xx_target; extern struct target_type testee_target; +extern struct target_type avr32_ap7k_target; static struct target_type *target_types[] = { @@ -78,6 +92,7 @@ static struct target_type *target_types[] = &arm920t_target, &arm720t_target, &arm966e_target, + &arm946e_target, &arm926ejs_target, &fa526_target, &feroceon_target, @@ -89,13 +104,16 @@ static struct target_type *target_types[] = &mips_m4k_target, &avr_target, &dsp563xx_target, + &dsp5680xx_target, &testee_target, + &avr32_ap7k_target, NULL, }; struct target *all_targets = NULL; static struct target_event_callback *target_event_callbacks = NULL; static struct target_timer_callback *target_timer_callbacks = NULL; +static const int polling_interval = 100; static const Jim_Nvp nvp_assert[] = { { .name = "assert", NVP_ASSERT }, @@ -273,6 +291,15 @@ uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer) return be_to_h_u32(buffer); } +/* read a uint24_t from a buffer in target memory endianness */ +uint32_t target_buffer_get_u24(struct target *target, const uint8_t *buffer) +{ + if (target->endianness == TARGET_LITTLE_ENDIAN) + return le_to_h_u24(buffer); + else + return be_to_h_u24(buffer); +} + /* read a uint16_t from a buffer in target memory endianness */ uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer) { @@ -297,6 +324,15 @@ void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t valu h_u32_to_be(buffer, value); } +/* write a uint24_t to a buffer in target memory endianness */ +void target_buffer_set_u24(struct target *target, uint8_t *buffer, uint32_t value) +{ + if (target->endianness == TARGET_LITTLE_ENDIAN) + h_u24_to_le(buffer, value); + else + h_u24_to_be(buffer, value); +} + /* write a uint16_t to a buffer in target memory endianness */ void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value) { @@ -312,6 +348,38 @@ static void target_buffer_set_u8(struct target *target, uint8_t *buffer, uint8_t *buffer = value; } +/* write a uint32_t array to a buffer in target memory endianness */ +void target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf) +{ + uint32_t i; + for(i = 0; i < count; i ++) + dstbuf[i] = target_buffer_get_u32(target,&buffer[i*4]); +} + +/* write a uint16_t array to a buffer in target memory endianness */ +void target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, uint32_t count, uint16_t *dstbuf) +{ + uint32_t i; + for(i = 0; i < count; i ++) + dstbuf[i] = target_buffer_get_u16(target,&buffer[i*2]); +} + +/* write a uint32_t array to a buffer in target memory endianness */ +void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, uint32_t *srcbuf) +{ + uint32_t i; + for(i = 0; i < count; i ++) + target_buffer_set_u32(target,&buffer[i*4],srcbuf[i]); +} + +/* write a uint16_t array to a buffer in target memory endianness */ +void target_buffer_set_u16_array(struct target *target, uint8_t *buffer, uint32_t count, uint16_t *srcbuf) +{ + uint32_t i; + for(i = 0; i < count; i ++) + target_buffer_set_u16(target,&buffer[i*2],srcbuf[i]); +} + /* return a pointer to a configured target; id is name or number */ struct target *get_target(const char *id) { @@ -474,19 +542,6 @@ int target_resume(struct target *target, int current, uint32_t address, int hand if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK) return retval; - /* Invalidate any cached protect/erase/... flash status, since - * almost all targets will now be able modify the flash by - * themselves. We want flash drivers and infrastructure to - * be able to rely on (non-invalidated) cached state. - * - * For now we require that algorithms provided by OpenOCD are - * used only by code which properly maintains that cached state. - * state - * - * REVISIT do the same for NAND ; maybe other flash flavors too... - */ - if (!target->running_alg) - nor_resume(target); return retval; } @@ -515,7 +570,8 @@ static int target_process_reset(struct command_context *cmd_ctx, enum target_res jtag_poll_set_enabled(save_poll); if (retval != JIM_OK) { - Jim_PrintErrorMessage(cmd_ctx->interp); + Jim_MakeErrorMessage(cmd_ctx->interp); + command_print(NULL,"%s\n", Jim_GetString(Jim_GetResult(cmd_ctx->interp), NULL)); return ERROR_FAIL; } @@ -600,7 +656,7 @@ const char *target_type_name(struct target *target) return target->type->name; } -static int target_write_memory_imp(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) +static int target_write_memory_imp(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { if (!target_was_examined(target)) { @@ -676,6 +732,81 @@ done: return retval; } +/** + * Downloads a target-specific native code algorithm to the target, + * executes and leaves it running. + * + * @param target used to run the algorithm + * @param arch_info target-specific description of the algorithm. + */ +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, + void *arch_info) +{ + int retval = ERROR_FAIL; + + if (!target_was_examined(target)) + { + LOG_ERROR("Target not examined yet"); + goto done; + } + if (!target->type->start_algorithm) { + LOG_ERROR("Target type '%s' does not support %s", + target_type_name(target), __func__); + goto done; + } + if (target->running_alg) { + LOG_ERROR("Target is already running an algorithm"); + goto done; + } + + target->running_alg = true; + retval = target->type->start_algorithm(target, + num_mem_params, mem_params, + num_reg_params, reg_params, + entry_point, exit_point, arch_info); + +done: + return retval; +} + +/** + * Waits for an algorithm started with target_start_algorithm() to complete. + * + * @param target used to run the algorithm + * @param arch_info target-specific description of the algorithm. + */ +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, + void *arch_info) +{ + int retval = ERROR_FAIL; + + if (!target->type->wait_algorithm) { + LOG_ERROR("Target type '%s' does not support %s", + target_type_name(target), __func__); + goto done; + } + if (!target->running_alg) { + LOG_ERROR("Target is not running an algorithm"); + goto done; + } + + retval = target->type->wait_algorithm(target, + num_mem_params, mem_params, + num_reg_params, reg_params, + exit_point, timeout_ms, arch_info); + if (retval != ERROR_TARGET_TIMEOUT) + target->running_alg = false; + +done: + return retval; +} + int target_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) @@ -690,19 +821,19 @@ static int target_read_phys_memory(struct target *target, } int target_write_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { return target->type->write_memory(target, address, size, count, buffer); } static int target_write_phys_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { return target->type->write_phys_memory(target, address, size, count, buffer); } int target_bulk_write_memory(struct target *target, - uint32_t address, uint32_t count, uint8_t *buffer) + uint32_t address, uint32_t count, const uint8_t *buffer) { return target->type->bulk_write_memory(target, address, count, buffer); } @@ -710,12 +841,33 @@ int target_bulk_write_memory(struct target *target, int target_add_breakpoint(struct target *target, struct breakpoint *breakpoint) { - if (target->state != TARGET_HALTED) { + if ((target->state != TARGET_HALTED)&&(breakpoint->type!=BKPT_HARD)) { LOG_WARNING("target %s is not halted", target->cmd_name); return ERROR_TARGET_NOT_HALTED; } return target->type->add_breakpoint(target, breakpoint); } + +int target_add_context_breakpoint(struct target *target, + struct breakpoint *breakpoint) +{ + if (target->state != TARGET_HALTED) { + LOG_WARNING("target %s is not halted", target->cmd_name); + return ERROR_TARGET_NOT_HALTED; + } + return target->type->add_context_breakpoint(target, breakpoint); +} + +int target_add_hybrid_breakpoint(struct target *target, + struct breakpoint *breakpoint) +{ + if (target->state != TARGET_HALTED) { + LOG_WARNING("target %s is not halted", target->cmd_name); + return ERROR_TARGET_NOT_HALTED; + } + return target->type->add_hybrid_breakpoint(target, breakpoint); +} + int target_remove_breakpoint(struct target *target, struct breakpoint *breakpoint) { @@ -768,7 +920,7 @@ err_read_phys_memory(struct target *target, uint32_t address, static int err_write_phys_memory(struct target *target, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer) { LOG_ERROR("Not implemented: %s", __func__); return ERROR_FAIL; @@ -852,6 +1004,13 @@ static int target_init_one(struct command_context *cmd_ctx, type->read_phys_memory = type->read_memory; type->virt2phys = identity_virt2phys; } + + if (target->type->read_buffer == NULL) + target->type->read_buffer = target_read_buffer_default; + + if (target->type->write_buffer == NULL) + target->type->write_buffer = target_write_buffer_default; + return ERROR_OK; } @@ -875,7 +1034,7 @@ static int target_init(struct command_context *cmd_ctx) return retval; retval = target_register_timer_callback(&handle_target, - 100, 1, cmd_ctx->interp); + polling_interval, 1, cmd_ctx->interp); if (ERROR_OK != retval) return retval; @@ -1220,7 +1379,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w } /* mark as used, and return the new (reused) area */ - new_wa->free = 0; + new_wa->free = false; *area = new_wa; /* user pointer */ @@ -1254,7 +1413,7 @@ static int target_free_working_area_restore(struct target *target, struct workin return retval; } - area->free = 1; + area->free = true; /* mark user pointer invalid */ *area->user = NULL; @@ -1318,9 +1477,8 @@ int target_arch_state(struct target *target) * mode respectively, otherwise data is handled as quickly as * possible */ -int target_write_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer) +int target_write_buffer(struct target *target, uint32_t address, uint32_t size, const uint8_t *buffer) { - int retval; LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", (int)size, (unsigned)address); @@ -1343,6 +1501,13 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size, return ERROR_FAIL; } + return target->type->write_buffer(target, address, size, buffer); +} + +static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t size, const uint8_t *buffer) +{ + int retval = ERROR_OK; + if (((address % 2) == 0) && (size == 2)) { return target_write_memory(target, address, 2, 1, buffer); @@ -1393,7 +1558,7 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size, return retval; } - return ERROR_OK; + return retval; } /* Single aligned words are guaranteed to use 16 or 32 bit access @@ -1402,7 +1567,6 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size, */ int target_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer) { - int retval; LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", (int)size, (unsigned)address); @@ -1425,6 +1589,13 @@ int target_read_buffer(struct target *target, uint32_t address, uint32_t size, u return ERROR_FAIL; } + return target->type->read_buffer(target, address, size, buffer); +} + +static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer) +{ + int retval = ERROR_OK; + if (((address % 2) == 0) && (size == 2)) { return target_read_memory(target, address, 2, 1, buffer); @@ -1509,7 +1680,7 @@ int target_checksum_memory(struct target *target, uint32_t address, uint32_t siz return retval; } - /* convert to target endianess */ + /* convert to target endianness */ for (i = 0; i < (size/sizeof(uint32_t)); i++) { uint32_t target_data; @@ -1813,6 +1984,9 @@ static int sense_handler(void) return ERROR_OK; } +static int backoff_times = 0; +static int backoff_count = 0; + /* process target state changes */ static int handle_target(void *priv) { @@ -1875,6 +2049,14 @@ static int handle_target(void *priv) recursive = 0; } + if (backoff_times > backoff_count) + { + /* do not poll this time as we failed previously */ + backoff_count++; + return ERROR_OK; + } + backoff_count = 0; + /* Poll targets for state changes unless that's globally disabled. * Skip targets that are currently disabled. */ @@ -1891,17 +2073,26 @@ static int handle_target(void *priv) /* polling may fail silently until the target has been examined */ if ((retval = target_poll(target)) != ERROR_OK) { - /* FIX!!!!! If we add a LOG_INFO() here to output a line in GDB - * *why* we are aborting GDB, then we'll spam telnet when the - * poll is failing persistently. - * - * If we could implement an event that detected the - * target going from non-pollable to pollable, we could issue - * an error only upon the transition. + /* 100ms polling interval. Increase interval between polling up to 5000ms */ + if (backoff_times * polling_interval < 5000) + { + backoff_times *= 2; + backoff_times++; + } + LOG_USER("Polling target failed, GDB will be halted. Polling again in %dms", backoff_times * polling_interval); + + /* Tell GDB to halt the debugger. This allows the user to + * run monitor commands to handle the situation. */ target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); return retval; } + /* Since we succeeded, we reset backoff count */ + if (backoff_times > 0) + { + LOG_USER("Polling succeeded again"); + } + backoff_times = 0; } } @@ -2148,11 +2339,11 @@ COMMAND_HANDLER(handle_halt_command) if (CMD_ARGC == 1) { - unsigned wait; - retval = parse_uint(CMD_ARGV[0], &wait); + unsigned wait_local; + retval = parse_uint(CMD_ARGV[0], &wait_local); if (ERROR_OK != retval) return ERROR_COMMAND_SYNTAX_ERROR; - if (!wait) + if (!wait_local) return ERROR_OK; } @@ -2301,7 +2492,7 @@ COMMAND_HANDLER(handle_md_command) bool physical=strcmp(CMD_ARGV[0], "phys")==0; int (*fn)(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t address, uint32_t size_value, uint32_t count, uint8_t *buffer); if (physical) { CMD_ARGC--; @@ -2336,10 +2527,10 @@ COMMAND_HANDLER(handle_md_command) } typedef int (*target_write_fn)(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); static int target_write_memory_fast(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { return target_write_buffer(target, address, size * count, buffer); } @@ -2391,7 +2582,7 @@ static int target_fill_mem(struct target *target, { current = chunk_size; } - int retval = fn(target, address + x * data_size, data_size, current, target_buf); + retval = fn(target, address + x * data_size, data_size, current, target_buf); if (retval != ERROR_OK) { break; @@ -2573,7 +2764,7 @@ COMMAND_HANDLER(handle_load_image_command) if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { command_print(CMD_CTX, "downloaded %" PRIu32 " bytes " - "in %fs (%0.3f kb/s)", image_size, + "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); } @@ -2586,33 +2777,25 @@ COMMAND_HANDLER(handle_load_image_command) COMMAND_HANDLER(handle_dump_image_command) { struct fileio fileio; - uint8_t buffer[560]; - int retvaltemp; - - + int retval, retvaltemp; + uint32_t address, size; + struct duration bench; struct target *target = get_current_target(CMD_CTX); if (CMD_ARGC != 3) - { - command_print(CMD_CTX, "usage: dump_image
"); - return ERROR_OK; - } + return ERROR_COMMAND_SYNTAX_ERROR; - uint32_t address; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], address); - uint32_t size; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], size); - if (fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) - { - return ERROR_OK; - } + retval = fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY); + if (retval != ERROR_OK) + return retval; - struct duration bench; duration_start(&bench); - int retval = ERROR_OK; + retval = ERROR_OK; while (size > 0) { size_t size_written; @@ -2633,16 +2816,20 @@ COMMAND_HANDLER(handle_dump_image_command) address += this_run_size; } - if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK) - return retvaltemp; - if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { + int filesize; + retval = fileio_size(&fileio, &filesize); + if (retval != ERROR_OK) + return retval; command_print(CMD_CTX, - "dumped %ld bytes in %fs (%0.3f kb/s)", (long)fileio.size, - duration_elapsed(&bench), duration_kbps(&bench, fileio.size)); + "dumped %ld bytes in %fs (%0.3f KiB/s)", (long)filesize, + duration_elapsed(&bench), duration_kbps(&bench, filesize)); } + if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK) + return retvaltemp; + return retval; } @@ -2695,6 +2882,7 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify) } image_size = 0x0; + int diffs = 0; retval = ERROR_OK; for (i = 0; i < image.num_sections; i++) { @@ -2715,7 +2903,12 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify) if (verify) { /* calculate checksum of image */ - image_calculate_checksum(buffer, buf_cnt, &checksum); + retval = image_calculate_checksum(buffer, buf_cnt, &checksum); + if (retval != ERROR_OK) + { + free(buffer); + break; + } retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum); if (retval != ERROR_OK) @@ -2729,7 +2922,10 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify) /* failed crc checksum, fall back to a binary compare */ uint8_t *data; - command_print(CMD_CTX, "checksum mismatch - attempting binary compare"); + if (diffs == 0) + { + LOG_ERROR("checksum mismatch - attempting binary compare"); + } data = (uint8_t*)malloc(buf_cnt); @@ -2750,22 +2946,22 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify) if (data[t] != buffer[t]) { command_print(CMD_CTX, - "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n", + "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x", + diffs, (unsigned)(t + image.sections[i].base_address), data[t], buffer[t]); - free(data); - free(buffer); - retval = ERROR_FAIL; - goto done; - } - if ((t%16384) == 0) - { - keep_alive(); + if (diffs++ >= 127) + { + command_print(CMD_CTX, "More than 128 errors, the rest are not printed."); + free(data); + free(buffer); + goto done; + } } + keep_alive(); } } - free(data); } } else @@ -2778,11 +2974,19 @@ static COMMAND_HELPER(handle_verify_image_command_internal, int verify) free(buffer); image_size += buf_cnt; } + if (diffs > 0) + { + command_print(CMD_CTX, "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 " - "in %fs (%0.3f kb/s)", image_size, + "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); } @@ -2811,7 +3015,7 @@ static int handle_bp_command_list(struct command_context *cmd_ctx) { char* buf = buf_to_str(breakpoint->orig_instr, breakpoint->length, 16); - command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i, 0x%s", + command_print(cmd_ctx, "IVA breakpoint: 0x%8.8" PRIx32 ", 0x%x, %i, 0x%s", breakpoint->address, breakpoint->length, breakpoint->set, buf); @@ -2819,9 +3023,22 @@ static int handle_bp_command_list(struct command_context *cmd_ctx) } else { - command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i", - breakpoint->address, - breakpoint->length, breakpoint->set); + if ((breakpoint->address == 0) && (breakpoint->asid != 0)) + command_print(cmd_ctx, "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): 0x%8.8" PRIx32 ", 0x%x, %i", + breakpoint->address, + breakpoint->length, breakpoint->set); + command_print(cmd_ctx, "\t|--->linked with ContextID: 0x%8.8" PRIx32, + breakpoint->asid); + } + else + command_print(cmd_ctx, "Breakpoint(IVA): 0x%8.8" PRIx32 ", 0x%x, %i", + breakpoint->address, + breakpoint->length, breakpoint->set); } breakpoint = breakpoint->next; @@ -2830,43 +3047,90 @@ static int handle_bp_command_list(struct command_context *cmd_ctx) } static int handle_bp_command_set(struct command_context *cmd_ctx, - uint32_t addr, uint32_t length, int hw) + uint32_t addr, uint32_t asid, uint32_t length, int hw) { struct target *target = get_current_target(cmd_ctx); - int retval = breakpoint_add(target, addr, length, hw); - if (ERROR_OK == retval) - command_print(cmd_ctx, "breakpoint set at 0x%8.8" PRIx32 "", addr); - else - LOG_ERROR("Failure setting breakpoint"); - return retval; + + if (asid == 0) + { int retval = breakpoint_add(target, addr, length, hw); + if (ERROR_OK == retval) + command_print(cmd_ctx, "breakpoint set at 0x%8.8" PRIx32 "", addr); + else + { + LOG_ERROR("Failure setting breakpoint, the same address(IVA) is already used"); + return retval; + } + } + else if (addr == 0) + { + int retval = context_breakpoint_add(target, asid, length, hw); + if (ERROR_OK == retval) + command_print(cmd_ctx, "Context breakpoint set at 0x%8.8" PRIx32 "", asid); + else + { + LOG_ERROR("Failure setting breakpoint, the same address(CONTEXTID) is already used"); + return retval; + } + } + else + { + int retval = hybrid_breakpoint_add(target, addr, asid, length, hw); + if(ERROR_OK == retval) + command_print(cmd_ctx, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid); + else + { + LOG_ERROR("Failure setting breakpoint, the same address is already used"); + return retval; + } + } + return ERROR_OK; + + } COMMAND_HANDLER(handle_bp_command) { - if (CMD_ARGC == 0) - return handle_bp_command_list(CMD_CTX); - - if (CMD_ARGC < 2 || CMD_ARGC > 3) - { - command_print(CMD_CTX, "usage: bp
['hw']"); - return ERROR_COMMAND_SYNTAX_ERROR; - } - uint32_t addr; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); + uint32_t asid; uint32_t length; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length); - int hw = BKPT_SOFT; - if (CMD_ARGC == 3) + switch(CMD_ARGC) { - if (strcmp(CMD_ARGV[2], "hw") == 0) + case 0: + return handle_bp_command_list(CMD_CTX); + case 3: + + if(strcmp(CMD_ARGV[2], "hw") == 0) + { + hw = BKPT_HARD; + COMMAND_PARSE_NUMBER(u32, 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); + } + 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); + } + + case 4: hw = BKPT_HARD; - else + COMMAND_PARSE_NUMBER(u32, 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); + default: + command_print(CMD_CTX, "usage: bp
[] ['hw'|'hw_ctx']"); return ERROR_COMMAND_SYNTAX_ERROR; } - return handle_bp_command_set(CMD_CTX, addr, length, hw); + } COMMAND_HANDLER(handle_rbp_command) @@ -3051,7 +3315,7 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam int addressSpace = (max-min + 1); - static const uint32_t maxBuckets = 256 * 1024; /* maximum buckets. */ + static const uint32_t maxBuckets = 16 * 1024; /* maximum buckets. */ uint32_t length = addressSpace; if (length > maxBuckets) { @@ -3070,15 +3334,15 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam long long a = address-min; long long b = length-1; long long c = addressSpace-1; - int index = (a*b)/c; /* danger!!!! int32 overflows */ - buckets[index]++; + 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); /* low_pc */ writeLong(f, max); /* high_pc */ writeLong(f, length); /* # of samples */ - writeLong(f, 64000000); /* 64MHz */ + writeLong(f, 100); /* KLUDGE! We lie, ca. 100Hz best case. */ writeString(f, "seconds"); for (i = 0; i < (15-strlen("seconds")); i++) writeData(f, &zero, 1); @@ -3604,7 +3868,8 @@ void target_handle_event(struct target *target, enum target_event e) Jim_GetString(teap->body, NULL)); if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK) { - Jim_PrintErrorMessage(teap->interp); + Jim_MakeErrorMessage(teap->interp); + command_print(NULL,"%s\n", Jim_GetString(Jim_GetResult(teap->interp), NULL)); } } } @@ -3633,7 +3898,10 @@ enum target_cfg_param { TCFG_WORK_AREA_BACKUP, TCFG_ENDIAN, TCFG_VARIANT, + TCFG_COREID, TCFG_CHAIN_POSITION, + TCFG_DBGBASE, + TCFG_RTOS, }; static Jim_Nvp nvp_config_opts[] = { @@ -3645,8 +3913,10 @@ static Jim_Nvp nvp_config_opts[] = { { .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP }, { .name = "-endian" , .value = TCFG_ENDIAN }, { .name = "-variant", .value = TCFG_VARIANT }, + { .name = "-coreid", .value = TCFG_COREID }, { .name = "-chain-position", .value = TCFG_CHAIN_POSITION }, - + { .name = "-dbgbase", .value = TCFG_DBGBASE }, + { .name = "-rtos", .value = TCFG_RTOS }, { .name = NULL, .value = -1 } }; @@ -3686,7 +3956,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) case TCFG_TYPE: /* not setable */ if (goi->isconfigure) { - Jim_SetResult_sprintf(goi->interp, + Jim_SetResultFormatted(goi->interp, "not settable: %s", n->name); return JIM_ERR; } else { @@ -3854,6 +4124,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) /* loop for more e*/ break; + case TCFG_ENDIAN: if (goi->isconfigure) { e = Jim_GetOpt_Nvp(goi, nvp_target_endian, &n); @@ -3879,7 +4150,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) case TCFG_VARIANT: if (goi->isconfigure) { if (goi->argc < 1) { - Jim_SetResult_sprintf(goi->interp, + Jim_SetResultFormatted(goi->interp, "%s ?STRING?", n->name); return JIM_ERR; @@ -3897,16 +4168,33 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) Jim_SetResultString(goi->interp, target->variant,-1); /* loop for more */ break; + + case TCFG_COREID: + if (goi->isconfigure) { + e = Jim_GetOpt_Wide(goi, &w); + if (e != JIM_OK) { + return e; + } + target->coreid = (int32_t)w; + } else { + if (goi->argc != 0) { + goto no_params; + } + } + Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size)); + /* loop for more */ + break; + case TCFG_CHAIN_POSITION: if (goi->isconfigure) { - Jim_Obj *o; + Jim_Obj *o_t; struct jtag_tap *tap; target_free_all_working_areas(target); - e = Jim_GetOpt_Obj(goi, &o); + e = Jim_GetOpt_Obj(goi, &o_t); if (e != JIM_OK) { return e; } - tap = jtag_tap_by_jim_obj(goi->interp, o); + tap = jtag_tap_by_jim_obj(goi->interp, o_t); if (tap == NULL) { return JIM_ERR; } @@ -3920,6 +4208,34 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) Jim_SetResultString(goi->interp, target->tap->dotted_name, -1); /* loop for more e*/ break; + case TCFG_DBGBASE: + if (goi->isconfigure) { + e = Jim_GetOpt_Wide(goi, &w); + if (e != JIM_OK) { + return e; + } + target->dbgbase = (uint32_t)w; + target->dbgbase_set = true; + } else { + if (goi->argc != 0) { + goto no_params; + } + } + Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase)); + /* loop for more */ + break; + + case TCFG_RTOS: + /* RTOS */ + { + int result = rtos_create( goi, target ); + if ( result != JIM_OK ) + { + return result; + } + } + /* loop for more */ + break; } } /* while (goi->argc) */ @@ -3955,19 +4271,30 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - /* danger! goi.argc will be modified below! */ - argc = goi.argc; - - if (argc != 2 && argc != 3) + if (goi.argc < 2 || goi.argc > 4) { - Jim_SetResult_sprintf(goi.interp, - "usage: %s
[]", cmd_name); + Jim_SetResultFormatted(goi.interp, + "usage: %s [phys]
[]", cmd_name); return JIM_ERR; } + target_write_fn fn; + fn = target_write_memory_fast; + + 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; - int e = Jim_GetOpt_Wide(&goi, &a); + e = Jim_GetOpt_Wide(&goi, &a); if (e != JIM_OK) return e; @@ -3977,13 +4304,19 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return e; jim_wide c = 1; - if (argc == 3) + 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) { @@ -3999,7 +4332,7 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } - return (target_fill_mem(target, a, target_write_memory_fast, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR; + return (target_fill_mem(target, a, fn, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR; } static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -4009,23 +4342,36 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); - /* danger! goi.argc will be modified below! */ - argc = goi.argc; - - if ((argc != 1) && (argc != 2)) + if ((goi.argc < 1) || (goi.argc > 3)) { - Jim_SetResult_sprintf(goi.interp, - "usage: %s
[]", cmd_name); + Jim_SetResultFormatted(goi.interp, + "usage: %s [phys]
[]", cmd_name); return JIM_ERR; } + int (*fn)(struct target *target, + uint32_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; + } + jim_wide a; - int e = Jim_GetOpt_Wide(&goi, &a); + e = Jim_GetOpt_Wide(&goi, &a); if (e != JIM_OK) { return JIM_ERR; } jim_wide c; - if (argc == 2) { + if (goi.argc == 1) { e = Jim_GetOpt_Wide(&goi, &c); if (e != JIM_OK) { return JIM_ERR; @@ -4033,6 +4379,13 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } else { c = 1; } + + /* all args must be consumed */ + if (goi.argc != 0) + { + return JIM_ERR; + } + jim_wide b = 1; /* shut up gcc */ if (strcasecmp(cmd_name, "mdw") == 0) b = 4; @@ -4056,42 +4409,44 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (y > 16) { y = 16; } - e = target_read_memory(target, a, b, y / b, target_buf); + e = fn(target, a, b, y / b, target_buf); if (e != ERROR_OK) { - Jim_SetResult_sprintf(interp, "error reading target @ 0x%08lx", (int)(a)); + char tmp[10]; + snprintf(tmp, sizeof(tmp), "%08lx", (long)a); + Jim_SetResultFormatted(interp, "error reading target @ 0x%s", tmp); return JIM_ERR; } - Jim_fprintf(interp, interp->cookie_stdout, "0x%08x ", (int)(a)); + command_print(NULL, "0x%08x ", (int)(a)); switch (b) { case 4: for (x = 0; x < 16 && x < y; x += 4) { z = target_buffer_get_u32(target, &(target_buf[ x ])); - Jim_fprintf(interp, interp->cookie_stdout, "%08x ", (int)(z)); + command_print(NULL, "%08x ", (int)(z)); } for (; (x < 16) ; x += 4) { - Jim_fprintf(interp, interp->cookie_stdout, " "); + command_print(NULL, " "); } break; case 2: for (x = 0; x < 16 && x < y; x += 2) { z = target_buffer_get_u16(target, &(target_buf[ x ])); - Jim_fprintf(interp, interp->cookie_stdout, "%04x ", (int)(z)); + command_print(NULL, "%04x ", (int)(z)); } for (; (x < 16) ; x += 2) { - Jim_fprintf(interp, interp->cookie_stdout, " "); + command_print(NULL, " "); } break; case 1: default: for (x = 0 ; (x < 16) && (x < y) ; x += 1) { z = target_buffer_get_u8(target, &(target_buf[ x ])); - Jim_fprintf(interp, interp->cookie_stdout, "%02x ", (int)(z)); + command_print(NULL, "%02x ", (int)(z)); } for (; (x < 16) ; x += 1) { - Jim_fprintf(interp, interp->cookie_stdout, " "); + command_print(NULL, " "); } break; } @@ -4113,7 +4468,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) /* terminate */ target_buf[16] = 0; /* print - with a newline */ - Jim_fprintf(interp, interp->cookie_stdout, "%s\n", target_buf); + command_print(NULL, "%s\n", target_buf); /* NEXT... */ c -= 16; a += 16; @@ -4137,7 +4492,7 @@ static int jim_target_array2mem(Jim_Interp *interp, static int jim_target_tap_disabled(Jim_Interp *interp) { - Jim_SetResult_sprintf(interp, "[TAP is disabled]"); + Jim_SetResultFormatted(interp, "[TAP is disabled]"); return JIM_ERR; } @@ -4155,7 +4510,6 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv int e = target->type->examine(target); if (e != ERROR_OK) { - Jim_SetResult_sprintf(interp, "examine-fails: %d", e); return JIM_ERR; } return JIM_OK; @@ -4195,7 +4549,6 @@ static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } if (e != ERROR_OK) { - Jim_SetResult_sprintf(interp, "poll-fails: %d", e); return JIM_ERR; } return JIM_OK; @@ -4236,7 +4589,7 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } if (!target->type->assert_reset || !target->type->deassert_reset) { - Jim_SetResult_sprintf(interp, + Jim_SetResultFormatted(interp, "No target-specific reset for %s", target_name(target)); return JIM_ERR; @@ -4277,7 +4630,7 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a if (goi.argc != 2) { const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_SetResult_sprintf(goi.interp, + Jim_SetResultFormatted(goi.interp, "%s ", cmd_name); return JIM_ERR; } @@ -4300,10 +4653,12 @@ 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_SetResult_sprintf(goi.interp, - "target: %s wait %s fails (%d) %s", + Jim_Obj *eObj = Jim_NewIntObj(interp, e); + Jim_SetResultFormatted(goi.interp, + "target: %s wait %s fails (%#s) %s", target_name(target), n->name, - e, target_strerror_safe(e)); + eObj, target_strerror_safe(e)); + Jim_FreeNewObj(interp, eObj); return JIM_ERR; } return JIM_OK; @@ -4352,7 +4707,7 @@ static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const if (goi.argc != 1) { const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_SetResult_sprintf(goi.interp, "%s ", cmd_name); + Jim_SetResultFormatted(goi.interp, "%s ", cmd_name); return JIM_ERR; } Jim_Nvp *n; @@ -4523,7 +4878,7 @@ static int target_create(Jim_GetOptInfo *goi) cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG); if (cmd) { cp = Jim_GetString(new_cmd, NULL); - Jim_SetResult_sprintf(goi->interp, "Command/target: %s Exists", cp); + Jim_SetResultFormatted(goi->interp, "Command/target: %s Exists", cp); return JIM_ERR; } @@ -4538,7 +4893,7 @@ static int target_create(Jim_GetOptInfo *goi) } } if (target_types[x] == NULL) { - Jim_SetResult_sprintf(goi->interp, "Unknown target type %s, try one of ", cp); + Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp); for (x = 0 ; target_types[x] ; x++) { if (target_types[x + 1]) { Jim_AppendStrings(goi->interp, @@ -4568,6 +4923,9 @@ static int target_create(Jim_GetOptInfo *goi) /* will be set by "-endian" */ target->endianness = TARGET_ENDIAN_UNKNOWN; + /* default to first core, override with -coreid */ + target->coreid = 0; + target->working_area = 0x0; target->working_area_size = 0x0; target->working_areas = NULL; @@ -4600,6 +4958,9 @@ static int target_create(Jim_GetOptInfo *goi) target->endianness = TARGET_ENDIAN_UNKNOWN; + target->rtos = NULL; + target->rtos_auto_detect = false; + /* Do the rest as "configure" options */ goi->isconfigure = 1; e = target_configure(goi, target); @@ -4726,6 +5087,61 @@ static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } +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_list *head, *curr, *new; + curr = (struct target_list*) NULL; + head = (struct target_list*) NULL; + new = (struct target_list*) NULL; + + retval = 0; + LOG_DEBUG("%d",argc); + /* argv[1] = target to associate in smp + * argv[2] = target to assoicate in smp + * argv[3] ... + */ + + for(i=1;itarget = target; + new->next = (struct target_list*)NULL; + if (head == (struct target_list*)NULL) + { + head = new; + curr = head; + } + else + { + curr->next = new; + curr = new; + } + } + } + /* now parse the list of cpu and put the target in smp mode*/ + curr=head; + + while(curr!=(struct target_list *)NULL) + { + target=curr->target; + target->smp = 1; + target->head = head; + curr=curr->next; + } + return retval; +} + + static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { Jim_GetOptInfo goi; @@ -4748,7 +5164,7 @@ static int jim_target_number(Jim_Interp *interp, int argc, Jim_Obj *const *argv) LOG_WARNING("don't use numbers as target identifiers; use names"); if (goi.argc != 1) { - Jim_SetResult_sprintf(goi.interp, "usage: target number "); + Jim_SetResultFormatted(goi.interp, "usage: target number "); return JIM_ERR; } jim_wide w; @@ -4765,8 +5181,12 @@ static int jim_target_number(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_SetResultString(goi.interp, target_name(target), -1); return JIM_OK; } - Jim_SetResult_sprintf(goi.interp, - "Target: number %d does not exist", (int)(w)); + { + Jim_Obj *wObj = Jim_NewIntObj(goi.interp, w); + Jim_SetResultFormatted(goi.interp, + "Target: number %#s does not exist", wObj); + Jim_FreeNewObj(interp, wObj); + } return JIM_ERR; } @@ -4837,6 +5257,14 @@ static const struct command_registration target_subcommand_handlers[] = { .help = "Returns the number of targets as an integer " "(DEPRECATED)", }, + { + .name = "smp", + .mode = COMMAND_ANY, + .jim_handler = jim_target_smp, + .usage = "targetname1 targetname2 ...", + .help = "gather several target in a smp list" + }, + COMMAND_REGISTRATION_DONE }; @@ -4888,9 +5316,10 @@ COMMAND_HANDLER(handle_fast_load_image_command) struct duration bench; duration_start(&bench); - if (image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) + retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL); + if (retval != ERROR_OK) { - return ERROR_OK; + return retval; } image_size = 0x0; @@ -4899,6 +5328,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) fastload = (struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections); if (fastload == NULL) { + command_print(CMD_CTX, "out of memory"); image_close(&image); return ERROR_FAIL; } @@ -4910,6 +5340,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) { command_print(CMD_CTX, "error allocating buffer for section (%d bytes)", (int)(image.sections[i].size)); + retval = ERROR_FAIL; break; } @@ -4945,6 +5376,9 @@ COMMAND_HANDLER(handle_fast_load_image_command) if (fastload[i].data == NULL) { free(buffer); + command_print(CMD_CTX, "error allocating buffer for section (%d bytes)", + length); + retval = ERROR_FAIL; break; } memcpy(fastload[i].data, buffer + offset, length); @@ -4962,7 +5396,7 @@ COMMAND_HANDLER(handle_fast_load_image_command) if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { command_print(CMD_CTX, "Loaded %" PRIu32 " bytes " - "in %fs (%0.3f kb/s)", image_size, + "in %fs (%0.3f KiB/s)", image_size, duration_elapsed(&bench), duration_kbps(&bench, image_size)); command_print(CMD_CTX, @@ -4999,14 +5433,18 @@ COMMAND_HANDLER(handle_fast_load_command) command_print(CMD_CTX, "Write to 0x%08x, length 0x%08x", (unsigned int)(fastload[i].address), (unsigned int)(fastload[i].length)); - if (retval == ERROR_OK) + retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data); + if (retval != ERROR_OK) { - retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data); + break; } size += fastload[i].length; } - int after = timeval_ms(); - command_print(CMD_CTX, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0)); + if (retval == ERROR_OK) + { + int after = timeval_ms(); + command_print(CMD_CTX, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0)); + } return retval; } @@ -5185,7 +5623,7 @@ 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 = "[address length ['hw']]", + .usage = "usage: bp
[] ['hw'|'hw_ctx']", }, { .name = "rbp", @@ -5234,7 +5672,7 @@ static const struct command_registration target_exec_command_handlers[] = { .usage = "filename [offset [type]]", }, { - .name = "ocd_mem2array", + .name = "mem2array", .mode = COMMAND_EXEC, .jim_handler = jim_mem2array, .help = "read 8/16/32 bit memory and return as a TCL array " @@ -5242,7 +5680,7 @@ static const struct command_registration target_exec_command_handlers[] = { .usage = "arrayname bitwidth address count", }, { - .name = "ocd_array2mem", + .name = "array2mem", .mode = COMMAND_EXEC, .jim_handler = jim_array2mem, .help = "convert a TCL array to memory locations "