Message ID | 20220128085501.8014-2-liweiwei@iscas.ac.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | support subsets of virtual memory extension | expand |
On Fri, Jan 28, 2022 at 7:11 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote: > > From: Guo Ren <ren_guo@c-sky.com> > > Highest bits of PTE has been used for svpbmt, ref: [1], [2], so we > need to ignore them. They cannot be a part of ppn. > > 1: The RISC-V Instruction Set Manual, Volume II: Privileged Architecture > 4.4 Sv39: Page-Based 39-bit Virtual-Memory System > 4.5 Sv48: Page-Based 48-bit Virtual-Memory System > > 2: https://github.com/riscv/virtual-memory/blob/main/specs/663-Svpbmt-diff.pdf > > Signed-off-by: Guo Ren <ren_guo@c-sky.com> > Reviewed-by: Liu Zhiwei <zhiwei_liu@c-sky.com> > Cc: Bin Meng <bmeng.cn@gmail.com> > Cc: Alistair Francis <alistair.francis@wdc.com> > --- > target/riscv/cpu.h | 15 +++++++++++++++ > target/riscv/cpu_bits.h | 3 +++ > target/riscv/cpu_helper.c | 14 +++++++++++++- > 3 files changed, 31 insertions(+), 1 deletion(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 55635d68d5..336fe8e3d5 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -341,6 +341,8 @@ struct RISCVCPU { > bool ext_counters; > bool ext_ifencei; > bool ext_icsr; > + bool ext_svnapot; > + bool ext_svpbmt; > bool ext_zfh; > bool ext_zfhmin; > bool ext_zve32f; Hello, thanks for the patches. This looks good, but you might need to rebase it as there are patches on list that move this into a different struct. > @@ -495,6 +497,19 @@ static inline int riscv_cpu_xlen(CPURISCVState *env) > return 16 << env->xl; > } > > +#ifdef TARGET_RISCV32 > +#define riscv_cpu_sxl(env) ((void)(env), MXL_RV32) > +#else > +static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env) > +{ > +#ifdef CONFIG_USER_ONLY > + return env->misa_mxl; > +#else > + return get_field(env->mstatus, MSTATUS64_SXL); > +#endif > +} > +#endif > + > /* > * Encode LMUL to lmul as follows: > * LMUL vlmul lmul > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h > index 7c87433645..6ea3944423 100644 > --- a/target/riscv/cpu_bits.h > +++ b/target/riscv/cpu_bits.h > @@ -493,6 +493,9 @@ typedef enum { > /* Page table PPN shift amount */ > #define PTE_PPN_SHIFT 10 > > +/* Page table PPN mask */ > +#define PTE_PPN_MASK 0x3FFFFFFFFFFC00ULL > + > /* Leaf page shift amount */ > #define PGSHIFT 12 > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c > index 327a2c4f1d..5a1c0e239e 100644 > --- a/target/riscv/cpu_helper.c > +++ b/target/riscv/cpu_helper.c > @@ -622,7 +622,19 @@ restart: > return TRANSLATE_FAIL; > } > > - hwaddr ppn = pte >> PTE_PPN_SHIFT; > + hwaddr ppn; > + RISCVCPU *cpu = env_archcpu(env); I know there is existing code in this function that does this, but please don't initiate variables mid function. Can you move this to the top of the function? Otherwise: Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > + > + if (riscv_cpu_sxl(env) == MXL_RV32) { > + ppn = pte >> PTE_PPN_SHIFT; > + } else if (cpu->cfg.ext_svpbmt || cpu->cfg.ext_svnapot) { > + ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT; > + } else { > + ppn = pte >> PTE_PPN_SHIFT; > + if ((pte & ~(target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT) { > + return TRANSLATE_FAIL; > + } > + } > > if (!(pte & PTE_V)) { > /* Invalid PTE */ > -- > 2.17.1 > >
在 2022/2/1 上午11:31, Alistair Francis 写道: > On Fri, Jan 28, 2022 at 7:11 PM Weiwei Li <liweiwei@iscas.ac.cn> wrote: >> From: Guo Ren <ren_guo@c-sky.com> >> >> Highest bits of PTE has been used for svpbmt, ref: [1], [2], so we >> need to ignore them. They cannot be a part of ppn. >> >> 1: The RISC-V Instruction Set Manual, Volume II: Privileged Architecture >> 4.4 Sv39: Page-Based 39-bit Virtual-Memory System >> 4.5 Sv48: Page-Based 48-bit Virtual-Memory System >> >> 2: https://github.com/riscv/virtual-memory/blob/main/specs/663-Svpbmt-diff.pdf >> >> Signed-off-by: Guo Ren <ren_guo@c-sky.com> >> Reviewed-by: Liu Zhiwei <zhiwei_liu@c-sky.com> >> Cc: Bin Meng <bmeng.cn@gmail.com> >> Cc: Alistair Francis <alistair.francis@wdc.com> >> --- >> target/riscv/cpu.h | 15 +++++++++++++++ >> target/riscv/cpu_bits.h | 3 +++ >> target/riscv/cpu_helper.c | 14 +++++++++++++- >> 3 files changed, 31 insertions(+), 1 deletion(-) >> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h >> index 55635d68d5..336fe8e3d5 100644 >> --- a/target/riscv/cpu.h >> +++ b/target/riscv/cpu.h >> @@ -341,6 +341,8 @@ struct RISCVCPU { >> bool ext_counters; >> bool ext_ifencei; >> bool ext_icsr; >> + bool ext_svnapot; >> + bool ext_svpbmt; >> bool ext_zfh; >> bool ext_zfhmin; >> bool ext_zve32f; > Hello, thanks for the patches. > > This looks good, but you might need to rebase it as there are patches > on list that move this into a different struct. Thanks for your review. I'll rebase it. > >> @@ -495,6 +497,19 @@ static inline int riscv_cpu_xlen(CPURISCVState *env) >> return 16 << env->xl; >> } >> >> +#ifdef TARGET_RISCV32 >> +#define riscv_cpu_sxl(env) ((void)(env), MXL_RV32) >> +#else >> +static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env) >> +{ >> +#ifdef CONFIG_USER_ONLY >> + return env->misa_mxl; >> +#else >> + return get_field(env->mstatus, MSTATUS64_SXL); >> +#endif >> +} >> +#endif >> + >> /* >> * Encode LMUL to lmul as follows: >> * LMUL vlmul lmul >> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h >> index 7c87433645..6ea3944423 100644 >> --- a/target/riscv/cpu_bits.h >> +++ b/target/riscv/cpu_bits.h >> @@ -493,6 +493,9 @@ typedef enum { >> /* Page table PPN shift amount */ >> #define PTE_PPN_SHIFT 10 >> >> +/* Page table PPN mask */ >> +#define PTE_PPN_MASK 0x3FFFFFFFFFFC00ULL >> + >> /* Leaf page shift amount */ >> #define PGSHIFT 12 >> >> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c >> index 327a2c4f1d..5a1c0e239e 100644 >> --- a/target/riscv/cpu_helper.c >> +++ b/target/riscv/cpu_helper.c >> @@ -622,7 +622,19 @@ restart: >> return TRANSLATE_FAIL; >> } >> >> - hwaddr ppn = pte >> PTE_PPN_SHIFT; >> + hwaddr ppn; >> + RISCVCPU *cpu = env_archcpu(env); > I know there is existing code in this function that does this, but > please don't initiate variables mid function. Can you move this to the > top of the function? OK. > > Otherwise: > > Reviewed-by: Alistair Francis <alistair.francis@wdc.com> > > Alistair > >> + >> + if (riscv_cpu_sxl(env) == MXL_RV32) { >> + ppn = pte >> PTE_PPN_SHIFT; >> + } else if (cpu->cfg.ext_svpbmt || cpu->cfg.ext_svnapot) { >> + ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT; >> + } else { >> + ppn = pte >> PTE_PPN_SHIFT; >> + if ((pte & ~(target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT) { >> + return TRANSLATE_FAIL; >> + } >> + } >> >> if (!(pte & PTE_V)) { >> /* Invalid PTE */ >> -- >> 2.17.1 >> >>
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 55635d68d5..336fe8e3d5 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -341,6 +341,8 @@ struct RISCVCPU { bool ext_counters; bool ext_ifencei; bool ext_icsr; + bool ext_svnapot; + bool ext_svpbmt; bool ext_zfh; bool ext_zfhmin; bool ext_zve32f; @@ -495,6 +497,19 @@ static inline int riscv_cpu_xlen(CPURISCVState *env) return 16 << env->xl; } +#ifdef TARGET_RISCV32 +#define riscv_cpu_sxl(env) ((void)(env), MXL_RV32) +#else +static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env) +{ +#ifdef CONFIG_USER_ONLY + return env->misa_mxl; +#else + return get_field(env->mstatus, MSTATUS64_SXL); +#endif +} +#endif + /* * Encode LMUL to lmul as follows: * LMUL vlmul lmul diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 7c87433645..6ea3944423 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -493,6 +493,9 @@ typedef enum { /* Page table PPN shift amount */ #define PTE_PPN_SHIFT 10 +/* Page table PPN mask */ +#define PTE_PPN_MASK 0x3FFFFFFFFFFC00ULL + /* Leaf page shift amount */ #define PGSHIFT 12 diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 327a2c4f1d..5a1c0e239e 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -622,7 +622,19 @@ restart: return TRANSLATE_FAIL; } - hwaddr ppn = pte >> PTE_PPN_SHIFT; + hwaddr ppn; + RISCVCPU *cpu = env_archcpu(env); + + if (riscv_cpu_sxl(env) == MXL_RV32) { + ppn = pte >> PTE_PPN_SHIFT; + } else if (cpu->cfg.ext_svpbmt || cpu->cfg.ext_svnapot) { + ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT; + } else { + ppn = pte >> PTE_PPN_SHIFT; + if ((pte & ~(target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT) { + return TRANSLATE_FAIL; + } + } if (!(pte & PTE_V)) { /* Invalid PTE */