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");
198 "Error: checking erase state of flash bank #%s at "
204 for (
unsigned int j = 0; j < p->
num_sectors; j++) {
208 erase_state =
"not erased";
212 erase_state =
"erase state unknown";
216 "\t#%3i: 0x%8.8" PRIx32
" (0x%" PRIx32
" %" PRIu32
"kB) %s",
239 bool do_unlock =
false;
247 if (strcmp(
"pad",
CMD_ARGV[0]) == 0)
249 else if (strcmp(
"unlock",
CMD_ARGV[0]) == 0)
318 LOG_INFO(
"bank has no sectors, ignoring specified sectors");
323 if (strcmp(
CMD_ARGV[2],
"last") == 0)
328 if (!(first <= last)) {
330 "first sector must be <= last");
336 "last sector must be <= %u",
357 "through %" PRIu32
" on flash bank %u "
386 if (strcmp(
CMD_ARGV[2],
"last") == 0)
387 last = num_blocks - 1;
394 if (!(first <= last)) {
396 "first %s must be <= last",
401 if (!(last <= (uint32_t)(num_blocks - 1))) {
403 "last %s must be <= %d",
416 " through %" PRIu32
" on flash bank %d",
417 set ?
"set" :
"cleared",
435 bool auto_unlock =
false;
438 if (strcmp(
CMD_ARGV[0],
"erase") == 0) {
443 }
else if (strcmp(
CMD_ARGV[0],
"unlock") == 0) {
478 auto_unlock,
true,
false);
486 "in %fs (%0.3f KiB/s)", written,
CMD_ARGV[0],
538 "in %fs (%0.3f KiB/s)", verified,
CMD_ARGV[0],
586 if ((wordsize <
sizeof(
pattern)) && (
pattern >> (8 * wordsize) != 0)) {
595 LOG_ERROR(
"Cannot cross flash bank borders");
599 uint32_t size_bytes =
count * wordsize;
603 uint32_t aligned_size = aligned_end + 1 - aligned_start;
604 uint32_t padding_at_start =
address - aligned_start;
605 uint32_t padding_at_end = aligned_end - end_addr;
607 uint8_t *
buffer = malloc(aligned_size);
611 if (padding_at_start) {
612 memset(
buffer,
bank->default_padded_value, padding_at_start);
614 " breaks the required alignment of flash bank %s",
617 padding_at_start, aligned_start);
620 uint8_t *ptr =
buffer + padding_at_start;
624 for (i = 0; i <
count; i++, ptr += wordsize)
628 for (i = 0; i <
count; i++, ptr += wordsize)
632 for (i = 0; i <
count; i++, ptr += wordsize)
645 if (padding_at_end) {
646 memset(ptr,
bank->default_padded_value, padding_at_end);
648 " bytes (bank write end alignment)",
649 end_addr + 1, padding_at_end);
664 uint64_t readback = 0;
683 ", read back 0x%02" PRIx64
", expected 0x%02" PRIx64,
693 " in %fs (%0.3f KiB/s)", size_bytes,
address,
707 if (CMD_ARGC < 1 || CMD_ARGC > 2)
717 unsigned int wordsize;
742 uint32_t sizebytes =
count * wordsize;
780 unsigned int width_bits;
787 switch (width_bits) {
803 const unsigned int width = width_bits / 8;
819 uint32_t sizebytes =
count * width_bits;
833 char *separator =
"";
836 const size_t chunk_len =
MIN(
count, max_chunk_len);
842 addr, width_bits, chunk_len);
852 for (
size_t i = 0; i < chunk_len ; i++) {
890 if (CMD_ARGC < 2 || CMD_ARGC > 3)
907 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
925 LOG_INFO(
"Nothing to write to flash bank");
931 LOG_INFO(
"File content exceeds flash bank size. Only writing the "
932 "first %zu bytes of the file",
length);
938 uint32_t aligned_size = aligned_end + 1 - aligned_start;
939 uint32_t padding_at_start = start_addr - aligned_start;
940 uint32_t padding_at_end = aligned_end - end_addr;
942 buffer = malloc(aligned_size);
949 if (padding_at_start) {
950 memset(
buffer,
bank->default_padded_value, padding_at_start);
952 " breaks the required alignment of flash bank %s",
955 padding_at_start, aligned_start);
958 uint8_t *ptr =
buffer + padding_at_start;
975 if (padding_at_end) {
976 memset(ptr,
bank->default_padded_value, padding_at_end);
978 " bytes (bank write end alignment)",
979 end_addr + 1, padding_at_end);
988 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
1006 if (CMD_ARGC < 2 || CMD_ARGC > 4)
1024 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
1035 LOG_ERROR(
"Length of %" PRIu32
" bytes with offset 0x%8.8" PRIx32
1070 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
1081 uint8_t *buffer_file, *buffer_flash;
1088 if (CMD_ARGC < 2 || CMD_ARGC > 3)
1105 LOG_ERROR(
"Offset 0x%8.8" PRIx32
" is out of range of the flash bank",
1125 LOG_INFO(
"Nothing to compare with flash bank");
1131 LOG_INFO(
"File content exceeds flash bank size. Only comparing the "
1132 "first %zu bytes of the file",
length);
1134 buffer_file = malloc(
length);
1149 if (read_cnt !=
length) {
1155 buffer_flash = malloc(
length);
1156 if (!buffer_flash) {
1172 " at offset 0x%8.8" PRIx32
" in %fs (%0.3f KiB/s)",
1176 differ = memcmp(buffer_file, buffer_flash,
length);
1181 for (t = 0; t <
length; t++) {
1182 if (buffer_flash[t] == buffer_file[t])
1184 command_print(
CMD,
"diff %d address 0x%08" PRIx32
". Was 0x%02x instead of 0x%02x",
1185 diffs, t +
offset, buffer_flash[t], buffer_file[t]);
1186 if (diffs++ >= 127) {
1222 command_print(
CMD,
"Default padded value set to 0x%" PRIx8
" for flash bank %u",
1231 .handler = handle_flash_probe_command,
1234 .help =
"Identify a flash bank.",
1238 .handler = handle_flash_info_command,
1240 .usage =
"bank_id ['sectors']",
1241 .help =
"Print information about a flash bank.",
1244 .name =
"erase_check",
1245 .handler = handle_flash_erase_check_command,
1248 .help =
"Check erase state of all blocks in a "
1252 .name =
"erase_sector",
1253 .handler = handle_flash_erase_command,
1255 .usage =
"bank_id first_sector_num (last_sector_num|'last')",
1256 .help =
"Erase a range of sectors in a flash bank.",
1259 .name =
"erase_address",
1260 .handler = handle_flash_erase_address_command,
1262 .usage =
"['pad'] ['unlock'] address length",
1263 .help =
"Erase flash sectors starting at address and "
1264 "continuing for length bytes. If 'pad' is specified, "
1265 "data outside that range may also be erased: the start "
1266 "address may be decreased, and length increased, so "
1267 "that all of the first and last sectors are erased. "
1268 "If 'unlock' is specified, then the flash is unprotected "
1274 .handler = handle_flash_fill_command,
1276 .usage =
"address value n",
1277 .help =
"Fill n double-words with 64-bit value, starting at "
1278 "word address. (No autoerase.)",
1282 .handler = handle_flash_fill_command,
1284 .usage =
"address value n",
1285 .help =
"Fill n words with 32-bit value, starting at "
1286 "word address. (No autoerase.)",
1290 .handler = handle_flash_fill_command,
1292 .usage =
"address value n",
1293 .help =
"Fill n halfwords with 16-bit value, starting at "
1294 "word address. (No autoerase.)",
1298 .handler = handle_flash_fill_command,
1300 .usage =
"address value n",
1301 .help =
"Fill n bytes with 8-bit value, starting at "
1302 "word address. (No autoerase.)",
1306 .handler = handle_flash_md_command,
1308 .usage =
"address [count]",
1309 .help =
"Display bytes from flash.",
1313 .handler = handle_flash_md_command,
1315 .usage =
"address [count]",
1316 .help =
"Display half-words from flash.",
1320 .handler = handle_flash_md_command,
1322 .usage =
"address [count]",
1323 .help =
"Display words from flash.",
1326 .name =
"read_memory",
1328 .handler = handle_flash_read_memory_command,
1329 .help =
"Read Tcl list of 8/16/32/64 bit numbers from flash memory",
1330 .usage =
"address width count",
1333 .name =
"write_bank",
1334 .handler = handle_flash_write_bank_command,
1336 .usage =
"bank_id filename [offset]",
1337 .help =
"Write binary data from file to flash bank. Allow optional "
1338 "offset from beginning of the bank (defaults to zero).",
1341 .name =
"write_image",
1342 .handler = handle_flash_write_image_command,
1344 .usage =
"[erase] [unlock] filename [offset [file_type]]",
1345 .help =
"Write an image to flash. Optionally first unprotect "
1346 "and/or erase the region to be used. Allow optional "
1347 "offset from beginning of bank (defaults to zero)",
1350 .name =
"verify_image",
1351 .handler = handle_flash_verify_image_command,
1353 .usage =
"filename [offset [file_type]]",
1354 .help =
"Verify an image against flash. Allow optional "
1355 "offset from beginning of bank (defaults to zero)",
1358 .name =
"read_bank",
1359 .handler = handle_flash_read_bank_command,
1361 .usage =
"bank_id filename [offset [length]]",
1362 .help =
"Read binary data from flash bank to file. Allow optional "
1363 "offset from beginning of the bank (defaults to zero).",
1366 .name =
"verify_bank",
1367 .handler = handle_flash_verify_bank_command,
1369 .usage =
"bank_id filename [offset]",
1370 .help =
"Compare the contents of a file with the contents of the "
1371 "flash bank. Allow optional offset from beginning of the bank "
1372 "(defaults to zero).",
1376 .handler = handle_flash_protect_command,
1378 .usage =
"bank_id first_block [last_block|'last'] "
1380 .help =
"Turn protection on or off for a range of protection "
1381 "blocks or sectors in a given flash bank. "
1382 "See 'flash info' output for a list of blocks.",
1385 .name =
"padded_value",
1386 .handler = handle_flash_padded_value_command,
1388 .usage =
"bank_id value",
1389 .help =
"Set default flash padded value",
1405 LOG_ERROR(
"usage: flash bank <name> <driver> "
1406 "<base> <size> <chip_width> <bus_width> <target>");
1410 const char *bank_name = *
CMD_ARGV++;
1419 const char *driver_name =
CMD_ARGV[0];
1423 LOG_ERROR(
"flash driver '%s' not found", driver_name);
1430 LOG_ERROR(
"flash bank name '%s' already exists", bank_name);
1438 LOG_ERROR(
"couldn't register '%s' commands",
1444 struct flash_bank *c = calloc(1,
sizeof(*c));
1445 c->
name = strdup(bank_name);
1466 LOG_DEBUG(
"'%s' driver usage field missing", driver_name);
1480 "buswidth %u, chipwidth %u", p->bank_number,
1481 p->name, p->driver->name, p->base, p->size,
1482 p->bus_width, p->chip_width);
1498 " size 0x%" PRIx32
"\n"
1503 p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width,
1515 static bool flash_initialized;
1516 if (flash_initialized) {
1517 LOG_INFO(
"'flash init' has already been called");
1520 flash_initialized =
true;
1522 LOG_DEBUG(
"Initializing flash devices...");
1529 .handler = handle_flash_bank_command,
1531 .usage =
"bank_id driver_name base_address size_bytes "
1532 "chip_width_bytes bus_width_bytes target "
1533 "[driver_options ...]",
1534 .help =
"Define a new bank with the given name, "
1535 "using the specified NOR flash driver.",
1540 .handler = handle_flash_init_command,
1541 .help =
"Initialize flash devices.",
1547 .handler = handle_flash_banks_command,
1548 .help =
"Display table with information about flash banks.",
1554 .handler = handle_flash_list,
1555 .help =
"Returns a list of details about the flash banks.",
1564 .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)
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
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_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_erase_address_range(struct target *target, bool pad, target_addr_t addr, uint32_t length, bool skip_banks_without_erase)
Erases length bytes in the target flash, starting at addr.
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)
int is_erased
Indication of erasure status: 0 = not erased, 1 = erased, other = unknown.
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)
struct target * get_current_target(struct command_context *cmd_ctx)
uint32_t target_buffer_get_u32(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, bool include_address)
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)