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, --
