feat: implement configure_protection and map_shared with real page mapping, remove dead context_switch from Platform trait
This commit is contained in:
@@ -2,4 +2,4 @@ pub mod allocator;
|
|||||||
pub mod page_table;
|
pub mod page_table;
|
||||||
|
|
||||||
pub use allocator::init_allocator;
|
pub use allocator::init_allocator;
|
||||||
pub use page_table::{activate, init_kernel_page_table, create_user_page_table, PageTable, PAGE_SIZE};
|
pub use page_table::{activate, init_kernel_page_table, create_user_page_table, map_range, PageTable, PAGE_SIZE};
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ fn map_page(root: &mut PageTable, va: usize, pa: usize, read: bool, write: bool,
|
|||||||
l0.entries[vpn0] = PageTableEntry::new_leaf(ppn, read, write, exec, user, global);
|
l0.entries[vpn0] = PageTableEntry::new_leaf(ppn, read, write, exec, user, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_range(root: &mut PageTable, va_start: usize, pa_start: usize, pages: usize, read: bool, write: bool, exec: bool, user: bool, global: bool) {
|
pub fn map_range(root: &mut PageTable, va_start: usize, pa_start: usize, pages: usize, read: bool, write: bool, exec: bool, user: bool, global: bool) {
|
||||||
for i in 0..pages {
|
for i in 0..pages {
|
||||||
let offset = i * PAGE_SIZE;
|
let offset = i * PAGE_SIZE;
|
||||||
map_page(root, va_start + offset, pa_start + offset, read, write, exec, user, global);
|
map_page(root, va_start + offset, pa_start + offset, read, write, exec, user, global);
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use domain::memory::MemoryRegion;
|
use domain::memory::MemoryRegion;
|
||||||
use domain::process::MAX_PROCESSES;
|
use domain::process::MAX_PROCESSES;
|
||||||
use domain::thread::SavedContext;
|
|
||||||
use platform::Platform;
|
use platform::Platform;
|
||||||
use types::{
|
use types::{
|
||||||
address::{EntryPoint, PhysicalAddress, StackPointer},
|
address::{EntryPoint, PhysicalAddress, StackPointer},
|
||||||
bounded::PageCount,
|
bounded::PageCount,
|
||||||
id::{CoreId, IrqId, ProcessId},
|
id::{CoreId, IrqId, ProcessId},
|
||||||
permission::PermissionSet,
|
permission::{Permission, PermissionSet},
|
||||||
time::{Ticks, TimerDuration},
|
time::{Ticks, TimerDuration},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -30,23 +29,28 @@ impl RiscVPlatform {
|
|||||||
pub fn page_table_for(&self, pid: ProcessId) -> usize {
|
pub fn page_table_for(&self, pid: ProcessId) -> usize {
|
||||||
self.page_tables[pid.raw() as usize]
|
self.page_tables[pid.raw() as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ensure_page_table(&mut self, pid: ProcessId) -> &mut mmu::PageTable {
|
||||||
|
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);
|
||||||
|
self.page_tables[idx] = user_pt as *const mmu::PageTable as usize;
|
||||||
|
}
|
||||||
|
unsafe { &mut *(self.page_tables[idx] as *mut mmu::PageTable) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform for RiscVPlatform {
|
impl Platform for RiscVPlatform {
|
||||||
fn configure_protection(&mut self, process: ProcessId, _regions: &[MemoryRegion]) {
|
fn configure_protection(&mut self, process: ProcessId, regions: &[MemoryRegion]) {
|
||||||
if self.page_tables[process.raw() as usize] == 0 {
|
let pt = self.ensure_page_table(process);
|
||||||
let kernel_pt_addr = self.page_tables[0];
|
for region in regions {
|
||||||
let kernel_pt = unsafe { &*(kernel_pt_addr as *const mmu::PageTable) };
|
let base_pa = region.base().raw();
|
||||||
let user_pt = mmu::create_user_page_table(kernel_pt, 0, 0, 0x10000);
|
let pages = region.size().value() as usize;
|
||||||
self.page_tables[process.raw() as usize] = user_pt as *const mmu::PageTable as usize;
|
mmu::map_range(pt, base_pa, base_pa, pages, true, true, true, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn context_switch(&mut self, from: &mut SavedContext, to: &SavedContext) {
|
|
||||||
let _ = from;
|
|
||||||
let _ = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable_user_mode(&mut self, entry: EntryPoint, stack: StackPointer) -> ! {
|
fn enable_user_mode(&mut self, entry: EntryPoint, stack: StackPointer) -> ! {
|
||||||
let kernel_sp: usize;
|
let kernel_sp: usize;
|
||||||
unsafe { core::arch::asm!("mv {0}, sp", out(reg) kernel_sp) };
|
unsafe { core::arch::asm!("mv {0}, sp", out(reg) kernel_sp) };
|
||||||
@@ -97,10 +101,17 @@ impl Platform for RiscVPlatform {
|
|||||||
|
|
||||||
fn map_shared(
|
fn map_shared(
|
||||||
&mut self,
|
&mut self,
|
||||||
_process: ProcessId,
|
process: ProcessId,
|
||||||
_base: PhysicalAddress,
|
base: PhysicalAddress,
|
||||||
_size: PageCount,
|
size: PageCount,
|
||||||
_permissions: PermissionSet,
|
permissions: PermissionSet,
|
||||||
) {
|
) {
|
||||||
|
let pt = self.ensure_page_table(process);
|
||||||
|
let pa = base.raw();
|
||||||
|
let pages = size.value() as usize;
|
||||||
|
let read = permissions.allows(Permission::Read);
|
||||||
|
let write = permissions.allows(Permission::Write);
|
||||||
|
let exec = permissions.allows(Permission::Execute);
|
||||||
|
mmu::map_range(pt, pa, pa, pages, read, write, exec, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use domain::memory::MemoryRegion;
|
use domain::memory::MemoryRegion;
|
||||||
use domain::thread::SavedContext;
|
|
||||||
use platform::Platform;
|
use platform::Platform;
|
||||||
use types::{
|
use types::{
|
||||||
address::{EntryPoint, PhysicalAddress, StackPointer},
|
address::{EntryPoint, PhysicalAddress, StackPointer},
|
||||||
@@ -31,7 +30,6 @@ impl MockPlatform {
|
|||||||
|
|
||||||
impl Platform for MockPlatform {
|
impl Platform for MockPlatform {
|
||||||
fn configure_protection(&mut self, _process: ProcessId, _regions: &[MemoryRegion]) {}
|
fn configure_protection(&mut self, _process: ProcessId, _regions: &[MemoryRegion]) {}
|
||||||
fn context_switch(&mut self, _from: &mut SavedContext, _to: &SavedContext) {}
|
|
||||||
fn enable_user_mode(&mut self, _entry: EntryPoint, _stack: StackPointer) -> ! {
|
fn enable_user_mode(&mut self, _entry: EntryPoint, _stack: StackPointer) -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use domain::{memory::MemoryRegion, thread::SavedContext};
|
use domain::memory::MemoryRegion;
|
||||||
use types::{
|
use types::{
|
||||||
address::{EntryPoint, PhysicalAddress, StackPointer},
|
address::{EntryPoint, PhysicalAddress, StackPointer},
|
||||||
bounded::PageCount,
|
bounded::PageCount,
|
||||||
@@ -9,11 +9,8 @@ use types::{
|
|||||||
time::{Ticks, TimerDuration},
|
time::{Ticks, TimerDuration},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait PlatformContext: Copy + Default {}
|
|
||||||
|
|
||||||
pub trait Platform {
|
pub trait Platform {
|
||||||
fn configure_protection(&mut self, process: ProcessId, regions: &[MemoryRegion]);
|
fn configure_protection(&mut self, process: ProcessId, regions: &[MemoryRegion]);
|
||||||
fn context_switch(&mut self, from: &mut SavedContext, to: &SavedContext);
|
|
||||||
fn enable_user_mode(&mut self, entry: EntryPoint, stack: StackPointer) -> !;
|
fn enable_user_mode(&mut self, entry: EntryPoint, stack: StackPointer) -> !;
|
||||||
fn set_timer(&mut self, duration: TimerDuration);
|
fn set_timer(&mut self, duration: TimerDuration);
|
||||||
fn current_ticks(&self) -> Ticks;
|
fn current_ticks(&self) -> Ticks;
|
||||||
|
|||||||
Reference in New Issue
Block a user