diff options
-rw-r--r-- | doc/openocd.texi | 13 | ||||
-rw-r--r-- | src/flash/nor/tcl.c | 82 |
2 files changed, 95 insertions, 0 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi index 35a41d4..2dbe770 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5121,6 +5121,19 @@ each block, and the specified length must stay within that bank. @end deffn @comment no current checks for errors if fill blocks touch multiple banks! +@deffn Command {flash mdw} addr [count] +@deffnx Command {flash mdh} addr [count] +@deffnx Command {flash mdb} addr [count] +Display contents of address @var{addr}, as +32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}), +or 8-bit bytes (@command{mdb}). +If @var{count} is specified, displays that many units. +Reads from flash using the flash driver, therefore it enables reading +from a bank not mapped in target address space. +The flash bank to use is inferred from the @var{address} of +each block, and the specified length must stay within that bank. +@end deffn + @deffn Command {flash write_bank} num filename [offset] Write the binary @file{filename} to flash bank @var{num}, starting at @var{offset} bytes from the beginning of the bank. If @var{offset} diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 30c5d4c..00bfeb1 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -628,6 +628,67 @@ done: return retval; } +COMMAND_HANDLER(handle_flash_md_command) +{ + int retval; + + if (CMD_ARGC < 1 || CMD_ARGC > 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + target_addr_t address; + COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address); + + uint32_t count = 1; + if (CMD_ARGC == 2) + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count); + + unsigned int wordsize; + switch (CMD_NAME[2]) { + case 'w': + wordsize = 4; + break; + case 'h': + wordsize = 2; + break; + case 'b': + wordsize = 1; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (count == 0) + return ERROR_OK; + + struct target *target = get_current_target(CMD_CTX); + struct flash_bank *bank; + retval = get_flash_bank_by_addr(target, address, true, &bank); + if (retval != ERROR_OK) + return retval; + + uint32_t offset = address - bank->base; + uint32_t sizebytes = count * wordsize; + if (offset + sizebytes > bank->size) { + command_print(CMD, "Cannot cross flash bank borders"); + return ERROR_FAIL; + } + + uint8_t *buffer = calloc(count, wordsize); + if (buffer == NULL) { + command_print(CMD, "No memory for flash read buffer"); + return ERROR_FAIL; + } + + retval = flash_driver_read(bank, buffer, offset, sizebytes); + if (retval == ERROR_OK) + target_handle_md_output(CMD, target, address, wordsize, count, buffer); + + free(buffer); + + return retval; +} + + COMMAND_HANDLER(handle_flash_write_bank_command) { uint32_t offset; @@ -1050,6 +1111,27 @@ static const struct command_registration flash_exec_command_handlers[] = { "word address. (No autoerase.)", }, { + .name = "mdb", + .handler = handle_flash_md_command, + .mode = COMMAND_EXEC, + .usage = "address [count]", + .help = "Display bytes from flash.", + }, + { + .name = "mdh", + .handler = handle_flash_md_command, + .mode = COMMAND_EXEC, + .usage = "address [count]", + .help = "Display half-words from flash.", + }, + { + .name = "mdw", + .handler = handle_flash_md_command, + .mode = COMMAND_EXEC, + .usage = "address [count]", + .help = "Display words from flash.", + }, + { .name = "write_bank", .handler = handle_flash_write_bank_command, .mode = COMMAND_EXEC, |