summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaximilian Brune <maximilian.brune@9elements.com>2024-06-08 20:22:45 +0200
committerFelix Held <felix-coreboot@felixheld.de>2024-08-11 17:10:45 +0000
commiteb28f3da7de7f1ba0203046c00254fb602080ab0 (patch)
treebaa79b82beb4b9326d5b5f56af85c9e4aee84609 /src
parent96719adda3f5e96cc5af537f3d9c70ae75073b46 (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.h2
-rw-r--r--src/arch/riscv/pmp.c46
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)
{