diff options
| author | Nicholas Piggin <npiggin@gmail.com> | 2026-04-30 14:55:18 +1000 |
|---|---|---|
| committer | Anup Patel <anup@brainfault.org> | 2026-06-10 09:56:29 +0530 |
| commit | 8ae3b0985a17ee7b955d4352cdd01ac6c8dd9f46 (patch) | |
| tree | 593ee3ac62a359525c54aa91fcd32e0dba62cd37 | |
| parent | 73bc794b40fc917feb146afd34970cf44563b561 (diff) | |
| download | opensbi-8ae3b0985a17ee7b955d4352cdd01ac6c8dd9f46.tar.gz opensbi-8ae3b0985a17ee7b955d4352cdd01ac6c8dd9f46.zip | |
lib: sbi: Introduce pmp_t type
To help abstract details of PMP encoding and access, add a new pmp_t
type which contains address and cfg in the format of the riscv CSRs.
There is no functional change.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260430045528.420437-2-npiggin@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
| -rw-r--r-- | lib/sbi/riscv_asm.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c index 3e44320f..acb6b5e6 100644 --- a/lib/sbi/riscv_asm.c +++ b/lib/sbi/riscv_asm.c @@ -272,6 +272,12 @@ void csr_write_num(int csr_num, unsigned long val) #undef switchcase_csr_write } +struct pmp { + unsigned long addr; + u8 cfg; +}; +typedef struct pmp pmp_t; + static unsigned long ctz(unsigned long x) { unsigned long ret = 0; @@ -335,7 +341,8 @@ int pmp_set(unsigned int n, unsigned long prot, unsigned long addr, { int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr; unsigned long cfgmask, pmpcfg; - unsigned long addrmask, pmpaddr; + unsigned long addrmask; + pmp_t pmp; /* check parameters */ if (n >= PMP_COUNT || log2len > __riscv_xlen || log2len < PMP_SHIFT) @@ -356,25 +363,26 @@ int pmp_set(unsigned int n, unsigned long prot, unsigned long addr, /* encode PMP config */ prot &= ~PMP_A; prot |= (log2len == PMP_SHIFT) ? PMP_A_NA4 : PMP_A_NAPOT; - cfgmask = ~(0xffUL << pmpcfg_shift); - pmpcfg = (csr_read_num(pmpcfg_csr) & cfgmask); - pmpcfg |= ((prot << pmpcfg_shift) & ~cfgmask); + pmp.cfg = prot; /* encode PMP address */ if (log2len == PMP_SHIFT) { - pmpaddr = (addr >> PMP_SHIFT); + pmp.addr = (addr >> PMP_SHIFT); } else { if (log2len == __riscv_xlen) { - pmpaddr = -1UL; + pmp.addr = -1UL; } else { addrmask = (1UL << (log2len - PMP_SHIFT)) - 1; - pmpaddr = ((addr >> PMP_SHIFT) & ~addrmask); - pmpaddr |= (addrmask >> 1); + pmp.addr = ((addr >> PMP_SHIFT) & ~addrmask); + pmp.addr |= (addrmask >> 1); } } /* write csrs */ - csr_write_num(pmpaddr_csr, pmpaddr); + 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 0; @@ -384,8 +392,9 @@ int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out, unsigned long *log2len) { int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr; - unsigned long cfgmask, pmpcfg, prot; + unsigned long cfgmask, prot; unsigned long t1, addr, len; + pmp_t pmp; /* check parameters */ if (n >= PMP_COUNT || !prot_out || !addr_out || !log2len) @@ -404,14 +413,16 @@ int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out, #endif pmpaddr_csr = CSR_PMPADDR0 + n; - /* decode PMP config */ cfgmask = (0xffUL << pmpcfg_shift); - pmpcfg = csr_read_num(pmpcfg_csr) & cfgmask; - prot = pmpcfg >> pmpcfg_shift; + pmp.cfg = (csr_read_num(pmpcfg_csr) & cfgmask) >> pmpcfg_shift; + pmp.addr = csr_read_num(pmpaddr_csr); + + /* decode PMP config */ + prot = pmp.cfg; /* decode PMP address */ if ((prot & PMP_A) == PMP_A_NAPOT) { - addr = csr_read_num(pmpaddr_csr); + addr = pmp.addr; if (addr == -1UL) { addr = 0; len = __riscv_xlen; @@ -421,7 +432,7 @@ int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out, len = (t1 + PMP_SHIFT + 1); } } else { - addr = csr_read_num(pmpaddr_csr) << PMP_SHIFT; + addr = pmp.addr << PMP_SHIFT; len = PMP_SHIFT; } |
