From a59c8fb9fb0ee4b56268b84cf94d6a5d66ead514 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 30 Apr 2026 14:55:25 +1000 Subject: [PATCH] lib: sbi: Move hart PMP functions to sbi_hart_pmp.c The sbi_hart_pmp.c looks like a good place for the hart PMP CSR access functions. Signed-off-by: Nicholas Piggin Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20260430045528.420437-9-npiggin@gmail.com Signed-off-by: Anup Patel --- include/sbi/riscv_asm.h | 14 ----- include/sbi/sbi_hart_pmp.h | 12 ++++ lib/sbi/riscv_asm.c | 109 ------------------------------------ lib/sbi/sbi_hart_pmp.c | 110 +++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 123 deletions(-) diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h index 105563e3..7765edb7 100644 --- a/include/sbi/riscv_asm.h +++ b/include/sbi/riscv_asm.h @@ -81,8 +81,6 @@ #ifndef __ASSEMBLER__ -#include - #define csr_swap(csr, val) \ ({ \ register unsigned long __v = (unsigned long)(val); \ @@ -211,18 +209,6 @@ int misa_xlen(void); /* Get RISC-V ISA string representation */ void misa_string(int xlen, char *out, unsigned int out_sz); -/* Disable pmp entry at a given index */ -int sbi_hart_pmp_disable(unsigned int n); - -/* Check if the matching field is set */ -bool sbi_hart_is_pmp_enabled(unsigned int n); - -int sbi_hart_pmp_set(unsigned int n, unsigned long prot, unsigned long addr, - unsigned long log2len); - -int sbi_hart_pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out, - unsigned long *log2len); - #endif /* !__ASSEMBLER__ */ #endif diff --git a/include/sbi/sbi_hart_pmp.h b/include/sbi/sbi_hart_pmp.h index a7765d17..6a8b3e79 100644 --- a/include/sbi/sbi_hart_pmp.h +++ b/include/sbi/sbi_hart_pmp.h @@ -9,6 +9,18 @@ #include +/* Disable pmp entry at a given index */ +int sbi_hart_pmp_disable(unsigned int n); + +/* Check if the matching field is set */ +bool sbi_hart_is_pmp_enabled(unsigned int n); + +int sbi_hart_pmp_set(unsigned int n, unsigned long prot, + unsigned long addr, unsigned long log2len); + +int sbi_hart_pmp_get(unsigned int n, unsigned long *prot_out, + unsigned long *addr_out, unsigned long *log2len); + struct sbi_scratch; unsigned int sbi_hart_pmp_count(struct sbi_scratch *scratch); diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c index e509f1c4..a1e0f2f8 100644 --- a/lib/sbi/riscv_asm.c +++ b/lib/sbi/riscv_asm.c @@ -272,112 +272,3 @@ void csr_write_num(int csr_num, unsigned long val) #undef switchcase_csr_write_2 #undef switchcase_csr_write } - -static int hart_pmp_read(pmp_t *pmp, unsigned int n) -{ - int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr; - unsigned long cfgmask; - - /* check parameters */ - if (n >= PMP_COUNT) - return SBI_EINVAL; - - /* calculate PMP register and offset */ -#if __riscv_xlen == 32 - pmpcfg_csr = CSR_PMPCFG0 + (n >> 2); - pmpcfg_shift = (n & 3) << 3; -#elif __riscv_xlen == 64 - pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1; - pmpcfg_shift = (n & 7) << 3; -#else -# error "Unexpected __riscv_xlen" -#endif - pmpaddr_csr = CSR_PMPADDR0 + n; - - cfgmask = (0xffUL << pmpcfg_shift); - pmp->cfg = (csr_read_num(pmpcfg_csr) & cfgmask) >> pmpcfg_shift; - pmp->addr = csr_read_num(pmpaddr_csr); - - return SBI_OK; -} - -static int hart_pmp_write(pmp_t *pmp, unsigned int n) -{ - int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr; - unsigned long cfgmask, pmpcfg; - - /* check parameters */ - if (n >= PMP_COUNT) - return SBI_EINVAL; - - /* calculate PMP register and offset */ -#if __riscv_xlen == 32 - pmpcfg_csr = CSR_PMPCFG0 + (n >> 2); - pmpcfg_shift = (n & 3) << 3; -#elif __riscv_xlen == 64 - pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1; - pmpcfg_shift = (n & 7) << 3; -#else -# error "Unexpected __riscv_xlen" -#endif - pmpaddr_csr = CSR_PMPADDR0 + n; - - /* write csrs */ - csr_write_num(pmpaddr_csr, pmp->addr); - cfgmask = ~(0xffUL << pmpcfg_shift); - pmpcfg = (csr_read_num(pmpcfg_csr) & cfgmask); - pmpcfg |= (((unsigned long)pmp->cfg << pmpcfg_shift) & ~cfgmask); - csr_write_num(pmpcfg_csr, pmpcfg); - - return SBI_OK; -} - -int sbi_hart_pmp_disable(unsigned int n) -{ - pmp_t pmp; - int rc; - - rc = hart_pmp_read(&pmp, n); - if (rc) - return rc; - - pmp.cfg = 0; - - return hart_pmp_write(&pmp, n); -} - -bool sbi_hart_is_pmp_enabled(unsigned int n) -{ - pmp_t pmp; - - if (hart_pmp_read(&pmp, n) != SBI_OK) - return false; - - return sbi_pmp_is_enabled(&pmp); -} - -int sbi_hart_pmp_set(unsigned int n, unsigned long prot, unsigned long addr, - unsigned long log2len) -{ - pmp_t pmp; - int rc; - - rc = sbi_pmp_encode(&pmp, prot, addr, log2len); - if (rc) - return rc; - - return hart_pmp_write(&pmp, n); -} - -int sbi_hart_pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out, - unsigned long *log2len) -{ - pmp_t pmp; - int rc; - - rc = hart_pmp_read(&pmp, n); - if (rc) - return rc; - - return sbi_pmp_decode(&pmp, prot_out, addr_out, log2len); -} diff --git a/lib/sbi/sbi_hart_pmp.c b/lib/sbi/sbi_hart_pmp.c index d1419302..4528258d 100644 --- a/lib/sbi/sbi_hart_pmp.c +++ b/lib/sbi/sbi_hart_pmp.c @@ -12,9 +12,119 @@ #include #include #include +#include #include #include +static int hart_pmp_read(pmp_t *pmp, unsigned int n) +{ + int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr; + unsigned long cfgmask; + + /* check parameters */ + if (n >= PMP_COUNT) + return SBI_EINVAL; + + /* calculate PMP register and offset */ +#if __riscv_xlen == 32 + pmpcfg_csr = CSR_PMPCFG0 + (n >> 2); + pmpcfg_shift = (n & 3) << 3; +#elif __riscv_xlen == 64 + pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1; + pmpcfg_shift = (n & 7) << 3; +#else +# error "Unexpected __riscv_xlen" +#endif + pmpaddr_csr = CSR_PMPADDR0 + n; + + cfgmask = (0xffUL << pmpcfg_shift); + pmp->cfg = (csr_read_num(pmpcfg_csr) & cfgmask) >> pmpcfg_shift; + pmp->addr = csr_read_num(pmpaddr_csr); + + return SBI_OK; +} + +static int hart_pmp_write(pmp_t *pmp, unsigned int n) +{ + int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr; + unsigned long cfgmask, pmpcfg; + + /* check parameters */ + if (n >= PMP_COUNT) + return SBI_EINVAL; + + /* calculate PMP register and offset */ +#if __riscv_xlen == 32 + pmpcfg_csr = CSR_PMPCFG0 + (n >> 2); + pmpcfg_shift = (n & 3) << 3; +#elif __riscv_xlen == 64 + pmpcfg_csr = (CSR_PMPCFG0 + (n >> 2)) & ~1; + pmpcfg_shift = (n & 7) << 3; +#else +# error "Unexpected __riscv_xlen" +#endif + pmpaddr_csr = CSR_PMPADDR0 + n; + + /* write csrs */ + csr_write_num(pmpaddr_csr, pmp->addr); + cfgmask = ~(0xffUL << pmpcfg_shift); + pmpcfg = (csr_read_num(pmpcfg_csr) & cfgmask); + pmpcfg |= (((unsigned long)pmp->cfg << pmpcfg_shift) & ~cfgmask); + csr_write_num(pmpcfg_csr, pmpcfg); + + return SBI_OK; +} + +int sbi_hart_pmp_disable(unsigned int n) +{ + pmp_t pmp; + int rc; + + rc = hart_pmp_read(&pmp, n); + if (rc) + return rc; + + pmp.cfg = 0; + + return hart_pmp_write(&pmp, n); +} + +bool sbi_hart_is_pmp_enabled(unsigned int n) +{ + pmp_t pmp; + + if (hart_pmp_read(&pmp, n) != SBI_OK) + return false; + + return sbi_pmp_is_enabled(&pmp); +} + +int sbi_hart_pmp_set(unsigned int n, unsigned long prot, unsigned long addr, + unsigned long log2len) +{ + pmp_t pmp; + int rc; + + rc = sbi_pmp_encode(&pmp, prot, addr, log2len); + if (rc) + return rc; + + return hart_pmp_write(&pmp, n); +} + +int sbi_hart_pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out, + unsigned long *log2len) +{ + pmp_t pmp; + int rc; + + rc = hart_pmp_read(&pmp, n); + if (rc) + return rc; + + return sbi_pmp_decode(&pmp, prot_out, addr_out, log2len); +} + /* * Smepmp enforces access boundaries between M-mode and * S/U-mode. When it is enabled, the PMPs are programmed