target/riscv: Use the RISCVException enum for CSR predicates

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Message-id: 187261fa671c3a77cf5aa482adb2a558c02a7cad.1617290165.git.alistair.francis@wdc.com
This commit is contained in:
Alistair Francis 2021-04-01 11:17:39 -04:00
parent 330d2ae32a
commit 0e62f92eac
2 changed files with 46 additions and 37 deletions

View File

@ -472,7 +472,8 @@ static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
return val; return val;
} }
typedef int (*riscv_csr_predicate_fn)(CPURISCVState *env, int csrno); typedef RISCVException (*riscv_csr_predicate_fn)(CPURISCVState *env,
int csrno);
typedef int (*riscv_csr_read_fn)(CPURISCVState *env, int csrno, typedef int (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
target_ulong *ret_value); target_ulong *ret_value);
typedef int (*riscv_csr_write_fn)(CPURISCVState *env, int csrno, typedef int (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,

View File

@ -35,29 +35,29 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
} }
/* Predicates */ /* Predicates */
static int fs(CPURISCVState *env, int csrno) static RISCVException fs(CPURISCVState *env, int csrno)
{ {
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
/* loose check condition for fcsr in vector extension */ /* loose check condition for fcsr in vector extension */
if ((csrno == CSR_FCSR) && (env->misa & RVV)) { if ((csrno == CSR_FCSR) && (env->misa & RVV)) {
return 0; return RISCV_EXCP_NONE;
} }
if (!env->debugger && !riscv_cpu_fp_enabled(env)) { if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
return -RISCV_EXCP_ILLEGAL_INST; return RISCV_EXCP_ILLEGAL_INST;
} }
#endif #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) { 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) #if !defined(CONFIG_USER_ONLY)
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
@ -65,7 +65,7 @@ static int ctr(CPURISCVState *env, int csrno)
if (!cpu->cfg.ext_counters) { if (!cpu->cfg.ext_counters) {
/* The Counters extensions is not enabled */ /* The Counters extensions is not enabled */
return -RISCV_EXCP_ILLEGAL_INST; return RISCV_EXCP_ILLEGAL_INST;
} }
if (riscv_cpu_virt_enabled(env)) { if (riscv_cpu_virt_enabled(env)) {
@ -73,25 +73,25 @@ static int ctr(CPURISCVState *env, int csrno)
case CSR_CYCLE: case CSR_CYCLE:
if (!get_field(env->hcounteren, HCOUNTEREN_CY) && if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
get_field(env->mcounteren, HCOUNTEREN_CY)) { get_field(env->mcounteren, HCOUNTEREN_CY)) {
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
} }
break; break;
case CSR_TIME: case CSR_TIME:
if (!get_field(env->hcounteren, HCOUNTEREN_TM) && if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
get_field(env->mcounteren, HCOUNTEREN_TM)) { get_field(env->mcounteren, HCOUNTEREN_TM)) {
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
} }
break; break;
case CSR_INSTRET: case CSR_INSTRET:
if (!get_field(env->hcounteren, HCOUNTEREN_IR) && if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
get_field(env->mcounteren, HCOUNTEREN_IR)) { get_field(env->mcounteren, HCOUNTEREN_IR)) {
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
} }
break; break;
case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) && if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
get_field(env->mcounteren, 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; break;
} }
@ -100,93 +100,101 @@ static int ctr(CPURISCVState *env, int csrno)
case CSR_CYCLEH: case CSR_CYCLEH:
if (!get_field(env->hcounteren, HCOUNTEREN_CY) && if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
get_field(env->mcounteren, HCOUNTEREN_CY)) { get_field(env->mcounteren, HCOUNTEREN_CY)) {
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
} }
break; break;
case CSR_TIMEH: case CSR_TIMEH:
if (!get_field(env->hcounteren, HCOUNTEREN_TM) && if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
get_field(env->mcounteren, HCOUNTEREN_TM)) { get_field(env->mcounteren, HCOUNTEREN_TM)) {
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
} }
break; break;
case CSR_INSTRETH: case CSR_INSTRETH:
if (!get_field(env->hcounteren, HCOUNTEREN_IR) && if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
get_field(env->mcounteren, HCOUNTEREN_IR)) { get_field(env->mcounteren, HCOUNTEREN_IR)) {
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT; return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
} }
break; break;
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) && if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
get_field(env->mcounteren, 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; break;
} }
} }
} }
#endif #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)) { if (!riscv_cpu_is_32bit(env)) {
return -RISCV_EXCP_ILLEGAL_INST; return RISCV_EXCP_ILLEGAL_INST;
} }
return ctr(env, csrno); return ctr(env, csrno);
} }
#if !defined(CONFIG_USER_ONLY) #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)) { if (!riscv_cpu_is_32bit(env)) {
return -RISCV_EXCP_ILLEGAL_INST; return RISCV_EXCP_ILLEGAL_INST;
} }
return any(env, csrno); 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) && if (riscv_has_ext(env, RVS) &&
riscv_has_ext(env, RVH)) { riscv_has_ext(env, RVH)) {
/* Hypervisor extension is supported */ /* Hypervisor extension is supported */
if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) || if ((env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
env->priv == PRV_M) { env->priv == PRV_M) {
return 0; return RISCV_EXCP_NONE;
} else { } 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)) { if (!riscv_cpu_is_32bit(env)) {
return 0; return RISCV_EXCP_NONE;
} }
return hmode(env, csrno); return hmode(env, csrno);
} }
static int pmp(CPURISCVState *env, int csrno) static RISCVException pmp(CPURISCVState *env, int csrno)
{ {
return -!riscv_feature(env, RISCV_FEATURE_PMP); if (riscv_feature(env, RISCV_FEATURE_PMP)) {
return RISCV_EXCP_NONE;
}
return RISCV_EXCP_ILLEGAL_INST;
} }
#endif #endif
@ -1293,8 +1301,8 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
return -RISCV_EXCP_ILLEGAL_INST; return -RISCV_EXCP_ILLEGAL_INST;
} }
ret = csr_ops[csrno].predicate(env, csrno); ret = csr_ops[csrno].predicate(env, csrno);
if (ret < 0) { if (ret != RISCV_EXCP_NONE) {
return ret; return -ret;
} }
/* execute combined read/write operation if it exists */ /* execute combined read/write operation if it exists */