1use linkme::distributed_slice as def_trap_handler;
4use memory_addr::VirtAddr;
5use page_table_entry::MappingFlags;
6
7pub use linkme::distributed_slice as register_trap_handler;
8
9use crate::arch::TrapFrame;
10
11#[def_trap_handler]
13pub static IRQ: [fn(usize) -> bool];
14
15#[def_trap_handler]
17pub static PAGE_FAULT: [fn(VirtAddr, MappingFlags, bool) -> bool];
18
19#[cfg(feature = "uspace")]
21#[def_trap_handler]
22pub static SYSCALL: [fn(&mut TrapFrame, usize) -> isize];
23
24#[linkme::distributed_slice]
26pub static POST_TRAP: [fn(&mut TrapFrame, bool)];
27
28#[allow(unused_macros)]
29macro_rules! handle_trap {
30 ($trap:ident, $($args:tt)*) => {{
31 let mut iter = $crate::trap::$trap.iter();
32 if let Some(func) = iter.next() {
33 if iter.next().is_some() {
34 warn!("Multiple handlers for trap {} are not currently supported", stringify!($trap));
35 }
36 func($($args)*)
37 } else {
38 warn!("No registered handler for trap {}", stringify!($trap));
39 false
40 }
41 }}
42}
43
44#[unsafe(no_mangle)]
45pub(crate) fn post_trap_callback(tf: &mut TrapFrame, from_user: bool) {
46 for cb in crate::trap::POST_TRAP.iter() {
47 cb(tf, from_user);
48 }
49}
50
51#[cfg(feature = "uspace")]
53pub(crate) fn handle_syscall(tf: &mut TrapFrame, syscall_num: usize) -> isize {
54 SYSCALL[0](tf, syscall_num)
55}