[PATCH v9 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking

Alexey Baturo posted 6 patches 6 months, 2 weeks ago
[PATCH v9 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
Posted by Alexey Baturo 6 months, 2 weeks ago
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
Re: [PATCH v9 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
Posted by LIU Zhiwei 6 months, 2 weeks ago
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
>   
>   /*
Re: [PATCH v9 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
Posted by LIU Zhiwei 6 months, 2 weeks ago
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
>>   
>>   /*
Re: [PATCH v9 3/6] target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
Posted by LIU Zhiwei 6 months, 2 weeks ago
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
>   
>   /*