From: Alexey Baturo <baturo.ale...@gmail.com> Signed-off-by: Alexey Baturo <baturo.ale...@gmail.com> --- target/riscv/cpu.h | 4 +++ target/riscv/cpu_helper.c | 58 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c9bed5c9fc..1c8979c1c8 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -671,6 +671,10 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags); +bool riscv_cpu_virt_mem_enabled(CPURISCVState *env); +RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env); +int riscv_pm_get_pmlen(RISCVPmPmm pmm); + 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 a3d477d226..9640e4c2c5 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -139,6 +139,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