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)

-- 

Reply via email to