1 use core::ops::Add; 2 3 use system_error::SystemError; 4 5 use crate::arch::CurrentIrqArch; 6 7 pub mod dummychip; 8 pub mod handle; 9 pub mod init; 10 pub mod ipi; 11 pub mod irqchip; 12 pub mod irqdata; 13 pub mod irqdesc; 14 pub mod irqdomain; 15 pub mod manage; 16 pub mod msi; 17 mod resend; 18 pub mod softirq; 19 pub mod sysfs; 20 21 /// 中断的架构相关的trait 22 pub trait InterruptArch: Send + Sync { 23 /// 架构相关的中断初始化 24 unsafe fn arch_irq_init() -> Result<(), SystemError>; 25 /// 使能中断 26 unsafe fn interrupt_enable(); 27 /// 禁止中断 28 unsafe fn interrupt_disable(); 29 /// 检查中断是否被禁止 30 fn is_irq_enabled() -> bool; 31 32 /// 保存当前中断状态,并且禁止中断 33 unsafe fn save_and_disable_irq() -> IrqFlagsGuard; 34 unsafe fn restore_irq(flags: IrqFlags); 35 36 /// 检测系统支持的中断总数 37 fn probe_total_irq_num() -> u32; 38 39 fn arch_early_irq_init() -> Result<(), SystemError> { 40 Ok(()) 41 } 42 43 /// ap启动时的中断初始化 44 fn arch_ap_early_irq_init() -> Result<(), SystemError> { 45 Ok(()) 46 } 47 48 /// 响应未注册的中断 49 fn ack_bad_irq(irq: IrqNumber); 50 } 51 52 #[derive(Debug, Clone, Copy)] 53 pub struct IrqFlags { 54 flags: usize, 55 } 56 57 impl IrqFlags { 58 pub fn new(flags: usize) -> Self { 59 IrqFlags { flags } 60 } 61 62 pub fn flags(&self) -> usize { 63 self.flags 64 } 65 } 66 67 /// @brief 当前中断状态的保护器,当该对象被drop时,会恢复之前的中断状态 68 /// 69 /// # Example 70 /// 71 /// ``` 72 /// use crate::arch::CurrentIrqArch; 73 /// 74 /// // disable irq and save irq state (这是唯一的获取IrqFlagsGuard的方法) 75 /// let guard = unsafe{CurrentIrqArch::save_and_disable_irq()}; 76 /// 77 /// // do something 78 /// 79 /// // 销毁guard时,会恢复之前的中断状态 80 /// drop(guard); 81 /// 82 /// ``` 83 #[derive(Debug)] 84 pub struct IrqFlagsGuard { 85 flags: IrqFlags, 86 } 87 88 impl IrqFlagsGuard { 89 /// @brief 创建IrqFlagsGuard对象 90 /// 91 /// # Safety 92 /// 93 /// 该函数不安全,因为它不会检查flags是否是一个有效的IrqFlags对象, 而当它被drop时,会恢复flags中的中断状态 94 /// 95 /// 该函数只应被`CurrentIrqArch::save_and_disable_irq`调用 96 pub unsafe fn new(flags: IrqFlags) -> Self { 97 IrqFlagsGuard { flags } 98 } 99 } 100 impl Drop for IrqFlagsGuard { 101 fn drop(&mut self) { 102 unsafe { 103 CurrentIrqArch::restore_irq(self.flags); 104 } 105 } 106 } 107 108 // 定义中断号结构体 109 // 用于表示软件逻辑视角的中断号,全局唯一 110 int_like!(IrqNumber, u32); 111 112 impl IrqNumber { 113 /// 如果一个(PCI)设备中断没有被连接,我们将设置irqnumber为IRQ_NOTCONNECTED。 114 /// 这导致request_irq()失败,返回-ENOTCONN,这样我们就可以区分这种情况和其他错误返回。 115 pub const IRQ_NOTCONNECTED: IrqNumber = IrqNumber::new(u32::MAX); 116 } 117 118 // 硬件中断号 119 // 用于表示在某个IrqDomain中的中断号 120 int_like!(HardwareIrqNumber, u32); 121 122 impl Add<u32> for HardwareIrqNumber { 123 type Output = HardwareIrqNumber; 124 125 fn add(self, rhs: u32) -> HardwareIrqNumber { 126 HardwareIrqNumber::new(self.0 + rhs) 127 } 128 } 129 130 impl Add<u32> for IrqNumber { 131 type Output = IrqNumber; 132 133 fn add(self, rhs: u32) -> IrqNumber { 134 IrqNumber::new(self.0 + rhs) 135 } 136 } 137