interrupt.rs 785 B

123456789101112131415161718192021222324252627282930313233343536
  1. use alloc::boxed::Box;
  2. use alloc::vec;
  3. use alloc::vec::Vec;
  4. use lazy_static::lazy_static;
  5. use crate::bindings::root::EINVAL;
  6. use crate::Spin;
  7. lazy_static! {
  8. static ref IRQ_HANDLERS: Spin<[Vec<Box<dyn Fn() + Send>>; 16]> =
  9. Spin::new(core::array::from_fn(|_| vec![]));
  10. }
  11. #[no_mangle]
  12. pub extern "C" fn irq_handler_rust(irqno: core::ffi::c_int) {
  13. assert!(irqno >= 0 && irqno < 16);
  14. let handlers = IRQ_HANDLERS.lock();
  15. for handler in handlers[irqno as usize].iter() {
  16. handler();
  17. }
  18. }
  19. pub fn register_irq_handler<F>(irqno: i32, handler: F) -> Result<(), u32>
  20. where
  21. F: Fn() + Send + 'static,
  22. {
  23. if irqno < 0 || irqno >= 16 {
  24. return Err(EINVAL);
  25. }
  26. IRQ_HANDLERS.lock_irq()[irqno as usize].push(Box::new(handler));
  27. Ok(())
  28. }