feat(adapter-riscv): replace static mut with KernelCell, complete all 17 syscall decoders, wire timer and PLIC interrupts to kernel

This commit is contained in:
2026-10-18 02:29:46 +02:00
parent ededdb2ed9
commit 5a45c14cf5
4 changed files with 156 additions and 80 deletions

View File

@@ -149,15 +149,15 @@ pub fn set_kernel_stack(kernel_sp: usize) {
fn decode_syscall(frame: &TrapFrame) -> Option<domain::syscall::Syscall> {
use domain::message::Message;
use domain::syscall::Syscall;
use domain::syscall::{Syscall, WaitSet};
use types::syscall_abi::*;
let nr = frame.regs[17]; // a7
let a0 = frame.regs[10]; // a0
let a1 = frame.regs[11]; // a1
let a2 = frame.regs[12]; // a2
let a3 = frame.regs[13]; // a3
let a4 = frame.regs[14]; // a4
let a0 = frame.regs[10];
let a1 = frame.regs[11];
let a2 = frame.regs[12];
let a3 = frame.regs[13];
let a4 = frame.regs[14];
match nr {
SYS_EXIT => Some(Syscall::Exit),
@@ -174,6 +174,46 @@ fn decode_syscall(frame: &TrapFrame) -> Option<domain::syscall::Syscall> {
let slot = types::bounded::CapSlot::new(a0 as u8)?;
Some(Syscall::Receive { endpoint: slot })
}
SYS_DELEGATE => {
let slot = types::bounded::CapSlot::new(a0 as u8)?;
let to = types::bounded::CapSlot::new(a1 as u8)?;
let perms = types::permission::PermissionSet::from_bits(a2 as u8);
Some(Syscall::Delegate { slot, to_endpoint: to, permissions: perms })
}
SYS_WAIT_FOR_INTERRUPT => {
let slot = types::bounded::CapSlot::new(a0 as u8)?;
Some(Syscall::WaitForInterrupt { irq: slot })
}
SYS_ACKNOWLEDGE_INTERRUPT => {
let slot = types::bounded::CapSlot::new(a0 as u8)?;
Some(Syscall::AcknowledgeInterrupt { irq: slot })
}
SYS_WAIT_ANY => {
let ep0 = if a0 != usize::MAX { types::bounded::CapSlot::new(a0 as u8) } else { None };
let ep1 = if a1 != usize::MAX { types::bounded::CapSlot::new(a1 as u8) } else { None };
let ep2 = if a2 != usize::MAX { types::bounded::CapSlot::new(a2 as u8) } else { None };
let ep3 = if a3 != usize::MAX { types::bounded::CapSlot::new(a3 as u8) } else { None };
let sources = WaitSet::new(
[ep0, ep1, ep2, ep3],
[None, None, None, None],
);
Some(Syscall::WaitAny { sources })
}
SYS_CREATE_PROCESS => {
let slot = types::bounded::CapSlot::new(a0 as u8)?;
Some(Syscall::CreateProcess {
create_cap: slot,
image: types::address::DataRef::empty(),
})
}
SYS_KILL => {
let slot = types::bounded::CapSlot::new(a0 as u8)?;
Some(Syscall::Kill { process: slot })
}
SYS_REVOKE => {
let slot = types::bounded::CapSlot::new(a0 as u8)?;
Some(Syscall::Revoke { slot })
}
SYS_SPAWN_THREAD => Some(Syscall::SpawnThread {
entry: types::address::EntryPoint::from_raw(a0),
stack: types::address::StackPointer::from_raw(a1),
@@ -182,6 +222,13 @@ fn decode_syscall(frame: &TrapFrame) -> Option<domain::syscall::Syscall> {
let count = types::bounded::PageCount::new(a0 as u16)?;
Some(Syscall::RequestPages { count })
}
SYS_RELEASE_PAGES => {
let count = types::bounded::PageCount::new(a1 as u16)?;
Some(Syscall::ReleasePages {
addr: types::address::VirtualAddress::from_raw(a0),
count,
})
}
_ => None,
}
}
@@ -214,49 +261,65 @@ extern "C" fn trap_handler_rust(frame: &mut TrapFrame) {
let scause: usize;
unsafe { core::arch::asm!("csrr {0}, scause", out(reg) scause) };
let uart = crate::hw::uart::Uart::new();
if scause & CAUSE_INTERRUPT_BIT != 0 {
let cause = scause & !CAUSE_INTERRUPT_BIT;
match cause {
CAUSE_S_TIMER => {
crate::hw::timer::handle_interrupt();
}
CAUSE_S_EXTERNAL => {
uart.write_str("[EXT]");
}
_ => {}
}
handle_interrupt(scause & !CAUSE_INTERRUPT_BIT);
} else {
match scause {
CAUSE_ECALL_U => {
frame.sepc += 4;
handle_exception(frame, scause);
}
}
if let Some(syscall) = decode_syscall(frame) {
let kern = crate::kernel_mut();
let outcome = kern.handle_syscall(syscall);
write_result(frame, &outcome);
fn handle_interrupt(cause: usize) {
match cause {
CAUSE_S_TIMER => {
crate::hw::timer::handle_interrupt();
let kern = crate::kernel_ref();
let core = types::id::CoreId::from_raw(0);
let _decision = kern.handle_tick(core);
}
CAUSE_S_EXTERNAL => {
let irq_num = crate::hw::plic::Plic::claim();
if irq_num != 0 {
let kern = crate::kernel_ref();
let irq = types::id::IrqId::from_raw(irq_num as u16);
kern.handle_interrupt(irq);
crate::hw::plic::Plic::complete(irq_num);
}
}
_ => {}
}
}
match &outcome {
kernel::SyscallOutcome::TerminateCaller => {
uart.write_str("k-os: process exited\n");
}
_ => {}
fn handle_exception(frame: &mut TrapFrame, scause: usize) {
match scause {
CAUSE_ECALL_U => {
frame.sepc += 4;
if let Some(syscall) = decode_syscall(frame) {
let kern = crate::kernel_ref();
let outcome = kern.handle_syscall(syscall);
write_result(frame, &outcome);
match &outcome {
kernel::SyscallOutcome::TerminateCaller => {
let uart = crate::hw::uart::Uart::new();
uart.write_str("k-os: process exited\n");
}
_ => {}
}
}
_ => {
uart.write_str("FAULT: scause=");
uart.write_hex(scause);
let stval: usize;
unsafe { core::arch::asm!("csrr {0}, stval", out(reg) stval) };
uart.write_str(" stval=");
uart.write_hex(stval);
uart.write_str(" sepc=");
uart.write_hex(frame.sepc);
uart.put_char(b'\n');
loop { unsafe { core::arch::asm!("wfi") }; }
}
}
_ => {
let uart = crate::hw::uart::Uart::new();
uart.write_str("FAULT: scause=");
uart.write_hex(scause);
let stval: usize;
unsafe { core::arch::asm!("csrr {0}, stval", out(reg) stval) };
uart.write_str(" stval=");
uart.write_hex(stval);
uart.write_str(" sepc=");
uart.write_hex(frame.sepc);
uart.put_char(b'\n');
loop { unsafe { core::arch::asm!("wfi") }; }
}
}
}