Merge patch series "target/riscv: Various fixes to gdbstub and CSR access"
Bin Meng <bmeng@tinylab.org> says:
At present gdbstub reports an incorrect / incomplete CSR list in the
target description XML, for example:
- menvcfg is reported in 'sifive_u' machine
- fcsr is missing in a F/D enabled processor
The issue is caused by:
- priv spec version check is missing when reporting CSRs
- CSR predicate() routine is called without turning on the debugger flag
* b4-shazam-merge:
target/riscv: Group all predicate() routines together
target/riscv: Drop priv level check in mseccfg predicate()
target/riscv: Allow debugger to access sstc CSRs
target/riscv: Allow debugger to access {h, s}stateen CSRs
target/riscv: Allow debugger to access seed CSR
target/riscv: Allow debugger to access user timer and counter CSRs
target/riscv: gdbstub: Drop the vector CSRs in riscv-vector.xml
target/riscv: gdbstub: Turn on debugger mode before calling CSR predicate()
target/riscv: Avoid reporting odd-numbered pmpcfgX in the CSR XML for RV64
target/riscv: Simplify getting RISCVCPU pointer from env
target/riscv: Simplify {read, write}_pmpcfg() a little bit
target/riscv: Use 'bool' type for read_only
target/riscv: Coding style fixes in csr.c
target/riscv: gdbstub: Do not generate CSR XML if Zicsr is disabled
target/riscv: gdbstub: Minor change for better readability
target/riscv: Use g_assert() for the predicate() NULL check
target/riscv: Add some comments to clarify the priority policy of riscv_csrrw_check()
target/riscv: gdbstub: Check priv spec version before reporting CSR
Message-ID: <20230228104035.1879882-1-bmeng@tinylab.org>
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index a1ecf62..a2cf353 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -40,43 +40,6 @@
csr_ops[csrno & (CSR_TABLE_SIZE - 1)] = *ops;
}
-/* Predicates */
-#if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
- uint64_t bit)
-{
- bool virt = riscv_cpu_virt_enabled(env);
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
-
- if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
- return RISCV_EXCP_NONE;
- }
-
- if (!(env->mstateen[index] & bit)) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- if (virt) {
- if (!(env->hstateen[index] & bit)) {
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
- }
-
- if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
- }
- }
-
- if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
- if (!(env->sstateen[index] & bit)) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
- }
-
- return RISCV_EXCP_NONE;
-}
-#endif
-
static RISCVException fs(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
@@ -90,8 +53,7 @@
static RISCVException vs(CPURISCVState *env, int csrno)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
if (cpu->cfg.ext_zve32f) {
#if !defined(CONFIG_USER_ONLY)
@@ -107,8 +69,7 @@
static RISCVException ctr(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
int ctr_index;
target_ulong ctr_mask;
int base_csrno = CSR_CYCLE;
@@ -133,6 +94,10 @@
skip_ext_pmu_check:
+ if (env->debugger) {
+ return RISCV_EXCP_NONE;
+ }
+
if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
return RISCV_EXCP_ILLEGAL_INST;
}
@@ -165,8 +130,7 @@
#if !defined(CONFIG_USER_ONLY)
static RISCVException mctr(CPURISCVState *env, int csrno)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
int ctr_index;
int base_csrno = CSR_MHPMCOUNTER3;
@@ -194,8 +158,7 @@
static RISCVException sscofpmf(CPURISCVState *env, int csrno)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
if (!cpu->cfg.ext_sscofpmf) {
return RISCV_EXCP_ILLEGAL_INST;
@@ -320,8 +283,7 @@
static RISCVException mstateen(CPURISCVState *env, int csrno)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
if (!cpu->cfg.ext_smstateen) {
return RISCV_EXCP_ILLEGAL_INST;
@@ -332,20 +294,28 @@
static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
if (!cpu->cfg.ext_smstateen) {
return RISCV_EXCP_ILLEGAL_INST;
}
+ RISCVException ret = hmode(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
+ if (env->debugger) {
+ return RISCV_EXCP_NONE;
+ }
+
if (env->priv < PRV_M) {
if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
return RISCV_EXCP_ILLEGAL_INST;
}
}
- return hmode(env, csrno);
+ return RISCV_EXCP_NONE;
}
static RISCVException hstateen(CPURISCVState *env, int csrno)
@@ -362,13 +332,21 @@
{
bool virt = riscv_cpu_virt_enabled(env);
int index = csrno - CSR_SSTATEEN0;
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
if (!cpu->cfg.ext_smstateen) {
return RISCV_EXCP_ILLEGAL_INST;
}
+ RISCVException ret = smode(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
+ if (env->debugger) {
+ return RISCV_EXCP_NONE;
+ }
+
if (env->priv < PRV_M) {
if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
return RISCV_EXCP_ILLEGAL_INST;
@@ -381,7 +359,61 @@
}
}
- return smode(env, csrno);
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException sstc(CPURISCVState *env, int csrno)
+{
+ RISCVCPU *cpu = env_archcpu(env);
+ bool hmode_check = false;
+
+ if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
+ hmode_check = true;
+ }
+
+ RISCVException ret = hmode_check ? hmode(env, csrno) : smode(env, csrno);
+ if (ret != RISCV_EXCP_NONE) {
+ return ret;
+ }
+
+ if (env->debugger) {
+ return RISCV_EXCP_NONE;
+ }
+
+ if (env->priv == PRV_M) {
+ return RISCV_EXCP_NONE;
+ }
+
+ /*
+ * No need of separate function for rv32 as menvcfg stores both menvcfg
+ * menvcfgh for RV32.
+ */
+ if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
+ get_field(env->menvcfg, MENVCFG_STCE))) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ if (riscv_cpu_virt_enabled(env)) {
+ if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
+ get_field(env->henvcfg, HENVCFG_STCE))) {
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+ }
+
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException sstc_32(CPURISCVState *env, int csrno)
+{
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ return sstc(env, csrno);
}
/* Checks if PointerMasking registers could be accessed */
@@ -419,6 +451,15 @@
static RISCVException pmp(CPURISCVState *env, int csrno)
{
if (riscv_cpu_cfg(env)->pmp) {
+ if (csrno <= CSR_PMPCFG3) {
+ uint32_t reg_index = csrno - CSR_PMPCFG0;
+
+ /* TODO: RV128 restriction check */
+ if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ }
+
return RISCV_EXCP_NONE;
}
@@ -427,7 +468,7 @@
static RISCVException epmp(CPURISCVState *env, int csrno)
{
- if (env->priv == PRV_M && riscv_cpu_cfg(env)->epmp) {
+ if (riscv_cpu_cfg(env)->epmp) {
return RISCV_EXCP_NONE;
}
@@ -453,6 +494,10 @@
}
#if !defined(CONFIG_USER_ONLY)
+ if (env->debugger) {
+ return RISCV_EXCP_NONE;
+ }
+
/*
* With a CSR read-write instruction:
* 1) The seed CSR is always available in machine mode as normal.
@@ -915,54 +960,8 @@
return RISCV_EXCP_NONE;
}
-static RISCVException sstc(CPURISCVState *env, int csrno)
-{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
- bool hmode_check = false;
-
- if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- if (env->priv == PRV_M) {
- return RISCV_EXCP_NONE;
- }
-
- /*
- * No need of separate function for rv32 as menvcfg stores both menvcfg
- * menvcfgh for RV32.
- */
- if (!(get_field(env->mcounteren, COUNTEREN_TM) &&
- get_field(env->menvcfg, MENVCFG_STCE))) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- if (riscv_cpu_virt_enabled(env)) {
- if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
- get_field(env->henvcfg, HENVCFG_STCE))) {
- return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
- }
- }
-
- if ((csrno == CSR_VSTIMECMP) || (csrno == CSR_VSTIMECMPH)) {
- hmode_check = true;
- }
-
- return hmode_check ? hmode(env, csrno) : smode(env, csrno);
-}
-
-static RISCVException sstc_32(CPURISCVState *env, int csrno)
-{
- if (riscv_cpu_mxl(env) != MXL_RV32) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- return sstc(env, csrno);
-}
-
static RISCVException read_vstimecmp(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
*val = env->vstimecmp;
@@ -970,7 +969,7 @@
}
static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
*val = env->vstimecmp >> 32;
@@ -978,7 +977,7 @@
}
static RISCVException write_vstimecmp(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
RISCVCPU *cpu = env_archcpu(env);
@@ -995,7 +994,7 @@
}
static RISCVException write_vstimecmph(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
RISCVCPU *cpu = env_archcpu(env);
@@ -1019,7 +1018,7 @@
}
static RISCVException read_stimecmph(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
if (riscv_cpu_virt_enabled(env)) {
*val = env->vstimecmp >> 32;
@@ -1031,7 +1030,7 @@
}
static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
RISCVCPU *cpu = env_archcpu(env);
@@ -1054,7 +1053,7 @@
}
static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
RISCVCPU *cpu = env_archcpu(env);
@@ -1151,8 +1150,7 @@
static RISCVException read_mvendorid(CPURISCVState *env, int csrno,
target_ulong *val)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
*val = cpu->cfg.mvendorid;
return RISCV_EXCP_NONE;
@@ -1161,8 +1159,7 @@
static RISCVException read_marchid(CPURISCVState *env, int csrno,
target_ulong *val)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
*val = cpu->cfg.marchid;
return RISCV_EXCP_NONE;
@@ -1171,8 +1168,7 @@
static RISCVException read_mimpid(CPURISCVState *env, int csrno,
target_ulong *val)
{
- CPUState *cs = env_cpu(env);
- RISCVCPU *cpu = RISCV_CPU(cs);
+ RISCVCPU *cpu = env_archcpu(env);
*val = cpu->cfg.mimpid;
return RISCV_EXCP_NONE;
@@ -1341,7 +1337,8 @@
/* 'E' excludes all other extensions */
if (val & RVE) {
- /* when we support 'E' we can do "val = RVE;" however
+ /*
+ * when we support 'E' we can do "val = RVE;" however
* for now we just drop writes if 'E' is present.
*/
return RISCV_EXCP_NONE;
@@ -1360,7 +1357,8 @@
val &= ~RVD;
}
- /* Suppress 'C' if next instruction is not aligned
+ /*
+ * Suppress 'C' if next instruction is not aligned
* TODO: this should check next_pc
*/
if ((val & RVC) && (GETPC() & ~3) != 0) {
@@ -1829,28 +1827,28 @@
}
static RISCVException read_mepc(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
*val = env->mepc;
return RISCV_EXCP_NONE;
}
static RISCVException write_mepc(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
env->mepc = val;
return RISCV_EXCP_NONE;
}
static RISCVException read_mcause(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
*val = env->mcause;
return RISCV_EXCP_NONE;
}
static RISCVException write_mcause(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
env->mcause = val;
return RISCV_EXCP_NONE;
@@ -1872,14 +1870,14 @@
/* Execution environment configuration setup */
static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
*val = env->menvcfg;
return RISCV_EXCP_NONE;
}
static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
@@ -1892,14 +1890,14 @@
}
static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
*val = env->menvcfg >> 32;
return RISCV_EXCP_NONE;
}
static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
uint64_t valh = (uint64_t)val << 32;
@@ -1909,8 +1907,41 @@
return RISCV_EXCP_NONE;
}
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
+ uint64_t bit)
+{
+ bool virt = riscv_cpu_virt_enabled(env);
+ RISCVCPU *cpu = env_archcpu(env);
+
+ if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
+ return RISCV_EXCP_NONE;
+ }
+
+ if (!(env->mstateen[index] & bit)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+
+ if (virt) {
+ if (!(env->hstateen[index] & bit)) {
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+
+ if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+ }
+ }
+
+ if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
+ if (!(env->sstateen[index] & bit)) {
+ return RISCV_EXCP_ILLEGAL_INST;
+ }
+ }
+
+ return RISCV_EXCP_NONE;
+}
+
static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
RISCVException ret;
@@ -1924,7 +1955,7 @@
}
static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
RISCVException ret;
@@ -1939,7 +1970,7 @@
}
static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
RISCVException ret;
@@ -1953,7 +1984,7 @@
}
static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
RISCVException ret;
@@ -1973,7 +2004,7 @@
}
static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
RISCVException ret;
@@ -1987,7 +2018,7 @@
}
static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
uint64_t valh = (uint64_t)val << 32;
@@ -2030,13 +2061,13 @@
}
static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
- target_ulong new_val)
+ target_ulong new_val)
{
return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
}
static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
- target_ulong *val)
+ target_ulong *val)
{
*val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
@@ -2057,7 +2088,7 @@
}
static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
- target_ulong new_val)
+ target_ulong new_val)
{
uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
@@ -2065,7 +2096,7 @@
}
static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
- target_ulong new_val)
+ target_ulong new_val)
{
return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
}
@@ -2102,7 +2133,7 @@
}
static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
- target_ulong new_val)
+ target_ulong new_val)
{
return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
}
@@ -2141,7 +2172,7 @@
}
static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
- target_ulong new_val)
+ target_ulong new_val)
{
return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
}
@@ -3334,30 +3365,18 @@
}
static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
- target_ulong val)
+ target_ulong val)
{
mseccfg_csr_write(env, val);
return RISCV_EXCP_NONE;
}
-static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
-{
- /* TODO: RV128 restriction check */
- if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
- return false;
- }
- return true;
-}
-
static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
target_ulong *val)
{
uint32_t reg_index = csrno - CSR_PMPCFG0;
- if (!check_pmp_reg_index(env, reg_index)) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
- *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
+ *val = pmpcfg_csr_read(env, reg_index);
return RISCV_EXCP_NONE;
}
@@ -3366,10 +3385,7 @@
{
uint32_t reg_index = csrno - CSR_PMPCFG0;
- if (!check_pmp_reg_index(env, reg_index)) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
- pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
+ pmpcfg_csr_write(env, reg_index, val);
return RISCV_EXCP_NONE;
}
@@ -3772,27 +3788,32 @@
RISCVCPU *cpu)
{
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
- int read_only = get_field(csrno, 0xC00) == 3;
+ bool read_only = get_field(csrno, 0xC00) == 3;
int csr_min_priv = csr_ops[csrno].min_priv_ver;
- /* ensure the CSR extension is enabled. */
+ /* ensure the CSR extension is enabled */
if (!cpu->cfg.ext_icsr) {
return RISCV_EXCP_ILLEGAL_INST;
}
+ /* privileged spec version check */
if (env->priv_ver < csr_min_priv) {
return RISCV_EXCP_ILLEGAL_INST;
}
- /* check predicate */
- if (!csr_ops[csrno].predicate) {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
+ /* read / write check */
if (write_mask && read_only) {
return RISCV_EXCP_ILLEGAL_INST;
}
+ /*
+ * The predicate() not only does existence check but also does some
+ * access control check which triggers for example virtual instruction
+ * exception in some cases. When writing read-only CSRs in those cases
+ * illegal instruction exception should be triggered instead of virtual
+ * instruction exception. Hence this comes after the read / write check.
+ */
+ g_assert(csr_ops[csrno].predicate != NULL);
RISCVException ret = csr_ops[csrno].predicate(env, csrno);
if (ret != RISCV_EXCP_NONE) {
return ret;
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 6e7bbdb..6048541 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -127,40 +127,6 @@
return 0;
}
-/*
- * Convert register index number passed by GDB to the correspond
- * vector CSR number. Vector CSRs are defined after vector registers
- * in dynamic generated riscv-vector.xml, thus the starting register index
- * of vector CSRs is 32.
- * Return 0 if register index number is out of range.
- */
-static int riscv_gdb_vector_csrno(int num_regs)
-{
- /*
- * The order of vector CSRs in the switch case
- * should match with the order defined in csr_ops[].
- */
- switch (num_regs) {
- case 32:
- return CSR_VSTART;
- case 33:
- return CSR_VXSAT;
- case 34:
- return CSR_VXRM;
- case 35:
- return CSR_VCSR;
- case 36:
- return CSR_VL;
- case 37:
- return CSR_VTYPE;
- case 38:
- return CSR_VLENB;
- default:
- /* Unknown register. */
- return 0;
- }
-}
-
static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
{
uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
@@ -174,19 +140,6 @@
return cnt;
}
- int csrno = riscv_gdb_vector_csrno(n);
-
- if (!csrno) {
- return 0;
- }
-
- target_ulong val = 0;
- int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
-
- if (result == RISCV_EXCP_NONE) {
- return gdb_get_regl(buf, val);
- }
-
return 0;
}
@@ -201,19 +154,6 @@
return vlenb;
}
- int csrno = riscv_gdb_vector_csrno(n);
-
- if (!csrno) {
- return 0;
- }
-
- target_ulong val = ldtul_p(mem_buf);
- int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
-
- if (result == RISCV_EXCP_NONE) {
- return sizeof(target_ulong);
- }
-
return 0;
}
@@ -280,6 +220,10 @@
int bitsize = 16 << env->misa_mxl_max;
int i;
+#if !defined(CONFIG_USER_ONLY)
+ env->debugger = true;
+#endif
+
/* Until gdb knows about 128-bit registers */
if (bitsize > 64) {
bitsize = 64;
@@ -290,6 +234,9 @@
g_string_append_printf(s, "<feature name=\"org.gnu.gdb.riscv.csr\">");
for (i = 0; i < CSR_TABLE_SIZE; i++) {
+ if (env->priv_ver < csr_ops[i].min_priv_ver) {
+ continue;
+ }
predicate = csr_ops[i].predicate;
if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
if (csr_ops[i].name) {
@@ -305,6 +252,11 @@
g_string_append_printf(s, "</feature>");
cpu->dyn_csr_xml = g_string_free(s, false);
+
+#if !defined(CONFIG_USER_ONLY)
+ env->debugger = false;
+#endif
+
return CSR_TABLE_SIZE;
}
@@ -349,21 +301,6 @@
num_regs++;
}
- /* Define vector CSRs */
- const char *vector_csrs[7] = {
- "vstart", "vxsat", "vxrm", "vcsr",
- "vl", "vtype", "vlenb"
- };
-
- for (i = 0; i < 7; i++) {
- g_string_append_printf(s,
- "<reg name=\"%s\" bitsize=\"%d\""
- " regnum=\"%d\" group=\"vector\""
- " type=\"int\"/>",
- vector_csrs[i], TARGET_LONG_BITS, base_reg++);
- num_regs++;
- }
-
g_string_append_printf(s, "</feature>");
cpu->dyn_vreg_xml = g_string_free(s, false);
@@ -382,9 +319,9 @@
32, "riscv-32bit-fpu.xml", 0);
}
if (env->misa_ext & RVV) {
+ int base_reg = cs->gdb_num_regs;
gdb_register_coprocessor(cs, riscv_gdb_get_vector, riscv_gdb_set_vector,
- ricsv_gen_dynamic_vector_xml(cs,
- cs->gdb_num_regs),
+ ricsv_gen_dynamic_vector_xml(cs, base_reg),
"riscv-vector.xml", 0);
}
switch (env->misa_mxl_max) {
@@ -403,7 +340,10 @@
g_assert_not_reached();
}
- 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);
+ if (cpu->cfg.ext_icsr) {
+ int base_reg = cs->gdb_num_regs;
+ gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
+ riscv_gen_dynamic_csr_xml(cs, base_reg),
+ "riscv-csr.xml", 0);
+ }
}