Message ID | 20230908182640.1102270-7-baturo.alexey@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | RISC-V Pointer Masking update to Zjpm v0.6.1 | expand |
On Sat, Sep 9, 2023 at 5:37 AM Alexey Baturo <baturo.alexey@gmail.com> wrote: > > Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com> > --- > target/riscv/cpu.h | 6 ++-- > target/riscv/cpu_helper.c | 58 +++++++++++++++++++++++++++++++++++++++ > 2 files changed, 62 insertions(+), 2 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 17d0088cb4..c87c4f26a2 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -91,11 +91,9 @@ typedef enum { > /* Enum holds maximum for N bits to be ignored depending on privilege level */ > typedef enum { > PM_BARE_N_BITS = 16, > - PM_SV32_N_BITS = 0, > PM_SV39_N_BITS = 25, > PM_SV48_N_BITS = 16, > PM_SV57_N_BITS = 7, > - PM_SV64_N_BITS = 0, > } RISCVZjpmMaxNBits; Didn't you just add this? Why remove parts from it Alistair > > #define MMU_USER_IDX 3 > @@ -633,6 +631,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); > > +void riscv_cpu_update_mask(CPURISCVState *env); > +RISCVZjpmMaxNBits riscv_cpu_pm_get_n_bits(int satp_mode, int priv_mode); > +bool riscv_cpu_pm_check_applicable(CPURISCVState *env, int priv_mode); > + > 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 b3871b0a28..6e68b2fc27 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -144,6 +144,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, > *pflags = flags; > } > > +/* > + * Curernt Zjpm v0.6.1 spec doesn't strictly specify the exact value of N bits. > + * It allows it to be dependent on both translation mode and priv level. > + * For now let's ignore priv mode and always return max available value. > + */ > +RISCVZjpmMaxNBits riscv_cpu_pm_get_n_bits(int satp_mode, int priv_mode) > +{ > + switch (satp_mode) { > + case VM_1_10_MBARE: > + return PM_BARE_N_BITS; > + case VM_1_10_SV39: > + return PM_SV39_N_BITS; > + case VM_1_10_SV48: > + return PM_SV48_N_BITS; > + case VM_1_10_SV57: > + return PM_SV57_N_BITS; > + default: > + g_assert_not_reached(); > + } > +} > + > +/* For current priv level check if pointer masking should be applied */ > +bool riscv_cpu_pm_check_applicable(CPURISCVState *env, int priv_mode) > +{ > + /* checks if appropriate extension is present and enable bit is set */ > + switch (priv_mode) { > + case PRV_M: > + return riscv_cpu_cfg(env)->ext_smmjpm && env->mseccfg & MSECCFG_MPMEN; > + case PRV_S: > + return riscv_cpu_cfg(env)->ext_smnjpm && env->menvcfg & MENVCFG_SPMEN; > + case PRV_U: > + return riscv_cpu_cfg(env)->ext_ssnjpm && env->senvcfg & SENVCFG_UPMEN; > + default: > + g_assert_not_reached(); > + } > + g_assert_not_reached(); > + return false; > +} > + > +void riscv_cpu_update_mask(CPURISCVState *env) > +{ > +#ifndef CONFIG_USER_ONLY > + int priv_mode = cpu_address_mode(env); > + int satp_mode = 0; > + if (riscv_cpu_mxl(env) == MXL_RV32) { > + satp_mode = get_field(env->satp, SATP32_MODE); > + } else { > + satp_mode = get_field(env->satp, SATP64_MODE); > + } > + RISCVZjpmMaxNBits n_bits = riscv_cpu_pm_get_n_bits(satp_mode, priv_mode); > + /* in bare mode address is not sign extended */ > + env->pm_signext = (satp_mode != VM_1_10_MBARE); > + /* if pointer masking is applicable set env variable */ > + bool applicable = riscv_cpu_pm_check_applicable(env, priv_mode); > + env->pm_n_bits = applicable ? n_bits : 0; > +#endif > +} > + > #ifndef CONFIG_USER_ONLY > > /* > -- > 2.34.1 > >
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 17d0088cb4..c87c4f26a2 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -91,11 +91,9 @@ typedef enum { /* Enum holds maximum for N bits to be ignored depending on privilege level */ typedef enum { PM_BARE_N_BITS = 16, - PM_SV32_N_BITS = 0, PM_SV39_N_BITS = 25, PM_SV48_N_BITS = 16, PM_SV57_N_BITS = 7, - PM_SV64_N_BITS = 0, } RISCVZjpmMaxNBits; #define MMU_USER_IDX 3 @@ -633,6 +631,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); +void riscv_cpu_update_mask(CPURISCVState *env); +RISCVZjpmMaxNBits riscv_cpu_pm_get_n_bits(int satp_mode, int priv_mode); +bool riscv_cpu_pm_check_applicable(CPURISCVState *env, int priv_mode); + 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 b3871b0a28..6e68b2fc27 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -144,6 +144,64 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, *pflags = flags; } +/* + * Curernt Zjpm v0.6.1 spec doesn't strictly specify the exact value of N bits. + * It allows it to be dependent on both translation mode and priv level. + * For now let's ignore priv mode and always return max available value. + */ +RISCVZjpmMaxNBits riscv_cpu_pm_get_n_bits(int satp_mode, int priv_mode) +{ + switch (satp_mode) { + case VM_1_10_MBARE: + return PM_BARE_N_BITS; + case VM_1_10_SV39: + return PM_SV39_N_BITS; + case VM_1_10_SV48: + return PM_SV48_N_BITS; + case VM_1_10_SV57: + return PM_SV57_N_BITS; + default: + g_assert_not_reached(); + } +} + +/* For current priv level check if pointer masking should be applied */ +bool riscv_cpu_pm_check_applicable(CPURISCVState *env, int priv_mode) +{ + /* checks if appropriate extension is present and enable bit is set */ + switch (priv_mode) { + case PRV_M: + return riscv_cpu_cfg(env)->ext_smmjpm && env->mseccfg & MSECCFG_MPMEN; + case PRV_S: + return riscv_cpu_cfg(env)->ext_smnjpm && env->menvcfg & MENVCFG_SPMEN; + case PRV_U: + return riscv_cpu_cfg(env)->ext_ssnjpm && env->senvcfg & SENVCFG_UPMEN; + default: + g_assert_not_reached(); + } + g_assert_not_reached(); + return false; +} + +void riscv_cpu_update_mask(CPURISCVState *env) +{ +#ifndef CONFIG_USER_ONLY + int priv_mode = cpu_address_mode(env); + int satp_mode = 0; + if (riscv_cpu_mxl(env) == MXL_RV32) { + satp_mode = get_field(env->satp, SATP32_MODE); + } else { + satp_mode = get_field(env->satp, SATP64_MODE); + } + RISCVZjpmMaxNBits n_bits = riscv_cpu_pm_get_n_bits(satp_mode, priv_mode); + /* in bare mode address is not sign extended */ + env->pm_signext = (satp_mode != VM_1_10_MBARE); + /* if pointer masking is applicable set env variable */ + bool applicable = riscv_cpu_pm_check_applicable(env, priv_mode); + env->pm_n_bits = applicable ? n_bits : 0; +#endif +} + #ifndef CONFIG_USER_ONLY /*
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com> --- target/riscv/cpu.h | 6 ++-- target/riscv/cpu_helper.c | 58 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-)