-
Notifications
You must be signed in to change notification settings - Fork 353
Open
Description
Currently there is a loop in deassert_reset()
handler that waits for the hart to come out of reset.
riscv-openocd/src/target/riscv/riscv-013.c
Lines 2930 to 2953 in e870c5f
LOG_TARGET_DEBUG(target, "Waiting for hart to come out of reset."); | |
do { | |
result = dmstatus_read(target, &dmstatus, true); | |
if (result != ERROR_OK) | |
return result; | |
if (time(NULL) - start > riscv_get_command_timeout_sec()) { | |
LOG_TARGET_ERROR(target, "Hart didn't leave reset in %ds; " | |
"dmstatus=0x%x (allunavail=%s, allhavereset=%s); " | |
"Increase the timeout with riscv set_command_timeout_sec.", | |
riscv_get_command_timeout_sec(), dmstatus, | |
get_field(dmstatus, DM_DMSTATUS_ALLUNAVAIL) ? "true" : "false", | |
get_field(dmstatus, DM_DMSTATUS_ALLHAVERESET) ? "true" : "false"); | |
return ERROR_TIMEOUT_REACHED; | |
} | |
/* Certain debug modules, like the one in GD32VF103 | |
* MCUs, violate the specification's requirement that | |
* each hart is in "exactly one of four states" and, | |
* during reset, report harts as both unavailable and | |
* halted/running. To work around this, we check for | |
* the absence of the unavailable state rather than | |
* the presence of any other state. */ | |
} while (get_field(dmstatus, DM_DMSTATUS_ALLUNAVAIL) && | |
!get_field(dmstatus, DM_DMSTATUS_ALLHAVERESET)); |
This is not necessary -- there is a call to arp_waitstate
:
riscv-openocd/src/target/startup.tcl
Line 140 in e870c5f
catch { $t arp_waitstate halted 1000 } |
The task is to move handling of a target coming out of reset from deassert_reset()
to poll()
. This will also allow to drop the awkward handling of an unexpected reset in riscv013_get_hart_state()
:
riscv-openocd/src/target/riscv/riscv-013.c
Lines 2716 to 2737 in e870c5f
if (get_field(dmstatus, DM_DMSTATUS_ANYHAVERESET)) { | |
LOG_TARGET_INFO(target, "Hart unexpectedly reset!"); | |
info->dcsr_ebreak_is_set = false; | |
/* TODO: Can we make this more obvious to eg. a gdb user? */ | |
uint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | | |
DM_DMCONTROL_ACKHAVERESET; | |
dmcontrol = set_dmcontrol_hartsel(dmcontrol, info->index); | |
/* If we had been halted when we reset, request another halt. If we | |
* ended up running out of reset, then the user will (hopefully) get a | |
* message that a reset happened, that the target is running, and then | |
* that it is halted again once the request goes through. | |
*/ | |
if (target->state == TARGET_HALTED) { | |
dmcontrol |= DM_DMCONTROL_HALTREQ; | |
/* `haltreq` should not be issued if `abstractcs.busy` | |
* is set. */ | |
int result = wait_for_idle_if_needed(target); | |
if (result != ERROR_OK) | |
return result; | |
} | |
dm_write(target, DM_DMCONTROL, dmcontrol); | |
} |
Metadata
Metadata
Assignees
Labels
No labels