+
+
+struct FastLoad
+{
+ uint32_t address;
+ uint8_t *data;
+ int length;
+
+};
+
+static int fastload_num;
+static struct FastLoad *fastload;
+
+static void free_fastload(void)
+{
+ if (fastload != NULL)
+ {
+ int i;
+ for (i = 0; i < fastload_num; i++)
+ {
+ if (fastload[i].data)
+ free(fastload[i].data);
+ }
+ free(fastload);
+ fastload = NULL;
+ }
+}
+
+
+
+
+static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ uint8_t *buffer;
+ uint32_t buf_cnt;
+ uint32_t image_size;
+ uint32_t min_address = 0;
+ uint32_t max_address = 0xffffffff;
+ int i;
+
+ image_t image;
+
+ int retval = parse_load_image_command_args(cmd_ctx, args, argc,
+ &image, &min_address, &max_address);
+ if (ERROR_OK != retval)
+ return retval;
+
+ struct duration bench;
+ duration_start(&bench);
+
+ if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
+ {
+ return ERROR_OK;
+ }
+
+ image_size = 0x0;
+ retval = ERROR_OK;
+ fastload_num = image.num_sections;
+ fastload = (struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
+ if (fastload == NULL)
+ {
+ image_close(&image);
+ return ERROR_FAIL;
+ }
+ memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
+ for (i = 0; i < image.num_sections; i++)
+ {
+ buffer = malloc(image.sections[i].size);
+ if (buffer == NULL)
+ {
+ command_print(cmd_ctx, "error allocating buffer for section (%d bytes)",
+ (int)(image.sections[i].size));
+ break;
+ }
+
+ if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
+ {
+ free(buffer);
+ break;
+ }
+
+ uint32_t offset = 0;
+ uint32_t length = buf_cnt;
+
+
+ /* DANGER!!! beware of unsigned comparision here!!! */
+
+ if ((image.sections[i].base_address + buf_cnt >= min_address)&&
+ (image.sections[i].base_address < max_address))
+ {
+ if (image.sections[i].base_address < min_address)
+ {
+ /* clip addresses below */
+ offset += min_address-image.sections[i].base_address;
+ length -= offset;
+ }
+
+ if (image.sections[i].base_address + buf_cnt > max_address)
+ {
+ length -= (image.sections[i].base_address + buf_cnt)-max_address;
+ }
+
+ fastload[i].address = image.sections[i].base_address + offset;
+ fastload[i].data = malloc(length);
+ if (fastload[i].data == NULL)
+ {
+ free(buffer);
+ break;
+ }
+ memcpy(fastload[i].data, buffer + offset, length);
+ fastload[i].length = length;
+
+ image_size += length;
+ command_print(cmd_ctx, "%u bytes written at address 0x%8.8x",
+ (unsigned int)length,
+ ((unsigned int)(image.sections[i].base_address + offset)));
+ }
+
+ free(buffer);
+ }
+
+ if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
+ {
+ command_print(cmd_ctx, "Loaded %" PRIu32 " bytes "
+ "in %fs (%0.3f kb/s)", image_size,
+ duration_elapsed(&bench), duration_kbps(&bench, image_size));
+
+ command_print(cmd_ctx,
+ "WARNING: image has not been loaded to target!"
+ "You can issue a 'fast_load' to finish loading.");
+ }
+
+ image_close(&image);
+
+ if (retval != ERROR_OK)
+ {
+ free_fastload();
+ }
+
+ return retval;
+}
+
+static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ if (argc > 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ if (fastload == NULL)
+ {
+ LOG_ERROR("No image in memory");
+ return ERROR_FAIL;
+ }
+ int i;
+ int ms = timeval_ms();
+ int size = 0;
+ int retval = ERROR_OK;
+ for (i = 0; i < fastload_num;i++)
+ {
+ target_t *target = get_current_target(cmd_ctx);
+ 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);
+ }
+ 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));
+ return retval;
+}
+
+static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ command_context_t *context;
+ target_t *target;
+ int retval;
+
+ context = Jim_GetAssocData(interp, "context");
+ if (context == NULL) {
+ LOG_ERROR("array2mem: no command context");
+ return JIM_ERR;
+ }
+ target = get_current_target(context);
+ if (target == NULL) {
+ LOG_ERROR("array2mem: no current target");
+ return JIM_ERR;
+ }
+
+ if ((argc < 6) || (argc > 7))
+ {
+ return JIM_ERR;
+ }
+
+ int cpnum;
+ uint32_t op1;
+ uint32_t op2;
+ uint32_t CRn;
+ uint32_t CRm;
+ uint32_t value;
+
+ int e;
+ long l;
+ e = Jim_GetLong(interp, argv[1], &l);
+ if (e != JIM_OK) {
+ return e;
+ }
+ cpnum = l;
+
+ e = Jim_GetLong(interp, argv[2], &l);
+ if (e != JIM_OK) {
+ return e;
+ }
+ op1 = l;
+
+ e = Jim_GetLong(interp, argv[3], &l);
+ if (e != JIM_OK) {
+ return e;
+ }
+ CRn = l;
+
+ e = Jim_GetLong(interp, argv[4], &l);
+ if (e != JIM_OK) {
+ return e;
+ }
+ CRm = l;
+
+ e = Jim_GetLong(interp, argv[5], &l);
+ if (e != JIM_OK) {
+ return e;
+ }
+ op2 = l;
+
+ value = 0;
+
+ if (argc == 7)
+ {
+ e = Jim_GetLong(interp, argv[6], &l);
+ if (e != JIM_OK) {
+ return e;
+ }
+ value = l;
+
+ retval = target_mcr(target, cpnum, op1, op2, CRn, CRm, value);
+ if (retval != ERROR_OK)
+ return JIM_ERR;
+ } else
+ {
+ retval = target_mrc(target, cpnum, op1, op2, CRn, CRm, &value);
+ if (retval != ERROR_OK)
+ return JIM_ERR;
+
+ Jim_SetResult(interp, Jim_NewIntObj(interp, value));
+ }
+
+ return JIM_OK;
+}
+
+int target_register_commands(struct command_context_s *cmd_ctx)
+{
+
+ register_command(cmd_ctx, NULL, "targets",
+ handle_targets_command, COMMAND_EXEC,
+ "change current command line target (one parameter) "
+ "or list targets (no parameters)");
+
+ register_jim(cmd_ctx, "target", jim_target, "configure target");
+
+ return ERROR_OK;
+}
+
+int target_register_user_commands(struct command_context_s *cmd_ctx)
+{
+ int retval = ERROR_OK;
+ if ((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)
+ return retval;
+
+ if ((retval = trace_register_commands(cmd_ctx)) != ERROR_OK)
+ return retval;
+
+ register_command(cmd_ctx, NULL, "profile",
+ handle_profile_command, COMMAND_EXEC,
+ "profiling samples the CPU PC");
+
+ register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array,
+ "read memory and return as a TCL array for script processing "
+ "<ARRAYNAME> <WIDTH = 32/16/8> <ADDRESS> <COUNT>");
+
+ register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem,
+ "convert a TCL array to memory locations and write the values "
+ "<ARRAYNAME> <WIDTH = 32/16/8> <ADDRESS> <COUNT>");
+
+ register_command(cmd_ctx, NULL, "fast_load_image",
+ handle_fast_load_image_command, COMMAND_ANY,
+ "same args as load_image, image stored in memory "
+ "- mainly for profiling purposes");
+
+ register_command(cmd_ctx, NULL, "fast_load",
+ handle_fast_load_command, COMMAND_ANY,
+ "loads active fast load image to current target "
+ "- mainly for profiling purposes");
+
+ /** @todo don't register virt2phys() unless target supports it */
+ register_command(cmd_ctx, NULL, "virt2phys",
+ handle_virt2phys_command, COMMAND_ANY,
+ "translate a virtual address into a physical address");
+
+ register_command(cmd_ctx, NULL, "reg",
+ handle_reg_command, COMMAND_EXEC,
+ "display or set a register");
+
+ register_command(cmd_ctx, NULL, "poll",
+ handle_poll_command, COMMAND_EXEC,
+ "poll target state");
+ register_command(cmd_ctx, NULL, "wait_halt",
+ handle_wait_halt_command, COMMAND_EXEC,
+ "wait for target halt [time (s)]");
+ register_command(cmd_ctx, NULL, "halt",
+ handle_halt_command, COMMAND_EXEC,
+ "halt target");
+ register_command(cmd_ctx, NULL, "resume",
+ handle_resume_command, COMMAND_EXEC,
+ "resume target [addr]");
+ register_command(cmd_ctx, NULL, "reset",
+ handle_reset_command, COMMAND_EXEC,
+ "reset target [run | halt | init] - default is run");
+ register_command(cmd_ctx, NULL, "soft_reset_halt",
+ handle_soft_reset_halt_command, COMMAND_EXEC,
+ "halt the target and do a soft reset");
+
+ register_command(cmd_ctx, NULL, "step",
+ handle_step_command, COMMAND_EXEC,
+ "step one instruction from current PC or [addr]");
+
+ register_command(cmd_ctx, NULL, "mdw",
+ handle_md_command, COMMAND_EXEC,
+ "display memory words [phys] <addr> [count]");
+ register_command(cmd_ctx, NULL, "mdh",
+ handle_md_command, COMMAND_EXEC,
+ "display memory half-words [phys] <addr> [count]");
+ register_command(cmd_ctx, NULL, "mdb",
+ handle_md_command, COMMAND_EXEC,
+ "display memory bytes [phys] <addr> [count]");
+
+ register_command(cmd_ctx, NULL, "mww",
+ handle_mw_command, COMMAND_EXEC,
+ "write memory word [phys] <addr> <value> [count]");
+ register_command(cmd_ctx, NULL, "mwh",
+ handle_mw_command, COMMAND_EXEC,
+ "write memory half-word [phys] <addr> <value> [count]");
+ register_command(cmd_ctx, NULL, "mwb",
+ handle_mw_command, COMMAND_EXEC,
+ "write memory byte [phys] <addr> <value> [count]");
+
+ register_command(cmd_ctx, NULL, "bp",
+ handle_bp_command, COMMAND_EXEC,
+ "list or set breakpoint [<address> <length> [hw]]");
+ register_command(cmd_ctx, NULL, "rbp",
+ handle_rbp_command, COMMAND_EXEC,
+ "remove breakpoint <address>");
+
+ register_command(cmd_ctx, NULL, "wp",
+ handle_wp_command, COMMAND_EXEC,
+ "list or set watchpoint "
+ "[<address> <length> <r/w/a> [value] [mask]]");
+ register_command(cmd_ctx, NULL, "rwp",
+ handle_rwp_command, COMMAND_EXEC,
+ "remove watchpoint <address>");
+
+ register_command(cmd_ctx, NULL, "load_image",
+ handle_load_image_command, COMMAND_EXEC,
+ "load_image <file> <address> "
+ "['bin'|'ihex'|'elf'|'s19'] [min_address] [max_length]");
+ register_command(cmd_ctx, NULL, "dump_image",
+ handle_dump_image_command, COMMAND_EXEC,
+ "dump_image <file> <address> <size>");
+ register_command(cmd_ctx, NULL, "verify_image",
+ handle_verify_image_command, COMMAND_EXEC,
+ "verify_image <file> [offset] [type]");
+ register_command(cmd_ctx, NULL, "test_image",
+ handle_test_image_command, COMMAND_EXEC,
+ "test_image <file> [offset] [type]");
+
+ return ERROR_OK;
+}