22 COMMAND_HELPER(flash_command_get_bank_probe_optional,
unsigned int name_index,
39 unsigned int bank_num;
55 name_index,
bank,
true);
63 bool show_sectors =
false;
64 bool prot_block_available;
66 if (CMD_ARGC < 1 || CMD_ARGC > 2)
70 if (strcmp(
"sectors",
CMD_ARGV[1]) == 0)
100 LOG_INFO(
"Flash protection check is not implemented.");
104 ", buswidth %u, chipwidth %u",
113 if (!show_sectors && prot_block_available) {
121 for (j = 0; j < num_blocks; j++) {
122 char *protect_state =
"";
125 protect_state =
"not protected";
127 protect_state =
"protected";
128 else if (!show_sectors || !prot_block_available)
129 protect_state =
"protection state unknown";
132 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIu32
"kB) %s",
136 block_array[j].
size >> 10,
145 LOG_ERROR(
"error retrieving flash info");
195 "unknown error when checking erase state of flash bank #%s at "
201 for (
unsigned int j = 0; j < p->
num_sectors; j++) {
205 erase_state =
"not erased";
209 erase_state =
"erase state unknown";
213 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIu32
"kB) %s",
233 bool do_unlock =
false;
241 if (strcmp(
"pad",
CMD_ARGV[0]) == 0)
243 else if (strcmp(
"unlock",
CMD_ARGV[0]) == 0)
280 " in %fs (%0.3f KiB/s)", address,
length,
303 if (strcmp(
CMD_ARGV[2],
"last") == 0)
308 if (!(first <= last)) {
310 "first sector must be <= last");
316 "last sector must be <= %u",
328 "through %" PRIu32
" on flash bank %u "
357 if (strcmp(
CMD_ARGV[2],
"last") == 0)
358 last = num_blocks - 1;
365 if (!(first <= last)) {
367 "first %s must be <= last",
372 if (!(last <= (uint32_t)(num_blocks - 1))) {
374 "last %s must be <= %d",
383 " through %" PRIu32
" on flash bank %d",
384 (set) ?
"set" :
"cleared",
403 bool auto_unlock =
false;
406 if (strcmp(
CMD_ARGV[0],
"erase") == 0) {
411 }
else if (strcmp(
CMD_ARGV[0],
"unlock") == 0) {
446 auto_unlock,
true,
false);
454 "in %fs (%0.3f KiB/s)", written,
CMD_ARGV[0],
506 "in %fs (%0.3f KiB/s)", verified,
CMD_ARGV[0],
554 if ((wordsize <
sizeof(pattern)) && (pattern >> (8 * wordsize) != 0)) {
555 command_print(
CMD,
"Fill pattern 0x%" PRIx64
" does not fit within %" PRIu32
"-byte word", pattern, wordsize);
563 LOG_ERROR(
"Cannot cross flash bank borders");
567 uint32_t size_bytes =
count * wordsize;
571 uint32_t aligned_size = aligned_end + 1 - aligned_start;
572 uint32_t padding_at_start = address - aligned_start;
573 uint32_t padding_at_end = aligned_end - end_addr;
575 uint8_t *
buffer = malloc(aligned_size);
579 if (padding_at_start) {
580 memset(
buffer,
bank->default_padded_value, padding_at_start);
582 " breaks the required alignment of flash bank %s",
583 address,
bank->name);
585 padding_at_start, aligned_start);
588 uint8_t *ptr =
buffer + padding_at_start;
592 for (i = 0; i <
count; i++, ptr += wordsize)
596 for (i = 0; i <
count; i++, ptr += wordsize)
600 for (i = 0; i <
count; i++, ptr += wordsize)
604 memset(ptr, pattern,
count);
612 if (padding_at_end) {
613 memset(ptr,
bank->default_padded_value, padding_at_end);
615 " bytes (bank write end alignment)",
616 end_addr + 1, padding_at_end);
631 uint64_t readback = 0;
647 if (readback != pattern) {
650 ", read back 0x%02" PRIx64
", expected 0x%02" PRIx64,
651 address + i * wordsize, readback, pattern);
660 " in %fs (%0.3f KiB/s)", size_bytes, address,
674 if (CMD_ARGC < 1 || CMD_ARGC > 2)
684 unsigned int wordsize;
709 uint32_t sizebytes =
count * wordsize;
738 if (CMD_ARGC < 2 || CMD_ARGC > 3)
755 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
773 LOG_INFO(
"Nothing to write to flash bank");
779 LOG_INFO(
"File content exceeds flash bank size. Only writing the "
780 "first %zu bytes of the file",
length);
786 uint32_t aligned_size = aligned_end + 1 - aligned_start;
787 uint32_t padding_at_start = start_addr - aligned_start;
788 uint32_t padding_at_end = aligned_end - end_addr;
790 buffer = malloc(aligned_size);
797 if (padding_at_start) {
798 memset(
buffer,
bank->default_padded_value, padding_at_start);
800 " breaks the required alignment of flash bank %s",
803 padding_at_start, aligned_start);
806 uint8_t *ptr =
buffer + padding_at_start;
823 if (padding_at_end) {
824 memset(ptr,
bank->default_padded_value, padding_at_end);
826 " bytes (bank write end alignment)",
827 end_addr + 1, padding_at_end);
836 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
854 if (CMD_ARGC < 2 || CMD_ARGC > 4)
872 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
883 LOG_ERROR(
"Length of %" PRIu32
" bytes with offset 0x%8.8" PRIx32
918 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
929 uint8_t *buffer_file, *buffer_flash;
936 if (CMD_ARGC < 2 || CMD_ARGC > 3)
953 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
973 LOG_INFO(
"Nothing to compare with flash bank");
979 LOG_INFO(
"File content exceeds flash bank size. Only comparing the "
980 "first %zu bytes of the file",
length);
982 buffer_file = malloc(
length);
1003 buffer_flash = malloc(
length);
1004 if (!buffer_flash) {
1020 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
1024 differ = memcmp(buffer_file, buffer_flash,
length);
1029 for (t = 0; t <
length; t++) {
1030 if (buffer_flash[t] == buffer_file[t])
1032 command_print(
CMD,
"diff %d address 0x%08" PRIx32
". Was 0x%02x instead of 0x%02x",
1033 diffs, t +
offset, buffer_flash[t], buffer_file[t]);
1034 if (diffs++ >= 127) {
1070 command_print(
CMD,
"Default padded value set to 0x%" PRIx8
" for flash bank %u",
1079 .handler = handle_flash_probe_command,
1082 .help =
"Identify a flash bank.",
1086 .handler = handle_flash_info_command,
1088 .usage =
"bank_id ['sectors']",
1089 .help =
"Print information about a flash bank.",
1092 .name =
"erase_check",
1093 .handler = handle_flash_erase_check_command,
1096 .help =
"Check erase state of all blocks in a "
1100 .name =
"erase_sector",
1101 .handler = handle_flash_erase_command,
1103 .usage =
"bank_id first_sector_num (last_sector_num|'last')",
1104 .help =
"Erase a range of sectors in a flash bank.",
1107 .name =
"erase_address",
1108 .handler = handle_flash_erase_address_command,
1110 .usage =
"['pad'] ['unlock'] address length",
1111 .help =
"Erase flash sectors starting at address and "
1112 "continuing for length bytes. If 'pad' is specified, "
1113 "data outside that range may also be erased: the start "
1114 "address may be decreased, and length increased, so "
1115 "that all of the first and last sectors are erased. "
1116 "If 'unlock' is specified, then the flash is unprotected "
1122 .handler = handle_flash_fill_command,
1124 .usage =
"address value n",
1125 .help =
"Fill n double-words with 64-bit value, starting at "
1126 "word address. (No autoerase.)",
1130 .handler = handle_flash_fill_command,
1132 .usage =
"address value n",
1133 .help =
"Fill n words with 32-bit value, starting at "
1134 "word address. (No autoerase.)",
1138 .handler = handle_flash_fill_command,
1140 .usage =
"address value n",
1141 .help =
"Fill n halfwords with 16-bit value, starting at "
1142 "word address. (No autoerase.)",
1146 .handler = handle_flash_fill_command,
1148 .usage =
"address value n",
1149 .help =
"Fill n bytes with 8-bit value, starting at "
1150 "word address. (No autoerase.)",
1154 .handler = handle_flash_md_command,
1156 .usage =
"address [count]",
1157 .help =
"Display bytes from flash.",
1161 .handler = handle_flash_md_command,
1163 .usage =
"address [count]",
1164 .help =
"Display half-words from flash.",
1168 .handler = handle_flash_md_command,
1170 .usage =
"address [count]",
1171 .help =
"Display words from flash.",
1174 .name =
"write_bank",
1175 .handler = handle_flash_write_bank_command,
1177 .usage =
"bank_id filename [offset]",
1178 .help =
"Write binary data from file to flash bank. Allow optional "
1179 "offset from beginning of the bank (defaults to zero).",
1182 .name =
"write_image",
1183 .handler = handle_flash_write_image_command,
1185 .usage =
"[erase] [unlock] filename [offset [file_type]]",
1186 .help =
"Write an image to flash. Optionally first unprotect "
1187 "and/or erase the region to be used. Allow optional "
1188 "offset from beginning of bank (defaults to zero)",
1191 .name =
"verify_image",
1192 .handler = handle_flash_verify_image_command,
1194 .usage =
"filename [offset [file_type]]",
1195 .help =
"Verify an image against flash. Allow optional "
1196 "offset from beginning of bank (defaults to zero)",
1199 .name =
"read_bank",
1200 .handler = handle_flash_read_bank_command,
1202 .usage =
"bank_id filename [offset [length]]",
1203 .help =
"Read binary data from flash bank to file. Allow optional "
1204 "offset from beginning of the bank (defaults to zero).",
1207 .name =
"verify_bank",
1208 .handler = handle_flash_verify_bank_command,
1210 .usage =
"bank_id filename [offset]",
1211 .help =
"Compare the contents of a file with the contents of the "
1212 "flash bank. Allow optional offset from beginning of the bank "
1213 "(defaults to zero).",
1217 .handler = handle_flash_protect_command,
1219 .usage =
"bank_id first_block [last_block|'last'] "
1221 .help =
"Turn protection on or off for a range of protection "
1222 "blocks or sectors in a given flash bank. "
1223 "See 'flash info' output for a list of blocks.",
1226 .name =
"padded_value",
1227 .handler = handle_flash_padded_value_command,
1229 .usage =
"bank_id value",
1230 .help =
"Set default flash padded value",
1246 LOG_ERROR(
"usage: flash bank <name> <driver> "
1247 "<base> <size> <chip_width> <bus_width> <target>");
1251 const char *bank_name = *
CMD_ARGV++;
1260 const char *driver_name =
CMD_ARGV[0];
1264 LOG_ERROR(
"flash driver '%s' not found", driver_name);
1271 LOG_ERROR(
"flash bank name '%s' already exists", bank_name);
1279 LOG_ERROR(
"couldn't register '%s' commands",
1285 struct flash_bank *c = calloc(1,
sizeof(*c));
1286 c->
name = strdup(bank_name);
1307 LOG_DEBUG(
"'%s' driver usage field missing", driver_name);
1322 "buswidth %u, chipwidth %u", p->bank_number,
1323 p->name, p->driver->name, p->base, p->size,
1324 p->bus_width, p->chip_width);
1340 " size 0x%" PRIx32
"\n"
1345 p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width,
1357 static bool flash_initialized;
1358 if (flash_initialized) {
1359 LOG_INFO(
"'flash init' has already been called");
1362 flash_initialized =
true;
1364 LOG_DEBUG(
"Initializing flash devices...");
1371 .handler = handle_flash_bank_command,
1373 .usage =
"bank_id driver_name base_address size_bytes "
1374 "chip_width_bytes bus_width_bytes target "
1375 "[driver_options ...]",
1376 .help =
"Define a new bank with the given name, "
1377 "using the specified NOR flash driver.",
1382 .handler = handle_flash_init_command,
1383 .help =
"Initialize flash devices.",
1389 .handler = handle_flash_banks_command,
1390 .help =
"Display table with information about flash banks.",
1396 .handler = handle_flash_list,
1397 .help =
"Returns a list of details about the flash banks.",
1406 .help =
"NOR flash command group",
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_NAME
Use this macro to access the name of the command being handled, rather than accessing the variable di...
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define COMMAND_PARSE_ADDRESS(in, out)
#define COMMAND_PARSE_ON_OFF(in, out)
parses an on/off command argument
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_COMMAND_ARGUMENT_INVALID
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
#define ERROR_FLASH_OPER_UNSUPPORTED
target_addr_t flash_write_align_start(struct flash_bank *bank, target_addr_t addr)
Get aligned start address of a flash write region.
int flash_driver_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
struct flash_bank * get_flash_bank_by_name_noprobe(const char *name)
Returns the flash bank specified by name, which matches the driver name and a suffix (option) specify...
target_addr_t flash_write_align_end(struct flash_bank *bank, target_addr_t addr)
Get aligned end address of a flash write region.
int flash_driver_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
int flash_driver_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
void flash_bank_add(struct flash_bank *bank)
Adds a new NOR bank to the global list of banks.
int flash_unlock_address_range(struct target *target, target_addr_t addr, uint32_t length)
struct flash_bank * get_flash_bank_by_num_noprobe(unsigned int num)
Returns the flash bank like get_flash_bank_by_num(), without probing.
int get_flash_bank_by_addr(struct target *target, target_addr_t addr, bool check, struct flash_bank **result_bank)
Returns the flash bank located at a specified address.
int flash_erase_address_range(struct target *target, bool pad, target_addr_t addr, uint32_t length)
Erases length bytes in the target flash, starting at addr.
int flash_driver_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result)
Returns the flash bank specified by name, which matches the driver name and a suffix (option) specify...
struct flash_bank * flash_bank_list(void)
int get_flash_bank_by_num(unsigned int num, struct flash_bank **bank)
Returns the flash bank like get_flash_bank_by_name(), without probing.
int flash_write_unlock_verify(struct target *target, struct image *image, uint32_t *written, bool erase, bool unlock, bool write, bool verify)
static const struct command_registration flash_config_command_handlers[]
static const struct command_registration flash_command_handlers[]
void flash_set_dirty(void)
Forces targets to re-examine their erase/protection state.
COMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index, struct flash_bank **bank, bool do_probe)
Retrieves bank from a command argument, reporting errors parsing the bank identifier or retrieving th...
static const struct command_registration flash_exec_command_handlers[]
static int flash_init_drivers(struct command_context *cmd_ctx)
COMMAND_HANDLER(handle_flash_info_command)
int flash_register_commands(struct command_context *cmd_ctx)
Registers the 'flash' subsystem commands.
int fileio_write(struct fileio *fileio, size_t size, const void *buffer, size_t *size_written)
int fileio_read(struct fileio *fileio, size_t size, void *buffer, size_t *size_read)
int fileio_close(struct fileio *fileio)
int fileio_size(struct fileio *fileio, size_t *size)
FIX!!!!
int fileio_open(struct fileio **fileio, const char *url, enum fileio_access access_type, enum fileio_type type)
void image_close(struct image *image)
int image_open(struct image *image, const char *url, const char *type_string)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
#define FLASH_WRITE_GAP_SECTOR
const struct flash_driver * flash_driver_find_by_name(const char *name)
Find a NOR flash driver by its name.
size_t size
Size of the control block search area.
const char * usage
a string listing the options and arguments, required or optional
Provides details of a flash bank, available either on-chip or through a major interface.
unsigned int num_prot_blocks
The number of protection blocks in this bank.
struct flash_sector * sectors
Array of sectors, allocated and initialized by the flash driver.
uint8_t default_padded_value
Default padded value used, normally this matches the flash erased value.
const struct flash_driver * driver
Driver for this bank.
unsigned int chip_width
Width of the chip in bytes (1,2,4 bytes)
target_addr_t base
The base address of this bank.
uint32_t size
The size of this chip bank, in bytes.
unsigned int num_sectors
The number of sectors on this chip.
struct flash_sector * prot_blocks
Array of protection blocks, allocated and initialized by the flash driver.
unsigned int bus_width
Maximum bus width, in bytes (1,2,4 bytes)
struct flash_bank * next
The next flash bank on this chip.
struct target * target
Target to which this bank belongs.
uint32_t minimal_write_gap
Minimal gap between sections to discontinue flash write Default FLASH_WRITE_GAP_SECTOR splits the wri...
uint8_t erased_value
Erased value.
unsigned int bank_number
The 'bank' (or chip number) of this instance.
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
const struct command_registration * commands
An array of driver-specific commands to register.
int(* auto_probe)(struct flash_bank *bank)
A more gentle flavor of flash_driver::probe, performing setup with less noise.
const char * usage
Gives a human-readable description of arguments.
int(* erase_check)(struct flash_bank *bank)
Check the erasure status of a flash bank.
int(* info)(struct flash_bank *bank, struct command_invocation *cmd)
Display human-readable information about the flash bank.
int(* probe)(struct flash_bank *bank)
Probe to determine what kind of flash is present.
int(* protect_check)(struct flash_bank *bank)
Determine if the specific bank is "protected" or not.
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Describes the geometry and status of a single flash sector within a flash bank.
int is_erased
Indication of erasure status: 0 = not erased, 1 = erased, other = unknown.
uint32_t offset
Bus offset from start of the flash chip (in bytes).
int is_protected
Indication of protection status: 0 = unprotected/unlocked, 1 = protected/locked, other = unknown.
uint32_t size
Number of bytes in this flash sector.
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer)
struct target * get_target(const char *id)
void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value)
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
void target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value)
uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)
void target_handle_md_output(struct command_invocation *cmd, struct target *target, target_addr_t address, unsigned int size, unsigned int count, const uint8_t *buffer)
struct target * get_current_target(struct command_context *cmd_ctx)
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
static const char * target_name(const struct target *target)
Returns the instance-specific name of the specified target.
float duration_elapsed(const struct duration *duration)
int duration_measure(struct duration *duration)
Update the duration->elapsed field to finish the duration measurement.
int duration_start(struct duration *duration)
Update the duration->start field to start the duration measurement.
float duration_kbps(const struct duration *duration, size_t count)