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/+/9694

-- gerrit

commit 6192e3e2e050aaf5ac7f8e84c92abe9044b51947
Author: Zane Leung <[email protected]>
Date:   Tue Jun 16 11:24:49 2026 +0800

    target/riscv: add `-check-dbgbase` control
    
    Introduce RISC-V-sepecific `configure` parameter `-check-dbgbase`
    to control whether OpenOCD verifies DM address (dbgbase) existence
    by reading nextdm registers. In systems where certain DMs may be
    powered down, reading their nextdm registers fails. The -check-dbgbase
    option allows users to disable verification and use the provided
    dbgbase address directly, enabling debugging of accessible DMs even
    when other DMs in the chain are powered down.
    
    Change-Id: Ie41cbf3ac4072f392d7a289c8bbf9a6057d09a91
    Signed-off-by: Zane Leung <[email protected]>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index 89900b06a7..dfe81aab0e 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -11750,6 +11750,22 @@ action pairs.
 @end itemize
 @end itemize
 
+@itemize
+@item @code{-check-dbgbase} @option{off}|@option{on} -- determines whether 
OpenOCD
+should check that DM address (dbgbase) really exists by read @code{nextdm}.
+Defaults to @option{on}.
+
+In some cases, certain DMs may be in a power-down state, preventing OpenOCD 
from
+reading their @code{nextdm} registers. However, debugging of hardware on 
powered-on DMs
+still needs to be supported. When @option{-check-dbgbase} is set to 
@option{off}, OpenOCD
+will skip the verification check and use the provided @code{dbgbase} address 
directly,
+allowing debugging of accessible DMs even when other DMs in the chain are 
powered down.
+
+@itemize
+@item @code{cget} returns the currently configured state for 
@code{-check-dbgbase}.
+@end itemize
+@end itemize
+
 @subsection RISC-V Debug Configuration Commands
 
 @deffn {Command} {riscv dump_sample_buf} [base64]
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 318a66ffe0..a5be868bec 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -537,6 +537,10 @@ static bool check_dbgbase_exists(struct target *target)
        unsigned int count = 1;
        riscv013_info_t *info = get_info(target);
 
+       struct riscv_private_config *config = target->private_config;
+       if (!config->check_dbgbase)
+               return ERROR_OK;
+
        LOG_TARGET_DEBUG(target, "Searching for DM with DMI base address 
(dbgbase) = 0x%x", target->dbgbase);
        while (1) {
                uint32_t current_dm = next_dm;
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 30094b34b5..b2a6ab8a05 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -486,6 +486,8 @@ static struct riscv_private_config 
*alloc_default_riscv_private_config(void)
        for (unsigned int i = 0; i < ARRAY_SIZE(config->dcsr_ebreak_fields); 
++i)
                config->dcsr_ebreak_fields[i] = true;
 
+       config->check_dbgbase = true;
+
        return config;
 }
 
@@ -525,6 +527,12 @@ static struct jim_nvp nvp_ebreak_mode_opts[] = {
        { .name = NULL, .value = RISCV_EBREAK_MODE_INVALID }
 };
 
+static struct jim_nvp nvp_on_off_opts[] = {
+       { .name = "off", .value = false },
+       { .name = "on", .value = true },
+       { .name = NULL, .value = -1 }
+};
+
 static int jim_configure_ebreak(struct riscv_private_config *config, struct 
jim_getopt_info *goi)
 {
        if (goi->argc == 0) {
@@ -613,11 +621,13 @@ static int jim_report_ebreak_config(const struct 
riscv_private_config *config,
 
 enum riscv_cfg_opts {
        RISCV_CFG_EBREAK,
+       RISCV_CFG_CHECK_DBGBASE,
        RISCV_CFG_INVALID = -1
 };
 
 static struct jim_nvp nvp_config_opts[] = {
        { .name = "-ebreak", .value = RISCV_CFG_EBREAK },
+       { .name = "-check-dbgbase", .value = RISCV_CFG_CHECK_DBGBASE },
        { .name = NULL, .value = RISCV_CFG_INVALID }
 };
 
@@ -654,10 +664,24 @@ static int riscv_jim_configure(struct target *target,
                return goi->is_configure
                        ? jim_configure_ebreak(config, goi)
                        : jim_report_ebreak_config(config, goi->interp);
+       case RISCV_CFG_CHECK_DBGBASE:
+               if (goi->is_configure) {
+                       struct jim_nvp *opt_nvp;
+                       e = jim_getopt_nvp(goi, nvp_on_off_opts, &opt_nvp);
+                       if (e != JIM_OK) {
+                               jim_getopt_nvp_unknown(goi, nvp_on_off_opts, 
/*hadprefix*/ true);
+                               return e;
+                       }
+                       config->check_dbgbase = opt_nvp->value;
+               } else {
+                       Jim_SetResultString(goi->interp,
+                               jim_nvp_value2name_simple(nvp_on_off_opts, 
config->check_dbgbase)->name, -1);
+               }
+               break;
        default:
                assert(false && "'jim_getopt_nvp' should have returned an 
error.");
        }
-       return JIM_ERR;
+       return JIM_OK;
 }
 
 static int riscv_init_target(struct command_context *cmd_ctx,
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 2a0a9b95f0..d73c64fd05 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -378,6 +378,7 @@ enum riscv_priv_mode {
 
 struct riscv_private_config {
        bool dcsr_ebreak_fields[N_RISCV_MODE];
+       bool check_dbgbase;
 };
 
 static inline struct riscv_private_config

-- 

Reply via email to