[PATCH v2 06/50] target/riscv: Extract monitor-related code to monitor.c

Philippe Mathieu-Daudé posted 50 patches 1 month ago
Maintainers: Laurent Vivier <laurent@vivier.eu>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Michael Rolnik <mrolnik@gmail.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Yanan Wang <wangyanan55@huawei.com>, Zhao Liu <zhao1.liu@intel.com>, "Dr. David Alan Gilbert" <dave@treblig.org>, Richard Henderson <richard.henderson@linaro.org>, Brian Cain <brian.cain@oss.qualcomm.com>, Paolo Bonzini <pbonzini@redhat.com>, Song Gao <gaosong@loongson.cn>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Aurelien Jarno <aurelien@aurel32.net>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Aleksandar Rikalo <arikalo@gmail.com>, Stafford Horne <shorne@gmail.com>, Nicholas Piggin <npiggin@gmail.com>, Chinmay Rath <rathc@linux.ibm.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Yoshinori Sato <yoshinori.sato@nifty.com>, Ilya Leoshkevich <iii@linux.ibm.com>, David Hildenbrand <david@kernel.org>, Thomas Huth <thuth@redhat.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>, Bastian Koppelmann <kbastian@rumtueddeln.de>
[PATCH v2 06/50] target/riscv: Extract monitor-related code to monitor.c
Posted by Philippe Mathieu-Daudé 1 month ago
Keep riscv-qmp-cmds.c for QMP, use monitor.c for HMP.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/riscv/monitor.c        | 148 +++++++++++++++++++++++++++++++++
 target/riscv/riscv-qmp-cmds.c | 150 ----------------------------------
 2 files changed, 148 insertions(+), 150 deletions(-)

diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 478fd392ac6..ccb7eb44d02 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -19,6 +19,8 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/ctype.h"
+#include "qemu/qemu-print.h"
 #include "cpu.h"
 #include "cpu_bits.h"
 #include "monitor/monitor.h"
@@ -241,3 +243,149 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
 
     mem_info_svxx(mon, env);
 }
