use core::sync::atomic::{AtomicUsize, Ordering};
#[cfg(feature = "ipi")]
pub use axconfig::devices::IPI_IRQ;
use axcpu::trap::{IRQ, register_trap_handler};
#[cfg(feature = "ipi")]
pub use axplat::irq::{IpiTarget, send_ipi};
pub use axplat::irq::{handle, register, set_enable, unregister};
static IRQ_HOOK: AtomicUsize = AtomicUsize::new(0);
pub fn register_irq_hook(hook: fn(usize)) -> bool {
IRQ_HOOK
.compare_exchange(
0,
hook as *const () as usize,
Ordering::Release,
Ordering::Relaxed,
)
.is_ok()
}
#[register_trap_handler(IRQ)]
pub fn irq_handler(vector: usize) -> bool {
let guard = kernel_guard::NoPreempt::new();
if let Some(irq) = handle(vector) {
let hook = IRQ_HOOK.load(Ordering::Acquire);
if hook != 0 {
let hook = unsafe { core::mem::transmute::<usize, fn(usize)>(hook) };
hook(irq);
}
}
drop(guard); true
}