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 - 2026 Red Hat, Inc.