This is an automated email from Gerrit.

"liangzhen <[email protected]>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/9789

-- gerrit

commit a2556066c0994bf13d253bc70e67c960f33e3d39
Author: Zane Leung <[email protected]>
Date:   Wed Jul 22 16:45:56 2026 +0800

    target/riscv: add reset method command support
    
    Add a new 'riscv reset_method' command that allows users to select
    a method for resetting harts:
    
    - ndmreset (default): resets the entire hardware platform except for
      the debugging system, via 'dmcontrol.ndmreset'.
    - hartreset: resets only the currently selected harts via
      'dmcontrol.hartreset'.
    
    Note: the reset command applies to all currently created targets.
    Using ndmreset for this purpose is technically incorrect, as ndmreset
    resets the entire platform rather than currently created targets.
    In addition, it is incorrect to execute ndmreset once for each hart
    in assert_reset().
    
    Change-Id: I00a2649d686e1faa05901de87c082e79586c1aa7
    Signed-off-by: Zane Leung <[email protected]>

diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 318a66ffe0..f5091cda9b 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -2920,7 +2920,11 @@ static int assert_reset(struct target *target)
                control = set_dmcontrol_hartsel(control, info->index);
                control = set_field(control, DM_DMCONTROL_HALTREQ,
                                target->reset_halt ? 1 : 0);
-               control = set_field(control, DM_DMCONTROL_NDMRESET, 1);
+
+               if (reset_method == RISCV_RESET_METHOD_HARTRESET)
+                       control = set_field(control, DM_DMCONTROL_HARTRESET, 1);
+               else
+                       control = set_field(control, DM_DMCONTROL_NDMRESET, 1);
                /* If `abstractcs.busy` is set, debugger should not
                 * change `hartsel` or set `haltreq`
                 */
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 30094b34b5..4ba426c9a4 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -170,6 +170,19 @@ const char *riscv_virt2phys_mode_to_str(enum 
riscv_virt2phys_mode mode)
        return names[mode];
 }
 
+const char *riscv_reset_method_to_str(enum riscv_reset_method method)
+{
+       assert(method == RISCV_RESET_METHOD_NDMRESET
+                       || method == RISCV_RESET_METHOD_HARTRESET);
+
+       static const char *const names[] = {
+               [RISCV_RESET_METHOD_NDMRESET] = "ndmreset",
+               [RISCV_RESET_METHOD_HARTRESET] = "hartreset",
+       };
+
+       return names[method];
+}
+
 /* Wall-clock timeout for a command/access. Settable via RISC-V Target 
commands.*/
 static int riscv_command_timeout_sec_value = DEFAULT_COMMAND_TIMEOUT_SEC;
 
@@ -5610,6 +5623,32 @@ COMMAND_HANDLER(handle_riscv_virt2phys_mode)
        return ERROR_OK;
 }
 
+enum riscv_reset_method reset_method = RISCV_RESET_METHOD_NDMRESET;
+
+COMMAND_HANDLER(riscv_reset_method)
+{
+       if (CMD_ARGC == 0) {
+               command_print(CMD, "%s", 
riscv_reset_method_to_str(reset_method));
+               return ERROR_OK;
+       }
+
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       if (!strcmp(CMD_ARGV[0],
+                       
riscv_reset_method_to_str(RISCV_RESET_METHOD_NDMRESET))) {
+               reset_method = RISCV_RESET_METHOD_NDMRESET;
+       } else if (!strcmp(CMD_ARGV[0],
+                       
riscv_reset_method_to_str(RISCV_RESET_METHOD_HARTRESET))) {
+               reset_method = RISCV_RESET_METHOD_HARTRESET;
+       } else {
+               command_print(CMD, "Unsupported reset method: %s", CMD_ARGV[0]);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
+       }
+
+       return ERROR_OK;
+}
+
 static const struct command_registration riscv_exec_command_handlers[] = {
        {
                .name = "dump_sample_buf",
@@ -5872,6 +5911,15 @@ static const struct command_registration 
riscv_exec_command_handlers[] = {
                        "When off, users need to take care of memory coherency 
themselves, for example by using "
                        "`riscv exec_progbuf` to execute fence or CMO 
instructions."
        },
+       {
+               .name = "reset_method",
+               .handler = riscv_reset_method,
+               .mode = COMMAND_ANY,
+               .usage = "['ndmreset'|'hartreset']",
+               .help = "Configure a reset method that allow a debugger to 
reset harts: "
+                               "ndmreset - resets the entire hardware platform 
except for the debugging system."
+                               "hartreset - resets all the currently selected 
harts."
+       },
        {
                .chain = smp_command_handlers
        },
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 2a0a9b95f0..b6705af908 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -68,6 +68,15 @@ enum riscv_virt2phys_mode {
 
 const char *riscv_virt2phys_mode_to_str(enum riscv_virt2phys_mode mode);
 
+enum riscv_reset_method {
+       RISCV_RESET_METHOD_NDMRESET,
+       RISCV_RESET_METHOD_HARTRESET,
+};
+
+extern enum riscv_reset_method reset_method;
+
+const char *riscv_reset_method_to_str(enum riscv_reset_method method);
+
 enum riscv_halt_reason {
        RISCV_HALT_INTERRUPT,
        RISCV_HALT_EBREAK,

-- 

Reply via email to