From: Alexey Baturo <baturo.alexey@gmail.com>
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 5 ++++
target/riscv/cpu_helper.c | 58 +++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 52b6ba73c8..9cac723b19 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -698,8 +698,13 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
+bool riscv_cpu_virt_mem_enabled(CPURISCVState *env);
+RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env);
+int riscv_pm_get_pmlen(RISCVPmPmm pmm);
+
RISCVException riscv_csrr(CPURISCVState *env, int csrno,
target_ulong *ret_value);
+
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 bf58350669..e4a127ca84 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
*pflags = flags;
}
+RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
+{
+ int pmm = 0;
+#ifndef CONFIG_USER_ONLY
+ int priv_mode = cpu_address_mode(env);
+ /* Get current PMM field */
+ switch (priv_mode) {
+ case PRV_M:
+ pmm = riscv_cpu_cfg(env)->ext_smmpm ?
+ get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED;
+ break;
+ case PRV_S:
+ pmm = riscv_cpu_cfg(env)->ext_smnpm ?
+ get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED;
+ break;
+ case PRV_U:
+ pmm = riscv_cpu_cfg(env)->ext_ssnpm ?
+ get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+#endif
+ return pmm;
+}
+
+bool riscv_cpu_virt_mem_enabled(CPURISCVState *env)
+{
+ bool virt_mem_en = false;
+#ifndef CONFIG_USER_ONLY
+ int satp_mode = 0;
+ int priv_mode = cpu_address_mode(env);
+ /* Get current PMM field */
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
+ satp_mode = get_field(env->satp, SATP32_MODE);
+ } else {
+ satp_mode = get_field(env->satp, SATP64_MODE);
+ }
+ virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M));
+#endif
+ return virt_mem_en;
+}
+
+int riscv_pm_get_pmlen(RISCVPmPmm pmm)
+{
+ switch (pmm) {
+ case PMM_FIELD_DISABLED:
+ return 0;
+ case PMM_FIELD_PMLEN7:
+ return 7;
+ case PMM_FIELD_PMLEN16:
+ return 16;
+ default:
+ g_assert_not_reached();
+ }
+ return -1;
+}
+
#ifndef CONFIG_USER_ONLY
/*
--
2.34.1
On 2024/5/11 18:10, Alexey Baturo wrote: > From: Alexey Baturo<baturo.alexey@gmail.com> > > Signed-off-by: Alexey Baturo<baturo.alexey@gmail.com> > > Reviewed-by: Alistair Francis<alistair.francis@wdc.com> > --- > target/riscv/cpu.h | 5 ++++ > target/riscv/cpu_helper.c | 58 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 63 insertions(+) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 52b6ba73c8..9cac723b19 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -698,8 +698,13 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, > > bool riscv_cpu_is_32bit(RISCVCPU *cpu); > > +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); > +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); > +int riscv_pm_get_pmlen(RISCVPmPmm pmm); > + > RISCVException riscv_csrr(CPURISCVState *env, int csrno, > target_ulong *ret_value); > + > 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 bf58350669..e4a127ca84 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, > *pflags = flags; > } > > +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) I think we should process XLEN here. Pack *XL32 into PMM_FIELD_DISABLED Zhiwei > +{ > + int pmm = 0; > +#ifndef CONFIG_USER_ONLY > + int priv_mode = cpu_address_mode(env); > + /* Get current PMM field */ > + switch (priv_mode) { > + case PRV_M: > + pmm = riscv_cpu_cfg(env)->ext_smmpm ? > + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; > + break; > + case PRV_S: > + pmm = riscv_cpu_cfg(env)->ext_smnpm ? > + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; > + break; > + case PRV_U: > + pmm = riscv_cpu_cfg(env)->ext_ssnpm ? > + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; > + break; > + default: > + g_assert_not_reached(); > + } > +#endif > + return pmm; > +} > + > +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) > +{ > + bool virt_mem_en = false; > +#ifndef CONFIG_USER_ONLY > + int satp_mode = 0; > + int priv_mode = cpu_address_mode(env); > + /* Get current PMM field */ > + if (riscv_cpu_mxl(env) == MXL_RV32) { > + satp_mode = get_field(env->satp, SATP32_MODE); > + } else { > + satp_mode = get_field(env->satp, SATP64_MODE); > + } > + virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); > +#endif > + return virt_mem_en; > +} > + > +int riscv_pm_get_pmlen(RISCVPmPmm pmm) > +{ > + switch (pmm) { > + case PMM_FIELD_DISABLED: > + return 0; > + case PMM_FIELD_PMLEN7: > + return 7; > + case PMM_FIELD_PMLEN16: > + return 16; > + default: > + g_assert_not_reached(); > + } > + return -1; > +} > + > #ifndef CONFIG_USER_ONLY > > /*
On 2024/5/13 20:35, LIU Zhiwei wrote: > > > On 2024/5/11 18:10, Alexey Baturo wrote: >> From: Alexey Baturo<baturo.alexey@gmail.com> >> >> Signed-off-by: Alexey Baturo<baturo.alexey@gmail.com> >> >> Reviewed-by: Alistair Francis<alistair.francis@wdc.com> >> --- >> target/riscv/cpu.h | 5 ++++ >> target/riscv/cpu_helper.c | 58 +++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 63 insertions(+) >> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h >> index 52b6ba73c8..9cac723b19 100644 >> --- a/target/riscv/cpu.h >> +++ b/target/riscv/cpu.h >> @@ -698,8 +698,13 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, >> >> bool riscv_cpu_is_32bit(RISCVCPU *cpu); >> >> +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); >> +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); >> +int riscv_pm_get_pmlen(RISCVPmPmm pmm); >> + >> RISCVException riscv_csrr(CPURISCVState *env, int csrno, >> target_ulong *ret_value); >> + >> 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 bf58350669..e4a127ca84 100644 >> --- a/target/riscv/cpu_helper.c >> +++ b/target/riscv/cpu_helper.c >> @@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, >> *pflags = flags; >> } >> >> +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) > > I think we should process XLEN here. > > Pack *XL32 into PMM_FIELD_DISABLED > Please ignore this comment. I see you have considered the XLEN in patch 5/6. > Zhiwei >> +{ >> + int pmm = 0; >> +#ifndef CONFIG_USER_ONLY >> + int priv_mode = cpu_address_mode(env); >> + /* Get current PMM field */ >> + switch (priv_mode) { >> + case PRV_M: >> + pmm = riscv_cpu_cfg(env)->ext_smmpm ? >> + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; >> + break; >> + case PRV_S: >> + pmm = riscv_cpu_cfg(env)->ext_smnpm ? >> + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; >> + break; >> + case PRV_U: >> + pmm = riscv_cpu_cfg(env)->ext_ssnpm ? >> + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; >> + break; >> + default: >> + g_assert_not_reached(); >> + } >> +#endif >> + return pmm; >> +} >> + >> +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) >> +{ >> + bool virt_mem_en = false; >> +#ifndef CONFIG_USER_ONLY >> + int satp_mode = 0; >> + int priv_mode = cpu_address_mode(env); >> + /* Get current PMM field */ >> + if (riscv_cpu_mxl(env) == MXL_RV32) { >> + satp_mode = get_field(env->satp, SATP32_MODE); >> + } else { >> + satp_mode = get_field(env->satp, SATP64_MODE); >> + } >> + virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); >> +#endif >> + return virt_mem_en; >> +} >> + >> +int riscv_pm_get_pmlen(RISCVPmPmm pmm) >> +{ >> + switch (pmm) { >> + case PMM_FIELD_DISABLED: >> + return 0; >> + case PMM_FIELD_PMLEN7: >> + return 7; >> + case PMM_FIELD_PMLEN16: >> + return 16; >> + default: >> + g_assert_not_reached(); >> + } >> + return -1; >> +} >> + >> #ifndef CONFIG_USER_ONLY >> >> /*
On 2024/5/11 18:10, Alexey Baturo wrote: > From: Alexey Baturo <baturo.alexey@gmail.com> > > Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com> > > Reviewed-by: Alistair Francis <alistair.francis@wdc.com> > --- > target/riscv/cpu.h | 5 ++++ > target/riscv/cpu_helper.c | 58 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 63 insertions(+) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 52b6ba73c8..9cac723b19 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -698,8 +698,13 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, > > bool riscv_cpu_is_32bit(RISCVCPU *cpu); > > +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); > +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); > +int riscv_pm_get_pmlen(RISCVPmPmm pmm); > + > RISCVException riscv_csrr(CPURISCVState *env, int csrno, > target_ulong *ret_value); > + > 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 bf58350669..e4a127ca84 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -142,6 +142,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, > *pflags = flags; > } > > +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env) > +{ > + int pmm = 0; > +#ifndef CONFIG_USER_ONLY > + int priv_mode = cpu_address_mode(env); This takes care of the MPRV and MPP, but is not enough. When MPRV == 1 and MXR == 1, we should ignore the address. In this case, we should return PMM_FIELD_DISABLED. We should also consider the MPV field, see the comments below. > + /* Get current PMM field */ > + switch (priv_mode) { > + case PRV_M: > + pmm = riscv_cpu_cfg(env)->ext_smmpm ? > + get_field(env->mseccfg, MSECCFG_PMM) : PMM_FIELD_DISABLED; > + break; > + case PRV_S: > + pmm = riscv_cpu_cfg(env)->ext_smnpm ? > + get_field(env->menvcfg, MENVCFG_PMM) : PMM_FIELD_DISABLED; When in virtualization mode, we should use henvcfg instead of menvcfg . > + break; > + case PRV_U: > + pmm = riscv_cpu_cfg(env)->ext_ssnpm ? > + get_field(env->senvcfg, SENVCFG_PMM) : PMM_FIELD_DISABLED; When Smode is not implemented, we should use smnpm here. > + break; > + default: > + g_assert_not_reached(); > + } > +#endif > + return pmm; > +} > + > +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env) > +{ > + bool virt_mem_en = false; > +#ifndef CONFIG_USER_ONLY > + int satp_mode = 0; > + int priv_mode = cpu_address_mode(env); Or S mode is not implemented. Zhiwei > + /* Get current PMM field */ > + if (riscv_cpu_mxl(env) == MXL_RV32) { > + satp_mode = get_field(env->satp, SATP32_MODE); > + } else { > + satp_mode = get_field(env->satp, SATP64_MODE); > + } > + virt_mem_en = ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M)); > +#endif > + return virt_mem_en; > +} > + > +int riscv_pm_get_pmlen(RISCVPmPmm pmm) > +{ > + switch (pmm) { > + case PMM_FIELD_DISABLED: > + return 0; > + case PMM_FIELD_PMLEN7: > + return 7; > + case PMM_FIELD_PMLEN16: > + return 16; > + default: > + g_assert_not_reached(); > + } > + return -1; > +} > + > #ifndef CONFIG_USER_ONLY > > /*
© 2016 - 2024 Red Hat, Inc.