diff --git a/crates/adapter-riscv/src/main.rs b/crates/adapter-riscv/src/main.rs index 2ccf4b9..3459cb8 100644 --- a/crates/adapter-riscv/src/main.rs +++ b/crates/adapter-riscv/src/main.rs @@ -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), ); diff --git a/crates/adapter-riscv/src/mmu/mod.rs b/crates/adapter-riscv/src/mmu/mod.rs index e84f952..24278dc 100644 --- a/crates/adapter-riscv/src/mmu/mod.rs +++ b/crates/adapter-riscv/src/mmu/mod.rs @@ -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}; diff --git a/crates/adapter-riscv/src/mmu/page_table.rs b/crates/adapter-riscv/src/mmu/page_table.rs index 547b7ff..7184d13 100644 --- a/crates/adapter-riscv/src/mmu/page_table.rs +++ b/crates/adapter-riscv/src/mmu/page_table.rs @@ -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) { 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(), }); } diff --git a/crates/adapter-riscv/src/platform.rs b/crates/adapter-riscv/src/platform.rs index 3245aa3..7e11b0c 100644 --- a/crates/adapter-riscv/src/platform.rs +++ b/crates/adapter-riscv/src/platform.rs @@ -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), diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index ca07831..3bf7f23 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -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; diff --git a/crates/types/src/mapping.rs b/crates/types/src/mapping.rs new file mode 100644 index 0000000..e3adf70 --- /dev/null +++ b/crates/types/src/mapping.rs @@ -0,0 +1,8 @@ +use crate::address::{PhysicalAddress, VirtualAddress}; + +pub struct Mapping { + pub va: VirtualAddress, + pub pa: PhysicalAddress, + pub pages: usize, + pub flags: F, +}