+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ retval = flash_driver_protect(p, set, first, last);
+ if (retval == ERROR_OK)
+ {
+ command_print(cmd_ctx, "%s protection for sectors %i through %i on flash bank %i", (set) ? "set" : "cleared", first, last, strtoul(args[0], 0, 0));
+ }
+ }
+ else
+ {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ }
+
+ return ERROR_OK;
+}
+
+static int handle_flash_write_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ target_t *target = get_current_target(cmd_ctx);
+
+ image_t image;
+ u32 written;
+
+ duration_t duration;
+ char *duration_text;
+
+ int retval, retvaltemp;
+
+ if (argc < 1)
+ {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ /* flash auto-erase is disabled by default*/
+ int auto_erase = 0;
+
+ if (strcmp(args[0], "erase")==0)
+ {
+ auto_erase = 1;
+ args++;
+ argc--;
+ command_print(cmd_ctx, "auto erase enabled");
+ }
+
+ if (argc < 1)
+ {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ if (!target)
+ {
+ LOG_ERROR("no target selected");
+ return ERROR_FAIL;
+ }
+
+ duration_start_measure(&duration);
+
+ if (argc >= 2)
+ {
+ image.base_address_set = 1;
+ image.base_address = strtoul(args[1], NULL, 0);
+ }
+ else
+ {
+ image.base_address_set = 0;
+ image.base_address = 0x0;
+ }
+
+ image.start_address_set = 0;
+
+ retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL);
+ if (retval != ERROR_OK)
+ {
+ return retval;
+ }
+
+ retval = flash_write(target, &image, &written, auto_erase);
+ if (retval != ERROR_OK)
+ {
+ image_close(&image);
+ return retval;
+ }
+
+ if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
+ {
+ image_close(&image);
+ return retvaltemp;
+ }
+ if (retval == ERROR_OK)
+ {
+ command_print(cmd_ctx, "wrote %u byte from file %s in %s (%f kb/s)",
+ written, args[0], duration_text,
+ (float)written / 1024.0 / ((float)duration.duration.tv_sec + ((float)duration.duration.tv_usec / 1000000.0)));
+ }
+ free(duration_text);
+
+ image_close(&image);
+
+ return retval;
+}
+
+static int handle_flash_fill_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ int err = ERROR_OK, retval;
+ u32 address;
+ u32 pattern;
+ u32 count;
+ u8 chunk[1024];
+ u8 readback[1024];
+ u32 wrote = 0;
+ u32 cur_size = 0;
+ u32 chunk_count;
+ char *duration_text;
+ duration_t duration;
+ target_t *target = get_current_target(cmd_ctx);
+ u32 i;
+ u32 wordsize;
+
+ if (argc != 3)
+ {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ address = strtoul(args[0], NULL, 0);
+ pattern = strtoul(args[1], NULL, 0);
+ count = strtoul(args[2], NULL, 0);
+
+ if(count == 0)
+ return ERROR_OK;
+
+ switch(cmd[4])
+ {
+ case 'w':
+ wordsize=4;
+ break;
+ case 'h':
+ wordsize=2;
+ break;
+ case 'b':
+ wordsize=1;
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ chunk_count = MIN(count, (1024 / wordsize));
+ switch(wordsize)
+ {
+ case 4:
+ for(i = 0; i < chunk_count; i++)
+ {
+ target_buffer_set_u32(target, chunk + i * wordsize, pattern);
+ }
+ break;
+ case 2:
+ for(i = 0; i < chunk_count; i++)
+ {
+ target_buffer_set_u16(target, chunk + i * wordsize, pattern);