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:
LIU Zhiwei 2022-01-20 20:20:38 +08:00 committed by Alistair Francis
parent 83b519b8a4
commit 40bfa5f695
5 changed files with 68 additions and 0 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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;
}