22 static COMMAND_HELPER(flash_command_get_bank_maybe_probe,
unsigned name_index,
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;
822 if (padding_at_end) {
823 memset(ptr,
bank->default_padded_value, padding_at_end);
825 " bytes (bank write end alignment)",
826 end_addr + 1, padding_at_end);
835 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
853 if (CMD_ARGC < 2 || CMD_ARGC > 4)
871 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
882 LOG_ERROR(
"Length of %" PRIu32
" bytes with offset 0x%8.8" PRIx32
917 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
928 uint8_t *buffer_file, *buffer_flash;
935 if (CMD_ARGC < 2 || CMD_ARGC > 3)
952 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
972 LOG_INFO(
"Nothing to compare with flash bank");
978 LOG_INFO(
"File content exceeds flash bank size. Only comparing the "
979 "first %zu bytes of the file",
length);
981 buffer_file = malloc(
length);
1002 buffer_flash = malloc(
length);
1003 if (!buffer_flash) {
1019 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
1023 differ = memcmp(buffer_file, buffer_flash,
length);
1028 for (t = 0; t <
length; t++) {
1029 if (buffer_flash[t] == buffer_file[t])
1031 command_print(
CMD,
"diff %d address 0x%08" PRIx32
". Was 0x%02x instead of 0x%02x",
1032 diffs, t +
offset, buffer_flash[t], buffer_file[t]);
1033 if (diffs++ >= 127) {
1069 command_print(
CMD,
"Default padded value set to 0x%" PRIx8
" for flash bank %u",
1078 .handler = handle_flash_probe_command,
1081 .help =
"Identify a flash bank.",
1085 .handler = handle_flash_info_command,
1087 .usage =
"bank_id ['sectors']",
1088 .help =
"Print information about a flash bank.",
1091 .name =
"erase_check",
1092 .handler = handle_flash_erase_check_command,
1095 .help =
"Check erase state of all blocks in a "
1099 .name =
"erase_sector",
1100 .handler = handle_flash_erase_command,
1102 .usage =
"bank_id first_sector_num (last_sector_num|'last')",
1103 .help =
"Erase a range of sectors in a flash bank.",
1106 .name =
"erase_address",
1107 .handler = handle_flash_erase_address_command,
1109 .usage =
"['pad'] ['unlock'] address length",
1110 .help =
"Erase flash sectors starting at address and "
1111 "continuing for length bytes. If 'pad' is specified, "
1112 "data outside that range may also be erased: the start "
1113 "address may be decreased, and length increased, so "
1114 "that all of the first and last sectors are erased. "
1115 "If 'unlock' is specified, then the flash is unprotected "
1121 .handler = handle_flash_fill_command,
1123 .usage =
"address value n",
1124 .help =
"Fill n double-words with 64-bit value, starting at "
1125 "word address. (No autoerase.)",
1129 .handler = handle_flash_fill_command,
1131 .usage =
"address value n",
1132 .help =
"Fill n words with 32-bit value, starting at "
1133 "word address. (No autoerase.)",
1137 .handler = handle_flash_fill_command,
1139 .usage =
"address value n",
1140 .help =
"Fill n halfwords with 16-bit value, starting at "
1141 "word address. (No autoerase.)",
1145 .handler = handle_flash_fill_command,
1147 .usage =
"address value n",
1148 .help =
"Fill n bytes with 8-bit value, starting at "
1149 "word address. (No autoerase.)",
1153 .handler = handle_flash_md_command,
1155 .usage =
"address [count]",
1156 .help =
"Display bytes from flash.",
1160 .handler = handle_flash_md_command,
1162 .usage =
"address [count]",
1163 .help =
"Display half-words from flash.",
1167 .handler = handle_flash_md_command,
1169 .usage =
"address [count]",
1170 .help =
"Display words from flash.",
1173 .name =
"write_bank",
1174 .handler = handle_flash_write_bank_command,
1176 .usage =
"bank_id filename [offset]",
1177 .help =
"Write binary data from file to flash bank. Allow optional "
1178 "offset from beginning of the bank (defaults to zero).",
1181 .name =
"write_image",
1182 .handler = handle_flash_write_image_command,
1184 .usage =
"[erase] [unlock] filename [offset [file_type]]",
1185 .help =
"Write an image to flash. Optionally first unprotect "
1186 "and/or erase the region to be used. Allow optional "
1187 "offset from beginning of bank (defaults to zero)",
1190 .name =
"verify_image",
1191 .handler = handle_flash_verify_image_command,
1193 .usage =
"filename [offset [file_type]]",
1194 .help =
"Verify an image against flash. Allow optional "
1195 "offset from beginning of bank (defaults to zero)",
1198 .name =
"read_bank",
1199 .handler = handle_flash_read_bank_command,
1201 .usage =
"bank_id filename [offset [length]]",
1202 .help =
"Read binary data from flash bank to file. Allow optional "
1203 "offset from beginning of the bank (defaults to zero).",
1206 .name =
"verify_bank",
1207 .handler = handle_flash_verify_bank_command,
1209 .usage =
"bank_id filename [offset]",
1210 .help =
"Compare the contents of a file with the contents of the "
1211 "flash bank. Allow optional offset from beginning of the bank "
1212 "(defaults to zero).",
1216 .handler = handle_flash_protect_command,
1218 .usage =
"bank_id first_block [last_block|'last'] "
1220 .help =
"Turn protection on or off for a range of protection "
1221 "blocks or sectors in a given flash bank. "
1222 "See 'flash info' output for a list of blocks.",
1225 .name =
"padded_value",
1226 .handler = handle_flash_padded_value_command,
1228 .usage =
"bank_id value",
1229 .help =
"Set default flash padded value",
1245 LOG_ERROR(
"usage: flash bank <name> <driver> "
1246 "<base> <size> <chip_width> <bus_width> <target>");
1250 const char *bank_name = *
CMD_ARGV++;
1259 const char *driver_name =
CMD_ARGV[0];
1263 LOG_ERROR(
"flash driver '%s' not found", driver_name);
1270 LOG_ERROR(
"flash bank name '%s' already exists", bank_name);
1278 LOG_ERROR(
"couldn't register '%s' commands",
1284 struct flash_bank *c = calloc(1,
sizeof(*c));
1285 c->
name = strdup(bank_name);
1305 LOG_DEBUG(
"'%s' driver usage field missing", driver_name);
1320 "buswidth %u, chipwidth %u", p->bank_number,
1321 p->name, p->driver->name, p->base, p->size,
1322 p->bus_width, p->chip_width);
1330 Jim_WrongNumArgs(interp, 1, argv,
1331 "no arguments to 'flash list' command");
1335 Jim_Obj *list = Jim_NewListObj(interp,
NULL, 0);
1338 Jim_Obj *elem = Jim_NewListObj(interp,
NULL, 0);
1340 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
"name", -1));
1341 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->name, -1));
1342 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
"driver", -1));
1343 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));
1344 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
"base", -1));
1345 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));
1346 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
"size", -1));
1347 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));
1348 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
"bus_width", -1));
1349 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));
1350 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
"chip_width", -1));
1351 Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
1352 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
"target", -1));
1353 Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp,
target_name(p->target), -1));
1355 Jim_ListAppendElement(interp, list, elem);
1358 Jim_SetResult(interp, list);
1368 static bool flash_initialized;
1369 if (flash_initialized) {
1370 LOG_INFO(
"'flash init' has already been called");
1373 flash_initialized =
true;
1375 LOG_DEBUG(
"Initializing flash devices...");
1382 .handler = handle_flash_bank_command,
1384 .usage =
"bank_id driver_name base_address size_bytes "
1385 "chip_width_bytes bus_width_bytes target "
1386 "[driver_options ...]",
1387 .help =
"Define a new bank with the given name, "
1388 "using the specified NOR flash driver.",
1393 .handler = handle_flash_init_command,
1394 .help =
"Initialize flash devices.",
1400 .handler = handle_flash_banks_command,
1401 .help =
"Display table with information about flash banks.",
1408 .help =
"Returns a list of details about the flash banks.",
1416 .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.
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)
static COMMAND_HELPER(flash_command_get_bank_maybe_probe, unsigned name_index, struct flash_bank **bank, bool do_probe)
int flash_register_commands(struct command_context *cmd_ctx)
Registers the 'flash' subsystem commands.
static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
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_s::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_handle_md_output(struct command_invocation *cmd, struct target *target, target_addr_t address, unsigned size, unsigned count, const uint8_t *buffer)
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)
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(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)