Interrupts aren't working anymore

This commit is contained in:
2026-03-15 10:48:41 +01:00
parent de6ef959ce
commit b1aac20b57
17 changed files with 455 additions and 89 deletions

View File

@@ -14,7 +14,7 @@ use crate::{
clear_csr,
process::{ExecutionContext, exit_process, sleep},
read_csr,
riscv::disable_interrupt,
riscv::{disable_interrupt, dump_cpu},
scheduler::SCHEDULER,
set_csr, syscall,
time::{IRQ_M_EXTERNAL, IRQ_M_TIMER, setup_next_timer_interrupt},
@@ -85,7 +85,13 @@ unsafe extern "C" fn machine_trap_handler(
),
};
disable_interrupt();
panic!("{} at PC=0x{:x}, mtval={}", message, mepc, mtval);
panic!(
"{} at PC=0x{:x}, mtval={}\n\n{}",
message,
mepc,
mtval,
dump_cpu()
);
} else {
#[allow(clippy::single_match)]
match mcause & !(1 << 63) {
@@ -120,6 +126,12 @@ unsafe extern "C" fn supervisor_trap_handler(
unsafe {
(*interrupt_state).mepc = (*interrupt_state).mepc.byte_add(4);
}
// Get back to run the syscall again
fn loop_syscall(interrupt_state: *mut ExecutionContext) {
unsafe {
(*interrupt_state).mepc = (*interrupt_state).mepc.byte_sub(4);
}
}
// Environment call from S-mode
let syscall_u64: u64 = unsafe { (*interrupt_state).a[0] };
@@ -134,10 +146,19 @@ unsafe extern "C" fn supervisor_trap_handler(
let mut scheduler = SCHEDULER.lock();
let current_process = scheduler.get_current_process();
let fd = current_process.next_fd;
current_process.fd_table.insert(fd, virtual_node);
current_process.next_fd += 1;
unsafe { (*interrupt_state).a[0] = fd };
let fd = if let Some(fd) =
current_process.fd_table.iter().position(Option::is_none)
{
current_process.fd_table[fd] = Some(virtual_node);
fd
} else {
let fd = current_process.fd_table.len();
current_process.fd_table.push(Some(virtual_node));
fd
};
unsafe { (*interrupt_state).a[0] = fd as u64 };
}
SysCall::Write => {
let fd = a1;
@@ -146,7 +167,7 @@ unsafe extern "C" fn supervisor_trap_handler(
let mut scheduler = SCHEDULER.lock();
let current_process = scheduler.get_current_process();
let vnode = current_process.fd_table.get_mut(&fd).unwrap();
let vnode = current_process.fd_table[fd as usize].as_mut().unwrap();
vnode.write(buf).unwrap();
}
SysCall::Read => {
@@ -156,8 +177,12 @@ unsafe extern "C" fn supervisor_trap_handler(
let mut scheduler = SCHEDULER.lock();
let current_process = scheduler.get_current_process();
let vnode = current_process.fd_table.get_mut(&fd).unwrap();
vnode.read(buf).unwrap();
let vnode = current_process.fd_table[fd as usize].as_mut().unwrap();
let res = vnode.read(buf).unwrap();
if res == 0 && !buf.is_empty() {
loop_syscall(interrupt_state);
scheduler.schedule(&mut interrupt_state);
}
}
SysCall::Seek => {
let fd = a1;
@@ -169,7 +194,7 @@ unsafe extern "C" fn supervisor_trap_handler(
};
let mut scheduler = SCHEDULER.lock();
let current_process = scheduler.get_current_process();
let vnode = current_process.fd_table.get_mut(&fd).unwrap();
let vnode = current_process.fd_table[fd as usize].as_mut().unwrap();
vnode.seek(seek).unwrap();
}
SysCall::Alloc => {
@@ -360,6 +385,17 @@ unsafe extern "C" fn _supervisor_mode_trap() {
csrr t0, sepc
sd t0, 248(sp)
csrr t0, sstatus
// Move SIE bit to SPIE. Restore_context, in the sret instruction, will do the inverse operation
// Isolate SIE bit (1)
andi t1, t0, 0x2
// li t1, 0x2
// Shift to bit 5 (SPIE)
slli t1, t1, 4
// Clear bit 1 and 5
li t2, ~0x22
and t0, t0, t2
// Add the SPIE bit
or t0, t0, t1
sd t0, 256(sp)
mv a0, sp