[RFC PATCH v3 6/6] [TEMP] demonstrate hole protection using reserved PMP
Yu-Chien Peter Lin
peter.lin at sifive.com
Sun Nov 30 03:16:43 PST 2025
This implementation shows how platforms can use the reserved PMP
allocator to protect critical memory regions during early boot.
Benefits of using reserved PMPs:
1) Reserved PMPs are not managed by domains - platforms have full control
over them. Since reserved entries won't be freed, they can safely set
lock bits (pmpcfg.L), unlike domain entries which must allow being
temporarily revoked during context switches.
2) One can allocate 2 consecutive entries to create ToR mode regions to
save PMP usage
3) The reserved PMPs have higher priority so their permissions are less
likely to be overwritten by other entries
Note: This is a demonstration patch and should not be merged.
Signed-off-by: Yu-Chien Peter Lin <peter.lin at sifive.com>
---
platform/generic/sifive/fu540.c | 56 +++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/platform/generic/sifive/fu540.c b/platform/generic/sifive/fu540.c
index 83e57145..3f0fd032 100644
--- a/platform/generic/sifive/fu540.c
+++ b/platform/generic/sifive/fu540.c
@@ -8,6 +8,10 @@
*/
#include <platform_override.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_error.h>
+#include <sbi/sbi_types.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <sbi_utils/fdt/fdt_fixup.h>
@@ -20,9 +24,61 @@ static u64 sifive_fu540_tlbr_flush_limit(void)
return 0;
}
+static u32 sifive_fu540_get_reserved_pmp_count(void)
+{
+ /*
+ * Reserve an entry for demonstrating hole protection
+ * on SiFive FU540.
+ */
+ return 1;
+}
+
+// This is a demonstration of PMP-based memory protection rather
+// than protecting an actual memory hole.
+static int sifive_fu540_hole_protection(void)
+{
+ int rc;
+ unsigned int pmp_id;
+
+ rc = reserved_pmp_alloc(&pmp_id);
+ if (rc)
+ return rc;
+
+ /*
+ * Protect the memory hole at 0x0 - 0x1000 by setting
+ * it as inaccessible (no R/W/X) with the lock bit set.
+ * This prevents any access to this region in all modes.
+ */
+ rc = pmp_set(pmp_id, PMP_L, 0x0, 12);
+ if (rc) {
+ reserved_pmp_free(pmp_id);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int sifive_fu540_early_init(bool cold_boot)
+{
+ int rc;
+
+ /* Set up memory hole protection */
+ rc = sifive_fu540_hole_protection();
+ if (rc)
+ return rc;
+
+ rc = generic_early_init(cold_boot);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
static int sifive_fu540_platform_init(const void *fdt, int nodeoff, const struct fdt_match *match)
{
generic_platform_ops.get_tlbr_flush_limit = sifive_fu540_tlbr_flush_limit;
+ generic_platform_ops.get_reserved_pmp_count = sifive_fu540_get_reserved_pmp_count;
+ generic_platform_ops.early_init = sifive_fu540_early_init;
return 0;
}
--
2.39.3
More information about the opensbi
mailing list