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