Message ID | 1610427124-49887-4-git-send-email-bmeng.cn@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | target/riscv: Generate the GDB XML file for CSR registers dynamically | expand |
On Mon, Jan 11, 2021 at 8:55 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > From: Bin Meng <bin.meng@windriver.com> > > 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 <bin.meng@windriver.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > > target/riscv/cpu.h | 2 + > target/riscv/cpu.c | 12 ++ > target/riscv/gdbstub.c | 308 +++++++------------------------------------------ > 3 files changed, 58 insertions(+), 264 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 6684316..f810169 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/cpu.c b/target/riscv/cpu.c > index dfe5d4e..c0dd646 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); > @@ -607,6 +618,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) > cc->write_elf32_note = riscv_cpu_write_elf32_note; > #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/gdbstub.c b/target/riscv/gdbstub.c > index eba12a8..5f96b7e 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, "<?xml version=\"1.0\"?>"); > + g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">"); > + g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">"); > + > + 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, "<reg name=\"%s\"", csr_ops[i].name); > + } else { > + g_string_append_printf(s, "<reg name=\"csr%03x\"", i); > + } > + g_string_append_printf(s, " bitsize=\"%d\"", bitsize); > + g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i); > + } > + } > + > + g_string_append_printf(s, "</feature>"); > + > + 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); > } > -- > 2.7.4 > >
On Fri, Jan 15, 2021 at 1:59 PM Alistair Francis <alistair23@gmail.com> wrote: > > On Mon, Jan 11, 2021 at 8:55 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > > > From: Bin Meng <bin.meng@windriver.com> > > > > 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 Do you mind rebasing this patch on the current riscv-to-apply.next branch: https://github.com/alistair23/qemu/tree/riscv-to-apply.next Alistair > > > > Signed-off-by: Bin Meng <bin.meng@windriver.com> > > Reviewed-by: Alistair Francis <alistair.francis@wdc.com> > > Alistair > > > --- > > > > target/riscv/cpu.h | 2 + > > target/riscv/cpu.c | 12 ++ > > target/riscv/gdbstub.c | 308 +++++++------------------------------------------ > > 3 files changed, 58 insertions(+), 264 deletions(-) > > > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > > index 6684316..f810169 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/cpu.c b/target/riscv/cpu.c > > index dfe5d4e..c0dd646 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); > > @@ -607,6 +618,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) > > cc->write_elf32_note = riscv_cpu_write_elf32_note; > > #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/gdbstub.c b/target/riscv/gdbstub.c > > index eba12a8..5f96b7e 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, "<?xml version=\"1.0\"?>"); > > + g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">"); > > + g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">"); > > + > > + 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, "<reg name=\"%s\"", csr_ops[i].name); > > + } else { > > + g_string_append_printf(s, "<reg name=\"csr%03x\"", i); > > + } > > + g_string_append_printf(s, " bitsize=\"%d\"", bitsize); > > + g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i); > > + } > > + } > > + > > + g_string_append_printf(s, "</feature>"); > > + > > + 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); > > } > > -- > > 2.7.4 > > > >
On Sat, Jan 16, 2021 at 6:08 AM Alistair Francis <alistair23@gmail.com> wrote: > > On Fri, Jan 15, 2021 at 1:59 PM Alistair Francis <alistair23@gmail.com> wrote: > > > > On Mon, Jan 11, 2021 at 8:55 PM Bin Meng <bmeng.cn@gmail.com> wrote: > > > > > > From: Bin Meng <bin.meng@windriver.com> > > > > > > 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 > > Do you mind rebasing this patch on the current riscv-to-apply.next > branch: https://github.com/alistair23/qemu/tree/riscv-to-apply.next > Yes, for sure. Regards, Bin
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6684316..f810169 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/cpu.c b/target/riscv/cpu.c index dfe5d4e..c0dd646 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); @@ -607,6 +618,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) cc->write_elf32_note = riscv_cpu_write_elf32_note; #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/gdbstub.c b/target/riscv/gdbstub.c index eba12a8..5f96b7e 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, "<?xml version=\"1.0\"?>"); + g_string_append_printf(s, "<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">"); + g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">"); + + 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, "<reg name=\"%s\"", csr_ops[i].name); + } else { + g_string_append_printf(s, "<reg name=\"csr%03x\"", i); + } + g_string_append_printf(s, " bitsize=\"%d\"", bitsize); + g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i); + } + } + + g_string_append_printf(s, "</feature>"); + + 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); }