diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h index 1ff36de7..2c34635a 100644 --- a/include/sbi/riscv_asm.h +++ b/include/sbi/riscv_asm.h @@ -181,6 +181,12 @@ 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 pmp_disable(unsigned int n); + +/* Check if the matching field is set */ +int is_pmp_entry_mapped(unsigned long entry); + int pmp_set(unsigned int n, unsigned long prot, unsigned long addr, unsigned long log2len); diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c index cd565534..881dea3e 100644 --- a/lib/sbi/riscv_asm.c +++ b/lib/sbi/riscv_asm.c @@ -246,6 +246,48 @@ static unsigned long ctz(unsigned long x) return ret; } +int pmp_disable(unsigned int n) +{ + int pmpcfg_csr, pmpcfg_shift; + unsigned long cfgmask, pmpcfg; + + if (n >= PMP_COUNT) + return SBI_EINVAL; + +#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 + + /* Clear the address matching bits to disable the pmp entry */ + cfgmask = ~(0xffUL << pmpcfg_shift); + pmpcfg = (csr_read_num(pmpcfg_csr) & cfgmask); + + csr_write_num(pmpcfg_csr, pmpcfg); + + return SBI_OK; +} + +int is_pmp_entry_mapped(unsigned long entry) +{ + unsigned long prot; + unsigned long addr; + unsigned long log2len; + + pmp_get(entry, &prot, &addr, &log2len); + + /* If address matching bits are non-zero, the entry is enable */ + if (prot & PMP_A) + return true; + + return false; +} + int pmp_set(unsigned int n, unsigned long prot, unsigned long addr, unsigned long log2len) {