+
+
+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;
+
+ duration_t duration;
+ char *duration_text;
+
+ int retval = parse_load_image_command_args(args, argc,
+ &image, &min_address, &max_address);
+ if (ERROR_OK != retval)
+ return retval;
+
+ duration_start_measure(&duration);
+
+ 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 byte written at address 0x%8.8x",
+ (unsigned int)length,
+ ((unsigned int)(image.sections[i].base_address + offset)));
+ }
+
+ free(buffer);
+ }
+
+ duration_stop_measure(&duration, &duration_text);
+ if (retval == ERROR_OK)
+ {
+ command_print(cmd_ctx, "Loaded %u bytes in %s", (unsigned int)image_size, duration_text);
+ command_print(cmd_ctx, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
+ }
+ free(duration_text);
+
+ 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;
+}
+
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */