diff options
author | Tomas Vanek <vanekt@fbl.cz> | 2015-04-24 07:33:50 +0200 |
---|---|---|
committer | Andreas Fritiofson <andreas.fritiofson@gmail.com> | 2016-07-17 23:30:09 +0100 |
commit | f4496b25e3040e29b9bc78dd5bf8ac8128c09a1e (patch) | |
tree | 68a139b78b74cef0d18ed5a3ba5f06e4441c8693 | |
parent | 7a0473bbb6cd4d83ce43fc4b722083b315b80a98 (diff) |
arm_adi_v5: add dap apreg command for AP register read/write
A developer tool: Direct access to AP registers can be useful
for handling vendor specific AP like Freescale Kinetis MDM or Atmel SMAP.
Change-Id: Ie2c7160fc6b2e398513eb23e1e52cbb52b88d9bd
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/2777
Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Tested-by: jenkins
-rw-r--r-- | doc/openocd.texi | 6 | ||||
-rw-r--r-- | src/target/arm_adi_v5.c | 47 |
2 files changed, 53 insertions, 0 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi index 1d517213..983ce3ca 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7836,6 +7836,12 @@ Displays ID register from AP @var{num}, defaulting to the currently selected AP. @end deffn +@deffn Command {dap apreg} ap_num reg [value] +Displays content of a register @var{reg} from AP @var{ap_num} +or set a new value @var{value}. +@var{reg} is byte address of a word register, 0, 4, 8 ... 0xfc. +@end deffn + @deffn Command {dap apsel} [num] Select AP @var{num}, defaulting to 0. @end deffn diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index eb3392bf..f58afdc0 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -1556,6 +1556,45 @@ COMMAND_HANDLER(dap_apid_command) return retval; } +COMMAND_HANDLER(dap_apreg_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target_to_arm(target); + struct adiv5_dap *dap = arm->dap; + + uint32_t apsel, reg, value; + int retval; + + if (CMD_ARGC < 2 || CMD_ARGC > 3) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); + /* AP address is in bits 31:24 of DP_SELECT */ + if (apsel >= 256) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg); + if (reg >= 256 || (reg & 3)) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 3) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); + retval = dap_queue_ap_write(dap_ap(dap, apsel), reg, value); + } else { + retval = dap_queue_ap_read(dap_ap(dap, apsel), reg, &value); + } + if (retval == ERROR_OK) + retval = dap_run(dap); + + if (retval != ERROR_OK) + return retval; + + if (CMD_ARGC == 2) + command_print(CMD_CTX, "0x%08" PRIx32, value); + + return retval; +} + COMMAND_HANDLER(dap_ti_be_32_quirks_command) { struct target *target = get_current_target(CMD_CTX); @@ -1616,6 +1655,14 @@ static const struct command_registration dap_commands[] = { .usage = "[ap_num]", }, { + .name = "apreg", + .handler = dap_apreg_command, + .mode = COMMAND_EXEC, + .help = "read/write a register from AP " + "(reg is byte address of a word register, like 0 4 8...)", + .usage = "ap_num reg [value]", + }, + { .name = "baseaddr", .handler = dap_baseaddr_command, .mode = COMMAND_EXEC, |