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