X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=026ca13b9c41875b43bac347893d7b42b3b50bd3;hp=82cbbff547340b767c192828c38c4b2d1190090a;hb=2615bf4398f393ee1e387128064093dcd44749c8;hpb=3931b99d142d337ea6558fd09aad2e0812c04507 diff --git a/src/target/target.c b/src/target/target.c index 82cbbff547..026ca13b9c 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -46,6 +46,10 @@ #include "image.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 +62,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; @@ -79,6 +84,7 @@ static struct target_type *target_types[] = &arm920t_target, &arm720t_target, &arm966e_target, + &arm946e_target, &arm926ejs_target, &fa526_target, &feroceon_target, @@ -276,6 +282,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) { @@ -300,6 +315,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) { @@ -505,7 +529,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; } @@ -590,7 +615,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)) { @@ -680,19 +705,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); } @@ -758,7 +783,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; @@ -842,6 +867,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; } @@ -1210,7 +1242,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 */ @@ -1244,7 +1276,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; @@ -1308,9 +1340,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); @@ -1333,6 +1364,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); @@ -1383,7 +1421,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 @@ -1392,7 +1430,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); @@ -1415,6 +1452,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); @@ -1499,7 +1543,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; @@ -2311,7 +2355,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--; @@ -2346,10 +2390,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); } @@ -2596,33 +2640,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; @@ -2643,9 +2679,6 @@ 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; @@ -2657,6 +2690,9 @@ COMMAND_HANDLER(handle_dump_image_command) duration_elapsed(&bench), duration_kbps(&bench, filesize)); } + if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK) + return retvaltemp; + return retval; } @@ -3082,7 +3118,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) { @@ -3109,7 +3145,7 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam 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); @@ -3635,7 +3671,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)); } } } @@ -3664,7 +3701,9 @@ enum target_cfg_param { TCFG_WORK_AREA_BACKUP, TCFG_ENDIAN, TCFG_VARIANT, + TCFG_COREID, TCFG_CHAIN_POSITION, + TCFG_DBGBASE, }; static Jim_Nvp nvp_config_opts[] = { @@ -3676,8 +3715,9 @@ 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 = NULL, .value = -1 } }; @@ -3717,7 +3757,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 { @@ -3910,7 +3950,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; @@ -3928,6 +3968,23 @@ 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 = (int)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_t; @@ -3951,6 +4008,22 @@ 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; } } /* while (goi->argc) */ @@ -3988,7 +4061,7 @@ static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (goi.argc < 2 || goi.argc > 4) { - Jim_SetResult_sprintf(goi.interp, + Jim_SetResultFormatted(goi.interp, "usage: %s [phys]
[]", cmd_name); return JIM_ERR; } @@ -4059,7 +4132,7 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if ((goi.argc < 1) || (goi.argc > 3)) { - Jim_SetResult_sprintf(goi.interp, + Jim_SetResultFormatted(goi.interp, "usage: %s [phys]
[]", cmd_name); return JIM_ERR; } @@ -4126,40 +4199,42 @@ static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } 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; } @@ -4181,7 +4256,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; @@ -4205,7 +4280,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; } @@ -4223,7 +4298,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; @@ -4263,7 +4337,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; @@ -4304,7 +4377,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; @@ -4345,7 +4418,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; } @@ -4368,10 +4441,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; @@ -4420,7 +4495,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; @@ -4591,7 +4666,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; } @@ -4606,7 +4681,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, @@ -4636,6 +4711,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; @@ -4816,7 +4894,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; @@ -4833,8 +4911,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; } @@ -4956,9 +5038,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; @@ -4967,6 +5050,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; } @@ -4978,6 +5062,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; } @@ -5013,6 +5098,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); @@ -5067,14 +5155,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; }