[PATCH] lib: add Enhanced PMP support
Anup Patel
Anup.Patel at wdc.com
Wed Aug 5 02:56:03 EDT 2020
> -----Original Message-----
> From: Hongzheng Li <ethan.lee.qnl at gmail.com>
> Sent: 05 August 2020 10:14
> To: Anup Patel <Anup.Patel at wdc.com>
> Cc: opensbi at lists.infradead.org; Hou Weiying <weiying_hou at outlook.com>;
> Nick Kossifidis <mick at ics.forth.gr>; Nick Kossifidis <mickflemm at gmail.com>
> Subject: Re: [PATCH] lib: add Enhanced PMP support
>
> Thanks!
>
> We are adding ePMP support to QEMU at the moment and are ready to send
> the patches. We have tested this patch with ePMP support we added to
> QEMU and it all works fine so far. So I guess the second concern will soon be
> solved.
>
> Should I resend this patch when ePMP is taken into the RISC-V ISA manual?
We can have your patches reviewed first but we will merge it after
RISC-V ISA manual and QEMU patches are available. Does that sound okay?
Regards,
Anup
>
> Best regards,
> Hongzheng-Li
>
> Anup Patel <Anup.Patel at wdc.com> 于2020年8月5日周三 上午11:46写道
> :
> >
> >
> >
> > > -----Original Message-----
> > > From: opensbi <opensbi-bounces at lists.infradead.org> On Behalf Of
> > > Hongzheng-Li
> > > Sent: 05 August 2020 09:00
> > > To: opensbi at lists.infradead.org
> > > Cc: Hou Weiying <weiying_hou at outlook.com>; Hongzheng-Li
> > > <ethan.lee.qnl at gmail.com>
> > > Subject: [PATCH] lib: add Enhanced PMP support
> > >
> > > From: Hongzheng-Li <ethan.lee.qnl at gmail.com>
> > >
> > > The Enhanced PMP(ePMP) is used for memory access and execution
> > > prevention on Machine mode.
> > > The latest spec can be found here:
> > >
> https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzH
> > > Z_nxZXgjgOUzbvc8/edit?pli=1#heading=h.ab3kl2ch725u
> >
> > As far as implementation goes, I only see only minor comments so no
> > issues on implementation part.
> >
> > My concerns is the state of ePMP spec. My understanding is that ePMP
> > is still in draft state. We are fine with specs in draft state but
> > spec should be part of https://github.com/riscv/riscv-isa-manual (Just
> Hypervisor spec).
> >
> > Another concerns is the mechanism to test this patch. We need some way
> > to test ePMP so we insist that someone please add QEMU emulation
> > support for ePMP. This will help users to test OpenSBI ePMP support on
> QEMU.
> >
> > If above two concerns are addressed then we can certainly merge ePMP
> > support in OpenSBI.
> >
> > Overall this is a good addition for OpenSBI. Thanks.
> >
> > Regards,
> > Anup
> >
> > >
> > > Signed-off-by: Hongzheng-Li <ethan.lee.qnl at gmail.com>
> > > Signed-off-by: Hou Weiying <weiying_hou at outlook.com>
> > > ---
> > > include/sbi/riscv_asm.h | 4 ++++
> > > include/sbi/riscv_encoding.h | 1 +
> > > include/sbi/sbi_hart.h | 9 ++++++---
> > > lib/sbi/riscv_asm.c | 30 ++++++++++++++++++++++++++++++
> > > lib/sbi/sbi_hart.c | 27 +++++++++++++++++++++++++++
> > > lib/sbi/sbi_init.c | 1 +
> > > 6 files changed, 69 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h index
> > > 6e093ca..badd8af 100644
> > > --- a/include/sbi/riscv_asm.h
> > > +++ b/include/sbi/riscv_asm.h
> > > @@ -182,6 +182,10 @@ int pmp_set(unsigned int n, unsigned long prot,
> > > unsigned long addr, int pmp_get(unsigned int n, unsigned long
> > > *prot_out, unsigned long *addr_out,
> > > unsigned long *size);
> > >
> > > +int epmp_set(int rlb, int mmwp, int mml);
> > > +
> > > +int epmp_get(int *rlb, int *mmwp, int *mml);
> > > +
> > > #endif /* !__ASSEMBLY__ */
> > >
> > > #endif
> > > diff --git a/include/sbi/riscv_encoding.h
> > > b/include/sbi/riscv_encoding.h index 827c86c..2052925 100644
> > > --- a/include/sbi/riscv_encoding.h
> > > +++ b/include/sbi/riscv_encoding.h
> > > @@ -279,6 +279,7 @@
> > > #define CSR_PMPADDR13 0x3bd
> > > #define CSR_PMPADDR14 0x3be
> > > #define CSR_PMPADDR15 0x3bf
> > > +#define CSR_MSECCFG 0x390
> > > #define CSR_TSELECT 0x7a0
> > > #define CSR_TDATA1 0x7a1
> > > #define CSR_TDATA2 0x7a2
> > > diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h index
> > > 51c2c35..4ed882f 100644
> > > --- a/include/sbi/sbi_hart.h
> > > +++ b/include/sbi/sbi_hart.h
> > > @@ -16,12 +16,14 @@
> > > enum sbi_hart_features {
> > > /** Hart has PMP support */
> > > SBI_HART_HAS_PMP = (1 << 0),
> > > + /** enhanced PMP */
> > > + SBI_HART_HAS_EPMP = (1 << 1),
> > > /** Hart has S-mode counter enable */
> > > - SBI_HART_HAS_SCOUNTEREN = (1 << 1),
> > > + SBI_HART_HAS_SCOUNTEREN = (1 << 2),
> > > /** Hart has M-mode counter enable */
> > > - SBI_HART_HAS_MCOUNTEREN = (1 << 2),
> > > + SBI_HART_HAS_MCOUNTEREN = (1 << 3),
> > > /** HART has timer csr implementation in hardware */
> > > - SBI_HART_HAS_TIME = (1 << 3),
> > > + SBI_HART_HAS_TIME = (1 << 4),
> > >
> > > /** Last index of Hart features*/
> > > SBI_HART_HAS_LAST_FEATURE = SBI_HART_HAS_TIME, @@ -43,6
> > > +45,7 @@ int sbi_hart_pmp_get(struct sbi_scratch *scratch, unsigned
> > > +int n,
> > > unsigned long *prot_out, unsigned long *addr_out,
> > > unsigned long *size); void
> > > sbi_hart_pmp_dump(struct sbi_scratch *scratch);
> > > +void sbi_hart_epmp_dump(struct sbi_scratch *scratch);
> > > int sbi_hart_pmp_check_addr(struct sbi_scratch *scratch, unsigned
> > > long daddr,
> > > unsigned long attr); bool
> > > sbi_hart_has_feature(struct sbi_scratch *scratch, unsigned long
> > > feature); diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c
> > > index
> > > 6dfebd9..4621f70 100644
> > > --- a/lib/sbi/riscv_asm.c
> > > +++ b/lib/sbi/riscv_asm.c
> > > @@ -349,3 +349,33 @@ int pmp_get(unsigned int n, unsigned long
> > > *prot_out, unsigned long *addr_out,
> > >
> > > return 0;
> > > }
> > > +
> > > +int epmp_set(int rlb, int mmwp, int mml) {
> > > + unsigned long mseccfg;
> > > +
> > > + if ((rlb | mmwp | mml) & ~1)
> > > + return SBI_EINVAL;
> > > +
> > > +#if __riscv_xlen == 32 || __riscv_xlen == 64
> > > + mseccfg = rlb << 2 | mmwp << 1 | mml; #else
> > > + mseccfg = -1;
> > > +#endif
> > > + if (mseccfg < 0)
> > > + return SBI_ENOTSUPP;
> > > +
> > > + csr_write(CSR_MSECCFG, mseccfg);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +int epmp_get(int *rlb, int *mmwp, int *mml) {
> > > + unsigned long mseccfg = csr_read(CSR_MSECCFG);
> > > + *rlb = (mseccfg >> 2) & 1;
> > > + *mmwp = (mseccfg >> 1) & 1;
> > > + *mml = mseccfg & 1;
> > > +
> > > + return 0;
> > > +}
> > > diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index
> > > fa20bd2..c1c6957
> > > 100644
> > > --- a/lib/sbi/sbi_hart.c
> > > +++ b/lib/sbi/sbi_hart.c
> > > @@ -184,6 +184,18 @@ void sbi_hart_pmp_dump(struct sbi_scratch
> > > *scratch)
> > > }
> > > }
> > >
> > > +void sbi_hart_epmp_dump(struct sbi_scratch *scratch) {
> > > + if (!sbi_hart_has_feature(scratch, SBI_HART_HAS_EPMP))
> > > + return;
> > > +
> > > + int rlb, mmwp, mml;
> > > +
> > > + epmp_get(&rlb, &mmwp, &mml);
> > > + sbi_printf("ePMP: RLB = %d, MMWP = %d, MML = %d\n",
> > > + rlb, mmwp, mml); }
> > > +
> > > int sbi_hart_pmp_check_addr(struct sbi_scratch *scratch, unsigned
> > > long addr,
> > > unsigned long attr) { @@ -239,6 +251,9 @@
> > > static int pmp_init(struct sbi_scratch *scratch, u32
> > > hartid)
> > > */
> > > pmp_set(pmp_idx++, PMP_R | PMP_W | PMP_X, 0, __riscv_xlen);
> > >
> > > + if (sbi_hart_has_feature(scratch, SBI_HART_HAS_EPMP))
> > > + epmp_set(0, 0, 0);
> > > +
> > > return 0;
> > > }
> > >
> > > @@ -288,6 +303,9 @@ static inline char
> > > *sbi_hart_feature_id2string(unsigned long feature)
> > > case SBI_HART_HAS_TIME:
> > > fstr = "time";
> > > break;
> > > + case SBI_HART_HAS_EPMP:
> > > + fstr = "epmp";
> > > + break;
> > > default:
> > > break;
> > > }
> > > @@ -397,6 +415,15 @@ static void hart_detect_features(struct
> > > sbi_scratch
> > > *scratch)
> > > hfeatures->features |=
> > > SBI_HART_HAS_MCOUNTEREN;
> > > }
> > >
> > > + /* Detect if hart supports EPMP(enhanced PMP) feature */
> > > + trap.cause = 0;
> > > + val = csr_read_allowed(CSR_MSECCFG, (unsigned long)&trap);
> > > + if (!trap.cause) {
> > > + csr_write_allowed(CSR_MSECCFG, (unsigned long)&trap,
> > > val);
> > > + if (!trap.cause)
> > > + hfeatures->features |= SBI_HART_HAS_EPMP;
> > > + }
> > > +
> > > /* Detect if hart supports time CSR */
> > > trap.cause = 0;
> > > csr_read_allowed(CSR_TIME, (unsigned long)&trap); diff --git
> > > a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c index a7fb848..1ced76b
> > > 100644
> > > --- a/lib/sbi/sbi_init.c
> > > +++ b/lib/sbi/sbi_init.c
> > > @@ -82,6 +82,7 @@ static void sbi_boot_prints(struct sbi_scratch
> > > *scratch,
> > > u32 hartid)
> > >
> > > sbi_hart_delegation_dump(scratch);
> > > sbi_hart_pmp_dump(scratch);
> > > + sbi_hart_epmp_dump(scratch);
> > > }
> > >
> > > static spinlock_t coldboot_lock = SPIN_LOCK_INITIALIZER;
> > > --
> > > 2.24.1.windows.2
> > >
> > >
> > > --
> > > opensbi mailing list
> > > opensbi at lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/opensbi
More information about the opensbi
mailing list