axhal/
trap.rs

1//! Trap handling.
2
3use linkme::distributed_slice as def_trap_handler;
4use memory_addr::VirtAddr;
5use page_table_entry::MappingFlags;
6
7#[cfg(feature = "uspace")]
8use crate::arch::TrapFrame;
9
10pub use linkme::distributed_slice as register_trap_handler;
11
12/// A slice of IRQ handler functions.
13#[def_trap_handler]
14pub static IRQ: [fn(usize) -> bool];
15
16/// A slice of page fault handler functions.
17#[def_trap_handler]
18pub static PAGE_FAULT: [fn(VirtAddr, MappingFlags, bool) -> bool];
19
20/// A slice of syscall handler functions.
21#[cfg(feature = "uspace")]
22#[def_trap_handler]
23pub static SYSCALL: [fn(&TrapFrame, usize) -> isize];
24
25#[allow(unused_macros)]
26macro_rules! handle_trap {
27    ($trap:ident, $($args:tt)*) => {{
28        let mut iter = $crate::trap::$trap.iter();
29        if let Some(func) = iter.next() {
30            if iter.next().is_some() {
31                warn!("Multiple handlers for trap {} are not currently supported", stringify!($trap));
32            }
33            func($($args)*)
34        } else {
35            warn!("No registered handler for trap {}", stringify!($trap));
36            false
37        }
38    }}
39}
40
41/// Call the external syscall handler.
42#[cfg(feature = "uspace")]
43pub(crate) fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize {
44    SYSCALL[0](tf, syscall_num)
45}