[PATCH v4 08/20] target/riscv: Create current pm fields in env

LIU Zhiwei posted 20 patches 4 years, 3 months ago
Maintainers: Bin Meng <bin.meng@windriver.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>
There is a newer version of this series
[PATCH v4 08/20] target/riscv: Create current pm fields in env
Posted by LIU Zhiwei 4 years, 3 months ago
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/cpu.c        |  1 +
 target/riscv/cpu.h        |  4 ++++
 target/riscv/cpu_helper.c | 43 +++++++++++++++++++++++++++++++++++++++
 target/riscv/csr.c        | 19 +++++++++++++++++
 target/riscv/machine.c    | 10 +++++++++
 5 files changed, 77 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0d2d175fa2..4f01abc989 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -393,6 +393,7 @@ static void riscv_cpu_reset(DeviceState *dev)
     /* mmte is supposed to have pm.current hardwired to 1 */
     env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
 #endif
+    riscv_cpu_update_mask(env);
     cs->exception_index = RISCV_EXCP_NONE;
     env->load_res = -1;
     set_default_nan_mode(1, &env->fp_status);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8befff0166..fa5a6ba1c8 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -250,6 +250,8 @@ struct CPURISCVState {
     target_ulong upmmask;
     target_ulong upmbase;
 #endif
+    target_ulong cur_pmmask;
+    target_ulong cur_pmbase;
 
     float_status fp_status;
 
@@ -441,6 +443,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);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 79aba9c880..8320f56d9f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -133,6 +133,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 (cpu_get_xl(env) == 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)
 {
@@ -331,6 +373,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;
+    riscv_cpu_update_mask(env);
 
     /*
      * Clear the load reservation - otherwise a reservation placed in one
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 74c0b788fd..6bb2d09519 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1496,6 +1496,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;
@@ -1571,6 +1572,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 */
@@ -1596,6 +1600,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 */
@@ -1621,6 +1628,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 */
@@ -1642,6 +1652,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 */
@@ -1667,6 +1680,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 */
@@ -1692,6 +1708,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 */
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 7b4c739564..19e982d3f0 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -164,10 +164,20 @@ static const VMStateDescription vmstate_hyper = {
     }
 };
 
+static int riscv_cpu_post_load(void *opaque, int version_id)
+{
+    RISCVCPU *cpu = opaque;
+    CPURISCVState *env = &cpu->env;
+
+    riscv_cpu_update_mask(env);
+    return 0;
+}
+
 const VMStateDescription vmstate_riscv_cpu = {
     .name = "cpu",
     .version_id = 3,
     .minimum_version_id = 3,
+    .post_load = riscv_cpu_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
         VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
-- 
2.25.1


Re: [PATCH v4 08/20] target/riscv: Create current pm fields in env
Posted by Alistair Francis 4 years, 2 months ago
On Fri, Nov 12, 2021 at 2:00 AM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c        |  1 +
>  target/riscv/cpu.h        |  4 ++++
>  target/riscv/cpu_helper.c | 43 +++++++++++++++++++++++++++++++++++++++
>  target/riscv/csr.c        | 19 +++++++++++++++++
>  target/riscv/machine.c    | 10 +++++++++
>  5 files changed, 77 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0d2d175fa2..4f01abc989 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -393,6 +393,7 @@ static void riscv_cpu_reset(DeviceState *dev)
>      /* mmte is supposed to have pm.current hardwired to 1 */
>      env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
>  #endif
> +    riscv_cpu_update_mask(env);
>      cs->exception_index = RISCV_EXCP_NONE;
>      env->load_res = -1;
>      set_default_nan_mode(1, &env->fp_status);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 8befff0166..fa5a6ba1c8 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -250,6 +250,8 @@ struct CPURISCVState {
>      target_ulong upmmask;
>      target_ulong upmbase;
>  #endif
> +    target_ulong cur_pmmask;
> +    target_ulong cur_pmbase;
>
>      float_status fp_status;
>
> @@ -441,6 +443,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);
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 79aba9c880..8320f56d9f 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -133,6 +133,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 (cpu_get_xl(env) == 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)
>  {
> @@ -331,6 +373,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;
> +    riscv_cpu_update_mask(env);
>
>      /*
>       * Clear the load reservation - otherwise a reservation placed in one
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 74c0b788fd..6bb2d09519 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1496,6 +1496,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;
> @@ -1571,6 +1572,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 */
> @@ -1596,6 +1600,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 */
> @@ -1621,6 +1628,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 */
> @@ -1642,6 +1652,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 */
> @@ -1667,6 +1680,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 */
> @@ -1692,6 +1708,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 */
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 7b4c739564..19e982d3f0 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -164,10 +164,20 @@ static const VMStateDescription vmstate_hyper = {
>      }
>  };
>
> +static int riscv_cpu_post_load(void *opaque, int version_id)
> +{
> +    RISCVCPU *cpu = opaque;
> +    CPURISCVState *env = &cpu->env;
> +
> +    riscv_cpu_update_mask(env);
> +    return 0;
> +}
> +
>  const VMStateDescription vmstate_riscv_cpu = {
>      .name = "cpu",
>      .version_id = 3,
>      .minimum_version_id = 3,
> +    .post_load = riscv_cpu_post_load,
>      .fields = (VMStateField[]) {
>          VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
>          VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
> --
> 2.25.1
>
>