:: commit 3a609b166a91a704a9a07ddfe865e20412ddf55e

Mintsuki <mintsuki@protonmail.com> — 2026-02-08 13:59

parents: 572e9f7116

mm/vmm: Use firmware-reported MMU type instead of satp probe on RISC-V

diff --git a/common/mm/vmm.c b/common/mm/vmm.c
index eec9fdd5..106f47e3 100644
--- a/common/mm/vmm.c
+++ b/common/mm/vmm.c
@@ -339,38 +339,11 @@ int paging_mode_va_bits(int paging_mode) {
 
 int vmm_max_paging_mode(void)
 {
-    static int max_level;
-    if (max_level > 0)
-        goto done;
-
-    pt_entry_t *table = ext_mem_alloc(PT_SIZE);
-
-    // Test each paging mode starting with Sv57.
-    // Since writes to `satp` with an invalid MODE have no effect, and pages can be mapped at
-    // any level, we can identity map the entire lower half (very likely guaranteeing everything
-    // this code needs will be mapped) and check if enabling the paging mode succeeds.
-    int lvl = 4;
-    for (; lvl >= 2; lvl--) {
-        pt_entry_t entry = PT_FLAG_ACCESSED | PT_FLAG_DIRTY | PT_FLAG_RWX | PT_FLAG_VALID;
-        for (int i = 0; i < 256; i++) {
-            table[i] = entry;
-            entry += page_sizes[lvl] >> 2;
-        }
-
-        uint64_t satp = ((uint64_t)(6 + lvl) << 60) | ((uint64_t)table >> 12);
-        csr_write("satp", satp);
-        if (csr_read("satp") == satp) {
-            max_level = lvl;
-            break;
-        }
+    if (bsp_hart == NULL || !(bsp_hart->flags & RISCV_HART_HAS_MMU)) {
+        panic(false, "vmm: BSP hart does not advertise MMU support");
     }
-    csr_write("satp", 0);
-    pmm_free(table, PT_SIZE);
 
-    if (max_level == 0)
-        panic(false, "vmm: paging is not supported");
-done:
-    return 6 + max_level;
+    return PAGING_MODE_RISCV_SV39 + bsp_hart->mmu_type;
 }
 
 static pt_entry_t pbmt_nc = 0;
diff --git a/common/sys/cpu.h b/common/sys/cpu.h
index 3534b121..8c2da436 100644
--- a/common/sys/cpu.h
+++ b/common/sys/cpu.h
@@ -360,6 +360,7 @@ struct riscv_hart {
 #define RISCV_HART_HAS_MMU ((uint8_t)1 << 1)  // `mmu_type` field is valid
 
 extern struct riscv_hart *hart_list;
+extern struct riscv_hart *bsp_hart;
 
 bool riscv_check_isa_extension_for(size_t hartid, const char *ext, size_t *maj, size_t *min);
 
diff --git a/common/sys/cpu_riscv.c b/common/sys/cpu_riscv.c
index 6802484f..1c141e66 100644
--- a/common/sys/cpu_riscv.c
+++ b/common/sys/cpu_riscv.c
@@ -62,7 +62,7 @@ void *riscv_fdt = NULL;
 
 size_t bsp_hartid;
 struct riscv_hart *hart_list = NULL;
-static struct riscv_hart *bsp_hart;
+struct riscv_hart *bsp_hart;
 static const char *current_config = NULL;
 
 static struct riscv_hart *riscv_get_hart(size_t hartid) {
tab: 248 wrap: offon