Re: [PATCH v10 3/7] [RISCV_PM] Support CSRs required for RISC-V PM extension except for the h-mode

2021-09-08 Thread Alistair Francis
On Mon, Aug 30, 2021 at 3:54 AM Alexey Baturo  wrote:
>
> Signed-off-by: Alexey Baturo 
> ---
>  target/riscv/cpu.c |   6 +
>  target/riscv/cpu.h |  11 ++
>  target/riscv/csr.c | 276 +
>  3 files changed, 293 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 991a6bb760..4178eecbec 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -553,6 +553,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>  }
>  set_vext_version(env, vext_version);
>  }
> +if (cpu->cfg.ext_j) {
> +#ifndef CONFIG_USER_ONLY
> +/* mmte is supposed to have pm.current hardwired to 1 */
> +env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);

This should probably be in the reset function instead.

> +#endif
> +}
>
>  set_misa(env, target_misa);
>  }
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 451a1637a1..94e680cbd0 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -238,6 +238,17 @@ struct CPURISCVState {
>
>  /* True if in debugger mode.  */
>  bool debugger;
> +
> +/*
> + * CSRs for PointerMasking extension
> + */
> +target_ulong mmte;
> +target_ulong mpmmask;
> +target_ulong mpmbase;
> +target_ulong spmmask;
> +target_ulong spmbase;
> +target_ulong upmmask;
> +target_ulong upmbase;
>  #endif
>
>  float_status fp_status;
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 9a4ed18ac5..42a0867e5d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -192,6 +192,16 @@ static RISCVException hmode32(CPURISCVState *env, int 
> csrno)
>
>  }
>
> +/* Checks if PointerMasking registers could be accessed */
> +static RISCVException pointer_masking(CPURISCVState *env, int csrno)
> +{
> +/* Check if j-ext is present */
> +if (riscv_has_ext(env, RVJ)) {
> +return RISCV_EXCP_NONE;
> +}
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
> +
>  static RISCVException pmp(CPURISCVState *env, int csrno)
>  {
>  if (riscv_feature(env, RISCV_FEATURE_PMP)) {
> @@ -1404,6 +1414,259 @@ static RISCVException write_pmpaddr(CPURISCVState 
> *env, int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> +/*
> + * Functions to access Pointer Masking feature registers
> + * We have to check if current priv lvl could modify
> + * csr in given mode
> + */
> +static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
> +{
> +int csr_priv = get_field(csrno, 0x300);

Can you add a newline between declarations and code?

> +/*
> + * If priv lvls differ that means we're accessing csr from higher priv 
> lvl,
> + * so allow the access
> + */
> +if (env->priv != csr_priv) {
> +return false;
> +}
> +int cur_bit_pos;

Can you keep all of the declarations at the start of blocks please.

> +switch (env->priv) {
> +case PRV_M:
> +cur_bit_pos = M_PM_CURRENT;
> +break;
> +case PRV_S:
> +cur_bit_pos = S_PM_CURRENT;
> +break;
> +case PRV_U:
> +cur_bit_pos = U_PM_CURRENT;
> +break;
> +default:
> +g_assert_not_reached();
> +}
> +int pm_current = get_field(env->mmte, cur_bit_pos);
> +/* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
> +return !pm_current;
> +}
> +
> +static RISCVException read_mmte(CPURISCVState *env, int csrno,
> +target_ulong *val)
> +{
> +*val = env->mmte & MMTE_MASK;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_mmte(CPURISCVState *env, int csrno,
> + target_ulong val)
> +{
> +uint64_t mstatus;
> +target_ulong wpri_val = val & MMTE_MASK;
> +if (val != wpri_val) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "MMTE: WPRI violation written 0x%lx vs expected 
> 0x%lx\n",
> +  val, wpri_val);
> +}
> +/* 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;
> +
> +/* Set XS and SD bits, since PM CSRs are dirty */
> +mstatus = env->mstatus | MSTATUS_XS;
> +write_mstatus(env, csrno, mstatus);
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException read_smte(CPURISCVState *env, int csrno,
> +target_ulong *val)
> +{
> +*val = env->mmte & SMTE_MASK;
> +return RISCV_EXCP_NONE;
> +}
> +
> +static RISCVException write_smte(CPURISCVState *env, int csrno,
> + target_ulong val)
> +{
> +target_ulong wpri_val = val & SMTE_MASK;
> +if (val != wpri_val) {
> +qemu_log_mask(LOG_GUEST_ERROR,
> +  "SMTE: WPRI violation 

[PATCH v10 3/7] [RISCV_PM] Support CSRs required for RISC-V PM extension except for the h-mode

2021-08-29 Thread Alexey Baturo
Signed-off-by: Alexey Baturo 
---
 target/riscv/cpu.c |   6 +
 target/riscv/cpu.h |  11 ++
 target/riscv/csr.c | 276 +
 3 files changed, 293 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 991a6bb760..4178eecbec 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -553,6 +553,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 set_vext_version(env, vext_version);
 }
+if (cpu->cfg.ext_j) {
+#ifndef CONFIG_USER_ONLY
+/* mmte is supposed to have pm.current hardwired to 1 */
+env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
+#endif
+}
 
 set_misa(env, target_misa);
 }
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 451a1637a1..94e680cbd0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -238,6 +238,17 @@ struct CPURISCVState {
 
 /* True if in debugger mode.  */
 bool debugger;
+
+/*
+ * CSRs for PointerMasking extension
+ */
+target_ulong mmte;
+target_ulong mpmmask;
+target_ulong mpmbase;
+target_ulong spmmask;
+target_ulong spmbase;
+target_ulong upmmask;
+target_ulong upmbase;
 #endif
 
 float_status fp_status;
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9a4ed18ac5..42a0867e5d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -192,6 +192,16 @@ static RISCVException hmode32(CPURISCVState *env, int 
csrno)
 
 }
 
+/* Checks if PointerMasking registers could be accessed */
+static RISCVException pointer_masking(CPURISCVState *env, int csrno)
+{
+/* Check if j-ext is present */
+if (riscv_has_ext(env, RVJ)) {
+return RISCV_EXCP_NONE;
+}
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 static RISCVException pmp(CPURISCVState *env, int csrno)
 {
 if (riscv_feature(env, RISCV_FEATURE_PMP)) {
@@ -1404,6 +1414,259 @@ static RISCVException write_pmpaddr(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+/*
+ * Functions to access Pointer Masking feature registers
+ * We have to check if current priv lvl could modify
+ * csr in given mode
+ */
+static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
+{
+int csr_priv = get_field(csrno, 0x300);
+/*
+ * If priv lvls differ that means we're accessing csr from higher priv lvl,
+ * so allow the access
+ */
+if (env->priv != csr_priv) {
+return false;
+}
+int cur_bit_pos;
+switch (env->priv) {
+case PRV_M:
+cur_bit_pos = M_PM_CURRENT;
+break;
+case PRV_S:
+cur_bit_pos = S_PM_CURRENT;
+break;
+case PRV_U:
+cur_bit_pos = U_PM_CURRENT;
+break;
+default:
+g_assert_not_reached();
+}
+int pm_current = get_field(env->mmte, cur_bit_pos);
+/* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
+return !pm_current;
+}
+
+static RISCVException read_mmte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & MMTE_MASK;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mmte(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+uint64_t mstatus;
+target_ulong wpri_val = val & MMTE_MASK;
+if (val != wpri_val) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "MMTE: WPRI violation written 0x%lx vs expected 0x%lx\n",
+  val, wpri_val);
+}
+/* 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;
+
+/* Set XS and SD bits, since PM CSRs are dirty */
+mstatus = env->mstatus | MSTATUS_XS;
+write_mstatus(env, csrno, mstatus);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_smte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & SMTE_MASK;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_smte(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+target_ulong wpri_val = val & SMTE_MASK;
+if (val != wpri_val) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "SMTE: WPRI violation written 0x%lx vs expected 0x%lx\n",
+  val, wpri_val);
+}
+
+/* if pm.current==0 we can't modify current PM CSRs */
+if (check_pm_current_disabled(env, csrno)) {
+return RISCV_EXCP_NONE;
+}
+
+target_ulong new_val = wpri_val | (env->mmte & ~SMTE_MASK);
+write_mmte(env, csrno, new_val);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_umte(CPURISCVState *env, int csrno,
+target_ulong *val)
+{
+*val = env->mmte & UMTE_MASK;
+