target/riscv: Create current pm fields in env
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220120122050.41546-12-zhiwei_liu@c-sky.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
83b519b8a4
commit
40bfa5f695
@ -430,6 +430,7 @@ static void riscv_cpu_reset(DeviceState *dev)
|
||||
env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
|
||||
#endif
|
||||
env->xl = riscv_cpu_mxl(env);
|
||||
riscv_cpu_update_mask(env);
|
||||
cs->exception_index = RISCV_EXCP_NONE;
|
||||
env->load_res = -1;
|
||||
set_default_nan_mode(1, &env->fp_status);
|
||||
|
@ -266,6 +266,8 @@ struct CPURISCVState {
|
||||
target_ulong upmmask;
|
||||
target_ulong upmbase;
|
||||
#endif
|
||||
target_ulong cur_pmmask;
|
||||
target_ulong cur_pmbase;
|
||||
|
||||
float_status fp_status;
|
||||
|
||||
@ -515,6 +517,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
|
||||
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, uint32_t *pflags);
|
||||
|
||||
void riscv_cpu_update_mask(CPURISCVState *env);
|
||||
|
||||
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
|
||||
target_ulong *ret_value,
|
||||
target_ulong new_value, target_ulong write_mask);
|
||||
|
@ -122,6 +122,48 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
||||
*pflags = flags;
|
||||
}
|
||||
|
||||
void riscv_cpu_update_mask(CPURISCVState *env)
|
||||
{
|
||||
target_ulong mask = -1, base = 0;
|
||||
/*
|
||||
* TODO: Current RVJ spec does not specify
|
||||
* how the extension interacts with XLEN.
|
||||
*/
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (riscv_has_ext(env, RVJ)) {
|
||||
switch (env->priv) {
|
||||
case PRV_M:
|
||||
if (env->mmte & M_PM_ENABLE) {
|
||||
mask = env->mpmmask;
|
||||
base = env->mpmbase;
|
||||
}
|
||||
break;
|
||||
case PRV_S:
|
||||
if (env->mmte & S_PM_ENABLE) {
|
||||
mask = env->spmmask;
|
||||
base = env->spmbase;
|
||||
}
|
||||
break;
|
||||
case PRV_U:
|
||||
if (env->mmte & U_PM_ENABLE) {
|
||||
mask = env->upmmask;
|
||||
base = env->upmbase;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (env->xl == MXL_RV32) {
|
||||
env->cur_pmmask = mask & UINT32_MAX;
|
||||
env->cur_pmbase = base & UINT32_MAX;
|
||||
} else {
|
||||
env->cur_pmmask = mask;
|
||||
env->cur_pmbase = base;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static int riscv_cpu_local_irq_pending(CPURISCVState *env)
|
||||
{
|
||||
@ -334,6 +376,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
|
||||
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
|
||||
env->priv = newpriv;
|
||||
env->xl = cpu_recompute_xl(env);
|
||||
riscv_cpu_update_mask(env);
|
||||
|
||||
/*
|
||||
* Clear the load reservation - otherwise a reservation placed in one
|
||||
|
@ -1607,6 +1607,7 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno,
|
||||
/* hardwiring pm.instruction bit to 0, since it's not supported yet */
|
||||
wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
|
||||
env->mmte = wpri_val | PM_EXT_DIRTY;
|
||||
riscv_cpu_update_mask(env);
|
||||
|
||||
/* Set XS and SD bits, since PM CSRs are dirty */
|
||||
mstatus = env->mstatus | MSTATUS_XS;
|
||||
@ -1682,6 +1683,9 @@ static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
|
||||
uint64_t mstatus;
|
||||
|
||||
env->mpmmask = val;
|
||||
if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
|
||||
env->cur_pmmask = val;
|
||||
}
|
||||
env->mmte |= PM_EXT_DIRTY;
|
||||
|
||||
/* Set XS and SD bits, since PM CSRs are dirty */
|
||||
@ -1707,6 +1711,9 @@ static RISCVException write_spmmask(CPURISCVState *env, int csrno,
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
env->spmmask = val;
|
||||
if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
|
||||
env->cur_pmmask = val;
|
||||
}
|
||||
env->mmte |= PM_EXT_DIRTY;
|
||||
|
||||
/* Set XS and SD bits, since PM CSRs are dirty */
|
||||
@ -1732,6 +1739,9 @@ static RISCVException write_upmmask(CPURISCVState *env, int csrno,
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
env->upmmask = val;
|
||||
if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
|
||||
env->cur_pmmask = val;
|
||||
}
|
||||
env->mmte |= PM_EXT_DIRTY;
|
||||
|
||||
/* Set XS and SD bits, since PM CSRs are dirty */
|
||||
@ -1753,6 +1763,9 @@ static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
|
||||
uint64_t mstatus;
|
||||
|
||||
env->mpmbase = val;
|
||||
if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
|
||||
env->cur_pmbase = val;
|
||||
}
|
||||
env->mmte |= PM_EXT_DIRTY;
|
||||
|
||||
/* Set XS and SD bits, since PM CSRs are dirty */
|
||||
@ -1778,6 +1791,9 @@ static RISCVException write_spmbase(CPURISCVState *env, int csrno,
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
env->spmbase = val;
|
||||
if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
|
||||
env->cur_pmbase = val;
|
||||
}
|
||||
env->mmte |= PM_EXT_DIRTY;
|
||||
|
||||
/* Set XS and SD bits, since PM CSRs are dirty */
|
||||
@ -1803,6 +1819,9 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
env->upmbase = val;
|
||||
if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
|
||||
env->cur_pmbase = val;
|
||||
}
|
||||
env->mmte |= PM_EXT_DIRTY;
|
||||
|
||||
/* Set XS and SD bits, since PM CSRs are dirty */
|
||||
|
@ -220,6 +220,7 @@ static int riscv_cpu_post_load(void *opaque, int version_id)
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
env->xl = cpu_recompute_xl(env);
|
||||
riscv_cpu_update_mask(env);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user