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);
env->mmte = wpri_val | PM_EXT_DIRTY;
riscv_cpu_update_mask(env);
--
2.25.1
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);
>
© 2016 - 2026 Red Hat, Inc.