aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMegan Wachs <megan@sifive.com>2017-04-04 16:33:17 -0700
committerMegan Wachs <megan@sifive.com>2017-04-04 16:33:17 -0700
commit14e26040b8c303d5feba7d735b62382e1b7aa325 (patch)
tree7da4a27241d3a17b1b3a652e33ee5c85b544ae03
parent9c1f6ea28b87704474e5a33cb2062a00ddd3a255 (diff)
downloadriscv-openocd-14e26040b8c303d5feba7d735b62382e1b7aa325.zip
riscv-openocd-14e26040b8c303d5feba7d735b62382e1b7aa325.tar.gz
riscv-openocd-14e26040b8c303d5feba7d735b62382e1b7aa325.tar.bz2
riscv: move value read to after autoexec is cleared.
-rw-r--r--src/target/riscv/riscv-013.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index ec9f951..2cd186d 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1868,12 +1868,25 @@ static int read_memory(struct target *target, uint32_t address,
uint32_t abstractcs;
for (uint32_t i = 0; i < count; i++) {
- uint32_t value = dmi_read(target, DMI_DATA0);
+
// On last iteration, turn off autoexec before reading the value
// so that we don't inadvertently read too far into memory.
if ((count > 1) && ((i + 1) == count)) {
dmi_write(target, DMI_ABSTRACTAUTO, 0);
}
+
+ uint32_t value = dmi_read(target, DMI_DATA0);
+ // If autoexec was set, the above dmi_read started an abstract command.
+ // If we just immediately loop and do another read here,
+ // we'll probably get a busy error. Wait for idle first,
+ // or otherwise take ac_command_busy into account (this defeats the purpose
+ // of autoexec, this whole code needs optimization).
+ if ((count > 1) && ((i + 1) < count)) {
+ if (wait_for_idle(target, &abstractcs) != ERROR_OK) {
+ dmi_write(target, DMI_ABSTRACTAUTO, 0);
+ return ERROR_FAIL;
+ }
+ }
switch (size) {
case 1:
buffer[i] = value;
@@ -1891,14 +1904,8 @@ static int read_memory(struct target *target, uint32_t address,
default:
return ERROR_FAIL;
}
- // The above dmi_read started an abstract command. If we just
- // immediately read here, we'll probably get a busy error. Wait for idle first,
- // or otherwise take ac_command_busy into account (this defeats the purpose
- // of autoexec, this whole code needs optimization).
- if (wait_for_idle(target, &abstractcs) != ERROR_OK) {
- return ERROR_FAIL;
- }
}
+
abstractcs = dmi_read(target, DMI_ABSTRACTCS);
unsigned cmderr = get_field(abstractcs, DMI_ABSTRACTCS_CMDERR);
if (cmderr == CMDERR_BUSY) {