The gdb CSR xml file has registers in documentation order, not numerical
order, so we need a table to map the register numbers. This also adds
fairly standard gdb hooks to access xml specified registers.
Signed-off-by: Jim Wilson <jimw@sifive.com>
---
target/riscv/cpu.c | 9 +-
target/riscv/cpu.h | 2 +
target/riscv/gdbstub.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 347 insertions(+), 12 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 28d7e53..c23bd01 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -311,6 +311,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
return;
}
+ riscv_cpu_register_gdb_regs_for_features(cs);
+
qemu_init_vcpu(cs);
cpu_reset(cs);
@@ -351,7 +353,12 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
cc->gdb_read_register = riscv_cpu_gdb_read_register;
cc->gdb_write_register = riscv_cpu_gdb_write_register;
- cc->gdb_num_core_regs = 65;
+ cc->gdb_num_core_regs = 33;
+#if defined(TARGET_RISCV32)
+ cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
+#elif defined(TARGET_RISCV64)
+ cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
+#endif
cc->gdb_stop_before_watchpoint = true;
cc->disas_set_info = riscv_cpu_disas_set_info;
#ifdef CONFIG_USER_ONLY
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 04a050e..c10e86c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -329,6 +329,8 @@ typedef struct {
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
+void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
+
#include "exec/cpu-all.h"
#endif /* RISCV_CPU_H */
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 3cabb21..621206d 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -21,6 +21,255 @@
#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_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_HTVEC,
+ CSR_HSCRATCH,
+ CSR_HEPC,
+ CSR_HCAUSE,
+ CSR_HBADADDR,
+ CSR_HIP,
+ 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, uint8_t *mem_buf, int n)
{
RISCVCPU *cpu = RISCV_CPU(cs);
@@ -30,13 +279,6 @@ int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
return gdb_get_regl(mem_buf, env->gpr[n]);
} else if (n == 32) {
return gdb_get_regl(mem_buf, env->pc);
- } else if (n < 65) {
- return gdb_get_reg64(mem_buf, env->fpr[n - 33]);
- } else if (n < 4096 + 65) {
- target_ulong val = 0;
- if (riscv_csrrw(env, n - 65, &val, 0, 0) == 0) {
- return gdb_get_regl(mem_buf, val);
- }
}
return 0;
}
@@ -55,14 +297,98 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
} else if (n == 32) {
env->pc = ldtul_p(mem_buf);
return sizeof(target_ulong);
- } else if (n < 65) {
- env->fpr[n - 33] = ldq_p(mem_buf); /* always 64-bit */
+ }
+ return 0;
+}
+
+static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
+{
+ if (n < 32) {
+ return gdb_get_reg64(mem_buf, env->fpr[n]);
+ } else if (n < 35) {
+ target_ulong val = 0;
+ int result;
+ /*
+ * CSR_FFLAGS is 0x001, and gdb says it is FP register 32, so we
+ * subtract 31 to map the gdb FP register number to the CSR number.
+ * This also works for CSR_FRM and CSR_FCSR.
+ */
+ result = riscv_csrrw_debug(env, n - 31, &val, 0, 0);
+ if (result == 0) {
+ return gdb_get_regl(mem_buf, val);
+ }
+ }
+ return 0;
+}
+
+static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
+{
+ if (n < 32) {
+ env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
return sizeof(uint64_t);
- } else if (n < 4096 + 65) {
+ } else if (n < 35) {
target_ulong val = ldtul_p(mem_buf);
- if (riscv_csrrw(env, n - 65, NULL, val, -1) == 0) {
+ int result;
+ /*
+ * CSR_FFLAGS is 0x001, and gdb says it is FP register 32, so we
+ * subtract 31 to map the gdb FP register number to the CSR number.
+ * This also works for CSR_FRM and CSR_FCSR.
+ */
+ result = riscv_csrrw_debug(env, n - 31, NULL, val, -1);
+ if (result == 0) {
return sizeof(target_ulong);
}
}
return 0;
}
+
+static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
+{
+ if (n < ARRAY_SIZE(csr_register_map)) {
+ target_ulong val = 0;
+ int result;
+
+ result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0);
+ if (result == 0) {
+ return gdb_get_regl(mem_buf, val);
+ }
+ }
+ return 0;
+}
+
+static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
+{
+ if (n < ARRAY_SIZE(csr_register_map)) {
+ target_ulong val = ldtul_p(mem_buf);
+ int result;
+
+ result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1);
+ if (result == 0) {
+ return sizeof(target_ulong);
+ }
+ }
+ return 0;
+}
+
+void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
+{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ CPURISCVState *env = &cpu->env;
+#if defined(TARGET_RISCV32)
+ if (env->misa & RVF) {
+ gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
+ 35, "riscv-32bit-fpu.xml", 0);
+ }
+
+ gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
+ 4096, "riscv-32bit-csr.xml", 0);
+#elif defined(TARGET_RISCV64)
+ if (env->misa & RVF) {
+ gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
+ 35, "riscv-64bit-fpu.xml", 0);
+ }
+
+ gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
+ 4096, "riscv-64bit-csr.xml", 0);
+#endif
+}
--
2.7.4
On Tue, Feb 12, 2019 at 3:10 PM Jim Wilson <jimw@sifive.com> wrote:
>
> The gdb CSR xml file has registers in documentation order, not numerical
> order, so we need a table to map the register numbers. This also adds
> fairly standard gdb hooks to access xml specified registers.
>
> Signed-off-by: Jim Wilson <jimw@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu.c | 9 +-
> target/riscv/cpu.h | 2 +
> target/riscv/gdbstub.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 347 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 28d7e53..c23bd01 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -311,6 +311,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
> return;
> }
>
> + riscv_cpu_register_gdb_regs_for_features(cs);
> +
> qemu_init_vcpu(cs);
> cpu_reset(cs);
>
> @@ -351,7 +353,12 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
> cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
> cc->gdb_read_register = riscv_cpu_gdb_read_register;
> cc->gdb_write_register = riscv_cpu_gdb_write_register;
> - cc->gdb_num_core_regs = 65;
> + cc->gdb_num_core_regs = 33;
> +#if defined(TARGET_RISCV32)
> + cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
> +#elif defined(TARGET_RISCV64)
> + cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
> +#endif
> cc->gdb_stop_before_watchpoint = true;
> cc->disas_set_info = riscv_cpu_disas_set_info;
> #ifdef CONFIG_USER_ONLY
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 04a050e..c10e86c 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -329,6 +329,8 @@ typedef struct {
> void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
> void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> +void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
> +
> #include "exec/cpu-all.h"
>
> #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 3cabb21..621206d 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -21,6 +21,255 @@
> #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_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_HTVEC,
> + CSR_HSCRATCH,
> + CSR_HEPC,
> + CSR_HCAUSE,
> + CSR_HBADADDR,
> + CSR_HIP,
> + 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, uint8_t *mem_buf, int n)
> {
> RISCVCPU *cpu = RISCV_CPU(cs);
> @@ -30,13 +279,6 @@ int riscv_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
> return gdb_get_regl(mem_buf, env->gpr[n]);
> } else if (n == 32) {
> return gdb_get_regl(mem_buf, env->pc);
> - } else if (n < 65) {
> - return gdb_get_reg64(mem_buf, env->fpr[n - 33]);
> - } else if (n < 4096 + 65) {
> - target_ulong val = 0;
> - if (riscv_csrrw(env, n - 65, &val, 0, 0) == 0) {
> - return gdb_get_regl(mem_buf, val);
> - }
> }
> return 0;
> }
> @@ -55,14 +297,98 @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
> } else if (n == 32) {
> env->pc = ldtul_p(mem_buf);
> return sizeof(target_ulong);
> - } else if (n < 65) {
> - env->fpr[n - 33] = ldq_p(mem_buf); /* always 64-bit */
> + }
> + return 0;
> +}
> +
> +static int riscv_gdb_get_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
> +{
> + if (n < 32) {
> + return gdb_get_reg64(mem_buf, env->fpr[n]);
> + } else if (n < 35) {
> + target_ulong val = 0;
> + int result;
> + /*
> + * CSR_FFLAGS is 0x001, and gdb says it is FP register 32, so we
> + * subtract 31 to map the gdb FP register number to the CSR number.
> + * This also works for CSR_FRM and CSR_FCSR.
> + */
> + result = riscv_csrrw_debug(env, n - 31, &val, 0, 0);
> + if (result == 0) {
> + return gdb_get_regl(mem_buf, val);
> + }
> + }
> + return 0;
> +}
> +
> +static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
> +{
> + if (n < 32) {
> + env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
> return sizeof(uint64_t);
> - } else if (n < 4096 + 65) {
> + } else if (n < 35) {
> target_ulong val = ldtul_p(mem_buf);
> - if (riscv_csrrw(env, n - 65, NULL, val, -1) == 0) {
> + int result;
> + /*
> + * CSR_FFLAGS is 0x001, and gdb says it is FP register 32, so we
> + * subtract 31 to map the gdb FP register number to the CSR number.
> + * This also works for CSR_FRM and CSR_FCSR.
> + */
> + result = riscv_csrrw_debug(env, n - 31, NULL, val, -1);
> + if (result == 0) {
> return sizeof(target_ulong);
> }
> }
> return 0;
> }
> +
> +static int riscv_gdb_get_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
> +{
> + if (n < ARRAY_SIZE(csr_register_map)) {
> + target_ulong val = 0;
> + int result;
> +
> + result = riscv_csrrw_debug(env, csr_register_map[n], &val, 0, 0);
> + if (result == 0) {
> + return gdb_get_regl(mem_buf, val);
> + }
> + }
> + return 0;
> +}
> +
> +static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
> +{
> + if (n < ARRAY_SIZE(csr_register_map)) {
> + target_ulong val = ldtul_p(mem_buf);
> + int result;
> +
> + result = riscv_csrrw_debug(env, csr_register_map[n], NULL, val, -1);
> + if (result == 0) {
> + return sizeof(target_ulong);
> + }
> + }
> + return 0;
> +}
> +
> +void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
> +{
> + RISCVCPU *cpu = RISCV_CPU(cs);
> + CPURISCVState *env = &cpu->env;
> +#if defined(TARGET_RISCV32)
> + if (env->misa & RVF) {
> + gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> + 35, "riscv-32bit-fpu.xml", 0);
> + }
> +
> + gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
> + 4096, "riscv-32bit-csr.xml", 0);
> +#elif defined(TARGET_RISCV64)
> + if (env->misa & RVF) {
> + gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
> + 35, "riscv-64bit-fpu.xml", 0);
> + }
> +
> + gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
> + 4096, "riscv-64bit-csr.xml", 0);
> +#endif
> +}
> --
> 2.7.4
>
>
© 2016 - 2025 Red Hat, Inc.