Properly consider 'reset halt' and do halt or resume as needed

This commit is contained in:
Megan Wachs 2017-04-05 15:07:09 -07:00 committed by Palmer Dabbelt
parent 75e7c79b2a
commit 3dc066382b
1 changed files with 30 additions and 3 deletions

View File

@ -1818,16 +1818,43 @@ static int riscv013_resume(struct target *target, int current, uint32_t address,
static int assert_reset(struct target *target) static int assert_reset(struct target *target)
{ {
select_dmi(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_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; return ERROR_OK;
} }
static int deassert_reset(struct target *target) static int deassert_reset(struct target *target)
{ {
select_dmi(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; return ERROR_OK;
} }