aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}