git: 509d65fae512 - main - riscv: Map the DTB when it is outside the kernel's 1GB region
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 26 Oct 2026 15:02:38 UTC
The branch main has been updated by mhorne:
URL: https://cgit.FreeBSD.org/src/commit/?id=509d65fae512c24fc755d6a8b3b41bb967e6c5e1
commit 509d65fae512c24fc755d6a8b3b41bb967e6c5e1
Author: Rick Richard <rick@sloservers.com>
AuthorDate: 2026-10-03 16:00:00 +0000
Commit: Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-10-26 15:01:39 +0000
riscv: Map the DTB when it is outside the kernel's 1GB region
When the kernel is started directly by SBI firmware, locore.S maps only
the 1GB region that contains the kernel, and initriscv() reads the DTB
through that mapping at the physical address passed in a1. If the
firmware put the DTB in another 1GB region, as QEMU does with more than
1GB of RAM, fake_preload_metadata() faults before the console is up and
the kernel hangs.
Also map the 1GB region that contains the DTB.
This fixes direct kernel booting without FreeBSD loader(8).
PR: 299088
Reviewed by: mhorne
Fixes: bfb857546984 ("riscv: Construct an identity map in locore.S")
MFC after: 1 week
Signed-off-by: Rick Richard <rick@sloservers.com>
---
sys/riscv/riscv/locore.S | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S
index e2126af5cad2..b4ab4aa43ff8 100644
--- a/sys/riscv/riscv/locore.S
+++ b/sys/riscv/riscv/locore.S
@@ -127,7 +127,8 @@ _start:
* starting from the first 2MB physical page into which the kernel was
* loaded.
*
- * We also use an L1 entry to create a 1GB identity map (1:1 PA->VA).
+ * We also use L1 entries to create 1GB identity maps (1:1 PA->VA)
+ * of the regions holding the kernel and the DTB.
* This is useful for two reasons:
* - handling the DTB pointer passed from SBI firmware (physical addr)
* - simpler construction of pagetables in pmap_bootstrap()
@@ -162,6 +163,17 @@ pagetables:
add t0, s1, a5
sd t6, (t0) /* Store new PTE */
+ /* Identity map the DTB's 1GB region too, if we were given a DTB */
+ beqz s4, 1f
+ srli s2, s4, L1_SHIFT /* dtbp >> L1_SHIFT */
+ andi a5, s2, Ln_ADDR_MASK /* & Ln_ADDR_MASK */
+ slli s2, s2, PTE_PPN2_S /* (s2 << PTE_PPN2_S) */
+ or t6, t4, s2
+ mulw a5, a5, a6 /* calculate L1 slot */
+ add t0, s1, a5
+ sd t6, (t0) /* Store new PTE */
+1:
+
/* Construct the virtual address space at KERNBASE */
/* Add L1 entry for kernel */
@@ -189,14 +201,14 @@ pagetables:
add t3, t4, t2
li t0, (PTE_KERN | PTE_X)
or t0, t0, s8 /* t0 |= pte bits */
-1:
+2:
slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */
or t5, t0, t2
sd t5, (s1) /* Store PTE entry to position */
addi s1, s1, PTE_SIZE
addi t4, t4, 1
- bltu t4, t3, 1b
+ bltu t4, t3, 2b
/* Page tables END */