This commit is contained in:
2026-02-25 14:08:27 +01:00
parent 8a8034bd11
commit 4dc05c4151
23 changed files with 554 additions and 66 deletions

View File

@@ -1,3 +1,8 @@
//!
//! Trap handling and syscall dispatch.
//!
//! This module contains the low-level trap handlers for machine and supervisor
//! modes and the syscall dispatch implementation used by user processes.
use alloc::str;
use log::info;
use shared::syscall::SysCall;
@@ -13,11 +18,16 @@ use crate::{
time::{setup_next_timer_interrupt, IRQ_M_TIMER},
write_csr,
};
use core::{arch::naked_asm, time::Duration};
use core::{alloc::Layout, arch::naked_asm, time::Duration};
use crate::time::{setup_timer_interrupt, timer_interrupt};
#[unsafe(no_mangle)]
/// Machine-mode trap handler.
///
/// Handles synchronous exceptions and SBI calls that occur while running in
/// machine mode. This function decodes `mcause` and either handles the
/// condition or forwards it to a panic.
unsafe extern "C" fn machine_trap_handler(
mcause: u64,
mie: u64,
@@ -86,6 +96,10 @@ unsafe extern "C" fn machine_trap_handler(
}
#[unsafe(no_mangle)]
/// Supervisor-mode trap handler and syscall dispatcher.
///
/// Handles exceptions and interrupts coming from supervisor mode, performs
/// syscall decoding, and invokes the scheduler when needed.
unsafe extern "C" fn supervisor_trap_handler(
mut interrupt_state: *mut ExecutionContext,
scause: u64,
@@ -105,8 +119,20 @@ unsafe extern "C" fn supervisor_trap_handler(
let syscall_u64: u64 = unsafe { (*interrupt_state).a[0] };
let a1: u64 = unsafe { (*interrupt_state).a[1] };
let a2: u64 = unsafe { (*interrupt_state).a[2] };
let a3: u64 = unsafe { (*interrupt_state).a[3] };
let syscall: SysCall = syscall_u64.into();
match syscall {
SysCall::Alloc => {
let layout = Layout::from_size_align(a1 as usize, a2 as usize).unwrap();
// Allocate memory and put the pointer in a0
unsafe { (*interrupt_state).a[0] = alloc::alloc::alloc(layout) as u64 };
}
SysCall::Dealloc => {
let ptr = a1 as *mut u8;
let layout = Layout::from_size_align(a2 as usize, a3 as usize).unwrap();
// Free memory
unsafe { alloc::alloc::dealloc(ptr, layout) };
}
SysCall::Exit => exit_process(&mut interrupt_state),
SysCall::NanoSleep => sleep(Duration::new(a1, a2 as u32), &mut interrupt_state),
SysCall::WriteTemp => {
@@ -146,10 +172,13 @@ unsafe extern "C" fn supervisor_trap_handler(
interrupt_state
}
/// Install the machine-mode trap entry point and enable timer interrupts.
pub unsafe fn setup_machine_trap_handler() {
write_csr!(mtvec, _machine_mode_trap);
set_csr!(mie, IRQ_M_TIMER);
}
/// Install the supervisor-mode trap entry point and configure periodic timer.
pub unsafe fn setup_supervisor_trap_handler() {
write_csr!(stvec, _supervisor_mode_trap);
setup_timer_interrupt();
@@ -157,6 +186,11 @@ pub unsafe fn setup_supervisor_trap_handler() {
#[unsafe(naked)]
#[unsafe(no_mangle)]
/// Low-level machine-mode trap entry (assembly stub).
///
/// Saves the machine-mode callee-saved context, constructs a stack frame and
/// calls `machine_trap_handler` in Rust. Implemented as a naked function
/// with inline assembly.
unsafe extern "C" fn _machine_mode_trap() {
naked_asm!(
"
@@ -210,6 +244,10 @@ unsafe extern "C" fn _machine_mode_trap() {
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
/// Low-level supervisor-mode trap entry (assembly stub).
///
/// This stub saves the full register state and forwards control to
/// `supervisor_trap_handler` implemented in Rust.
unsafe extern "C" fn _supervisor_mode_trap() {
naked_asm!(concat!(
"
@@ -267,6 +305,7 @@ unsafe extern "C" fn _supervisor_mode_trap() {
#[unsafe(naked)]
#[unsafe(no_mangle)]
/// Restore a saved execution context and perform `sret` to return to user code.
pub unsafe extern "C" fn restore_context(context: *const ExecutionContext) -> ! {
naked_asm!(concat!(
"