refactor: move Mapping<F> to types crate with VirtualAddress/PhysicalAddress newtypes, rename MapFlags to Sv39Flags
This commit is contained in:
@@ -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),
|
||||
);
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user