Message ID | 20230404020653.18911-7-liweiwei@iscas.ac.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | target/riscv: Fix pointer mask related support | expand |
On 2023/4/4 10:06, Weiwei Li wrote: > Transform the fetch address in cpu_get_tb_cpu_state() when pointer > mask for instruction is enabled. > > Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> > Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> > Reviewed-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/riscv/cpu.h | 1 + > target/riscv/cpu_helper.c | 20 +++++++++++++++++++- > target/riscv/csr.c | 2 -- > 3 files changed, 20 insertions(+), 3 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 638e47c75a..57bd9c3279 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -368,6 +368,7 @@ struct CPUArchState { > #endif > target_ulong cur_pmmask; > target_ulong cur_pmbase; > + bool cur_pminsn; > > /* Fields from here on are preserved across CPU reset. */ > QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > index f88c503cf4..b683a770fe 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -40,6 +40,19 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) > #endif > } > > +static target_ulong adjust_pc_address(CPURISCVState *env, target_ulong pc) > +{ > + target_ulong adjust_pc = pc; > + > + if (env->cur_pminsn) { > + adjust_pc = (adjust_pc & ~env->cur_pmmask) | env->cur_pmbase; > + } else if (env->xl == MXL_RV32) { > + adjust_pc &= UINT32_MAX; > + } > + > + return adjust_pc; > +} > + > void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, > target_ulong *cs_base, uint32_t *pflags) > { > @@ -48,7 +61,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, > > uint32_t flags = 0; > > - *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; > + *pc = adjust_pc_address(env, env->pc); > *cs_base = 0; > > if (cpu->cfg.ext_zve32f) { > @@ -124,6 +137,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, > void riscv_cpu_update_mask(CPURISCVState *env) > { > target_ulong mask = -1, base = 0; > + bool insn = false; > /* > * TODO: Current RVJ spec does not specify > * how the extension interacts with XLEN. > @@ -135,18 +149,21 @@ void riscv_cpu_update_mask(CPURISCVState *env) > if (env->mmte & M_PM_ENABLE) { > mask = env->mpmmask; > base = env->mpmbase; > + insn = env->mmte & MMTE_M_PM_INSN; > } > break; > case PRV_S: > if (env->mmte & S_PM_ENABLE) { > mask = env->spmmask; > base = env->spmbase; > + insn = env->mmte & MMTE_S_PM_INSN; > } > break; > case PRV_U: > if (env->mmte & U_PM_ENABLE) { > mask = env->upmmask; > base = env->upmbase; > + insn = env->mmte & MMTE_U_PM_INSN; > } > break; > default: > @@ -161,6 +178,7 @@ void riscv_cpu_update_mask(CPURISCVState *env) > env->cur_pmmask = mask; > env->cur_pmbase = base; > } > + env->cur_pminsn = insn; > } > > #ifndef CONFIG_USER_ONLY > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 43b9ad4500..0902b64129 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -3518,8 +3518,6 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno, > /* for machine mode pm.current is hardwired to 1 */ > wpri_val |= MMTE_M_PM_CURRENT; > > - /* 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); Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> Zhiwei > env->mmte = wpri_val | PM_EXT_DIRTY; > riscv_cpu_update_mask(env); >
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 638e47c75a..57bd9c3279 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -368,6 +368,7 @@ struct CPUArchState { #endif target_ulong cur_pmmask; target_ulong cur_pmbase; + bool cur_pminsn; /* Fields from here on are preserved across CPU reset. */ QEMUTimer *stimer; /* Internal timer for S-mode interrupt */ diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index f88c503cf4..b683a770fe 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -40,6 +40,19 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) #endif } +static target_ulong adjust_pc_address(CPURISCVState *env, target_ulong pc) +{ + target_ulong adjust_pc = pc; + + if (env->cur_pminsn) { + adjust_pc = (adjust_pc & ~env->cur_pmmask) | env->cur_pmbase; + } else if (env->xl == MXL_RV32) { + adjust_pc &= UINT32_MAX; + } + + return adjust_pc; +} + void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, target_ulong *cs_base, uint32_t *pflags) { @@ -48,7 +61,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, uint32_t flags = 0; - *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc; + *pc = adjust_pc_address(env, env->pc); *cs_base = 0; if (cpu->cfg.ext_zve32f) { @@ -124,6 +137,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, void riscv_cpu_update_mask(CPURISCVState *env) { target_ulong mask = -1, base = 0; + bool insn = false; /* * TODO: Current RVJ spec does not specify * how the extension interacts with XLEN. @@ -135,18 +149,21 @@ void riscv_cpu_update_mask(CPURISCVState *env) if (env->mmte & M_PM_ENABLE) { mask = env->mpmmask; base = env->mpmbase; + insn = env->mmte & MMTE_M_PM_INSN; } break; case PRV_S: if (env->mmte & S_PM_ENABLE) { mask = env->spmmask; base = env->spmbase; + insn = env->mmte & MMTE_S_PM_INSN; } break; case PRV_U: if (env->mmte & U_PM_ENABLE) { mask = env->upmmask; base = env->upmbase; + insn = env->mmte & MMTE_U_PM_INSN; } break; default: @@ -161,6 +178,7 @@ void riscv_cpu_update_mask(CPURISCVState *env) env->cur_pmmask = mask; env->cur_pmbase = base; } + env->cur_pminsn = insn; } #ifndef CONFIG_USER_ONLY diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 43b9ad4500..0902b64129 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -3518,8 +3518,6 @@ static RISCVException write_mmte(CPURISCVState *env, int csrno, /* for machine mode pm.current is hardwired to 1 */ wpri_val |= MMTE_M_PM_CURRENT; - /* 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);