[PATCH 04/22] platform: generic: mips p8700: prohibit accessing memory beyond DRAM

Vladimir Kondratiev vladimir.kondratiev at mobileye.com
Wed Jan 14 01:21:00 PST 2026


SBI code arranges domain PMP regions in a way that last entry is
all-inclusive "0..~0 RWX". When PMP is actually programmed on the
later stage, only defined entries get programmed. Therefore,
if boot code configured some entries beyond what is set in domain
configuration, it will be untouched. Thus, to prevent left over PMP
entries, domain should configure all possible PMP regions.

Find last PMP entry configured by generic code, adjust its limits
to match DRAM. Fill the rest of PMP entries with valid values that
will not interfere with actual memory access configuration required,
but will force SBI to configure these regions.

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev at mobileye.com>
---
 platform/generic/mips/p8700.c | 44 +++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/platform/generic/mips/p8700.c b/platform/generic/mips/p8700.c
index 07cea604a415..2ba412a057a8 100644
--- a/platform/generic/mips/p8700.c
+++ b/platform/generic/mips/p8700.c
@@ -12,6 +12,7 @@
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_hsm.h>
 #include <sbi/sbi_timer.h>
+#include <sbi/sbi_hart_pmp.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <mips/p8700.h>
 #include <mips/mips-cm.h>
@@ -19,6 +20,7 @@
 extern void mips_warm_boot(void);
 #define MMIO_BASE 0x00000000
 #define MMIO_SIZE 0x80000000
+#define PMP_REGION_MAX (16)
 
 static void mips_p8700_pmp_set(unsigned int n, unsigned long flags,
 			       unsigned long prot, unsigned long addr,
@@ -141,10 +143,48 @@ static const struct sbi_hsm_device mips_hsm = {
 	.hart_stop	= mips_hart_stop,
 };
 
+static struct sbi_domain_memregion *find_last_memregion(const struct sbi_domain *dom)
+{
+	struct sbi_domain_memregion *reg;
+
+	sbi_domain_for_each_memregion(dom, reg) {}
+	return --reg;
+}
+
 static int mips_p8700_final_init(bool cold_boot)
 {
-	if (cold_boot)
-		sbi_hsm_set_device(&mips_hsm);
+	const struct sbi_domain *dom;
+	struct sbi_domain_memregion *reg;
+	const unsigned long end_of_dram = 0x1000000000LU;
+	unsigned long gran = sbi_hart_pmp_log2gran(sbi_scratch_thishart_ptr());
+
+	if (!cold_boot)
+		return 0;
+
+	sbi_hsm_set_device(&mips_hsm);
+
+	/*
+	 * sbi_domain_init adds last "all-inclusive" memory region
+	 * 0 .. ~0 RWX
+	 * Find this region (it is the last one) and update size according to DRAM
+	 */
+	dom = sbi_domain_thishart_ptr();
+	reg = find_last_memregion(dom);
+	sbi_printf("Fix region[%ld]: base 0x%lx order %ld flags 0x%lx\n",
+		   reg - dom->regions, reg->base, reg->order, reg->flags);
+	reg->order = sbi_fls(end_of_dram);
+	sbi_printf("Modified order: %ld to match end of DRAM 0x%lx\n",
+		   reg->order, end_of_dram);
+	/*
+	 * clear the rest of regions that may be set by the boot code
+	 * SBI code don't let to disable PMP region, so configure it to
+	 * some fake values. order should be valid or region won't be set.
+	 */
+	for (++reg; reg < &dom->regions[PMP_REGION_MAX]; reg++) {
+		reg->order = gran; // order should be not 0, this is minimum valid
+		reg->base = 0;
+		reg->flags = SBI_DOMAIN_MEMREGION_MMIO; // disable cache & prefetch
+	}
 
 	return generic_final_init(cold_boot);
 }
-- 
2.43.0




More information about the opensbi mailing list