+
+/*
+ * We have way too many potential CSRs and regs being added
+ * regularly to register them in a static array.
+ *
+ * Declare an empty array instead, making get_monitor_def() use
+ * the target_get_monitor_def() API directly.
+ */
+const MonitorDef monitor_defs[] = { { } };
+const MonitorDef *target_monitor_defs(void)
+{
+    return monitor_defs;
+}
+
+static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
+                                 target_ulong *val, bool is_gprh)
+{
+    const char * const *reg_names;
+    target_ulong *vals;
+
+    if (is_gprh) {
+        reg_names = riscv_int_regnamesh;
+        vals = env->gprh;
+    } else {
+        reg_names = riscv_int_regnames;
+        vals = env->gpr;
+    }
+
+    for (int i = 0; i < 32; i++) {
+        g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
+
+        g_assert(reg_name[0]);
+        g_assert(reg_name[1]);
+
+        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
+            g_ascii_strcasecmp(reg_name[1], name) == 0) {
+            *val = vals[i];
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
+{
+    if (qemu_tolower(name[0]) != 'f') {
+        return false;
+    }
+
+    for (int i = 0; i < 32; i++) {
+        g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
+
+        g_assert(reg_name[0]);
+        g_assert(reg_name[1]);
+
+        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
+            g_ascii_strcasecmp(reg_name[1], name) == 0) {
+            *val = env->fpr[i];
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static bool reg_is_vreg(const char *name)
+{
+    if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
+        return false;
+    }
+
+    for (int i = 0; i < 32; i++) {
+        if (strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
+{
+    CPURISCVState *env = &RISCV_CPU(cs)->env;
+    target_ulong val = 0;
+    uint64_t val64 = 0;
+    int i;
+
+    if (reg_is_ulong_integer(env, name, &val, false) ||
+        reg_is_ulong_integer(env, name, &val, true)) {
+        *pval = val;
+        return 0;
+    }
+
+    if (reg_is_u64_fpu(env, name, &val64)) {
+        *pval = val64;
+        return 0;
+    }
+
+    if (reg_is_vreg(name)) {
+        if (!riscv_cpu_cfg(env)->ext_zve32x) {
+            return -EINVAL;
+        }
+
+        qemu_printf("Unable to print the value of vector "
+                    "vreg '%s' from this API\n", name);
+
+        /*
+         * We're returning 0 because returning -EINVAL triggers
+         * an 'unknown register' message in exp_unary() later,
+         * which feels ankward after our own error message.
+         */
+        *pval = 0;
+        return 0;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
+        RISCVException res;
+        int csrno = i;
+
+        /*
+         * Early skip when possible since we're going
+         * through a lot of NULL entries.
+         */
+        if (csr_ops[csrno].predicate == NULL) {
+            continue;
+        }
+
+        if (strcasecmp(csr_ops[csrno].name, name) != 0) {
+            continue;
+        }
+
+        res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
+
+        /*
+         * Rely on the smode, hmode, etc, predicates within csr.c
+         * to do the filtering of the registers that are present.
+         */
+        if (res == RISCV_EXCP_NONE) {
+            *pval = val;
+            return 0;
+        }
+    }
+
+    return -EINVAL;
+}
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index d5e9bec0f86..8a1856c50e0 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -31,10 +31,6 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/visitor.h"
 #include "qom/qom-qobject.h"
-#include "qemu/ctype.h"
-#include "qemu/qemu-print.h"
-#include "monitor/hmp.h"
-#include "monitor/hmp-target.h"
 #include "system/kvm.h"
 #include "system/tcg.h"
 #include "cpu-qom.h"
@@ -244,149 +240,3 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
 
     return expansion_info;
 }
-
-/*
- * We have way too many potential CSRs and regs being added
- * regularly to register them in a static array.
- *
- * Declare an empty array instead, making get_monitor_def() use
- * the target_get_monitor_def() API directly.
- */
-const MonitorDef monitor_defs[] = { { } };
-const MonitorDef *target_monitor_defs(void)
-{
-    return monitor_defs;
-}
-
-static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
-                                 target_ulong *val, bool is_gprh)
-{
-    const char * const *reg_names;
-    target_ulong *vals;
-
-    if (is_gprh) {
-        reg_names = riscv_int_regnamesh;
-        vals = env->gprh;
-    } else {
-        reg_names = riscv_int_regnames;
-        vals = env->gpr;
-    }
-
-    for (int i = 0; i < 32; i++) {
-        g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
-
-        g_assert(reg_name[0]);
-        g_assert(reg_name[1]);
-
-        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
-            g_ascii_strcasecmp(reg_name[1], name) == 0) {
-            *val = vals[i];
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
-{
-    if (qemu_tolower(name[0]) != 'f') {
-        return false;
-    }
-
-    for (int i = 0; i < 32; i++) {
-        g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
-
-        g_assert(reg_name[0]);
-        g_assert(reg_name[1]);
-
-        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
-            g_ascii_strcasecmp(reg_name[1], name) == 0) {
-            *val = env->fpr[i];
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static bool reg_is_vreg(const char *name)
-{
-    if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
-        return false;
-    }
-
-    for (int i = 0; i < 32; i++) {
-        if (strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
-{
-    CPURISCVState *env = &RISCV_CPU(cs)->env;
-    target_ulong val = 0;
-    uint64_t val64 = 0;
-    int i;
-
-    if (reg_is_ulong_integer(env, name, &val, false) ||
-        reg_is_ulong_integer(env, name, &val, true)) {
-        *pval = val;
-        return 0;
-    }
-
-    if (reg_is_u64_fpu(env, name, &val64)) {
-        *pval = val64;
-        return 0;
-    }
-
-    if (reg_is_vreg(name)) {
-        if (!riscv_cpu_cfg(env)->ext_zve32x) {
-            return -EINVAL;
-        }
-
-        qemu_printf("Unable to print the value of vector "
-                    "vreg '%s' from this API\n", name);
-
-        /*
-         * We're returning 0 because returning -EINVAL triggers
-         * an 'unknown register' message in exp_unary() later,
-         * which feels ankward after our own error message.
-         */
-        *pval = 0;
-        return 0;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
-        RISCVException res;
-        int csrno = i;
-
-        /*
-         * Early skip when possible since we're going
-         * through a lot of NULL entries.
-         */
-        if (csr_ops[csrno].predicate == NULL) {
-            continue;
-        }
-
-        if (strcasecmp(csr_ops[csrno].name, name) != 0) {
-            continue;
-        }
-
-        res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
-
-        /*
-         * Rely on the smode, hmode, etc, predicates within csr.c
-         * to do the filtering of the registers that are present.
-         */
-        if (res == RISCV_EXCP_NONE) {
-            *pval = val;
-            return 0;
-        }
-    }
-
-    return -EINVAL;
-}
-- 
2.52.0


Re: [PATCH v2 06/50] target/riscv: Extract monitor-related code to monitor.c
Posted by Daniel Henrique Barboza 1 month ago

On 2/19/2026 4:19 PM, Philippe Mathieu-Daudé wrote:
> Keep riscv-qmp-cmds.c for QMP, use monitor.c for HMP.
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---


Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>

>   target/riscv/monitor.c        | 148 +++++++++++++++++++++++++++++++++
>   target/riscv/riscv-qmp-cmds.c | 150 ----------------------------------
>   2 files changed, 148 insertions(+), 150 deletions(-)
> 
> diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
> index 478fd392ac6..ccb7eb44d02 100644
> --- a/target/riscv/monitor.c
> +++ b/target/riscv/monitor.c
> @@ -19,6 +19,8 @@
>    */
>   
>   #include "qemu/osdep.h"
> +#include "qemu/ctype.h"
> +#include "qemu/qemu-print.h"
>   #include "cpu.h"
>   #include "cpu_bits.h"
>   #include "monitor/monitor.h"
> @@ -241,3 +243,149 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
>   
>       mem_info_svxx(mon, env);
>   }
> +
> +/*
> + * We have way too many potential CSRs and regs being added
> + * regularly to register them in a static array.
> + *
> + * Declare an empty array instead, making get_monitor_def() use
> + * the target_get_monitor_def() API directly.
> + */
> +const MonitorDef monitor_defs[] = { { } };
> +const MonitorDef *target_monitor_defs(void)
> +{
> +    return monitor_defs;
> +}
> +
> +static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
> +                                 target_ulong *val, bool is_gprh)
> +{
> +    const char * const *reg_names;
> +    target_ulong *vals;
> +
> +    if (is_gprh) {
> +        reg_names = riscv_int_regnamesh;
> +        vals = env->gprh;
> +    } else {
> +        reg_names = riscv_int_regnames;
> +        vals = env->gpr;
> +    }
> +
> +    for (int i = 0; i < 32; i++) {
> +        g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
> +
> +        g_assert(reg_name[0]);
> +        g_assert(reg_name[1]);
> +
> +        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
> +            g_ascii_strcasecmp(reg_name[1], name) == 0) {
> +            *val = vals[i];
> +            return true;
> +        }
> +    }
> +
> +    return false;
> +}
> +
> +static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
> +{
> +    if (qemu_tolower(name[0]) != 'f') {
> +        return false;
> +    }
> +
> +    for (int i = 0; i < 32; i++) {
> +        g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
> +
> +        g_assert(reg_name[0]);
> +        g_assert(reg_name[1]);
> +
> +        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
> +            g_ascii_strcasecmp(reg_name[1], name) == 0) {
> +            *val = env->fpr[i];
> +            return true;
> +        }
> +    }
> +
> +    return false;
> +}
> +
> +static bool reg_is_vreg(const char *name)
> +{
> +    if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
> +        return false;
> +    }
> +
> +    for (int i = 0; i < 32; i++) {
> +        if (strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
> +            return true;
> +        }
> +    }
> +
> +    return false;
> +}
> +
> +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
> +{
> +    CPURISCVState *env = &RISCV_CPU(cs)->env;
> +    target_ulong val = 0;
> +    uint64_t val64 = 0;
> +    int i;
> +
> +    if (reg_is_ulong_integer(env, name, &val, false) ||
> +        reg_is_ulong_integer(env, name, &val, true)) {
> +        *pval = val;
> +        return 0;
> +    }
> +
> +    if (reg_is_u64_fpu(env, name, &val64)) {
> +        *pval = val64;
> +        return 0;
> +    }
> +
> +    if (reg_is_vreg(name)) {
> +        if (!riscv_cpu_cfg(env)->ext_zve32x) {
> +            return -EINVAL;
> +        }
> +
> +        qemu_printf("Unable to print the value of vector "
> +                    "vreg '%s' from this API\n", name);
> +
> +        /*
> +         * We're returning 0 because returning -EINVAL triggers
> +         * an 'unknown register' message in exp_unary() later,
> +         * which feels ankward after our own error message.
> +         */
> +        *pval = 0;
> +        return 0;
> +    }
> +
> +    for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
> +        RISCVException res;
> +        int csrno = i;
> +
> +        /*
> +         * Early skip when possible since we're going
> +         * through a lot of NULL entries.
> +         */
> +        if (csr_ops[csrno].predicate == NULL) {
> +            continue;
> +        }
> +
> +        if (strcasecmp(csr_ops[csrno].name, name) != 0) {
> +            continue;
> +        }
> +
> +        res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
> +
> +        /*
> +         * Rely on the smode, hmode, etc, predicates within csr.c
> +         * to do the filtering of the registers that are present.
> +         */
> +        if (res == RISCV_EXCP_NONE) {
> +            *pval = val;
> +            return 0;
> +        }
> +    }
> +
> +    return -EINVAL;
> +}
> diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
> index d5e9bec0f86..8a1856c50e0 100644
> --- a/target/riscv/riscv-qmp-cmds.c
> +++ b/target/riscv/riscv-qmp-cmds.c
> @@ -31,10 +31,6 @@
>   #include "qapi/qobject-input-visitor.h"
>   #include "qapi/visitor.h"
>   #include "qom/qom-qobject.h"
> -#include "qemu/ctype.h"
> -#include "qemu/qemu-print.h"
> -#include "monitor/hmp.h"
> -#include "monitor/hmp-target.h"
>   #include "system/kvm.h"
>   #include "system/tcg.h"
>   #include "cpu-qom.h"
> @@ -244,149 +240,3 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
>   
>       return expansion_info;
>   }
> -
> -/*
> - * We have way too many potential CSRs and regs being added
> - * regularly to register them in a static array.
> - *
> - * Declare an empty array instead, making get_monitor_def() use
> - * the target_get_monitor_def() API directly.
> - */
> -const MonitorDef monitor_defs[] = { { } };
> -const MonitorDef *target_monitor_defs(void)
> -{
> -    return monitor_defs;
> -}
> -
> -static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
> -                                 target_ulong *val, bool is_gprh)
> -{
> -    const char * const *reg_names;
> -    target_ulong *vals;
> -
> -    if (is_gprh) {
> -        reg_names = riscv_int_regnamesh;
> -        vals = env->gprh;
> -    } else {
> -        reg_names = riscv_int_regnames;
> -        vals = env->gpr;
> -    }
> -
> -    for (int i = 0; i < 32; i++) {
> -        g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
> -
> -        g_assert(reg_name[0]);
> -        g_assert(reg_name[1]);
> -
> -        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
> -            g_ascii_strcasecmp(reg_name[1], name) == 0) {
> -            *val = vals[i];
> -            return true;
> -        }
> -    }
> -
> -    return false;
> -}
> -
> -static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
> -{
> -    if (qemu_tolower(name[0]) != 'f') {
> -        return false;
> -    }
> -
> -    for (int i = 0; i < 32; i++) {
> -        g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
> -
> -        g_assert(reg_name[0]);
> -        g_assert(reg_name[1]);
> -
> -        if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
> -            g_ascii_strcasecmp(reg_name[1], name) == 0) {
> -            *val = env->fpr[i];
> -            return true;
> -        }
> -    }
> -
> -    return false;
> -}
> -
> -static bool reg_is_vreg(const char *name)
> -{
> -    if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
> -        return false;
> -    }
> -
> -    for (int i = 0; i < 32; i++) {
> -        if (strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
> -            return true;
> -        }
> -    }
> -
> -    return false;
> -}
> -
> -int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
> -{
> -    CPURISCVState *env = &RISCV_CPU(cs)->env;
> -    target_ulong val = 0;
> -    uint64_t val64 = 0;
> -    int i;
> -
> -    if (reg_is_ulong_integer(env, name, &val, false) ||
> -        reg_is_ulong_integer(env, name, &val, true)) {
> -        *pval = val;
> -        return 0;
> -    }
> -
> -    if (reg_is_u64_fpu(env, name, &val64)) {
> -        *pval = val64;
> -        return 0;
> -    }
> -
> -    if (reg_is_vreg(name)) {
> -        if (!riscv_cpu_cfg(env)->ext_zve32x) {
> -            return -EINVAL;
> -        }
> -
> -        qemu_printf("Unable to print the value of vector "
> -                    "vreg '%s' from this API\n", name);
> -
> -        /*
> -         * We're returning 0 because returning -EINVAL triggers
> -         * an 'unknown register' message in exp_unary() later,
> -         * which feels ankward after our own error message.
> -         */
> -        *pval = 0;
> -        return 0;
> -    }
> -
> -    for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
> -        RISCVException res;
> -        int csrno = i;
> -
> -        /*
> -         * Early skip when possible since we're going
> -         * through a lot of NULL entries.
> -         */
> -        if (csr_ops[csrno].predicate == NULL) {
> -            continue;
> -        }
> -
> -        if (strcasecmp(csr_ops[csrno].name, name) != 0) {
> -            continue;
> -        }
> -
> -        res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
> -
> -        /*
> -         * Rely on the smode, hmode, etc, predicates within csr.c
> -         * to do the filtering of the registers that are present.
> -         */
> -        if (res == RISCV_EXCP_NONE) {
> -            *pval = val;
> -            return 0;
> -        }
> -    }
> -
> -    return -EINVAL;
> -}


Re: [PATCH v2 06/50] target/riscv: Extract monitor-related code to monitor.c
Posted by Pierrick Bouvier 1 month ago
On 2/19/26 11:19 AM, Philippe Mathieu-Daudé wrote:
> Keep riscv-qmp-cmds.c for QMP, use monitor.c for HMP.
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   target/riscv/monitor.c        | 148 +++++++++++++++++++++++++++++++++
>   target/riscv/riscv-qmp-cmds.c | 150 ----------------------------------
>   2 files changed, 148 insertions(+), 150 deletions(-)
> 

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>