+
+ return ERROR_OK;
+}
+
+int default_flash_blank_check(struct flash_bank_s *bank)
+{
+ struct target *target = bank->target;
+ int i;
+ int retval;
+ int fast_check = 0;
+ uint32_t blank;
+
+ if (bank->target->state != TARGET_HALTED)
+ {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ for (i = 0; i < bank->num_sectors; i++)
+ {
+ uint32_t address = bank->base + bank->sectors[i].offset;
+ uint32_t size = bank->sectors[i].size;
+
+ if ((retval = target_blank_check_memory(target, address, size, &blank)) != ERROR_OK)
+ {
+ fast_check = 0;
+ break;
+ }
+ if (blank == 0xFF)
+ bank->sectors[i].is_erased = 1;
+ else
+ bank->sectors[i].is_erased = 0;
+ fast_check = 1;
+ }
+
+ if (!fast_check)
+ {
+ LOG_USER("Running slow fallback erase check - add working memory");
+ return default_flash_mem_blank_check(bank);
+ }
+
+ return ERROR_OK;
+}
+
+int flash_init_drivers(struct command_context_s *cmd_ctx)
+{
+ register_jim(cmd_ctx, "ocd_flash_banks",
+ jim_flash_banks, "return information about the flash banks");
+
+ if (!flash_banks)
+ return ERROR_OK;
+
+ register_command(cmd_ctx, flash_cmd, "info",
+ handle_flash_info_command, COMMAND_EXEC,
+ "print info about flash bank <num>");
+ register_command(cmd_ctx, flash_cmd, "probe",
+ handle_flash_probe_command, COMMAND_EXEC,
+ "identify flash bank <num>");
+ register_command(cmd_ctx, flash_cmd, "erase_check",
+ handle_flash_erase_check_command, COMMAND_EXEC,
+ "check erase state of sectors in flash bank <num>");
+ register_command(cmd_ctx, flash_cmd, "protect_check",
+ handle_flash_protect_check_command, COMMAND_EXEC,
+ "check protection state of sectors in flash bank <num>");
+ register_command(cmd_ctx, flash_cmd, "erase_sector",
+ handle_flash_erase_command, COMMAND_EXEC,
+ "erase sectors at <bank> <first> <last>");
+ register_command(cmd_ctx, flash_cmd, "erase_address",
+ handle_flash_erase_address_command, COMMAND_EXEC,
+ "erase address range <address> <length>");
+
+ register_command(cmd_ctx, flash_cmd, "fillw",
+ handle_flash_fill_command, COMMAND_EXEC,
+ "fill with pattern (no autoerase) <address> <word_pattern> <count>");
+ register_command(cmd_ctx, flash_cmd, "fillh",
+ handle_flash_fill_command, COMMAND_EXEC,
+ "fill with pattern <address> <halfword_pattern> <count>");
+ register_command(cmd_ctx, flash_cmd, "fillb",
+ handle_flash_fill_command, COMMAND_EXEC,
+ "fill with pattern <address> <byte_pattern> <count>");
+
+ register_command(cmd_ctx, flash_cmd, "write_bank",
+ handle_flash_write_bank_command, COMMAND_EXEC,
+ "write binary data to <bank> <file> <offset>");
+ register_command(cmd_ctx, flash_cmd, "write_image",
+ handle_flash_write_image_command, COMMAND_EXEC,
+ "write_image [erase] [unlock] <file> [offset] [type]");
+ register_command(cmd_ctx, flash_cmd, "protect",
+ handle_flash_protect_command, COMMAND_EXEC,
+ "set protection of sectors at <bank> <first> <last> <on | off>");
+
+ return ERROR_OK;
+}
+
+int flash_register_commands(struct command_context_s *cmd_ctx)
+{
+ flash_cmd = register_command(cmd_ctx, NULL, "flash",
+ NULL, COMMAND_ANY, NULL);
+
+ register_command(cmd_ctx, flash_cmd, "bank",
+ handle_flash_bank_command, COMMAND_CONFIG,
+ "flash bank <driver> <base> <size> "
+ "<chip_width> <bus_width> <target> [driver_options ...]");