Load dynamic programs using FAT32

This commit is contained in:
2026-02-20 22:10:09 +01:00
parent 00d9ce656c
commit 235f17e7cf
26 changed files with 112 additions and 68 deletions

327
src/interrupt.rs Normal file
View File

@@ -0,0 +1,327 @@
use alloc::str;
use log::info;
use crate::{
boot::sbi::{EextensionID, TimerFunctionID},
clear_csr, generate_trap_handler,
process::{sleep, ExecutionContext},
read_csr,
riscv::disable_interrupt,
scheduler::scheduler,
set_csr,
syscall::SysCall,
time::{setup_next_timer_interrupt, IRQ_M_TIMER},
write_csr,
};
use core::{arch::naked_asm, time::Duration};
use crate::time::{setup_timer_interrupt, timer_interrupt};
#[unsafe(no_mangle)]
unsafe extern "C" fn machine_trap_handler(
mcause: u64,
mie: u64,
mip: u64,
interrupt_state: *const MachineInterruptState,
) {
let mepc = read_csr!(mepc);
let mtval = read_csr!(mtval);
if mcause & (1 << 63) == 0 {
let message = match mcause & !(1 << 63) {
0 => "Instruction address misaligned",
1 => "Instruction access fault",
2 => "Illegal instruction",
3 => "Breakpoint",
4 => "Load address misaligned",
5 => "Load access fault",
6 => "Store/AMO address misaligned",
7 => "Store/AMO access fault",
8 => "Environment call from U-mode",
9 => {
// Environment call from S-mode
let eid = unsafe { (*interrupt_state).a[7] };
let fid = unsafe { (*interrupt_state).a[6] };
#[allow(clippy::single_match)]
match eid {
c if c == EextensionID::Time as usize => match fid {
c if c == TimerFunctionID::SetTimer as usize => {
clear_csr!(mip, 1 << 5);
// setup_next_timer_interrupt();
}
_ => {}
},
_ => panic!("Unhandled SBI call eid={eid}, fid={fid}"),
}
// Advance mepc to exit the ecall
let mepc = read_csr!(mepc);
write_csr!(mepc, mepc + 4);
return;
}
11 => "Environment call from M-mode",
12 => "Instruction page fault",
13 => "Load page fault",
15 => "Store/AMO page fault",
16 => "Double trap",
18 => "Software check",
19 => "Hardware error",
_ => panic!(
"unknown exception, mcause={}, mie={}, mip={}",
mcause, mie, mip
),
};
disable_interrupt();
panic!("{} at PC=0x{:x}, mtval={}", message, mepc, mtval);
} else {
#[allow(clippy::single_match)]
match mcause & !(1 << 63) {
7 => {
setup_next_timer_interrupt();
set_csr!(mip, 1 << 5);
}
_ => {}
}
}
}
#[unsafe(no_mangle)]
unsafe extern "C" fn supervisor_trap_handler(
interrupt_state: *mut ExecutionContext,
scause: u64,
_sie: u64,
_sip: u64,
) -> *const ExecutionContext {
if scause & (1 << 63) == 0 {
#[allow(clippy::single_match)]
match scause & !(1 << 63) {
8 => {
// Environment call from S-mode
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 syscall: SysCall = syscall_u64.into();
match syscall {
SysCall::NanoSleep => sleep(Duration::new(a1, a2 as u32)),
SysCall::WriteTemp => {
info!("Print from user space : {}", unsafe {
str::from_raw_parts(a1 as *const u8, a2 as usize)
})
}
SysCall::WriteIntTemp => {
info!("Print from user space int : {}, {:x}", a1, a1)
}
SysCall::Unimplemented => {
unimplemented!("Syscall {syscall_u64} is not implemented")
}
}
// Advance sepc to exit the ecall
unsafe {
(*interrupt_state).mepc = (*interrupt_state).mepc.byte_add(4);
}
}
_ => {}
}
} else {
#[allow(clippy::single_match)]
match scause & !(1 << 63) {
5 => {
unsafe {
core::arch::asm!(
"ecall",
in("a0") 0,
in("a6") TimerFunctionID::SetTimer as u64,
in("a7") EextensionID::Time as u64,
clobber_abi("system")
);
}
timer_interrupt();
return scheduler(unsafe { *interrupt_state });
}
_ => {}
}
}
interrupt_state
}
pub unsafe fn setup_machine_trap_handler() {
write_csr!(mtvec, _machine_mode_trap);
set_csr!(mie, IRQ_M_TIMER);
}
pub unsafe fn setup_supervisor_trap_handler() {
write_csr!(stvec, _supervisor_mode_trap);
setup_timer_interrupt();
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
unsafe extern "C" fn _machine_mode_trap() {
naked_asm!(
"
addi sp, sp, -128
# Store the current frame
sd ra, 120(sp)
sd a0, 0(sp)
sd a1, 8(sp)
sd a2, 16(sp)
sd a3, 24(sp)
sd a4, 32(sp)
sd a5, 40(sp)
sd a6, 48(sp)
sd a7, 56(sp)
sd t0, 64(sp)
sd t1, 72(sp)
sd t2, 80(sp)
sd t3, 88(sp)
sd t4, 96(sp)
sd t5, 104(sp)
sd t6, 112(sp)
csrr a0, mcause
csrr a1, mie
csrr a2, mip
mv a3, sp
jal machine_trap_handler
# Restore registers
ld ra, 120(sp)
ld a0, 0(sp)
ld a1, 8(sp)
ld a2, 16(sp)
ld a3, 24(sp)
ld a4, 32(sp)
ld a5, 40(sp)
ld a6, 48(sp)
ld a7, 56(sp)
ld t0, 64(sp)
ld t1, 72(sp)
ld t2, 80(sp)
ld t3, 88(sp)
ld t4, 96(sp)
ld t5, 104(sp)
ld t6, 112(sp)
addi sp, sp, 128
mret"
)
}
generate_trap_handler! {
_supervisor_mode_trap, supervisor_trap_handler, s
}
#[macro_export]
macro_rules! generate_trap_handler {
($name:ident, $jump_to:ident, $mode:ident) => {
#[unsafe(naked)]
#[unsafe(no_mangle)]
unsafe extern "C" fn $name() {
naked_asm!(concat!(
"
mv t0, sp
addi sp, sp, -264
# Store the current frame
sd ra, 0(sp)
sd t0, 8(sp) // sp
sd gp, 16(sp)
sd tp, 24(sp)
sd a0, 32(sp)
sd a1, 40(sp)
sd a2, 48(sp)
sd a3, 56(sp)
sd a4, 64(sp)
sd a5, 72(sp)
sd a6, 80(sp)
sd a7, 88(sp)
sd t0, 96(sp)
sd t1, 104(sp)
sd t2, 112(sp)
sd t3, 120(sp)
sd t4, 128(sp)
sd t5, 136(sp)
sd t6, 144(sp)
sd s0, 152(sp)
sd s1, 160(sp)
sd s2, 168(sp)
sd s3, 176(sp)
sd s4, 184(sp)
sd s5, 192(sp)
sd s6, 200(sp)
sd s7, 208(sp)
sd s8, 216(sp)
sd s9, 224(sp)
sd s10, 232(sp)
sd s11, 240(sp)
csrr t0, sepc
sd t0, 248(sp)
csrr t0, sstatus
sd t0, 256(sp)
mv a0, sp
csrr a1, ",
stringify!($mode),
"cause
csrr a2, ",
stringify!($mode),
"ie
csrr a3, ",
stringify!($mode),
"ip
jal ",
stringify!($jump_to),
"
# Restore registers
ld t0, 248(a0)
csrw sepc, t0
ld t0, 256(a0)
csrw sstatus, t0
ld ra, 0(a0)
ld sp, 8(a0)
ld gp, 16(a0)
ld tp, 24(a0)
ld a1, 40(a0)
ld a2, 48(a0)
ld a3, 56(a0)
ld a4, 64(a0)
ld a5, 72(a0)
ld a6, 80(a0)
ld a7, 88(a0)
ld t0, 96(a0)
ld t1, 104(a0)
ld t2, 112(a0)
ld t3, 120(a0)
ld t4, 128(a0)
ld t5, 136(a0)
ld t6, 144(a0)
ld s0, 152(a0)
ld s1, 160(a0)
ld s2, 168(a0)
ld s3, 176(a0)
ld s4, 184(a0)
ld s5, 192(a0)
ld s6, 200(a0)
ld s7, 208(a0)
ld s8, 216(a0)
ld s9, 224(a0)
ld s10, 232(a0)
ld s11, 240(a0)
ld a0, 32(a0)
",
stringify!($mode),
"ret"
))
}
};
}
#[repr(C)]
struct MachineInterruptState {
pub a: [usize; 8],
pub t: [usize; 7],
pub ra: usize,
}