diff options
author | Maximilian Brune <maximilian.brune@9elements.com> | 2024-06-08 20:22:45 +0200 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2024-08-11 17:10:45 +0000 |
commit | eb28f3da7de7f1ba0203046c00254fb602080ab0 (patch) | |
tree | baa79b82beb4b9326d5b5f56af85c9e4aee84609 /src | |
parent | 96719adda3f5e96cc5af537f3d9c70ae75073b46 (diff) |
arch/riscv: Add PMP print function
For easier debugging it is useful to have a function that prints the PMP
regions.
Signed-off-by: Maximilian Brune <maximilian.brune@9elements.com>
Change-Id: I6ab1531c65b14690e37aecf57ff441bf22db1ce5
Reviewed-on: https://review.coreboot.org/c/coreboot/+/83283
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Elyes Haouas <ehaouas@noos.fr>
Reviewed-by: ron minnich <rminnich@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/riscv/include/arch/pmp.h | 2 | ||||
-rw-r--r-- | src/arch/riscv/pmp.c | 46 |
2 files changed, 48 insertions, 0 deletions
diff --git a/src/arch/riscv/include/arch/pmp.h b/src/arch/riscv/include/arch/pmp.h index f98adf724a..273ccfe514 100644 --- a/src/arch/riscv/include/arch/pmp.h +++ b/src/arch/riscv/include/arch/pmp.h @@ -11,6 +11,8 @@ */ int pmp_entries_num(void); +void print_pmp_regions(void); + /* reset PMP setting */ void reset_pmp(void); diff --git a/src/arch/riscv/pmp.c b/src/arch/riscv/pmp.c index b643441e62..cb605cb64b 100644 --- a/src/arch/riscv/pmp.c +++ b/src/arch/riscv/pmp.c @@ -314,6 +314,52 @@ static void mask_pmp_entry_used(int idx) pmp_entry_used_mask |= 1 << idx; } +/* prints the pmp regions by reading the PMP address and configuration registers */ +void print_pmp_regions(void) +{ + uintptr_t prev_pmpaddr = 0; + uintptr_t base = 0; + uintptr_t size = 0; + const char *mode; + for (int i = 0; i < pmp_entries_num(); i++) { + uintptr_t pmpcfg = read_pmpcfg(i); + uintptr_t pmpaddr = read_pmpaddr(i); + if ((pmpcfg & PMP_A) == 0) { + continue; // PMP entry is disabled + } else if (pmpcfg & PMP_NA4) { + base = pmpaddr << PMP_SHIFT; + size = 4; + mode = "NA4"; + } else if (pmpcfg & PMP_NAPOT) { + unsigned int count_trailing_ones = 0; + base = pmpaddr; + while (base) { + if ((base & 1) == 0) + break; // we got a zero + count_trailing_ones++; + base >>= 1; + } + size = 8 << count_trailing_ones; + base = (pmpaddr & ~((2 << count_trailing_ones) - 1)) >> PMP_SHIFT; + mode = "NAPOT"; + } else if (pmpcfg & PMP_TOR) { + base = pmpaddr; + size = pmpaddr - prev_pmpaddr; + mode = "TOR"; + } + + printk(BIOS_DEBUG, "base: 0x%lx, size: 0x%lx, perm: %c%c%c, mode: %s, locked: %d\n", + base, size, + (pmpcfg & PMP_R) ? 'r' : ' ', + (pmpcfg & PMP_W) ? 'w' : ' ', + (pmpcfg & PMP_X) ? 'x' : ' ', + mode, + (pmpcfg & PMP_L) ? 1 : 0); + + prev_pmpaddr = pmpaddr; + } +} + /* reset PMP setting */ void reset_pmp(void) { |