kernel/arch/riscv64/trap/
interrupt.rs

1use crate::arch::{Trapframe, get_cpu};
2use crate::interrupt::InterruptManager;
3
4/// RISC-V S-mode interrupt causes
5const SUPERVISOR_SOFTWARE_INTERRUPT: usize = 1;
6const SUPERVISOR_TIMER_INTERRUPT: usize = 5;
7const SUPERVISOR_EXTERNAL_INTERRUPT: usize = 9;
8
9pub fn arch_interrupt_handler(trapframe: &mut Trapframe, cause: usize) {
10    match cause {
11        SUPERVISOR_SOFTWARE_INTERRUPT => handle_software_interrupt(),
12        SUPERVISOR_TIMER_INTERRUPT => handle_timer_interrupt(trapframe),
13        SUPERVISOR_EXTERNAL_INTERRUPT => handle_external_interrupt(trapframe),
14        _ => handle_unknown_interrupt(trapframe, cause),
15    }
16}
17
18/// Handle software interrupt (IPI)
19/// TODO: Implement inter-processor interrupt handling
20fn handle_software_interrupt() {
21    crate::early_println!("[interrupt] Software interrupt received - TODO: implement IPI");
22    // TODO: CLINT software interrupt handling
23    // TODO: Inter-processor interrupt (IPI) support
24}
25
26/// Handle timer interrupt from CLINT
27fn handle_timer_interrupt(trapframe: &mut Trapframe) {
28    // Increment the global tick counter
29    crate::timer::tick(trapframe);
30}
31
32/// Handle external interrupt from PLIC
33fn handle_external_interrupt(trapframe: &mut Trapframe) {
34    let cpu_id = get_cpu().get_cpuid() as u32;
35
36    // Claim and handle external interrupt through PLIC
37    match InterruptManager::with_manager(|mgr| mgr.claim_and_handle_external_interrupt(cpu_id)) {
38        Ok(Some(interrupt_id)) => {
39            // crate::early_println!("[interrupt] Handled external interrupt {} on CPU {}", interrupt_id, cpu_id);
40        }
41        Ok(None) => {
42            crate::early_println!(
43                "[interrupt] No pending external interrupt on CPU {}",
44                cpu_id
45            );
46        }
47        Err(e) => {
48            crate::early_println!("[interrupt] Failed to handle external interrupt: {}", e);
49        }
50    }
51}
52
53/// Handle unknown interrupt
54fn handle_unknown_interrupt(trapframe: &mut Trapframe, cause: usize) {
55    crate::early_println!("[interrupt] Unknown interrupt trapframe: {:x?}", trapframe);
56    panic!("Unknown interrupt cause: {}", cause);
57}