1 use system_error::SystemError; 2 3 use crate::arch::CurrentIrqArch; 4 5 pub mod dummychip; 6 pub mod handle; 7 pub mod init; 8 pub mod ipi; 9 pub mod irqchip; 10 pub mod irqdata; 11 pub mod irqdesc; 12 pub mod irqdomain; 13 pub mod msi; 14 pub mod softirq; 15 pub mod sysfs; 16 17 /// 中断的架构相关的trait 18 pub trait InterruptArch: Send + Sync { 19 /// 架构相关的中断初始化 20 unsafe fn arch_irq_init() -> Result<(), SystemError>; 21 /// 使能中断 22 unsafe fn interrupt_enable(); 23 /// 禁止中断 24 unsafe fn interrupt_disable(); 25 /// 检查中断是否被禁止 26 fn is_irq_enabled() -> bool; 27 28 /// 保存当前中断状态,并且禁止中断 29 unsafe fn save_and_disable_irq() -> IrqFlagsGuard; 30 unsafe fn restore_irq(flags: IrqFlags); 31 32 /// 检测系统支持的中断总数 33 fn probe_total_irq_num() -> u32; 34 35 fn arch_early_irq_init() -> Result<(), SystemError> { 36 Ok(()) 37 } 38 39 /// 响应未注册的中断 40 fn ack_bad_irq(irq: IrqNumber); 41 } 42 43 #[derive(Debug, Clone, Copy)] 44 pub struct IrqFlags { 45 flags: usize, 46 } 47 48 impl IrqFlags { 49 pub fn new(flags: usize) -> Self { 50 IrqFlags { flags } 51 } 52 53 pub fn flags(&self) -> usize { 54 self.flags 55 } 56 } 57 58 /// @brief 当前中断状态的保护器,当该对象被drop时,会恢复之前的中断状态 59 /// 60 /// # Example 61 /// 62 /// ``` 63 /// use crate::arch::CurrentIrqArch; 64 /// 65 /// // disable irq and save irq state (这是唯一的获取IrqFlagsGuard的方法) 66 /// let guard = unsafe{CurrentIrqArch::save_and_disable_irq()}; 67 /// 68 /// // do something 69 /// 70 /// // 销毁guard时,会恢复之前的中断状态 71 /// drop(guard); 72 /// 73 /// ``` 74 #[derive(Debug)] 75 pub struct IrqFlagsGuard { 76 flags: IrqFlags, 77 } 78 79 impl IrqFlagsGuard { 80 /// @brief 创建IrqFlagsGuard对象 81 /// 82 /// # Safety 83 /// 84 /// 该函数不安全,因为它不会检查flags是否是一个有效的IrqFlags对象, 而当它被drop时,会恢复flags中的中断状态 85 /// 86 /// 该函数只应被`CurrentIrqArch::save_and_disable_irq`调用 87 pub unsafe fn new(flags: IrqFlags) -> Self { 88 IrqFlagsGuard { flags } 89 } 90 } 91 impl Drop for IrqFlagsGuard { 92 fn drop(&mut self) { 93 unsafe { 94 CurrentIrqArch::restore_irq(self.flags); 95 } 96 } 97 } 98 99 // 定义中断号结构体 100 // 用于表示软件逻辑视角的中断号,全局唯一 101 int_like!(IrqNumber, u32); 102 103 // 硬件中断号 104 // 用于表示在某个IrqDomain中的中断号 105 int_like!(HardwareIrqNumber, u32); 106