This is an automated email from Gerrit. "Tom Hebb <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9313
-- gerrit commit 0d7f3a3e59ad54509274a84f4d3f52966d227840 Author: Thomas Hebb <[email protected]> Date: Thu Dec 11 18:25:28 2025 -0500 target/riscv: don't finish reset until allunavail clears This used to be our behavior, but it regressed in commit 1c168242e9f5 ("target/riscv: simplify reset"), which was intended purely as a code cleanup. On some chips, like the GD32VF103, anyhavereset/allhavereset assert before anyunavail/allunavail deassert, causing us to leave this routine before the reset finishes. That behavior is arguably a violation of the debug spec, which says that havereset should be set "when harts have been reset". But the spec also says that the system coming out of reset is "reported by allunavail, anyunavail", which makes me believe it's more correct to check only those bits. This change restores the previous behavior, where we use the value of havereset to decide whether to set ackhavereset only after allunavail has deasserted. Fixes: 5754aebc4945 ("target: riscv: Sync with the RISC-V fork") Signed-off-by: Thomas Hebb <[email protected]> Change-Id: Ie3b5fa48fedf240d89c61010995c0044d2b62804 diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 6fa5e025be..69a8417e88 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -3008,8 +3008,7 @@ static int deassert_reset(struct target *target) * 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)); + } while (get_field(dmstatus, DM_DMSTATUS_ALLUNAVAIL)); riscv_scan_set_delay(&info->learned_delays, RISCV_DELAY_BASE, orig_base_delay); @@ -3017,7 +3016,8 @@ static int deassert_reset(struct target *target) /* Ack reset and clear DM_DMCONTROL_HALTREQ if previously set */ control = 0; control = set_field(control, DM_DMCONTROL_DMACTIVE, 1); - control = set_field(control, DM_DMCONTROL_ACKHAVERESET, 1); + if (get_field(dmstatus, DM_DMSTATUS_ALLHAVERESET)) + control = set_field(control, DM_DMCONTROL_ACKHAVERESET, 1); control = set_dmcontrol_hartsel(control, info->index); result = dm_write(target, DM_DMCONTROL, control); if (result != ERROR_OK) --
