Re: [PATCH v10 3/7] [RISCV_PM] Support CSRs required for RISC-V PM extension except for the h-mode
On Mon, Aug 30, 2021 at 3:54 AM Alexey Baturo wrote: > > Signed-off-by: Alexey Baturo > --- > target/riscv/cpu.c | 6 + > target/riscv/cpu.h | 11 ++ > target/riscv/csr.c | 276 + > 3 files changed, 293 insertions(+) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 991a6bb760..4178eecbec 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -553,6 +553,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error > **errp) > } > set_vext_version(env, vext_version); > } > +if (cpu->cfg.ext_j) { > +#ifndef CONFIG_USER_ONLY > +/* mmte is supposed to have pm.current hardwired to 1 */ > +env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT); This should probably be in the reset function instead. > +#endif > +} > > set_misa(env, target_misa); > } > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 451a1637a1..94e680cbd0 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -238,6 +238,17 @@ struct CPURISCVState { > > /* True if in debugger mode. */ > bool debugger; > + > +/* > + * CSRs for PointerMasking extension > + */ > +target_ulong mmte; > +target_ulong mpmmask; > +target_ulong mpmbase; > +target_ulong spmmask; > +target_ulong spmbase; > +target_ulong upmmask; > +target_ulong upmbase; > #endif > > float_status fp_status; > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 9a4ed18ac5..42a0867e5d 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -192,6 +192,16 @@ static RISCVException hmode32(CPURISCVState *env, int > csrno) > > } > > +/* Checks if PointerMasking registers could be accessed */ > +static RISCVException pointer_masking(CPURISCVState *env, int csrno) > +{ > +/* Check if j-ext is present */ > +if (riscv_has_ext(env, RVJ)) { > +return RISCV_EXCP_NONE; > +} > +return RISCV_EXCP_ILLEGAL_INST; > +} > + > static RISCVException pmp(CPURISCVState *env, int csrno) > { > if (riscv_feature(env, RISCV_FEATURE_PMP)) { > @@ -1404,6 +1414,259 @@ static RISCVException write_pmpaddr(CPURISCVState > *env, int csrno, > return RISCV_EXCP_NONE; > } > > +/* > + * Functions to access Pointer Masking feature registers > + * We have to check if current priv lvl could modify > + * csr in given mode > + */ > +static bool check_pm_current_disabled(CPURISCVState *env, int csrno) > +{ > +int csr_priv = get_field(csrno, 0x300); Can you add a newline between declarations and code? > +/* > + * If priv lvls differ that means we're accessing csr from higher priv > lvl, > + * so allow the access > + */ > +if (env->priv != csr_priv) { > +return false; > +} > +int cur_bit_pos; Can you keep all of the declarations at the start of blocks please. > +switch (env->priv) { > +case PRV_M: > +cur_bit_pos = M_PM_CURRENT; > +break; > +case PRV_S: > +cur_bit_pos = S_PM_CURRENT; > +break; > +case PRV_U: > +cur_bit_pos = U_PM_CURRENT; > +break; > +default: > +g_assert_not_reached(); > +} > +int pm_current = get_field(env->mmte, cur_bit_pos); > +/* It's same priv lvl, so we allow to modify csr only if pm.current==1 */ > +return !pm_current; > +} > + > +static RISCVException read_mmte(CPURISCVState *env, int csrno, > +target_ulong *val) > +{ > +*val = env->mmte & MMTE_MASK; > +return RISCV_EXCP_NONE; > +} > + > +static RISCVException write_mmte(CPURISCVState *env, int csrno, > + target_ulong val) > +{ > +uint64_t mstatus; > +target_ulong wpri_val = val & MMTE_MASK; > +if (val != wpri_val) { > +qemu_log_mask(LOG_GUEST_ERROR, > + "MMTE: WPRI violation written 0x%lx vs expected > 0x%lx\n", > + val, wpri_val); > +} > +/* for machine mode pm.current is hardwired to 1 */ > +wpri_val |= MMTE_M_PM_CURRENT; > + > +/* hardwiring pm.instruction bit to 0, since it's not supported yet */ > +wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN); > +env->mmte = wpri_val | PM_EXT_DIRTY; > + > +/* Set XS and SD bits, since PM CSRs are dirty */ > +mstatus = env->mstatus | MSTATUS_XS; > +write_mstatus(env, csrno, mstatus); > +return RISCV_EXCP_NONE; > +} > + > +static RISCVException read_smte(CPURISCVState *env, int csrno, > +target_ulong *val) > +{ > +*val = env->mmte & SMTE_MASK; > +return RISCV_EXCP_NONE; > +} > + > +static RISCVException write_smte(CPURISCVState *env, int csrno, > + target_ulong val) > +{ > +target_ulong wpri_val = val & SMTE_MASK; > +if (val != wpri_val) { > +qemu_log_mask(LOG_GUEST_ERROR, > + "SMTE: WPRI violation
[PATCH v10 3/7] [RISCV_PM] Support CSRs required for RISC-V PM extension except for the h-mode
Signed-off-by: Alexey Baturo --- target/riscv/cpu.c | 6 + target/riscv/cpu.h | 11 ++ target/riscv/csr.c | 276 + 3 files changed, 293 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 991a6bb760..4178eecbec 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -553,6 +553,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } set_vext_version(env, vext_version); } +if (cpu->cfg.ext_j) { +#ifndef CONFIG_USER_ONLY +/* mmte is supposed to have pm.current hardwired to 1 */ +env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT); +#endif +} set_misa(env, target_misa); } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 451a1637a1..94e680cbd0 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -238,6 +238,17 @@ struct CPURISCVState { /* True if in debugger mode. */ bool debugger; + +/* + * CSRs for PointerMasking extension + */ +target_ulong mmte; +target_ulong mpmmask; +target_ulong mpmbase; +target_ulong spmmask; +target_ulong spmbase; +target_ulong upmmask; +target_ulong upmbase; #endif float_status fp_status; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 9a4ed18ac5..42a0867e5d 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -192,6 +192,16 @@ static RISCVException hmode32(CPURISCVState *env, int csrno) } +/* Checks if PointerMasking registers could be accessed */ +static RISCVException pointer_masking(CPURISCVState *env, int csrno) +{ +/* Check if j-ext is present */ +if (riscv_has_ext(env, RVJ)) { +return RISCV_EXCP_NONE; +} +return RISCV_EXCP_ILLEGAL_INST; +} + static RISCVException pmp(CPURISCVState *env, int csrno) { if (riscv_feature(env, RISCV_FEATURE_PMP)) { @@ -1404,6 +1414,259 @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +/* + * Functions to access Pointer Masking feature registers + * We have to check if current priv lvl could modify + * csr in given mode + */ +static bool check_pm_current_disabled(CPURISCVState *env, int csrno) +{ +int csr_priv = get_field(csrno, 0x300); +/* + * If priv lvls differ that means we're accessing csr from higher priv lvl, + * so allow the access + */ +if (env->priv != csr_priv) { +return false; +} +int cur_bit_pos; +switch (env->priv) { +case PRV_M: +cur_bit_pos = M_PM_CURRENT; +break; +case PRV_S: +cur_bit_pos = S_PM_CURRENT; +break; +case PRV_U: +cur_bit_pos = U_PM_CURRENT; +break; +default: +g_assert_not_reached(); +} +int pm_current = get_field(env->mmte, cur_bit_pos); +/* It's same priv lvl, so we allow to modify csr only if pm.current==1 */ +return !pm_current; +} + +static RISCVException read_mmte(CPURISCVState *env, int csrno, +target_ulong *val) +{ +*val = env->mmte & MMTE_MASK; +return RISCV_EXCP_NONE; +} + +static RISCVException write_mmte(CPURISCVState *env, int csrno, + target_ulong val) +{ +uint64_t mstatus; +target_ulong wpri_val = val & MMTE_MASK; +if (val != wpri_val) { +qemu_log_mask(LOG_GUEST_ERROR, + "MMTE: WPRI violation written 0x%lx vs expected 0x%lx\n", + val, wpri_val); +} +/* for machine mode pm.current is hardwired to 1 */ +wpri_val |= MMTE_M_PM_CURRENT; + +/* hardwiring pm.instruction bit to 0, since it's not supported yet */ +wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN); +env->mmte = wpri_val | PM_EXT_DIRTY; + +/* Set XS and SD bits, since PM CSRs are dirty */ +mstatus = env->mstatus | MSTATUS_XS; +write_mstatus(env, csrno, mstatus); +return RISCV_EXCP_NONE; +} + +static RISCVException read_smte(CPURISCVState *env, int csrno, +target_ulong *val) +{ +*val = env->mmte & SMTE_MASK; +return RISCV_EXCP_NONE; +} + +static RISCVException write_smte(CPURISCVState *env, int csrno, + target_ulong val) +{ +target_ulong wpri_val = val & SMTE_MASK; +if (val != wpri_val) { +qemu_log_mask(LOG_GUEST_ERROR, + "SMTE: WPRI violation written 0x%lx vs expected 0x%lx\n", + val, wpri_val); +} + +/* if pm.current==0 we can't modify current PM CSRs */ +if (check_pm_current_disabled(env, csrno)) { +return RISCV_EXCP_NONE; +} + +target_ulong new_val = wpri_val | (env->mmte & ~SMTE_MASK); +write_mmte(env, csrno, new_val); +return RISCV_EXCP_NONE; +} + +static RISCVException read_umte(CPURISCVState *env, int csrno, +target_ulong *val) +{ +*val = env->mmte & UMTE_MASK; +