diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 17201d61f..0957bdc6a 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; }