Skip to content

Commit cb2b4e8

Browse files
committed
riscv64: load page table early at boot
1 parent 6c77042 commit cb2b4e8

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

src/arch/riscv64/kernel/start.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use hermit_entry::boot_info::RawBootInfo;
66

77
use super::{CPU_ONLINE, CURRENT_BOOT_ID, HART_MASK, NUM_CPUS};
88
use crate::arch::riscv64::kernel::CURRENT_STACK_ADDRESS;
9+
use crate::arch::riscv64::mm::paging::SATP_VALUE;
910
#[cfg(not(feature = "smp"))]
1011
use crate::arch::riscv64::kernel::processor;
1112
use crate::{KERNEL_STACK_SIZE, env};
@@ -30,6 +31,13 @@ pub unsafe extern "C" fn _start(hart_id: usize, boot_info: Option<&'static RawBo
3031
}
3132

3233
naked_asm!(
34+
// Load page table if set
35+
// Required in order to be able to change the stack pointer just after
36+
"ld t0, {satp_value}",
37+
"beqz t0, 1f",
38+
"csrrw t0, satp, t0",
39+
40+
"1:",
3341
// Use stack pointer from `CURRENT_STACK_ADDRESS` if set
3442
"ld t0, {current_stack_pointer}",
3543
"beqz t0, 2f",
@@ -39,6 +47,7 @@ pub unsafe extern "C" fn _start(hart_id: usize, boot_info: Option<&'static RawBo
3947
"2:",
4048

4149
"j {pre_init}",
50+
satp_value = sym SATP_VALUE,
4251
current_stack_pointer = sym CURRENT_STACK_ADDRESS,
4352
top_offset = const KERNEL_STACK_SIZE,
4453
pre_init = sym pre_init,

src/arch/riscv64/mm/paging.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::marker::PhantomData;
22
use core::ptr;
3-
3+
use core::sync::atomic::{AtomicPtr, AtomicU64, AtomicUsize, Ordering};
44
use align_address::Align;
55
use free_list::PageLayout;
66
use hermit_sync::SpinMutex;
@@ -11,6 +11,7 @@ use riscv::register::satp;
1111
use crate::mm::{FrameAlloc, PageRangeAllocator};
1212

1313
static ROOT_PAGETABLE: SpinMutex<PageTable<L2Table>> = SpinMutex::new(PageTable::new());
14+
pub(crate) static SATP_VALUE: AtomicUsize = AtomicUsize::new(0);
1415

1516
/// Number of Offset bits of a virtual address for a 4 KiB page, which are shifted away to get its Page Frame Number (PFN).
1617
const PAGE_BITS: usize = 12;
@@ -660,4 +661,10 @@ pub unsafe fn enable_page_table() {
660661
satp::set(mode, asid, ppn);
661662
asm::sfence_vma_all();
662663
}
664+
665+
#[cfg(feature = "smp")]
666+
SATP_VALUE.store(
667+
((mode as usize) << 60) | (asid << 44) | ppn,
668+
Ordering::Relaxed
669+
);
663670
}

0 commit comments

Comments
 (0)