diff options
Diffstat (limited to 'target/riscv/csr.c')
-rw-r--r-- | target/riscv/csr.c | 824 |
1 files changed, 491 insertions, 333 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c index d2585395bf..fe5628fea6 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -35,29 +35,29 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops) } /* Predicates */ -static int fs(CPURISCVState *env, int csrno) +static RISCVException fs(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) /* loose check condition for fcsr in vector extension */ if ((csrno == CSR_FCSR) && (env->misa & RVV)) { - return 0; + return RISCV_EXCP_NONE; } if (!env->debugger && !riscv_cpu_fp_enabled(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } #endif - return 0; + return RISCV_EXCP_NONE; } -static int vs(CPURISCVState *env, int csrno) +static RISCVException vs(CPURISCVState *env, int csrno) { if (env->misa & RVV) { - return 0; + return RISCV_EXCP_NONE; } - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } -static int ctr(CPURISCVState *env, int csrno) +static RISCVException ctr(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) CPUState *cs = env_cpu(env); @@ -65,7 +65,7 @@ static int ctr(CPURISCVState *env, int csrno) if (!cpu->cfg.ext_counters) { /* The Counters extensions is not enabled */ - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } if (riscv_cpu_virt_enabled(env)) { @@ -73,25 +73,25 @@ static int ctr(CPURISCVState *env, int csrno) case CSR_CYCLE: if (!get_field(env->hcounteren, HCOUNTEREN_CY) && get_field(env->mcounteren, HCOUNTEREN_CY)) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; case CSR_TIME: if (!get_field(env->hcounteren, HCOUNTEREN_TM) && get_field(env->mcounteren, HCOUNTEREN_TM)) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; case CSR_INSTRET: if (!get_field(env->hcounteren, HCOUNTEREN_IR) && get_field(env->mcounteren, HCOUNTEREN_IR)) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) && get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; } @@ -100,148 +100,174 @@ static int ctr(CPURISCVState *env, int csrno) case CSR_CYCLEH: if (!get_field(env->hcounteren, HCOUNTEREN_CY) && get_field(env->mcounteren, HCOUNTEREN_CY)) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; case CSR_TIMEH: if (!get_field(env->hcounteren, HCOUNTEREN_TM) && get_field(env->mcounteren, HCOUNTEREN_TM)) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; case CSR_INSTRETH: if (!get_field(env->hcounteren, HCOUNTEREN_IR) && get_field(env->mcounteren, HCOUNTEREN_IR)) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) && get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } break; } } } #endif - return 0; + return RISCV_EXCP_NONE; } -static int ctr32(CPURISCVState *env, int csrno) +static RISCVException ctr32(CPURISCVState *env, int csrno) { if (!riscv_cpu_is_32bit(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } return ctr(env, csrno); } #if !defined(CONFIG_USER_ONLY) -static int any(CPURISCVState *env, int csrno) +static RISCVException any(CPURISCVState *env, int csrno) { - return 0; + return RISCV_EXCP_NONE; } -static int any32(CPURISCVState *env, int csrno) +static RISCVException any32(CPURISCVState *env, int csrno) { if (!riscv_cpu_is_32bit(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } return any(env, csrno); } -static int smode(CPURISCVState *env, int csrno) +static RISCVException smode(CPURISCVState *env, int csrno) { - return -!riscv_has_ext(env, RVS); + if (riscv_has_ext(env, RVS)) { + return RISCV_EXCP_NONE; + } + + return RISCV_EXCP_ILLEGAL_INST; } -static int hmode(CPURISCVState *env, int csrno) +static RISCVException hmode(CPURISCVState *env, int csrno) { if (riscv_has_ext(env, RVS) && riscv_has_ext(env, RVH)) { /* Hypervisor extension is supported */ if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) || env->priv == PRV_M) { - return 0; + return RISCV_EXCP_NONE; } else { - return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } } - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } -static int hmode32(CPURISCVState *env, int csrno) +static RISCVException hmode32(CPURISCVState *env, int csrno) { if (!riscv_cpu_is_32bit(env)) { - return 0; + if (riscv_cpu_virt_enabled(env)) { + return RISCV_EXCP_ILLEGAL_INST; + } else { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } } return hmode(env, csrno); } -static int pmp(CPURISCVState *env, int csrno) +static RISCVException pmp(CPURISCVState *env, int csrno) +{ + if (riscv_feature(env, RISCV_FEATURE_PMP)) { + return RISCV_EXCP_NONE; + } + + return RISCV_EXCP_ILLEGAL_INST; +} + +static RISCVException epmp(CPURISCVState *env, int csrno) { - return -!riscv_feature(env, RISCV_FEATURE_PMP); + if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) { + return RISCV_EXCP_NONE; + } + + return RISCV_EXCP_ILLEGAL_INST; } #endif /* User Floating-Point CSRs */ -static int read_fflags(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_fflags(CPURISCVState *env, int csrno, + target_ulong *val) { #if !defined(CONFIG_USER_ONLY) if (!env->debugger && !riscv_cpu_fp_enabled(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } #endif *val = riscv_cpu_get_fflags(env); - return 0; + return RISCV_EXCP_NONE; } -static int write_fflags(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_fflags(CPURISCVState *env, int csrno, + target_ulong val) { #if !defined(CONFIG_USER_ONLY) if (!env->debugger && !riscv_cpu_fp_enabled(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } env->mstatus |= MSTATUS_FS; #endif riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT)); - return 0; + return RISCV_EXCP_NONE; } -static int read_frm(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_frm(CPURISCVState *env, int csrno, + target_ulong *val) { #if !defined(CONFIG_USER_ONLY) if (!env->debugger && !riscv_cpu_fp_enabled(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } #endif *val = env->frm; - return 0; + return RISCV_EXCP_NONE; } -static int write_frm(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_frm(CPURISCVState *env, int csrno, + target_ulong val) { #if !defined(CONFIG_USER_ONLY) if (!env->debugger && !riscv_cpu_fp_enabled(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } env->mstatus |= MSTATUS_FS; #endif env->frm = val & (FSR_RD >> FSR_RD_SHIFT); - return 0; + return RISCV_EXCP_NONE; } -static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_fcsr(CPURISCVState *env, int csrno, + target_ulong *val) { #if !defined(CONFIG_USER_ONLY) if (!env->debugger && !riscv_cpu_fp_enabled(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } #endif *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT) @@ -250,14 +276,15 @@ static int read_fcsr(CPURISCVState *env, int csrno, target_ulong *val) *val |= (env->vxrm << FSR_VXRM_SHIFT) | (env->vxsat << FSR_VXSAT_SHIFT); } - return 0; + return RISCV_EXCP_NONE; } -static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_fcsr(CPURISCVState *env, int csrno, + target_ulong val) { #if !defined(CONFIG_USER_ONLY) if (!env->debugger && !riscv_cpu_fp_enabled(env)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } env->mstatus |= MSTATUS_FS; #endif @@ -267,59 +294,68 @@ static int write_fcsr(CPURISCVState *env, int csrno, target_ulong val) env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT; } riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT); - return 0; + return RISCV_EXCP_NONE; } -static int read_vtype(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vtype(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vtype; - return 0; + return RISCV_EXCP_NONE; } -static int read_vl(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vl(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vl; - return 0; + return RISCV_EXCP_NONE; } -static int read_vxrm(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vxrm(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vxrm; - return 0; + return RISCV_EXCP_NONE; } -static int write_vxrm(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vxrm(CPURISCVState *env, int csrno, + target_ulong val) { env->vxrm = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_vxsat(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vxsat(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vxsat; - return 0; + return RISCV_EXCP_NONE; } -static int write_vxsat(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vxsat(CPURISCVState *env, int csrno, + target_ulong val) { env->vxsat = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_vstart(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vstart(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vstart; - return 0; + return RISCV_EXCP_NONE; } -static int write_vstart(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vstart(CPURISCVState *env, int csrno, + target_ulong val) { env->vstart = val; - return 0; + return RISCV_EXCP_NONE; } /* User Timers and Counters */ -static int read_instret(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_instret(CPURISCVState *env, int csrno, + target_ulong *val) { #if !defined(CONFIG_USER_ONLY) if (icount_enabled()) { @@ -330,10 +366,11 @@ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val) #else *val = cpu_get_host_ticks(); #endif - return 0; + return RISCV_EXCP_NONE; } -static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_instreth(CPURISCVState *env, int csrno, + target_ulong *val) { #if !defined(CONFIG_USER_ONLY) if (icount_enabled()) { @@ -344,46 +381,50 @@ static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val) #else *val = cpu_get_host_ticks() >> 32; #endif - return 0; + return RISCV_EXCP_NONE; } #if defined(CONFIG_USER_ONLY) -static int read_time(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_time(CPURISCVState *env, int csrno, + target_ulong *val) { *val = cpu_get_host_ticks(); - return 0; + return RISCV_EXCP_NONE; } -static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_timeh(CPURISCVState *env, int csrno, + target_ulong *val) { *val = cpu_get_host_ticks() >> 32; - return 0; + return RISCV_EXCP_NONE; } #else /* CONFIG_USER_ONLY */ -static int read_time(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_time(CPURISCVState *env, int csrno, + target_ulong *val) { uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0; if (!env->rdtime_fn) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } *val = env->rdtime_fn(env->rdtime_fn_arg) + delta; - return 0; + return RISCV_EXCP_NONE; } -static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_timeh(CPURISCVState *env, int csrno, + target_ulong *val) { uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0; if (!env->rdtime_fn) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32; - return 0; + return RISCV_EXCP_NONE; } /* Machine constants */ @@ -418,7 +459,7 @@ static const target_ulong delegable_excps = (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)); static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | - SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD; + SSTATUS_SUM | SSTATUS_MXR; static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP; static const target_ulong hip_writable_mask = MIP_VSSIP; static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP; @@ -437,22 +478,26 @@ static const char valid_vm_1_10_64[16] = { }; /* Machine Information Registers */ -static int read_zero(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_zero(CPURISCVState *env, int csrno, + target_ulong *val) { - return *val = 0; + *val = 0; + return RISCV_EXCP_NONE; } -static int read_mhartid(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mhartid(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mhartid; - return 0; + return RISCV_EXCP_NONE; } /* Machine Trap Setup */ -static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mstatus(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mstatus; - return 0; + return RISCV_EXCP_NONE; } static int validate_vm(CPURISCVState *env, target_ulong vm) @@ -464,7 +509,8 @@ static int validate_vm(CPURISCVState *env, target_ulong vm) } } -static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mstatus(CPURISCVState *env, int csrno, + target_ulong val) { uint64_t mstatus = env->mstatus; uint64_t mask = 0; @@ -492,19 +538,25 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) | ((mstatus & MSTATUS_XS) == MSTATUS_XS); - mstatus = set_field(mstatus, MSTATUS_SD, dirty); + if (riscv_cpu_is_32bit(env)) { + mstatus = set_field(mstatus, MSTATUS32_SD, dirty); + } else { + mstatus = set_field(mstatus, MSTATUS64_SD, dirty); + } env->mstatus = mstatus; - return 0; + return RISCV_EXCP_NONE; } -static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mstatush(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mstatus >> 32; - return 0; + return RISCV_EXCP_NONE; } -static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mstatush(CPURISCVState *env, int csrno, + target_ulong val) { uint64_t valh = (uint64_t)val << 32; uint64_t mask = MSTATUS_MPV | MSTATUS_GVA; @@ -515,26 +567,28 @@ static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val) env->mstatus = (env->mstatus & ~mask) | (valh & mask); - return 0; + return RISCV_EXCP_NONE; } -static int read_misa(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_misa(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->misa; - return 0; + return RISCV_EXCP_NONE; } -static int write_misa(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_misa(CPURISCVState *env, int csrno, + target_ulong val) { if (!riscv_feature(env, RISCV_FEATURE_MISA)) { /* drop write to misa */ - return 0; + return RISCV_EXCP_NONE; } /* 'I' or 'E' must be present */ if (!(val & (RVI | RVE))) { /* It is not, drop write to misa */ - return 0; + return RISCV_EXCP_NONE; } /* 'E' excludes all other extensions */ @@ -542,7 +596,7 @@ static int write_misa(CPURISCVState *env, int csrno, target_ulong val) /* when we support 'E' we can do "val = RVE;" however * for now we just drop writes if 'E' is present. */ - return 0; + return RISCV_EXCP_NONE; } /* Mask extensions that are not supported by this hart */ @@ -564,7 +618,11 @@ static int write_misa(CPURISCVState *env, int csrno, target_ulong val) } /* misa.MXL writes are not supported by QEMU */ - val = (env->misa & MISA_MXL) | (val & ~MISA_MXL); + if (riscv_cpu_is_32bit(env)) { + val = (env->misa & MISA32_MXL) | (val & ~MISA32_MXL); + } else { + val = (env->misa & MISA64_MXL) | (val & ~MISA64_MXL); + } /* flush translation cache */ if (val != env->misa) { @@ -573,55 +631,63 @@ static int write_misa(CPURISCVState *env, int csrno, target_ulong val) env->misa = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_medeleg(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_medeleg(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->medeleg; - return 0; + return RISCV_EXCP_NONE; } -static int write_medeleg(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_medeleg(CPURISCVState *env, int csrno, + target_ulong val) { env->medeleg = (env->medeleg & ~delegable_excps) | (val & delegable_excps); - return 0; + return RISCV_EXCP_NONE; } -static int read_mideleg(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mideleg(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mideleg; - return 0; + return RISCV_EXCP_NONE; } -static int write_mideleg(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mideleg(CPURISCVState *env, int csrno, + target_ulong val) { env->mideleg = (env->mideleg & ~delegable_ints) | (val & delegable_ints); if (riscv_has_ext(env, RVH)) { env->mideleg |= VS_MODE_INTERRUPTS; } - return 0; + return RISCV_EXCP_NONE; } -static int read_mie(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mie(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mie; - return 0; + return RISCV_EXCP_NONE; } -static int write_mie(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mie(CPURISCVState *env, int csrno, + target_ulong val) { env->mie = (env->mie & ~all_ints) | (val & all_ints); - return 0; + return RISCV_EXCP_NONE; } -static int read_mtvec(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mtvec(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mtvec; - return 0; + return RISCV_EXCP_NONE; } -static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mtvec(CPURISCVState *env, int csrno, + target_ulong val) { /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */ if ((val & 3) < 2) { @@ -629,92 +695,83 @@ static int write_mtvec(CPURISCVState *env, int csrno, target_ulong val) } else { qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: reserved mode not supported\n"); } - return 0; -} - -static int read_mcounteren(CPURISCVState *env, int csrno, target_ulong *val) -{ - *val = env->mcounteren; - return 0; -} - -static int write_mcounteren(CPURISCVState *env, int csrno, target_ulong val) -{ - env->mcounteren = val; - return 0; + return RISCV_EXCP_NONE; } -/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */ -static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mcounteren(CPURISCVState *env, int csrno, + target_ulong *val) { - if (env->priv_ver < PRIV_VERSION_1_11_0) { - return -RISCV_EXCP_ILLEGAL_INST; - } *val = env->mcounteren; - return 0; + return RISCV_EXCP_NONE; } -/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */ -static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mcounteren(CPURISCVState *env, int csrno, + target_ulong val) { - if (env->priv_ver < PRIV_VERSION_1_11_0) { - return -RISCV_EXCP_ILLEGAL_INST; - } env->mcounteren = val; - return 0; + return RISCV_EXCP_NONE; } /* Machine Trap Handling */ -static int read_mscratch(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mscratch(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mscratch; - return 0; + return RISCV_EXCP_NONE; } -static int write_mscratch(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mscratch(CPURISCVState *env, int csrno, + target_ulong val) { env->mscratch = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_mepc(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mepc(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mepc; - return 0; + return RISCV_EXCP_NONE; } -static int write_mepc(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mepc(CPURISCVState *env, int csrno, + target_ulong val) { env->mepc = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_mcause(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mcause(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mcause; - return 0; + return RISCV_EXCP_NONE; } -static int write_mcause(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mcause(CPURISCVState *env, int csrno, + target_ulong val) { env->mcause = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_mbadaddr(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mtval(CPURISCVState *env, int csrno, + target_ulong *val) { - *val = env->mbadaddr; - return 0; + *val = env->mtval; + return RISCV_EXCP_NONE; } -static int write_mbadaddr(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mtval(CPURISCVState *env, int csrno, + target_ulong val) { - env->mbadaddr = val; - return 0; + env->mtval = val; + return RISCV_EXCP_NONE; } -static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +static RISCVException rmw_mip(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, target_ulong write_mask) { RISCVCPU *cpu = env_archcpu(env); /* Allow software control of delegable interrupts not claimed by hardware */ @@ -731,42 +788,54 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value, *ret_value = old_mip; } - return 0; + return RISCV_EXCP_NONE; } /* Supervisor Trap Setup */ -static int read_sstatus(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_sstatus(CPURISCVState *env, int csrno, + target_ulong *val) { target_ulong mask = (sstatus_v1_10_mask); + + if (riscv_cpu_is_32bit(env)) { + mask |= SSTATUS32_SD; + } else { + mask |= SSTATUS64_SD; + } + *val = env->mstatus & mask; - return 0; + return RISCV_EXCP_NONE; } -static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_sstatus(CPURISCVState *env, int csrno, + target_ulong val) { target_ulong mask = (sstatus_v1_10_mask); target_ulong newval = (env->mstatus & ~mask) | (val & mask); return write_mstatus(env, CSR_MSTATUS, newval); } -static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vsie(CPURISCVState *env, int csrno, + target_ulong *val) { /* Shift the VS bits to their S bit location in vsie */ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1; - return 0; + return RISCV_EXCP_NONE; } -static int read_sie(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_sie(CPURISCVState *env, int csrno, + target_ulong *val) { if (riscv_cpu_virt_enabled(env)) { read_vsie(env, CSR_VSIE, val); } else { *val = env->mie & env->mideleg; } - return 0; + return RISCV_EXCP_NONE; } -static int write_vsie(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vsie(CPURISCVState *env, int csrno, + target_ulong val) { /* Shift the S bits to their VS bit location in mie */ target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) | @@ -784,16 +853,18 @@ static int write_sie(CPURISCVState *env, int csrno, target_ulong val) write_mie(env, CSR_MIE, newval); } - return 0; + return RISCV_EXCP_NONE; } -static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_stvec(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->stvec; - return 0; + return RISCV_EXCP_NONE; } -static int write_stvec(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_stvec(CPURISCVState *env, int csrno, + target_ulong val) { /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */ if ((val & 3) < 2) { @@ -801,72 +872,83 @@ static int write_stvec(CPURISCVState *env, int csrno, target_ulong val) } else { qemu_log_mask(LOG_UNIMP, "CSR_STVEC: reserved mode not supported\n"); } - return 0; + return RISCV_EXCP_NONE; } -static int read_scounteren(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_scounteren(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->scounteren; - return 0; + return RISCV_EXCP_NONE; } -static int write_scounteren(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_scounteren(CPURISCVState *env, int csrno, + target_ulong val) { env->scounteren = val; - return 0; + return RISCV_EXCP_NONE; } /* Supervisor Trap Handling */ -static int read_sscratch(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_sscratch(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->sscratch; - return 0; + return RISCV_EXCP_NONE; } -static int write_sscratch(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_sscratch(CPURISCVState *env, int csrno, + target_ulong val) { env->sscratch = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_sepc(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_sepc(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->sepc; - return 0; + return RISCV_EXCP_NONE; } -static int write_sepc(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_sepc(CPURISCVState *env, int csrno, + target_ulong val) { env->sepc = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_scause(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_scause(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->scause; - return 0; + return RISCV_EXCP_NONE; } -static int write_scause(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_scause(CPURISCVState *env, int csrno, + target_ulong val) { env->scause = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_sbadaddr(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_stval(CPURISCVState *env, int csrno, + target_ulong *val) { - *val = env->sbadaddr; - return 0; + *val = env->stval; + return RISCV_EXCP_NONE; } -static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_stval(CPURISCVState *env, int csrno, + target_ulong val) { - env->sbadaddr = val; - return 0; + env->stval = val; + return RISCV_EXCP_NONE; } -static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +static RISCVException rmw_vsip(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, target_ulong write_mask) { /* Shift the S bits to their VS bit location in mip */ int ret = rmw_mip(env, 0, ret_value, new_value << 1, @@ -877,8 +959,9 @@ static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value, return ret; } -static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +static RISCVException rmw_sip(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, target_ulong write_mask) { int ret; @@ -894,44 +977,58 @@ static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value, } /* Supervisor Protection and Translation */ -static int read_satp(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_satp(CPURISCVState *env, int csrno, + target_ulong *val) { if (!riscv_feature(env, RISCV_FEATURE_MMU)) { *val = 0; - return 0; + return RISCV_EXCP_NONE; } if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } else { *val = env->satp; } - return 0; + return RISCV_EXCP_NONE; } -static int write_satp(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_satp(CPURISCVState *env, int csrno, + target_ulong val) { + int vm, mask, asid; + if (!riscv_feature(env, RISCV_FEATURE_MMU)) { - return 0; + return RISCV_EXCP_NONE; + } + + if (riscv_cpu_is_32bit(env)) { + vm = validate_vm(env, get_field(val, SATP32_MODE)); + mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN); + asid = (val ^ env->satp) & SATP32_ASID; + } else { + vm = validate_vm(env, get_field(val, SATP64_MODE)); + mask = (val ^ env->satp) & (SATP64_MODE | SATP64_ASID | SATP64_PPN); + asid = (val ^ env->satp) & SATP64_ASID; } - if (validate_vm(env, get_field(val, SATP_MODE)) && - ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN))) - { + + if (vm && mask) { if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } else { - if ((val ^ env->satp) & SATP_ASID) { + if (asid) { tlb_flush(env_cpu(env)); } env->satp = val; } } - return 0; + return RISCV_EXCP_NONE; } /* Hypervisor Extensions */ -static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hstatus(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->hstatus; if (!riscv_cpu_is_32bit(env)) { @@ -940,10 +1037,11 @@ static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val) } /* We only support little endian */ *val = set_field(*val, HSTATUS_VSBE, 0); - return 0; + return RISCV_EXCP_NONE; } -static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hstatus(CPURISCVState *env, int csrno, + target_ulong val) { env->hstatus = val; if (!riscv_cpu_is_32bit(env) && get_field(val, HSTATUS_VSXL) != 2) { @@ -952,35 +1050,40 @@ static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val) if (get_field(val, HSTATUS_VSBE) != 0) { qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests."); } - return 0; + return RISCV_EXCP_NONE; } -static int read_hedeleg(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hedeleg(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->hedeleg; - return 0; + return RISCV_EXCP_NONE; } -static int write_hedeleg(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hedeleg(CPURISCVState *env, int csrno, + target_ulong val) { env->hedeleg = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_hideleg(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hideleg(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->hideleg; - return 0; + return RISCV_EXCP_NONE; } -static int write_hideleg(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hideleg(CPURISCVState *env, int csrno, + target_ulong val) { env->hideleg = val; - return 0; + return RISCV_EXCP_NONE; } -static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +static RISCVException rmw_hvip(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, target_ulong write_mask) { int ret = rmw_mip(env, 0, ret_value, new_value, write_mask & hvip_writable_mask); @@ -990,8 +1093,9 @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value, return ret; } -static int rmw_hip(CPURISCVState *env, int csrno, target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +static RISCVException rmw_hip(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, target_ulong write_mask) { int ret = rmw_mip(env, 0, ret_value, new_value, write_mask & hip_writable_mask); @@ -1001,103 +1105,119 @@ static int rmw_hip(CPURISCVState *env, int csrno, target_ulong *ret_value, return ret; } -static int read_hie(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hie(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mie & VS_MODE_INTERRUPTS; - return 0; + return RISCV_EXCP_NONE; } -static int write_hie(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hie(CPURISCVState *env, int csrno, + target_ulong val) { target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) | (val & VS_MODE_INTERRUPTS); return write_mie(env, CSR_MIE, newval); } -static int read_hcounteren(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hcounteren(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->hcounteren; - return 0; + return RISCV_EXCP_NONE; } -static int write_hcounteren(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hcounteren(CPURISCVState *env, int csrno, + target_ulong val) { env->hcounteren = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_hgeie(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hgeie(CPURISCVState *env, int csrno, + target_ulong *val) { qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN."); - return 0; + return RISCV_EXCP_NONE; } -static int write_hgeie(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hgeie(CPURISCVState *env, int csrno, + target_ulong val) { qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN."); - return 0; + return RISCV_EXCP_NONE; } -static int read_htval(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_htval(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->htval; - return 0; + return RISCV_EXCP_NONE; } -static int write_htval(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_htval(CPURISCVState *env, int csrno, + target_ulong val) { env->htval = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_htinst(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_htinst(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->htinst; - return 0; + return RISCV_EXCP_NONE; } -static int write_htinst(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_htinst(CPURISCVState *env, int csrno, + target_ulong val) { - return 0; + return RISCV_EXCP_NONE; } -static int read_hgeip(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hgeip(CPURISCVState *env, int csrno, + target_ulong *val) { qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN."); - return 0; + return RISCV_EXCP_NONE; } -static int write_hgeip(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hgeip(CPURISCVState *env, int csrno, + target_ulong val) { qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN."); - return 0; + return RISCV_EXCP_NONE; } -static int read_hgatp(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_hgatp(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->hgatp; - return 0; + return RISCV_EXCP_NONE; } -static int write_hgatp(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_hgatp(CPURISCVState *env, int csrno, + target_ulong val) { env->hgatp = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_htimedelta(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_htimedelta(CPURISCVState *env, int csrno, + target_ulong *val) { if (!env->rdtime_fn) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } *val = env->htimedelta; - return 0; + return RISCV_EXCP_NONE; } -static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_htimedelta(CPURISCVState *env, int csrno, + target_ulong val) { if (!env->rdtime_fn) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } if (riscv_cpu_is_32bit(env)) { @@ -1105,162 +1225,199 @@ static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val) } else { env->htimedelta = val; } - return 0; + return RISCV_EXCP_NONE; } -static int read_htimedeltah(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_htimedeltah(CPURISCVState *env, int csrno, + target_ulong *val) { if (!env->rdtime_fn) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } *val = env->htimedelta >> 32; - return 0; + return RISCV_EXCP_NONE; } -static int write_htimedeltah(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_htimedeltah(CPURISCVState *env, int csrno, + target_ulong val) { if (!env->rdtime_fn) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val); - return 0; + return RISCV_EXCP_NONE; } /* Virtual CSR Registers */ -static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vsstatus(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vsstatus; - return 0; + return RISCV_EXCP_NONE; } -static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vsstatus(CPURISCVState *env, int csrno, + target_ulong val) { uint64_t mask = (target_ulong)-1; env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val; - return 0; + return RISCV_EXCP_NONE; } static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val) { *val = env->vstvec; - return 0; + return RISCV_EXCP_NONE; } -static int write_vstvec(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vstvec(CPURISCVState *env, int csrno, + target_ulong val) { env->vstvec = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_vsscratch(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vsscratch(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vsscratch; - return 0; + return RISCV_EXCP_NONE; } -static int write_vsscratch(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vsscratch(CPURISCVState *env, int csrno, + target_ulong val) { env->vsscratch = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_vsepc(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vsepc(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vsepc; - return 0; + return RISCV_EXCP_NONE; } -static int write_vsepc(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vsepc(CPURISCVState *env, int csrno, + target_ulong val) { env->vsepc = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_vscause(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vscause(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vscause; - return 0; + return RISCV_EXCP_NONE; } -static int write_vscause(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vscause(CPURISCVState *env, int csrno, + target_ulong val) { env->vscause = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_vstval(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vstval(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vstval; - return 0; + return RISCV_EXCP_NONE; } -static int write_vstval(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vstval(CPURISCVState *env, int csrno, + target_ulong val) { env->vstval = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_vsatp(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_vsatp(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->vsatp; - return 0; + return RISCV_EXCP_NONE; } -static int write_vsatp(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_vsatp(CPURISCVState *env, int csrno, + target_ulong val) { env->vsatp = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_mtval2(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mtval2(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mtval2; - return 0; + return RISCV_EXCP_NONE; } -static int write_mtval2(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mtval2(CPURISCVState *env, int csrno, + target_ulong val) { env->mtval2 = val; - return 0; + return RISCV_EXCP_NONE; } -static int read_mtinst(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mtinst(CPURISCVState *env, int csrno, + target_ulong *val) { *val = env->mtinst; - return 0; + return RISCV_EXCP_NONE; } -static int write_mtinst(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_mtinst(CPURISCVState *env, int csrno, + target_ulong val) { env->mtinst = val; - return 0; + return RISCV_EXCP_NONE; } /* Physical Memory Protection */ -static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_mseccfg(CPURISCVState *env, int csrno, + target_ulong *val) +{ + *val = mseccfg_csr_read(env); + return RISCV_EXCP_NONE; +} + +static RISCVException write_mseccfg(CPURISCVState *env, int csrno, + target_ulong val) +{ + mseccfg_csr_write(env, val); + return RISCV_EXCP_NONE; +} + +static RISCVException read_pmpcfg(CPURISCVState *env, int csrno, + target_ulong *val) { *val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0); - return 0; + return RISCV_EXCP_NONE; } -static int write_pmpcfg(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_pmpcfg(CPURISCVState *env, int csrno, + target_ulong val) { pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val); - return 0; + return RISCV_EXCP_NONE; } -static int read_pmpaddr(CPURISCVState *env, int csrno, target_ulong *val) +static RISCVException read_pmpaddr(CPURISCVState *env, int csrno, + target_ulong *val) { *val = pmpaddr_csr_read(env, csrno - CSR_PMPADDR0); - return 0; + return RISCV_EXCP_NONE; } -static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException write_pmpaddr(CPURISCVState *env, int csrno, + target_ulong val) { pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val); - return 0; + return RISCV_EXCP_NONE; } #endif @@ -1274,10 +1431,11 @@ static int write_pmpaddr(CPURISCVState *env, int csrno, target_ulong val) * csrrc <-> riscv_csrrw(env, csrno, ret_value, 0, value); */ -int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +RISCVException riscv_csrrw(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, target_ulong write_mask) { - int ret; + RISCVException ret; target_ulong old_value; RISCVCPU *cpu = env_archcpu(env); @@ -1299,21 +1457,21 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, if ((write_mask && read_only) || (!env->debugger && (effective_priv < get_field(csrno, 0x300)))) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } #endif /* ensure the CSR extension is enabled. */ if (!cpu->cfg.ext_icsr) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } /* check predicate */ if (!csr_ops[csrno].predicate) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } ret = csr_ops[csrno].predicate(env, csrno); - if (ret < 0) { + if (ret != RISCV_EXCP_NONE) { return ret; } @@ -1324,12 +1482,11 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, /* if no accessor exists then return failure */ if (!csr_ops[csrno].read) { - return -RISCV_EXCP_ILLEGAL_INST; + return RISCV_EXCP_ILLEGAL_INST; } - /* read old value */ ret = csr_ops[csrno].read(env, csrno, &old_value); - if (ret < 0) { + if (ret != RISCV_EXCP_NONE) { return ret; } @@ -1338,7 +1495,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, new_value = (old_value & ~write_mask) | (new_value & write_mask); if (csr_ops[csrno].write) { ret = csr_ops[csrno].write(env, csrno, new_value); - if (ret < 0) { + if (ret != RISCV_EXCP_NONE) { return ret; } } @@ -1349,17 +1506,19 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, *ret_value = old_value; } - return 0; + return RISCV_EXCP_NONE; } /* * Debugger support. If not in user mode, set env->debugger before the * riscv_csrrw call and clear it after the call. */ -int riscv_csrrw_debug(CPURISCVState *env, int csrno, target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno, + target_ulong *ret_value, + target_ulong new_value, + target_ulong write_mask) { - int ret; + RISCVException ret; #if !defined(CONFIG_USER_ONLY) env->debugger = true; #endif @@ -1419,13 +1578,11 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MSTATUSH] = { "mstatush", any32, read_mstatush, write_mstatush }, - [CSR_MSCOUNTEREN] = { "msounteren", any, read_mscounteren, write_mscounteren }, - /* Machine Trap Handling */ [CSR_MSCRATCH] = { "mscratch", any, read_mscratch, write_mscratch }, [CSR_MEPC] = { "mepc", any, read_mepc, write_mepc }, [CSR_MCAUSE] = { "mcause", any, read_mcause, write_mcause }, - [CSR_MBADADDR] = { "mbadaddr", any, read_mbadaddr, write_mbadaddr }, + [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval }, [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip }, /* Supervisor Trap Setup */ @@ -1438,7 +1595,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_SSCRATCH] = { "sscratch", smode, read_sscratch, write_sscratch }, [CSR_SEPC] = { "sepc", smode, read_sepc, write_sepc }, [CSR_SCAUSE] = { "scause", smode, read_scause, write_scause }, - [CSR_SBADADDR] = { "sbadaddr", smode, read_sbadaddr, write_sbadaddr }, + [CSR_STVAL] = { "stval", smode, read_stval, write_stval }, [CSR_SIP] = { "sip", smode, NULL, NULL, rmw_sip }, /* Supervisor Protection and Translation */ @@ -1473,6 +1630,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst }, /* Physical Memory Protection */ + [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg }, [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg }, [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg }, [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg }, |