feat: implement context switching, SavedContext with pc/status fields, wire all syscall outcomes and timer preemption

This commit is contained in:
2026-10-18 02:34:36 +02:00
parent 5a45c14cf5
commit 7724a5bd0a
7 changed files with 195 additions and 27 deletions

View File

@@ -1,4 +1,5 @@
use domain::memory::MemoryRegion;
use domain::process::MAX_PROCESSES;
use domain::thread::SavedContext;
use platform::Platform;
use types::{
@@ -11,24 +12,60 @@ use types::{
use crate::board;
use crate::hw::{plic::Plic, timer};
use crate::mmu;
use crate::trap;
pub struct RiscVPlatform {
num_cores: u8,
page_tables: [usize; MAX_PROCESSES],
}
impl RiscVPlatform {
pub fn new() -> Self {
Self { num_cores: 1 }
pub fn new(kernel_pt_addr: usize) -> Self {
let mut pt = [0usize; MAX_PROCESSES];
pt[0] = kernel_pt_addr;
Self { num_cores: 1, page_tables: pt }
}
pub fn page_table_for(&self, pid: ProcessId) -> usize {
self.page_tables[pid.raw() as usize]
}
}
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 kernel_pt_addr = self.page_tables[0];
let kernel_pt = unsafe { &*(kernel_pt_addr as *const mmu::PageTable) };
let user_pt = mmu::create_user_page_table(kernel_pt, 0, 0, 0x10000);
self.page_tables[process.raw() as usize] = user_pt as *const mmu::PageTable as usize;
}
}
fn context_switch(&mut self, _from: &mut SavedContext, _to: &SavedContext) {}
fn context_switch(&mut self, from: &mut SavedContext, to: &SavedContext) {
let _ = from;
let _ = to;
}
fn enable_user_mode(&mut self, _entry: EntryPoint, _stack: StackPointer) -> ! {
loop { unsafe { core::arch::asm!("wfi") }; }
fn enable_user_mode(&mut self, entry: EntryPoint, stack: StackPointer) -> ! {
let kernel_sp: usize;
unsafe { core::arch::asm!("mv {0}, sp", out(reg) kernel_sp) };
trap::set_kernel_stack(kernel_sp);
unsafe {
core::arch::asm!(
"csrc sstatus, {spp}",
"csrs sstatus, {spie}",
"csrw sepc, {entry}",
"mv sp, {stack}",
"sret",
spp = in(reg) 1usize << 8,
spie = in(reg) 1usize << 5,
entry = in(reg) entry.raw(),
stack = in(reg) stack.raw(),
options(noreturn),
);
}
}
fn set_timer(&mut self, _duration: TimerDuration) {