diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2025-10-03 04:57:12 -0700 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2025-10-03 04:57:12 -0700 |
| commit | 91f80dda70aeedeb78979b07ad2a0e5503f7dd47 (patch) | |
| tree | 3ec229eb07158e34798e389d56506894d11e97ea /target/riscv/riscv-qmp-cmds.c | |
| parent | 517e9b4862cc9798b7a24b1935d94c2f96787f12 (diff) | |
| parent | ad2a0aa2824b1dac9f61bac33980e866e9a88856 (diff) | |
| download | focaccia-qemu-91f80dda70aeedeb78979b07ad2a0e5503f7dd47.tar.gz focaccia-qemu-91f80dda70aeedeb78979b07ad2a0e5503f7dd47.zip | |
Merge tag 'pull-riscv-to-apply-20251003-3' of https://github.com/alistair23/qemu into staging
First RISC-V PR for 10.2 * Fix MSI table size limit * Add riscv64 to FirmwareArchitecture * Sync RISC-V hwprobe with Linux * Implement MonitorDef HMP API * Update OpenSBI to v1.7 * Fix SiFive UART character drop issue and minor refactors * Fix RISC-V timer migration issues * Use riscv_cpu_is_32bit() when handling SBI_DBCN reg * Use riscv_csrr in riscv_csr_read * Align memory allocations to 2M on RISC-V * Do not use translator_ldl in opcode_at * Minor fixes of RISC-V CFI * Modify minimum VLEN rule * Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64 * Fixup IOMMU PDT Nested Walk * Fix endianness swap on compressed instructions * Update status of IOMMU kernel support # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEaukCtqfKh31tZZKWr3yVEwxTgBMFAmjfQhoACgkQr3yVEwxT # gBPnTg//eQ9GMFTLcW4kFMsVYeY8TbkmQN9Wnk+XubG92siGkzuNmfy36yo7oeib # dB6/h5JLjycjttOfgyx73/TKUucyZs+ZYkVVWWQCSU+sqPTA370MmGNM8CSmPms/ # lFuNIixd+sSUDIOod9zQHzxv+f3ZN2bjEAyzJAEhSXgTO+1xnOeJHHjxB5O2Z/a1 # ccd3Po1wR6nm2T4x88LcHDHj8svLsfG0G1RRkU+yeLu7J6Qpp0d/lOZI7if+AQqb # Nmz65n2uSuUEuNNQIxYaQp/nbkF3DSxi3mg3+hCQjF+hMjXL4hAhSEPril3MQjGi # 802nEaqG8Qdzec+bZiKt0c3e0f4SrnpDXDnz7NrtfSO6vXAvqqZuC8kTdZy8dsPU # 1D809ksZoNDIB87z89MQPsQ7k1Bs2Iq9pNpB9huD3mzY4DHqYhkzysAwc8Qhvimv # pBaeSDV66OrI/al5c0FqSN0LiLHvlRcwqiATiQwIdCV+PUe+cVPwIKq6ABQiYpVu # mvnzgEJ4r7iO92hOoAGM+eRC7krafF1/gbe3SDI3RLUTDPM6hcTRcluvBlpBdNDj # lIYXs89f0jBh0I4IRGm8ftqD9xPDP56mZVEIIjSWDRTT6mfZLxWWMmXC/OK63U7/ # bpJKohFOKy8P6SSvTACcLSOQlP3r+FRrmBOXs7S24U+Hr9xUep0= # =DGkt # -----END PGP SIGNATURE----- # gpg: Signature made Thu 02 Oct 2025 08:25:14 PM PDT # gpg: using RSA key 6AE902B6A7CA877D6D659296AF7C95130C538013 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6AE9 02B6 A7CA 877D 6D65 9296 AF7C 9513 0C53 8013 * tag 'pull-riscv-to-apply-20251003-3' of https://github.com/alistair23/qemu: (26 commits) docs: riscv-iommu: Update status of kernel support target/riscv: Fix endianness swap on compressed instructions hw/riscv/riscv-iommu: Fixup PDT Nested Walk target/riscv: rvv: Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64 target/riscv: rvv: Modify minimum VLEN according to enabled vector extensions target/riscv: rvv: Replace checking V by checking Zve32x target/riscv: Fix ssamoswap error handling target/riscv: Fix SSP CSR error handling in VU/VS mode target/riscv: Fix the mepc when sspopchk triggers the exception target/riscv: do not use translator_ldl in opcode_at qemu/osdep: align memory allocations to 2M on RISC-V target/riscv: use riscv_csrr in riscv_csr_read target/riscv/kvm: Use riscv_cpu_is_32bit() when handling SBI_DBCN reg target/riscv: Save stimer and vstimer in CPU vmstate hw/intc: Save timers array in RISC-V mtimer VMState migration: Add support for a variable-length array of UINT32 pointers hw/intc: Save time_delta in RISC-V mtimer VMState hw/char: sifive_uart: Add newline to error message hw/char: sifive_uart: Remove outdated comment about Tx FIFO hw/char: sifive_uart: Avoid pushing Tx FIFO when size is zero ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/riscv/riscv-qmp-cmds.c')
| -rw-r--r-- | target/riscv/riscv-qmp-cmds.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c index 8a1856c50e..c499f9b9a7 100644 --- a/target/riscv/riscv-qmp-cmds.c +++ b/target/riscv/riscv-qmp-cmds.c @@ -31,6 +31,10 @@ #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" @@ -240,3 +244,147 @@ 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_autofree char *reg_name = g_strdup(reg_names[i]); + char *reg1 = strtok(reg_name, "/"); + char *reg2 = strtok(NULL, "/"); + + if (strcasecmp(reg1, name) == 0 || + (reg2 && strcasecmp(reg2, 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_autofree char *reg_name = g_strdup(riscv_fpr_regnames[i]); + char *reg1 = strtok(reg_name, "/"); + char *reg2 = strtok(NULL, "/"); + + if (strcasecmp(reg1, name) == 0 || + (reg2 && strcasecmp(reg2, 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; +} |