From edf647864bdab84ed4b1a4f47ea05be6bb075c69 Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Wed, 6 Jan 2021 21:41:41 +0100 Subject: gdb: riscv: Add target description Target description is not currently implemented in RISC-V architecture. Thus GDB won't set it properly when attached. The patch implements the target description response. Signed-off-by: Sylvain Pelissier Reviewed-by: Bin Meng Reviewed-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Message-id: 20210106204141.14027-1-sylvain.pelissier@gmail.com Signed-off-by: Alistair Francis --- target/riscv/cpu.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'target') diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 8227d7aea9..6aafe4e62c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -557,6 +557,18 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static gchar *riscv_gdb_arch_name(CPUState *cs) +{ + RISCVCPU *cpu = RISCV_CPU(cs); + CPURISCVState *env = &cpu->env; + + if (riscv_cpu_is_32bit(env)) { + return g_strdup("riscv:rv32"); + } else { + return g_strdup("riscv:rv64"); + } +} + static void riscv_cpu_class_init(ObjectClass *c, void *data) { RISCVCPUClass *mcc = RISCV_CPU_CLASS(c); @@ -592,6 +604,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) /* For now, mark unmigratable: */ cc->vmsd = &vmstate_riscv_cpu; #endif + cc->gdb_arch_name = riscv_gdb_arch_name; #ifdef CONFIG_TCG cc->tcg_initialize = riscv_translate_init; cc->tlb_fill = riscv_cpu_tlb_fill; -- cgit v1.2.3-55-g7522 From d102f19a2085ac931cb998e6153b73248cca49f1 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Wed, 23 Dec 2020 11:25:53 -0800 Subject: target/riscv/pmp: Raise exception if no PMP entry is configured As per the privilege specification, any access from S/U mode should fail if no pmp region is configured. Signed-off-by: Atish Patra Reviewed-by: Alistair Francis Message-id: 20201223192553.332508-1-atish.patra@wdc.com Signed-off-by: Alistair Francis --- target/riscv/op_helper.c | 5 +++++ target/riscv/pmp.c | 4 ++-- target/riscv/pmp.h | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'target') diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index d55def76cf..1eddcb94de 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -150,6 +150,11 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb) uint64_t mstatus = env->mstatus; target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP); + + if (!pmp_get_num_rules(env) && (prev_priv != PRV_M)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + } + target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV); mstatus = set_field(mstatus, MSTATUS_MIE, get_field(mstatus, MSTATUS_MPIE)); diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 2eda8e1e2f..80d0334e1b 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -74,7 +74,7 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index) /* * Count the number of active rules. */ -static inline uint32_t pmp_get_num_rules(CPURISCVState *env) +uint32_t pmp_get_num_rules(CPURISCVState *env) { return env->pmp_state.num_rules; } @@ -237,7 +237,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, /* Short cut if no rules */ if (0 == pmp_get_num_rules(env)) { - return true; + return (env->priv == PRV_M) ? true : false; } if (size == 0) { diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h index 6c6b4c9bef..c8d5ef4a69 100644 --- a/target/riscv/pmp.h +++ b/target/riscv/pmp.h @@ -64,5 +64,6 @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa, target_ulong *tlb_size); void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index); void pmp_update_rule_nums(CPURISCVState *env); +uint32_t pmp_get_num_rules(CPURISCVState *env); #endif -- cgit v1.2.3-55-g7522 From 56118ee88ddf0498e0c8c4c81ef91d793c76866f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 12 Jan 2021 12:52:01 +0800 Subject: target/riscv: Make csr_ops[CSR_TABLE_SIZE] external In preparation to generate the CSR register list for GDB stub dynamically, change csr_ops[] to non-static so that it can be referenced externally. Signed-off-by: Bin Meng Reviewed-by: Alistair Francis Message-id: 1610427124-49887-2-git-send-email-bmeng.cn@gmail.com Signed-off-by: Alistair Francis --- target/riscv/cpu.h | 8 ++++++++ target/riscv/csr.c | 10 +--------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'target') diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6339e84819..464653d70d 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -478,6 +478,14 @@ typedef struct { riscv_csr_op_fn op; } riscv_csr_operations; +/* CSR function table constants */ +enum { + CSR_TABLE_SIZE = 0x1000 +}; + +/* CSR function table */ +extern riscv_csr_operations csr_ops[]; + void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops); void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops); diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 10ab82ed1f..507e8ee763 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -23,14 +23,6 @@ #include "qemu/main-loop.h" #include "exec/exec-all.h" -/* CSR function table */ -static riscv_csr_operations csr_ops[]; - -/* CSR function table constants */ -enum { - CSR_TABLE_SIZE = 0x1000 -}; - /* CSR function table public API */ void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops) { @@ -1378,7 +1370,7 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value, } /* Control and Status Register function table */ -static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { +riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* User Floating-Point CSRs */ [CSR_FFLAGS] = { fs, read_fflags, write_fflags }, [CSR_FRM] = { fs, read_frm, write_frm }, -- cgit v1.2.3-55-g7522 From 8ceac5dc3d7ded3cc408255da09a7f0e52ae8416 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Tue, 12 Jan 2021 12:52:02 +0800 Subject: target/riscv: Add CSR name in the CSR function table In preparation to generate the CSR register list for GDB stub dynamically, let's add the CSR name in the CSR function table. Signed-off-by: Bin Meng Reviewed-by: Alistair Francis Message-id: 1610427124-49887-3-git-send-email-bmeng.cn@gmail.com Signed-off-by: Alistair Francis --- target/riscv/cpu.h | 1 + target/riscv/csr.c | 332 +++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 249 insertions(+), 84 deletions(-) (limited to 'target') diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 464653d70d..2718617ef4 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -472,6 +472,7 @@ typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask); typedef struct { + const char *name; riscv_csr_predicate_fn predicate; riscv_csr_read_fn read; riscv_csr_write_fn write; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 507e8ee763..fd2e6363f3 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1372,112 +1372,276 @@ int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value, /* Control and Status Register function table */ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* User Floating-Point CSRs */ - [CSR_FFLAGS] = { fs, read_fflags, write_fflags }, - [CSR_FRM] = { fs, read_frm, write_frm }, - [CSR_FCSR] = { fs, read_fcsr, write_fcsr }, + [CSR_FFLAGS] = { "fflags", fs, read_fflags, write_fflags }, + [CSR_FRM] = { "frm", fs, read_frm, write_frm }, + [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr }, /* Vector CSRs */ - [CSR_VSTART] = { vs, read_vstart, write_vstart }, - [CSR_VXSAT] = { vs, read_vxsat, write_vxsat }, - [CSR_VXRM] = { vs, read_vxrm, write_vxrm }, - [CSR_VL] = { vs, read_vl }, - [CSR_VTYPE] = { vs, read_vtype }, + [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart }, + [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat }, + [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm }, + [CSR_VL] = { "vl", vs, read_vl }, + [CSR_VTYPE] = { "vtype", vs, read_vtype }, /* User Timers and Counters */ - [CSR_CYCLE] = { ctr, read_instret }, - [CSR_INSTRET] = { ctr, read_instret }, - [CSR_CYCLEH] = { ctr32, read_instreth }, - [CSR_INSTRETH] = { ctr32, read_instreth }, - - /* In privileged mode, the monitor will have to emulate TIME CSRs only if - * rdtime callback is not provided by machine/platform emulation */ - [CSR_TIME] = { ctr, read_time }, - [CSR_TIMEH] = { ctr32, read_timeh }, + [CSR_CYCLE] = { "cycle", ctr, read_instret }, + [CSR_INSTRET] = { "instret", ctr, read_instret }, + [CSR_CYCLEH] = { "cycleh", ctr32, read_instreth }, + [CSR_INSTRETH] = { "instreth", ctr32, read_instreth }, + + /* + * In privileged mode, the monitor will have to emulate TIME CSRs only if + * rdtime callback is not provided by machine/platform emulation. + */ + [CSR_TIME] = { "time", ctr, read_time }, + [CSR_TIMEH] = { "timeh", ctr32, read_timeh }, #if !defined(CONFIG_USER_ONLY) /* Machine Timers and Counters */ - [CSR_MCYCLE] = { any, read_instret }, - [CSR_MINSTRET] = { any, read_instret }, - [CSR_MCYCLEH] = { any32, read_instreth }, - [CSR_MINSTRETH] = { any32, read_instreth }, + [CSR_MCYCLE] = { "mcycle", any, read_instret }, + [CSR_MINSTRET] = { "minstret", any, read_instret }, + [CSR_MCYCLEH] = { "mcycleh", any32, read_instreth }, + [CSR_MINSTRETH] = { "minstreth", any32, read_instreth }, /* Machine Information Registers */ - [CSR_MVENDORID] = { any, read_zero }, - [CSR_MARCHID] = { any, read_zero }, - [CSR_MIMPID] = { any, read_zero }, - [CSR_MHARTID] = { any, read_mhartid }, + [CSR_MVENDORID] = { "mvendorid", any, read_zero }, + [CSR_MARCHID] = { "marchid", any, read_zero }, + [CSR_MIMPID] = { "mimpid", any, read_zero }, + [CSR_MHARTID] = { "mhartid", any, read_mhartid }, /* Machine Trap Setup */ - [CSR_MSTATUS] = { any, read_mstatus, write_mstatus }, - [CSR_MISA] = { any, read_misa, write_misa }, - [CSR_MIDELEG] = { any, read_mideleg, write_mideleg }, - [CSR_MEDELEG] = { any, read_medeleg, write_medeleg }, - [CSR_MIE] = { any, read_mie, write_mie }, - [CSR_MTVEC] = { any, read_mtvec, write_mtvec }, - [CSR_MCOUNTEREN] = { any, read_mcounteren, write_mcounteren }, + [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus }, + [CSR_MISA] = { "misa", any, read_misa, write_misa }, + [CSR_MIDELEG] = { "mideleg", any, read_mideleg, write_mideleg }, + [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg }, + [CSR_MIE] = { "mie", any, read_mie, write_mie }, + [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec }, + [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren }, - [CSR_MSTATUSH] = { any32, read_mstatush, write_mstatush }, + [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush }, - [CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren }, + [CSR_MSCOUNTEREN] = { "msounteren", any, read_mscounteren, write_mscounteren }, /* Machine Trap Handling */ - [CSR_MSCRATCH] = { any, read_mscratch, write_mscratch }, - [CSR_MEPC] = { any, read_mepc, write_mepc }, - [CSR_MCAUSE] = { any, read_mcause, write_mcause }, - [CSR_MBADADDR] = { any, read_mbadaddr, write_mbadaddr }, - [CSR_MIP] = { any, NULL, NULL, rmw_mip }, + [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch }, + [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc }, + [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause }, + [CSR_MBADADDR] = { "mbadaddr", any, read_mbadaddr, write_mbadaddr }, + [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip }, /* Supervisor Trap Setup */ - [CSR_SSTATUS] = { smode, read_sstatus, write_sstatus }, - [CSR_SIE] = { smode, read_sie, write_sie }, - [CSR_STVEC] = { smode, read_stvec, write_stvec }, - [CSR_SCOUNTEREN] = { smode, read_scounteren, write_scounteren }, + [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus }, + [CSR_SIE] = { "sie", smode, read_sie, write_sie }, + [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec }, + [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren }, /* Supervisor Trap Handling */ - [CSR_SSCRATCH] = { smode, read_sscratch, write_sscratch }, - [CSR_SEPC] = { smode, read_sepc, write_sepc }, - [CSR_SCAUSE] = { smode, read_scause, write_scause }, - [CSR_SBADADDR] = { smode, read_sbadaddr, write_sbadaddr }, - [CSR_SIP] = { smode, NULL, NULL, rmw_sip }, + [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch }, + [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc }, + [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause }, + [CSR_SBADADDR] = { "sbadaddr", smode, read_sbadaddr, write_sbadaddr }, + [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip }, /* Supervisor Protection and Translation */ - [CSR_SATP] = { smode, read_satp, write_satp }, - - [CSR_HSTATUS] = { hmode, read_hstatus, write_hstatus }, - [CSR_HEDELEG] = { hmode, read_hedeleg, write_hedeleg }, - [CSR_HIDELEG] = { hmode, read_hideleg, write_hideleg }, - [CSR_HVIP] = { hmode, NULL, NULL, rmw_hvip }, - [CSR_HIP] = { hmode, NULL, NULL, rmw_hip }, - [CSR_HIE] = { hmode, read_hie, write_hie }, - [CSR_HCOUNTEREN] = { hmode, read_hcounteren, write_hcounteren }, - [CSR_HGEIE] = { hmode, read_hgeie, write_hgeie }, - [CSR_HTVAL] = { hmode, read_htval, write_htval }, - [CSR_HTINST] = { hmode, read_htinst, write_htinst }, - [CSR_HGEIP] = { hmode, read_hgeip, write_hgeip }, - [CSR_HGATP] = { hmode, read_hgatp, write_hgatp }, - [CSR_HTIMEDELTA] = { hmode, read_htimedelta, write_htimedelta }, - [CSR_HTIMEDELTAH] = { hmode32, read_htimedeltah, write_htimedeltah}, - - [CSR_VSSTATUS] = { hmode, read_vsstatus, write_vsstatus }, - [CSR_VSIP] = { hmode, NULL, NULL, rmw_vsip }, - [CSR_VSIE] = { hmode, read_vsie, write_vsie }, - [CSR_VSTVEC] = { hmode, read_vstvec, write_vstvec }, - [CSR_VSSCRATCH] = { hmode, read_vsscratch, write_vsscratch }, - [CSR_VSEPC] = { hmode, read_vsepc, write_vsepc }, - [CSR_VSCAUSE] = { hmode, read_vscause, write_vscause }, - [CSR_VSTVAL] = { hmode, read_vstval, write_vstval }, - [CSR_VSATP] = { hmode, read_vsatp, write_vsatp }, - - [CSR_MTVAL2] = { hmode, read_mtval2, write_mtval2 }, - [CSR_MTINST] = { hmode, read_mtinst, write_mtinst }, + [CSR_SATP] = { "satp", smode, read_satp, write_satp }, + + [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus }, + [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg }, + [CSR_HIDELEG] = { "hideleg", hmode, read_hideleg, write_hideleg }, + [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip }, + [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip }, + [CSR_HIE] = { "hie", hmode, read_hie, write_hie }, + [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren }, + [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie }, + [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval }, + [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst }, + [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, write_hgeip }, + [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp }, + [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta }, + [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah }, + + [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus }, + [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip }, + [CSR_VSIE] = { "vsie", hmode, read_vsie, write_vsie }, + [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec }, + [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch }, + [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc }, + [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause }, + [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval }, + [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp }, + + [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2 }, + [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst }, /* Physical Memory Protection */ - [CSR_PMPCFG0 ... CSR_PMPCFG3] = { pmp, read_pmpcfg, write_pmpcfg }, - [CSR_PMPADDR0 ... CSR_PMPADDR15] = { pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg }, + [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg }, + [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg }, + [CSR_PMPCFG3] = { "pmpcfg3", pmp, read_pmpcfg, write_pmpcfg }, + [CSR_PMPADDR0] = { "pmpaddr0", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR1] = { "pmpaddr1", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR2] = { "pmpaddr2", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR3] = { "pmpaddr3", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR4] = { "pmpaddr4", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR5] = { "pmpaddr5", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR6] = { "pmpaddr6", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR7] = { "pmpaddr7", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR8] = { "pmpaddr8", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR9] = { "pmpaddr9", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR10] = { "pmpaddr10", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR11] = { "pmpaddr11", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR12] = { "pmpaddr12", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR13] = { "pmpaddr13", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr }, + [CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr }, /* Performance Counters */ - [CSR_HPMCOUNTER3 ... CSR_HPMCOUNTER31] = { ctr, read_zero }, - [CSR_MHPMCOUNTER3 ... CSR_MHPMCOUNTER31] = { any, read_zero }, - [CSR_MHPMEVENT3 ... CSR_MHPMEVENT31] = { any, read_zero }, - [CSR_HPMCOUNTER3H ... CSR_HPMCOUNTER31H] = { ctr32, read_zero }, - [CSR_MHPMCOUNTER3H ... CSR_MHPMCOUNTER31H] = { any32, read_zero }, + [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_zero }, + [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_zero }, + [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_zero }, + [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_zero }, + [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_zero }, + [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_zero }, + [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_zero }, + [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_zero }, + [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_zero }, + [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_zero }, + [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_zero }, + [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_zero }, + [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_zero }, + [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_zero }, + [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_zero }, + [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_zero }, + [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_zero }, + [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_zero }, + [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_zero }, + [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_zero }, + [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_zero }, + [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_zero }, + [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_zero }, + [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_zero }, + [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_zero }, + [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_zero }, + [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_zero }, + [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero }, + [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero }, + + [CSR_MHPMCOUNTER3] = { "mhpmcounter3", any, read_zero }, + [CSR_MHPMCOUNTER4] = { "mhpmcounter4", any, read_zero }, + [CSR_MHPMCOUNTER5] = { "mhpmcounter5", any, read_zero }, + [CSR_MHPMCOUNTER6] = { "mhpmcounter6", any, read_zero }, + [CSR_MHPMCOUNTER7] = { "mhpmcounter7", any, read_zero }, + [CSR_MHPMCOUNTER8] = { "mhpmcounter8", any, read_zero }, + [CSR_MHPMCOUNTER9] = { "mhpmcounter9", any, read_zero }, + [CSR_MHPMCOUNTER10] = { "mhpmcounter10", any, read_zero }, + [CSR_MHPMCOUNTER11] = { "mhpmcounter11", any, read_zero }, + [CSR_MHPMCOUNTER12] = { "mhpmcounter12", any, read_zero }, + [CSR_MHPMCOUNTER13] = { "mhpmcounter13", any, read_zero }, + [CSR_MHPMCOUNTER14] = { "mhpmcounter14", any, read_zero }, + [CSR_MHPMCOUNTER15] = { "mhpmcounter15", any, read_zero }, + [CSR_MHPMCOUNTER16] = { "mhpmcounter16", any, read_zero }, + [CSR_MHPMCOUNTER17] = { "mhpmcounter17", any, read_zero }, + [CSR_MHPMCOUNTER18] = { "mhpmcounter18", any, read_zero }, + [CSR_MHPMCOUNTER19] = { "mhpmcounter19", any, read_zero }, + [CSR_MHPMCOUNTER20] = { "mhpmcounter20", any, read_zero }, + [CSR_MHPMCOUNTER21] = { "mhpmcounter21", any, read_zero }, + [CSR_MHPMCOUNTER22] = { "mhpmcounter22", any, read_zero }, + [CSR_MHPMCOUNTER23] = { "mhpmcounter23", any, read_zero }, + [CSR_MHPMCOUNTER24] = { "mhpmcounter24", any, read_zero }, + [CSR_MHPMCOUNTER25] = { "mhpmcounter25", any, read_zero }, + [CSR_MHPMCOUNTER26] = { "mhpmcounter26", any, read_zero }, + [CSR_MHPMCOUNTER27] = { "mhpmcounter27", any, read_zero }, + [CSR_MHPMCOUNTER28] = { "mhpmcounter28", any, read_zero }, + [CSR_MHPMCOUNTER29] = { "mhpmcounter29", any, read_zero }, + [CSR_MHPMCOUNTER30] = { "mhpmcounter30", any, read_zero }, + [CSR_MHPMCOUNTER31] = { "mhpmcounter31", any, read_zero }, + + [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero }, + [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero }, + [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_zero }, + [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_zero }, + [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_zero }, + [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_zero }, + [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_zero }, + [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_zero }, + [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_zero }, + [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_zero }, + [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_zero }, + [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_zero }, + [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_zero }, + [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_zero }, + [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_zero }, + [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_zero }, + [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_zero }, + [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_zero }, + [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_zero }, + [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_zero }, + [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_zero }, + [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_zero }, + [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_zero }, + [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_zero }, + [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_zero }, + [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_zero }, + [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_zero }, + [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_zero }, + [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_zero }, + + [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_zero }, + [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_zero }, + [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_zero }, + [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_zero }, + [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_zero }, + [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_zero }, + [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_zero }, + [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_zero }, + [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_zero }, + [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_zero }, + [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_zero }, + [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_zero }, + [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_zero }, + [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_zero }, + [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_zero }, + [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_zero }, + [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_zero }, + [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_zero }, + [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_zero }, + [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_zero }, + [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_zero }, + [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_zero }, + [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_zero }, + [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_zero }, + [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_zero }, + [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_zero }, + [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_zero }, + [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_zero }, + [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_zero }, + + [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", any32, read_zero }, + [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", any32, read_zero }, + [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", any32, read_zero }, + [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", any32, read_zero }, + [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", any32, read_zero }, + [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", any32, read_zero }, + [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", any32, read_zero }, + [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32, read_zero }, + [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32, read_zero }, + [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32, read_zero }, + [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32, read_zero }, + [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32, read_zero }, + [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32, read_zero }, + [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32, read_zero }, + [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32, read_zero }, + [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32, read_zero }, + [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32, read_zero }, + [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32, read_zero }, + [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32, read_zero }, + [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32, read_zero }, + [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32, read_zero }, + [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32, read_zero }, + [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32, read_zero }, + [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32, read_zero }, + [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32, read_zero }, + [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32, read_zero }, + [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32, read_zero }, + [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32, read_zero }, + [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32, read_zero }, #endif /* !CONFIG_USER_ONLY */ }; -- cgit v1.2.3-55-g7522 From b93777e1b4999b1f51f1fa3398f5d400f75a4aab Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 16 Jan 2021 13:41:22 +0800 Subject: target/riscv: Generate the GDB XML file for CSR registers dynamically At present QEMU RISC-V uses a hardcoded XML to report the feature "org.gnu.gdb.riscv.csr" [1]. There are two major issues with the approach being used currently: - The XML does not specify the "regnum" field of a CSR entry, hence consecutive numbers are used by the remote GDB client to access CSRs. In QEMU we have to maintain a map table to convert the GDB number to the hardware number which is error prone. - The XML contains some CSRs that QEMU does not implement at all, which causes an "E14" response sent to remote GDB client. Change to generate the CSR register list dynamically, based on the availability presented in the CSR function table. This new approach will reflect a correct list of CSRs that QEMU actually implements. [1] https://sourceware.org/gdb/current/onlinedocs/gdb/RISC_002dV-Features.html#RISC_002dV-Features Signed-off-by: Bin Meng Reviewed-by: Alistair Francis Message-id: 20210116054123.5457-2-bmeng.cn@gmail.com Signed-off-by: Alistair Francis --- target/riscv/cpu.c | 12 ++ target/riscv/cpu.h | 2 + target/riscv/gdbstub.c | 308 +++++++------------------------------------------ 3 files changed, 58 insertions(+), 264 deletions(-) (limited to 'target') diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6aafe4e62c..27788021eb 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -569,6 +569,17 @@ static gchar *riscv_gdb_arch_name(CPUState *cs) } } +static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname) +{ + RISCVCPU *cpu = RISCV_CPU(cs); + + if (strcmp(xmlname, "riscv-csr.xml") == 0) { + return cpu->dyn_csr_xml; + } + + return NULL; +} + static void riscv_cpu_class_init(ObjectClass *c, void *data) { RISCVCPUClass *mcc = RISCV_CPU_CLASS(c); @@ -605,6 +616,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) cc->vmsd = &vmstate_riscv_cpu; #endif cc->gdb_arch_name = riscv_gdb_arch_name; + cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml; #ifdef CONFIG_TCG cc->tcg_initialize = riscv_translate_init; cc->tlb_fill = riscv_cpu_tlb_fill; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 2718617ef4..02758ae0eb 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -272,6 +272,8 @@ struct RISCVCPU { CPUNegativeOffsetState neg; CPURISCVState env; + char *dyn_csr_xml; + /* Configuration Settings */ struct { bool ext_i; diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c index eba12a86f2..5f96b7ea2a 100644 --- a/target/riscv/gdbstub.c +++ b/target/riscv/gdbstub.c @@ -20,256 +20,6 @@ #include "exec/gdbstub.h" #include "cpu.h" -/* - * The GDB CSR xml files list them in documentation order, not numerical order, - * and are missing entries for unnamed CSRs. So we need to map the gdb numbers - * to the hardware numbers. - */ - -static int csr_register_map[] = { - CSR_USTATUS, - CSR_UIE, - CSR_UTVEC, - CSR_USCRATCH, - CSR_UEPC, - CSR_UCAUSE, - CSR_UTVAL, - CSR_UIP, - CSR_FFLAGS, - CSR_FRM, - CSR_FCSR, - CSR_CYCLE, - CSR_TIME, - CSR_INSTRET, - CSR_HPMCOUNTER3, - CSR_HPMCOUNTER4, - CSR_HPMCOUNTER5, - CSR_HPMCOUNTER6, - CSR_HPMCOUNTER7, - CSR_HPMCOUNTER8, - CSR_HPMCOUNTER9, - CSR_HPMCOUNTER10, - CSR_HPMCOUNTER11, - CSR_HPMCOUNTER12, - CSR_HPMCOUNTER13, - CSR_HPMCOUNTER14, - CSR_HPMCOUNTER15, - CSR_HPMCOUNTER16, - CSR_HPMCOUNTER17, - CSR_HPMCOUNTER18, - CSR_HPMCOUNTER19, - CSR_HPMCOUNTER20, - CSR_HPMCOUNTER21, - CSR_HPMCOUNTER22, - CSR_HPMCOUNTER23, - CSR_HPMCOUNTER24, - CSR_HPMCOUNTER25, - CSR_HPMCOUNTER26, - CSR_HPMCOUNTER27, - CSR_HPMCOUNTER28, - CSR_HPMCOUNTER29, - CSR_HPMCOUNTER30, - CSR_HPMCOUNTER31, - CSR_CYCLEH, - CSR_TIMEH, - CSR_INSTRETH, - CSR_HPMCOUNTER3H, - CSR_HPMCOUNTER4H, - CSR_HPMCOUNTER5H, - CSR_HPMCOUNTER6H, - CSR_HPMCOUNTER7H, - CSR_HPMCOUNTER8H, - CSR_HPMCOUNTER9H, - CSR_HPMCOUNTER10H, - CSR_HPMCOUNTER11H, - CSR_HPMCOUNTER12H, - CSR_HPMCOUNTER13H, - CSR_HPMCOUNTER14H, - CSR_HPMCOUNTER15H, - CSR_HPMCOUNTER16H, - CSR_HPMCOUNTER17H, - CSR_HPMCOUNTER18H, - CSR_HPMCOUNTER19H, - CSR_HPMCOUNTER20H, - CSR_HPMCOUNTER21H, - CSR_HPMCOUNTER22H, - CSR_HPMCOUNTER23H, - CSR_HPMCOUNTER24H, - CSR_HPMCOUNTER25H, - CSR_HPMCOUNTER26H, - CSR_HPMCOUNTER27H, - CSR_HPMCOUNTER28H, - CSR_HPMCOUNTER29H, - CSR_HPMCOUNTER30H, - CSR_HPMCOUNTER31H, - CSR_SSTATUS, - CSR_SEDELEG, - CSR_SIDELEG, - CSR_SIE, - CSR_STVEC, - CSR_SCOUNTEREN, - CSR_SSCRATCH, - CSR_SEPC, - CSR_SCAUSE, - CSR_STVAL, - CSR_SIP, - CSR_SATP, - CSR_MVENDORID, - CSR_MARCHID, - CSR_MIMPID, - CSR_MHARTID, - CSR_MSTATUS, - CSR_MISA, - CSR_MEDELEG, - CSR_MIDELEG, - CSR_MIE, - CSR_MTVEC, - CSR_MCOUNTEREN, - CSR_MSCRATCH, - CSR_MEPC, - CSR_MCAUSE, - CSR_MTVAL, - CSR_MIP, - CSR_MTINST, - CSR_MTVAL2, - CSR_PMPCFG0, - CSR_PMPCFG1, - CSR_PMPCFG2, - CSR_PMPCFG3, - CSR_PMPADDR0, - CSR_PMPADDR1, - CSR_PMPADDR2, - CSR_PMPADDR3, - CSR_PMPADDR4, - CSR_PMPADDR5, - CSR_PMPADDR6, - CSR_PMPADDR7, - CSR_PMPADDR8, - CSR_PMPADDR9, - CSR_PMPADDR10, - CSR_PMPADDR11, - CSR_PMPADDR12, - CSR_PMPADDR13, - CSR_PMPADDR14, - CSR_PMPADDR15, - CSR_MCYCLE, - CSR_MINSTRET, - CSR_MHPMCOUNTER3, - CSR_MHPMCOUNTER4, - CSR_MHPMCOUNTER5, - CSR_MHPMCOUNTER6, - CSR_MHPMCOUNTER7, - CSR_MHPMCOUNTER8, - CSR_MHPMCOUNTER9, - CSR_MHPMCOUNTER10, - CSR_MHPMCOUNTER11, - CSR_MHPMCOUNTER12, - CSR_MHPMCOUNTER13, - CSR_MHPMCOUNTER14, - CSR_MHPMCOUNTER15, - CSR_MHPMCOUNTER16, - CSR_MHPMCOUNTER17, - CSR_MHPMCOUNTER18, - CSR_MHPMCOUNTER19, - CSR_MHPMCOUNTER20, - CSR_MHPMCOUNTER21, - CSR_MHPMCOUNTER22, - CSR_MHPMCOUNTER23, - CSR_MHPMCOUNTER24, - CSR_MHPMCOUNTER25, - CSR_MHPMCOUNTER26, - CSR_MHPMCOUNTER27, - CSR_MHPMCOUNTER28, - CSR_MHPMCOUNTER29, - CSR_MHPMCOUNTER30, - CSR_MHPMCOUNTER31, - CSR_MCYCLEH, - CSR_MINSTRETH, - CSR_MHPMCOUNTER3H, - CSR_MHPMCOUNTER4H, - CSR_MHPMCOUNTER5H, - CSR_MHPMCOUNTER6H, - CSR_MHPMCOUNTER7H, - CSR_MHPMCOUNTER8H, - CSR_MHPMCOUNTER9H, - CSR_MHPMCOUNTER10H, - CSR_MHPMCOUNTER11H, - CSR_MHPMCOUNTER12H, - CSR_MHPMCOUNTER13H, - CSR_MHPMCOUNTER14H, - CSR_MHPMCOUNTER15H, - CSR_MHPMCOUNTER16H, - CSR_MHPMCOUNTER17H, - CSR_MHPMCOUNTER18H, - CSR_MHPMCOUNTER19H, - CSR_MHPMCOUNTER20H, - CSR_MHPMCOUNTER21H, - CSR_MHPMCOUNTER22H, - CSR_MHPMCOUNTER23H, - CSR_MHPMCOUNTER24H, - CSR_MHPMCOUNTER25H, - CSR_MHPMCOUNTER26H, - CSR_MHPMCOUNTER27H, - CSR_MHPMCOUNTER28H, - CSR_MHPMCOUNTER29H, - CSR_MHPMCOUNTER30H, - CSR_MHPMCOUNTER31H, - CSR_MHPMEVENT3, - CSR_MHPMEVENT4, - CSR_MHPMEVENT5, - CSR_MHPMEVENT6, - CSR_MHPMEVENT7, - CSR_MHPMEVENT8, - CSR_MHPMEVENT9, - CSR_MHPMEVENT10, - CSR_MHPMEVENT11, - CSR_MHPMEVENT12, - CSR_MHPMEVENT13, - CSR_MHPMEVENT14, - CSR_MHPMEVENT15, - CSR_MHPMEVENT16, - CSR_MHPMEVENT17, - CSR_MHPMEVENT18, - CSR_MHPMEVENT19, - CSR_MHPMEVENT20, - CSR_MHPMEVENT21, - CSR_MHPMEVENT22, - CSR_MHPMEVENT23, - CSR_MHPMEVENT24, - CSR_MHPMEVENT25, - CSR_MHPMEVENT26, - CSR_MHPMEVENT27, - CSR_MHPMEVENT28, - CSR_MHPMEVENT29, - CSR_MHPMEVENT30, - CSR_MHPMEVENT31, - CSR_TSELECT, - CSR_TDATA1, - CSR_TDATA2, - CSR_TDATA3, - CSR_DCSR, - CSR_DPC, - CSR_DSCRATCH, - CSR_HSTATUS, - CSR_HEDELEG, - CSR_HIDELEG, - CSR_HIE, - CSR_HCOUNTEREN, - CSR_HTVAL, - CSR_HIP, - CSR_HTINST, - CSR_HGATP, - CSR_MBASE, - CSR_MBOUND, - CSR_MIBASE, - CSR_MIBOUND, - CSR_MDBASE, - CSR_MDBOUND, - CSR_MUCOUNTEREN, - CSR_MSCOUNTEREN, - CSR_MHCOUNTEREN, -}; - int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { RISCVCPU *cpu = RISCV_CPU(cs); @@ -315,11 +65,11 @@ static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n) target_ulong val = 0; int result; /* - * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP + * CSR_FFLAGS is at index 1 in csr_register, and gdb says it is FP * register 33, so we recalculate the map index. * This also works for CSR_FRM and CSR_FCSR. */ - result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], &val, + result = riscv_csrrw_debug(env, n - 32, &val, 0, 0); if (result == 0) { return gdb_get_regl(buf, val); @@ -338,11 +88,11 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) target_ulong val = ldtul_p(mem_buf); int result; /* - * CSR_FFLAGS is at index 8 in csr_register, and gdb says it is FP + * CSR_FFLAGS is at index 1 in csr_register, and gdb says it is FP * register 33, so we recalculate the map index. * This also works for CSR_FRM and CSR_FCSR. */ - result = riscv_csrrw_debug(env, n - 33 + csr_register_map[8], NULL, + result = riscv_csrrw_debug(env, n - 32, NULL, val, -1); if (result == 0) { return sizeof(target_ulong); @@ -353,11 +103,11 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n) static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n) { - if (n < ARRAY_SIZE(csr_register_map)) { + if (n < CSR_TABLE_SIZE) { target_ulong val = 0; int result; - result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0); + result = riscv_csrrw_debug(env, n, &val, 0, 0); if (result == 0) { return gdb_get_regl(buf, val); } @@ -367,11 +117,11 @@ static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n) static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n) { - if (n < ARRAY_SIZE(csr_register_map)) { + if (n < CSR_TABLE_SIZE) { target_ulong val = ldtul_p(mem_buf); int result; - result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1); + result = riscv_csrrw_debug(env, n, NULL, val, -1); if (result == 0) { return sizeof(target_ulong); } @@ -405,6 +155,38 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs, uint8_t *mem_buf, int n) return 0; } +static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg) +{ + RISCVCPU *cpu = RISCV_CPU(cs); + CPURISCVState *env = &cpu->env; + GString *s = g_string_new(NULL); + riscv_csr_predicate_fn predicate; + int bitsize = riscv_cpu_is_32bit(env) ? 32 : 64; + int i; + + g_string_printf(s, ""); + g_string_append_printf(s, ""); + g_string_append_printf(s, ""); + + for (i = 0; i < CSR_TABLE_SIZE; i++) { + predicate = csr_ops[i].predicate; + if (predicate && !predicate(env, i)) { + if (csr_ops[i].name) { + g_string_append_printf(s, "", base_reg + i); + } + } + + g_string_append_printf(s, ""); + + cpu->dyn_csr_xml = g_string_free(s, false); + return CSR_TABLE_SIZE; +} + void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) { RISCVCPU *cpu = RISCV_CPU(cs); @@ -417,16 +199,14 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs) 36, "riscv-32bit-fpu.xml", 0); } #if defined(TARGET_RISCV32) - gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, - 240, "riscv-32bit-csr.xml", 0); - gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual, 1, "riscv-32bit-virtual.xml", 0); #elif defined(TARGET_RISCV64) - gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, - 240, "riscv-64bit-csr.xml", 0); - gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual, 1, "riscv-64bit-virtual.xml", 0); #endif + + gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr, + riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs), + "riscv-csr.xml", 0); } -- cgit v1.2.3-55-g7522