+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if ((retval = flash_check_sector_parameters(cmd_ctx,
+ first, last, p->num_sectors)) != ERROR_OK)
+ return retval;
+
+ 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", (int) first,
+ (int) last, (int) bank_nr);
+ }
+ }
+ 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;
+ uint32_t 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;
+ }
+
+ float speed;
+
+ speed = written / 1024.0;
+ speed /= ((float)duration.duration.tv_sec
+ + ((float)duration.duration.tv_usec / 1000000.0));
+ command_print(cmd_ctx,
+ "wrote %" PRIu32 " byte from file %s in %s (%f kb/s)",
+ written, args[0], duration_text, speed);
+
+ 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;
+ uint32_t address;
+ uint32_t pattern;
+ uint32_t count;
+ uint8_t chunk[1024];
+ uint8_t readback[1024];
+ uint32_t wrote = 0;
+ uint32_t cur_size = 0;
+ uint32_t chunk_count;
+ char *duration_text;
+ duration_t duration;
+ target_t *target = get_current_target(cmd_ctx);
+ uint32_t i;
+ uint32_t 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++)