Refactor
This commit is contained in:
@@ -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!(
|
||||
"
|
||||
|
||||
Reference in New Issue
Block a user