@samitouri / QOSamiQemu / commits / c60750fe5e

target/riscv: Extract monitor-related code to monitor.c

Keep riscv-qmp-cmds.c for QMP, use monitor.c for HMP. Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260219191955.83815-7-philmd@linaro.org>

Philippe Mathieu-Daudé committed Feb 17, 2026 at 08:54 UTC c60750fe5ef287c7324c5d5945b0b5a392ac67ee
2 files changed +148 -150
target/riscv/monitor.c
+148
@@ -19,6 +19,8 @@
19 */
20
21 #include "qemu/osdep.h"
22 +#include "qemu/ctype.h"
23 +#include "qemu/qemu-print.h"
24 #include "cpu.h"
25 #include "cpu_bits.h"
26 #include "monitor/monitor.h"
@@ -241,3 +243,149 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
243
244 mem_info_svxx(mon, env);
245 }
246 +
247 +/*
248 + * We have way too many potential CSRs and regs being added
249 + * regularly to register them in a static array.
250 + *
251 + * Declare an empty array instead, making get_monitor_def() use
252 + * the target_get_monitor_def() API directly.
253 + */
254 +const MonitorDef monitor_defs[] = { { } };
255 +const MonitorDef *target_monitor_defs(void)
256 +{
257 + return monitor_defs;
258 +}
259 +
260 +static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
261 + target_ulong *val, bool is_gprh)
262 +{
263 + const char * const *reg_names;
264 + target_ulong *vals;
265 +
266 + if (is_gprh) {
267 + reg_names = riscv_int_regnamesh;
268 + vals = env->gprh;
269 + } else {
270 + reg_names = riscv_int_regnames;
271 + vals = env->gpr;
272 + }
273 +
274 + for (int i = 0; i < 32; i++) {
275 + g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
276 +
277 + g_assert(reg_name[0]);
278 + g_assert(reg_name[1]);
279 +
280 + if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
281 + g_ascii_strcasecmp(reg_name[1], name) == 0) {
282 + *val = vals[i];
283 + return true;
284 + }
285 + }
286 +
287 + return false;
288 +}
289 +
290 +static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
291 +{
292 + if (qemu_tolower(name[0]) != 'f') {
293 + return false;
294 + }
295 +
296 + for (int i = 0; i < 32; i++) {
297 + g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
298 +
299 + g_assert(reg_name[0]);
300 + g_assert(reg_name[1]);
301 +
302 + if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
303 + g_ascii_strcasecmp(reg_name[1], name) == 0) {
304 + *val = env->fpr[i];
305 + return true;
306 + }
307 + }
308 +
309 + return false;
310 +}
311 +
312 +static bool reg_is_vreg(const char *name)
313 +{
314 + if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
315 + return false;
316 + }
317 +
318 + for (int i = 0; i < 32; i++) {
319 + if (strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
320 + return true;
321 + }
322 + }
323 +
324 + return false;
325 +}
326 +
327 +int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
328 +{
329 + CPURISCVState *env = &RISCV_CPU(cs)->env;
330 + target_ulong val = 0;
331 + uint64_t val64 = 0;
332 + int i;
333 +
334 + if (reg_is_ulong_integer(env, name, &val, false) ||
335 + reg_is_ulong_integer(env, name, &val, true)) {
336 + *pval = val;
337 + return 0;
338 + }
339 +
340 + if (reg_is_u64_fpu(env, name, &val64)) {
341 + *pval = val64;
342 + return 0;
343 + }
344 +
345 + if (reg_is_vreg(name)) {
346 + if (!riscv_cpu_cfg(env)->ext_zve32x) {
347 + return -EINVAL;
348 + }
349 +
350 + qemu_printf("Unable to print the value of vector "
351 + "vreg '%s' from this API\n", name);
352 +
353 + /*
354 + * We're returning 0 because returning -EINVAL triggers
355 + * an 'unknown register' message in exp_unary() later,
356 + * which feels ankward after our own error message.
357 + */
358 + *pval = 0;
359 + return 0;
360 + }
361 +
362 + for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
363 + RISCVException res;
364 + int csrno = i;
365 +
366 + /*
367 + * Early skip when possible since we're going
368 + * through a lot of NULL entries.
369 + */
370 + if (csr_ops[csrno].predicate == NULL) {
371 + continue;
372 + }
373 +
374 + if (strcasecmp(csr_ops[csrno].name, name) != 0) {
375 + continue;
376 + }
377 +
378 + res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
379 +
380 + /*
381 + * Rely on the smode, hmode, etc, predicates within csr.c
382 + * to do the filtering of the registers that are present.
383 + */
384 + if (res == RISCV_EXCP_NONE) {
385 + *pval = val;
386 + return 0;
387 + }
388 + }
389 +
390 + return -EINVAL;
391 +}
target/riscv/riscv-qmp-cmds.c
-150
@@ -31,10 +31,6 @@
31 #include "qapi/qobject-input-visitor.h"
32 #include "qapi/visitor.h"
33 #include "qom/qom-qobject.h"
34 -#include "qemu/ctype.h"
35 -#include "qemu/qemu-print.h"
36 -#include "monitor/hmp.h"
37 -#include "monitor/hmp-target.h"
34 #include "system/kvm.h"
35 #include "system/tcg.h"
36 #include "cpu-qom.h"
@@ -244,149 +240,3 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
240
241 return expansion_info;
242 }
247 -
248 -/*
249 - * We have way too many potential CSRs and regs being added
250 - * regularly to register them in a static array.
251 - *
252 - * Declare an empty array instead, making get_monitor_def() use
253 - * the target_get_monitor_def() API directly.
254 - */
255 -const MonitorDef monitor_defs[] = { { } };
256 -const MonitorDef *target_monitor_defs(void)
257 -{
258 - return monitor_defs;
259 -}
260 -
261 -static bool reg_is_ulong_integer(CPURISCVState *env, const char *name,
262 - target_ulong *val, bool is_gprh)
263 -{
264 - const char * const *reg_names;
265 - target_ulong *vals;
266 -
267 - if (is_gprh) {
268 - reg_names = riscv_int_regnamesh;
269 - vals = env->gprh;
270 - } else {
271 - reg_names = riscv_int_regnames;
272 - vals = env->gpr;
273 - }
274 -
275 - for (int i = 0; i < 32; i++) {
276 - g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2);
277 -
278 - g_assert(reg_name[0]);
279 - g_assert(reg_name[1]);
280 -
281 - if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
282 - g_ascii_strcasecmp(reg_name[1], name) == 0) {
283 - *val = vals[i];
284 - return true;
285 - }
286 - }
287 -
288 - return false;
289 -}
290 -
291 -static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val)
292 -{
293 - if (qemu_tolower(name[0]) != 'f') {
294 - return false;
295 - }
296 -
297 - for (int i = 0; i < 32; i++) {
298 - g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2);
299 -
300 - g_assert(reg_name[0]);
301 - g_assert(reg_name[1]);
302 -
303 - if (g_ascii_strcasecmp(reg_name[0], name) == 0 ||
304 - g_ascii_strcasecmp(reg_name[1], name) == 0) {
305 - *val = env->fpr[i];
306 - return true;
307 - }
308 - }
309 -
310 - return false;
311 -}
312 -
313 -static bool reg_is_vreg(const char *name)
314 -{
315 - if (qemu_tolower(name[0]) != 'v' || strlen(name) > 3) {
316 - return false;
317 - }
318 -
319 - for (int i = 0; i < 32; i++) {
320 - if (strcasecmp(name, riscv_rvv_regnames[i]) == 0) {
321 - return true;
322 - }
323 - }
324 -
325 - return false;
326 -}
327 -
328 -int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
329 -{
330 - CPURISCVState *env = &RISCV_CPU(cs)->env;
331 - target_ulong val = 0;
332 - uint64_t val64 = 0;
333 - int i;
334 -
335 - if (reg_is_ulong_integer(env, name, &val, false) ||
336 - reg_is_ulong_integer(env, name, &val, true)) {
337 - *pval = val;
338 - return 0;
339 - }
340 -
341 - if (reg_is_u64_fpu(env, name, &val64)) {
342 - *pval = val64;
343 - return 0;
344 - }
345 -
346 - if (reg_is_vreg(name)) {
347 - if (!riscv_cpu_cfg(env)->ext_zve32x) {
348 - return -EINVAL;
349 - }
350 -
351 - qemu_printf("Unable to print the value of vector "
352 - "vreg '%s' from this API\n", name);
353 -
354 - /*
355 - * We're returning 0 because returning -EINVAL triggers
356 - * an 'unknown register' message in exp_unary() later,
357 - * which feels ankward after our own error message.
358 - */
359 - *pval = 0;
360 - return 0;
361 - }
362 -
363 - for (i = 0; i < ARRAY_SIZE(csr_ops); i++) {
364 - RISCVException res;
365 - int csrno = i;
366 -
367 - /*
368 - * Early skip when possible since we're going
369 - * through a lot of NULL entries.
370 - */
371 - if (csr_ops[csrno].predicate == NULL) {
372 - continue;
373 - }
374 -
375 - if (strcasecmp(csr_ops[csrno].name, name) != 0) {
376 - continue;
377 - }
378 -
379 - res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
380 -
381 - /*
382 - * Rely on the smode, hmode, etc, predicates within csr.c
383 - * to do the filtering of the registers that are present.
384 - */
385 - if (res == RISCV_EXCP_NONE) {
386 - *pval = val;
387 - return 0;
388 - }
389 - }
390 -
391 - return -EINVAL;
392 -}