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)
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)) {
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",
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)
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;
650 ", read back 0x%02" PRIx64
", expected 0x%02" PRIx64,
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;
746 unsigned int width_bits;
753 switch (width_bits) {
769 const unsigned int width = width_bits / 8;
785 uint32_t sizebytes =
count * width_bits;
799 char *separator =
"";
802 const size_t chunk_len =
MIN(
count, max_chunk_len);
808 addr, width_bits, chunk_len);
818 for (
size_t i = 0; i < chunk_len ; i++) {
856 if (CMD_ARGC < 2 || CMD_ARGC > 3)
873 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
891 LOG_INFO(
"Nothing to write to flash bank");
897 LOG_INFO(
"File content exceeds flash bank size. Only writing the "
898 "first %zu bytes of the file",
length);
904 uint32_t aligned_size = aligned_end + 1 - aligned_start;
905 uint32_t padding_at_start = start_addr - aligned_start;
906 uint32_t padding_at_end = aligned_end - end_addr;
908 buffer = malloc(aligned_size);
915 if (padding_at_start) {
916 memset(
buffer,
bank->default_padded_value, padding_at_start);
918 " breaks the required alignment of flash bank %s",
921 padding_at_start, aligned_start);
924 uint8_t *ptr =
buffer + padding_at_start;
941 if (padding_at_end) {
942 memset(ptr,
bank->default_padded_value, padding_at_end);
944 " bytes (bank write end alignment)",
945 end_addr + 1, padding_at_end);
954 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
972 if (CMD_ARGC < 2 || CMD_ARGC > 4)
990 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
1001 LOG_ERROR(
"Length of %" PRIu32
" bytes with offset 0x%8.8" PRIx32
1036 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
1047 uint8_t *buffer_file, *buffer_flash;
1054 if (CMD_ARGC < 2 || CMD_ARGC > 3)
1071 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
1091 LOG_INFO(
"Nothing to compare with flash bank");
1097 LOG_INFO(
"File content exceeds flash bank size. Only comparing the "
1098 "first %zu bytes of the file",
length);
1100 buffer_file = malloc(
length);
1115 if (read_cnt !=
length) {
1121 buffer_flash = malloc(
length);
1122 if (!buffer_flash) {
1138 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
1142 differ = memcmp(buffer_file, buffer_flash,
length);
1147 for (t = 0; t <
length; t++) {
1148 if (buffer_flash[t] == buffer_file[t])
1150 command_print(
CMD,
"diff %d address 0x%08" PRIx32
". Was 0x%02x instead of 0x%02x",
1151 diffs, t +
offset, buffer_flash[t], buffer_file[t]);
1152 if (diffs++ >= 127) {
1188 command_print(
CMD,
"Default padded value set to 0x%" PRIx8
" for flash bank %u",
1197 .handler = handle_flash_probe_command,
1200 .help =
"Identify a flash bank.",
1204 .handler = handle_flash_info_command,
1206 .usage =
"bank_id ['sectors']",
1207 .help =
"Print information about a flash bank.",
1210 .name =
"erase_check",
1211 .handler = handle_flash_erase_check_command,
1214 .help =
"Check erase state of all blocks in a "
1218 .name =
"erase_sector",
1219 .handler = handle_flash_erase_command,
1221 .usage =
"bank_id first_sector_num (last_sector_num|'last')",
1222 .help =
"Erase a range of sectors in a flash bank.",
1225 .name =
"erase_address",
1226 .handler = handle_flash_erase_address_command,
1228 .usage =
"['pad'] ['unlock'] address length",
1229 .help =
"Erase flash sectors starting at address and "
1230 "continuing for length bytes. If 'pad' is specified, "
1231 "data outside that range may also be erased: the start "
1232 "address may be decreased, and length increased, so "
1233 "that all of the first and last sectors are erased. "
1234 "If 'unlock' is specified, then the flash is unprotected "
1240 .handler = handle_flash_fill_command,
1242 .usage =
"address value n",
1243 .help =
"Fill n double-words with 64-bit value, starting at "
1244 "word address. (No autoerase.)",
1248 .handler = handle_flash_fill_command,
1250 .usage =
"address value n",
1251 .help =
"Fill n words with 32-bit value, starting at "
1252 "word address. (No autoerase.)",
1256 .handler = handle_flash_fill_command,
1258 .usage =
"address value n",
1259 .help =
"Fill n halfwords with 16-bit value, starting at "
1260 "word address. (No autoerase.)",
1264 .handler = handle_flash_fill_command,
1266 .usage =
"address value n",
1267 .help =
"Fill n bytes with 8-bit value, starting at "
1268 "word address. (No autoerase.)",
1272 .handler = handle_flash_md_command,
1274 .usage =
"address [count]",
1275 .help =
"Display bytes from flash.",
1279 .handler = handle_flash_md_command,
1281 .usage =
"address [count]",
1282 .help =
"Display half-words from flash.",
1286 .handler = handle_flash_md_command,
1288 .usage =
"address [count]",
1289 .help =
"Display words from flash.",
1292 .name =
"read_memory",
1294 .handler = handle_flash_read_memory_command,
1295 .help =
"Read Tcl list of 8/16/32/64 bit numbers from flash memory",
1296 .usage =
"address width count",
1299 .name =
"write_bank",
1300 .handler = handle_flash_write_bank_command,
1302 .usage =
"bank_id filename [offset]",
1303 .help =
"Write binary data from file to flash bank. Allow optional "
1304 "offset from beginning of the bank (defaults to zero).",
1307 .name =
"write_image",
1308 .handler = handle_flash_write_image_command,
1310 .usage =
"[erase] [unlock] filename [offset [file_type]]",
1311 .help =
"Write an image to flash. Optionally first unprotect "
1312 "and/or erase the region to be used. Allow optional "
1313 "offset from beginning of bank (defaults to zero)",
1316 .name =
"verify_image",
1317 .handler = handle_flash_verify_image_command,
1319 .usage =
"filename [offset [file_type]]",
1320 .help =
"Verify an image against flash. Allow optional "
1321 "offset from beginning of bank (defaults to zero)",
1324 .name =
"read_bank",
1325 .handler = handle_flash_read_bank_command,
1327 .usage =
"bank_id filename [offset [length]]",
1328 .help =
"Read binary data from flash bank to file. Allow optional "
1329 "offset from beginning of the bank (defaults to zero).",
1332 .name =
"verify_bank",
1333 .handler = handle_flash_verify_bank_command,
1335 .usage =
"bank_id filename [offset]",
1336 .help =
"Compare the contents of a file with the contents of the "
1337 "flash bank. Allow optional offset from beginning of the bank "
1338 "(defaults to zero).",
1342 .handler = handle_flash_protect_command,
1344 .usage =
"bank_id first_block [last_block|'last'] "
1346 .help =
"Turn protection on or off for a range of protection "
1347 "blocks or sectors in a given flash bank. "
1348 "See 'flash info' output for a list of blocks.",
1351 .name =
"padded_value",
1352 .handler = handle_flash_padded_value_command,
1354 .usage =
"bank_id value",
1355 .help =
"Set default flash padded value",
1371 LOG_ERROR(
"usage: flash bank <name> <driver> "
1372 "<base> <size> <chip_width> <bus_width> <target>");
1376 const char *bank_name = *
CMD_ARGV++;
1385 const char *driver_name =
CMD_ARGV[0];
1389 LOG_ERROR(
"flash driver '%s' not found", driver_name);
1396 LOG_ERROR(
"flash bank name '%s' already exists", bank_name);
1404 LOG_ERROR(
"couldn't register '%s' commands",
1410 struct flash_bank *c = calloc(1,
sizeof(*c));
1411 c->
name = strdup(bank_name);
1432 LOG_DEBUG(
"'%s' driver usage field missing", driver_name);
1447 "buswidth %u, chipwidth %u", p->bank_number,
1448 p->name, p->driver->name, p->base, p->size,
1449 p->bus_width, p->chip_width);
1465 " size 0x%" PRIx32
"\n"
1470 p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width,
1482 static bool flash_initialized;
1483 if (flash_initialized) {
1484 LOG_INFO(
"'flash init' has already been called");
1487 flash_initialized =
true;
1489 LOG_DEBUG(
"Initializing flash devices...");
1496 .handler = handle_flash_bank_command,
1498 .usage =
"bank_id driver_name base_address size_bytes "
1499 "chip_width_bytes bus_width_bytes target "
1500 "[driver_options ...]",
1501 .help =
"Define a new bank with the given name, "
1502 "using the specified NOR flash driver.",
1507 .handler = handle_flash_init_command,
1508 .help =
"Initialize flash devices.",
1514 .handler = handle_flash_banks_command,
1515 .help =
"Display table with information about flash banks.",
1521 .handler = handle_flash_list,
1522 .help =
"Returns a list of details about the flash banks.",
1531 .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,...
uint8_t pattern
Fill pattern.
uint64_t buffer
Pointer to data buffer to send over SPI.
uint32_t size
Size of dw_spi_transaction::buffer.
uint32_t buffer_size
Size of dw_spi_program::buffer.
uint32_t address
Starting address. Sector aligned.
#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.
target_addr_t addr
Start address to search for the control block.
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)