aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMegan Wachs <megan@sifive.com>2017-04-05 15:07:09 -0700
committerPalmer Dabbelt <palmer@dabbelt.com>2017-04-10 12:03:15 -0700
commit3dc066382bebce5a86a72a095c17b1eaa58b0b89 (patch)
tree319170b3f34146cc511667940dad7221d4e96eb8
parent75e7c79b2a9a02c828f5e213ad34292cb1c6796a (diff)
downloadriscv-openocd-3dc066382bebce5a86a72a095c17b1eaa58b0b89.zip
riscv-openocd-3dc066382bebce5a86a72a095c17b1eaa58b0b89.tar.gz
riscv-openocd-3dc066382bebce5a86a72a095c17b1eaa58b0b89.tar.bz2
Properly consider 'reset halt' and do halt or resume as needed
-rw-r--r--src/target/riscv/riscv-013.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 17201d6..0957bdc 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1818,16 +1818,43 @@ static int riscv013_resume(struct target *target, int current, uint32_t address,
static int assert_reset(struct target *target)
{
select_dmi(target);
+ uint32_t control = DMI_DMCONTROL_DMACTIVE | DMI_DMCONTROL_NDMRESET;
+ if (target->reset_halt) {
+ LOG_DEBUG("TARGET RESET HALT SET, Requesting halt during reset.\n");
+ control |= DMI_DMCONTROL_HALTREQ;
+ }
+
dmi_write(target, DMI_DMCONTROL,
- DMI_DMCONTROL_DMACTIVE | DMI_DMCONTROL_NDMRESET);
+ control);
+
+ if (!target->reset_halt) {
+ LOG_DEBUG("TARGET RESET HALT NOT SET, Requesting resume during reset.\n");
+ control = DMI_DMCONTROL_DMACTIVE | DMI_DMCONTROL_RESUMEREQ;
+ dmi_write(target, DMI_DMCONTROL, control);
+ }
+
return ERROR_OK;
}
static int deassert_reset(struct target *target)
{
select_dmi(target);
- dmi_write(target, DMI_DMCONTROL,
- DMI_DMCONTROL_DMACTIVE);
+
+ // Note that we don't need to keep asserting
+ // haltreq since we already set it in assert_reset.
+ dmi_write(target, DMI_DMCONTROL, DMI_DMCONTROL_DMACTIVE);
+
+ if (target->reset_halt) {
+ LOG_DEBUG("TARGET RESET HALT SET, waiting for hart to be halted.\n");
+ while (get_field(dmi_read(target, DMI_DMSTATUS), DMI_DMSTATUS_ALLHALTED) == 0) {
+ }
+ // This is necessary to re-read all the registers.
+ handle_halt(target, true);
+ } else {
+ LOG_DEBUG("TARGET RESET HALT NOT SET, waiting for hart to be running.\n");
+ while (get_field(dmi_read(target, DMI_DMSTATUS), DMI_DMSTATUS_ALLRUNNING) == 0) {
+ }
+ }
return ERROR_OK;
}