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>
This commit is contained in:
Palmer Dabbelt 2023-03-01 16:40:30 -08:00
commit 73b9da4aa3
No known key found for this signature in database
GPG Key ID: 2E1319F35FBB1889
2 changed files with 201 additions and 240 deletions

View File

@ -40,43 +40,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
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 fs(CPURISCVState *env, int csrno)
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 vs(CPURISCVState *env, int csrno)
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 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
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 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
#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 mctr32(CPURISCVState *env, int csrno)
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 umode32(CPURISCVState *env, int csrno)
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 mstateen(CPURISCVState *env, int csrno)
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 @@ static RISCVException sstateen(CPURISCVState *env, int csrno)
{
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 @@ static RISCVException sstateen(CPURISCVState *env, int csrno)
}
}
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 int aia_hmode32(CPURISCVState *env, int csrno)
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 pmp(CPURISCVState *env, int csrno)
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 @@ static RISCVException seed(CPURISCVState *env, int csrno)
}
#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 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
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_vstimecmp(CPURISCVState *env, int csrno,
}
static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
target_ulong *val)
target_ulong *val)
{
*val = env->vstimecmp >> 32;
@ -978,7 +977,7 @@ static RISCVException read_vstimecmph(CPURISCVState *env, int csrno,
}
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_vstimecmp(CPURISCVState *env, int csrno,
}
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_stimecmp(CPURISCVState *env, int csrno,
}
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 read_stimecmph(CPURISCVState *env, int csrno,
}
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_stimecmp(CPURISCVState *env, int csrno,
}
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 write_ignore(CPURISCVState *env, int csrno,
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_mvendorid(CPURISCVState *env, int csrno,
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_marchid(CPURISCVState *env, int csrno,
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 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
/* '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 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
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 write_mscratch(CPURISCVState *env, int csrno,
}
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 @@ static RISCVException write_mtval(CPURISCVState *env, int csrno,
/* 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 write_menvcfg(CPURISCVState *env, int csrno,
}
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 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
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 read_senvcfg(CPURISCVState *env, int csrno,
}
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 write_senvcfg(CPURISCVState *env, int csrno,
}
static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
target_ulong *val)
target_ulong *val)
{
RISCVException ret;
@ -1953,7 +1984,7 @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
}
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 write_henvcfg(CPURISCVState *env, int csrno,
}
static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
target_ulong *val)
target_ulong *val)
{
RISCVException ret;
@ -1987,7 +2018,7 @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
}
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_mstateen0(CPURISCVState *env, int csrno,
}
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_mstateenh(CPURISCVState *env, int csrno,
}
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_mstateen0h(CPURISCVState *env, int csrno,
}
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_hstateen0(CPURISCVState *env, int csrno,
}
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_hstateen0h(CPURISCVState *env, int csrno,
}
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 read_mseccfg(CPURISCVState *env, int csrno,
}
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 @@ static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
{
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 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
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;

View File

@ -127,40 +127,6 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
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 @@ static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
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 @@ static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
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 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
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 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
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 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
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 @@ static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
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 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
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 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
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);
}
}