refactor: move Mapping<F> to types crate with VirtualAddress/PhysicalAddress newtypes, rename MapFlags to Sv39Flags

This commit is contained in:
2026-10-18 02:45:53 +02:00
parent 7df3034fca
commit 5c29c0845d
6 changed files with 57 additions and 57 deletions

View File

@@ -91,7 +91,7 @@ static USER_EXIT_PROGRAM: [u8; 12] = [
0x6f, 0xf0, 0xdf, 0xff, // j -4
];
const USER_VA: usize = 0x10000;
const USER_VA_RAW: usize = 0x10000;
fn userspace_demo(uart: &Uart, kernel_pt: &mmu::PageTable) {
uart.write_str("k-os: --- userspace demo ---\n");
@@ -105,7 +105,12 @@ fn userspace_demo(uart: &Uart, kernel_pt: &mmu::PageTable) {
);
}
let user_pt = mmu::create_user_page_table(kernel_pt, program_page, 1, USER_VA);
let user_pt = mmu::create_user_page_table(
kernel_pt,
types::address::PhysicalAddress::from_raw(program_page),
1,
types::address::VirtualAddress::from_raw(USER_VA_RAW),
);
uart.write_str("k-os: user page table created, entering U-mode\n");
@@ -115,7 +120,7 @@ fn userspace_demo(uart: &Uart, kernel_pt: &mmu::PageTable) {
unsafe { core::arch::asm!("mv {0}, sp", out(reg) kernel_sp) };
trap::set_kernel_stack(kernel_sp);
let user_stack = USER_VA - 8;
let user_stack = USER_VA_RAW - 8;
unsafe {
core::arch::asm!(
"csrc sstatus, {spp}",
@@ -125,7 +130,7 @@ fn userspace_demo(uart: &Uart, kernel_pt: &mmu::PageTable) {
"sret",
spp = in(reg) 1usize << 8,
spie = in(reg) 1usize << 5,
entry = in(reg) USER_VA,
entry = in(reg) USER_VA_RAW,
stack = in(reg) user_stack,
options(noreturn),
);

View File

@@ -2,4 +2,4 @@ pub mod allocator;
pub mod page_table;
pub use allocator::init_allocator;
pub use page_table::{activate, init_kernel_page_table, create_user_page_table, map, MapFlags, Mapping, PageTable, PAGE_SIZE};
pub use page_table::{activate, init_kernel_page_table, create_user_page_table, map, Sv39Flags, Mapping, PageTable, PAGE_SIZE};

View File

@@ -1,6 +1,8 @@
use crate::board;
use super::allocator::alloc_page_table;
use types::address::{PhysicalAddress, VirtualAddress};
pub use types::mapping::Mapping;
pub const PAGE_SIZE: usize = 4096;
const PTE_V: u64 = 1 << 0;
@@ -13,11 +15,11 @@ const PTE_A: u64 = 1 << 6;
const PTE_D: u64 = 1 << 7;
#[derive(Clone, Copy)]
pub struct MapFlags {
pub struct Sv39Flags {
bits: u64,
}
impl MapFlags {
impl Sv39Flags {
pub fn kernel_rwx() -> Self {
Self { bits: PTE_R | PTE_W | PTE_X | PTE_G }
}
@@ -47,14 +49,6 @@ impl MapFlags {
}
}
#[derive(Clone, Copy)]
pub struct Mapping {
pub va: usize,
pub pa: usize,
pub pages: usize,
pub flags: MapFlags,
}
#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct PageTableEntry(u64);
@@ -64,7 +58,7 @@ impl PageTableEntry {
Self(0)
}
fn new_leaf(ppn: u64, flags: MapFlags) -> Self {
fn new_leaf(ppn: u64, flags: Sv39Flags) -> Self {
Self(flags.to_pte_flags() | (ppn << 10))
}
@@ -98,7 +92,7 @@ fn vpn(va: usize, level: usize) -> usize {
(va >> (12 + 9 * level)) & 0x1FF
}
fn map_page(root: &mut PageTable, va: usize, pa: usize, flags: MapFlags) {
fn map_page(root: &mut PageTable, va: usize, pa: usize, flags: Sv39Flags) {
let vpn2 = vpn(va, 2);
let vpn1 = vpn(va, 1);
let vpn0 = vpn(va, 0);
@@ -125,43 +119,29 @@ fn map_page(root: &mut PageTable, va: usize, pa: usize, flags: MapFlags) {
l0.entries[vpn0] = PageTableEntry::new_leaf(ppn, flags);
}
pub fn map(root: &mut PageTable, mapping: Mapping) {
pub fn map(root: &mut PageTable, mapping: Mapping<Sv39Flags>) {
for i in 0..mapping.pages {
let offset = i * PAGE_SIZE;
map_page(root, mapping.va + offset, mapping.pa + offset, mapping.flags);
map_page(root, mapping.va.raw() + offset, mapping.pa.raw() + offset, mapping.flags);
}
}
pub fn init_kernel_page_table() -> &'static mut PageTable {
let root = alloc_page_table();
map(root, Mapping {
va: board::RAM_BASE,
pa: board::RAM_BASE,
pages: board::RAM_SIZE / PAGE_SIZE,
flags: MapFlags::kernel_rwx(),
});
let identity = |addr: usize| (VirtualAddress::from_raw(addr), PhysicalAddress::from_raw(addr));
map(root, Mapping {
va: board::UART_BASE,
pa: board::UART_BASE,
pages: 1,
flags: MapFlags::kernel_rw(),
});
let (va, pa) = identity(board::RAM_BASE);
map(root, Mapping { va, pa, pages: board::RAM_SIZE / PAGE_SIZE, flags: Sv39Flags::kernel_rwx() });
map(root, Mapping {
va: board::PLIC_BASE,
pa: board::PLIC_BASE,
pages: 0x400000 / PAGE_SIZE,
flags: MapFlags::kernel_rw(),
});
let (va, pa) = identity(board::UART_BASE);
map(root, Mapping { va, pa, pages: 1, flags: Sv39Flags::kernel_rw() });
map(root, Mapping {
va: board::CLINT_BASE,
pa: board::CLINT_BASE,
pages: 0x10000 / PAGE_SIZE,
flags: MapFlags::kernel_rw(),
});
let (va, pa) = identity(board::PLIC_BASE);
map(root, Mapping { va, pa, pages: 0x400000 / PAGE_SIZE, flags: Sv39Flags::kernel_rw() });
let (va, pa) = identity(board::CLINT_BASE);
map(root, Mapping { va, pa, pages: 0x10000 / PAGE_SIZE, flags: Sv39Flags::kernel_rw() });
root
}
@@ -180,9 +160,9 @@ pub fn activate(root: &PageTable) {
pub fn create_user_page_table(
kernel_root: &PageTable,
program_pa: usize,
program_pa: PhysicalAddress,
program_pages: usize,
user_va: usize,
user_va: VirtualAddress,
) -> &'static mut PageTable {
let root = alloc_page_table();
@@ -197,16 +177,17 @@ pub fn create_user_page_table(
va: user_va,
pa: program_pa,
pages: program_pages,
flags: MapFlags::user_rx(),
flags: Sv39Flags::user_rx(),
});
let stack_table = alloc_page_table();
let stack_pa = stack_table as *const PageTable as usize;
let stack_pa = PhysicalAddress::from_raw(stack_table as *const PageTable as usize);
let stack_va = VirtualAddress::from_raw(user_va.raw().wrapping_sub(PAGE_SIZE));
map(root, Mapping {
va: user_va.wrapping_sub(PAGE_SIZE),
va: stack_va,
pa: stack_pa,
pages: 1,
flags: MapFlags::user_rw(),
flags: Sv39Flags::user_rw(),
});
}

View File

@@ -2,7 +2,7 @@ use domain::memory::MemoryRegion;
use domain::process::MAX_PROCESSES;
use platform::Platform;
use types::{
address::{EntryPoint, PhysicalAddress, StackPointer},
address::{EntryPoint, PhysicalAddress, StackPointer, VirtualAddress},
bounded::PageCount,
id::{CoreId, IrqId, ProcessId},
permission::{Permission, PermissionSet},
@@ -34,7 +34,12 @@ impl RiscVPlatform {
let idx = pid.raw() as usize;
if self.page_tables[idx] == 0 {
let kernel_pt = unsafe { &*(self.page_tables[0] as *const mmu::PageTable) };
let user_pt = mmu::create_user_page_table(kernel_pt, 0, 0, 0x10000);
let user_pt = mmu::create_user_page_table(
kernel_pt,
PhysicalAddress::from_raw(0),
0,
VirtualAddress::from_raw(0x10000),
);
self.page_tables[idx] = user_pt as *const mmu::PageTable as usize;
}
unsafe { &mut *(self.page_tables[idx] as *mut mmu::PageTable) }
@@ -46,10 +51,10 @@ impl Platform for RiscVPlatform {
let pt = self.ensure_page_table(process);
for region in regions {
mmu::map(pt, mmu::Mapping {
va: region.base().raw(),
pa: region.base().raw(),
va: VirtualAddress::from_raw(region.base().raw()),
pa: region.base(),
pages: region.size().value() as usize,
flags: mmu::MapFlags::user(true, true, true),
flags: mmu::Sv39Flags::user(true, true, true),
});
}
}
@@ -111,10 +116,10 @@ impl Platform for RiscVPlatform {
) {
let pt = self.ensure_page_table(process);
mmu::map(pt, mmu::Mapping {
va: base.raw(),
pa: base.raw(),
va: VirtualAddress::from_raw(base.raw()),
pa: base,
pages: size.value() as usize,
flags: mmu::MapFlags::user(
flags: mmu::Sv39Flags::user(
permissions.allows(Permission::Read),
permissions.allows(Permission::Write),
permissions.allows(Permission::Execute),

View File

@@ -5,6 +5,7 @@ pub mod bounded;
pub mod generation;
pub mod id;
pub mod macros;
pub mod mapping;
pub mod permission;
#[cfg(kani)]
pub mod proofs;

View File

@@ -0,0 +1,8 @@
use crate::address::{PhysicalAddress, VirtualAddress};
pub struct Mapping<F> {
pub va: VirtualAddress,
pub pa: PhysicalAddress,
pub pages: usize,
pub flags: F,
}