1*e2841179SLoGin use core::ops::Add; 2*e2841179SLoGin 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; 15*e2841179SLoGin pub mod manage; 16ce5850adSLoGin pub mod msi; 17*e2841179SLoGin 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 433bc96fa4SLoGin /// 响应未注册的中断 443bc96fa4SLoGin fn ack_bad_irq(irq: IrqNumber); 45f678331aShanjiezhou } 46f678331aShanjiezhou 47f678331aShanjiezhou #[derive(Debug, Clone, Copy)] 48f678331aShanjiezhou pub struct IrqFlags { 4940fe15e0SLoGin flags: usize, 50f678331aShanjiezhou } 51f678331aShanjiezhou 52f678331aShanjiezhou impl IrqFlags { 5340fe15e0SLoGin pub fn new(flags: usize) -> Self { 54f678331aShanjiezhou IrqFlags { flags } 55f678331aShanjiezhou } 56f678331aShanjiezhou 5740fe15e0SLoGin pub fn flags(&self) -> usize { 58f678331aShanjiezhou self.flags 59f678331aShanjiezhou } 60f678331aShanjiezhou } 61f678331aShanjiezhou 62f678331aShanjiezhou /// @brief 当前中断状态的保护器,当该对象被drop时,会恢复之前的中断状态 63f678331aShanjiezhou /// 64f678331aShanjiezhou /// # Example 65f678331aShanjiezhou /// 66f678331aShanjiezhou /// ``` 67f678331aShanjiezhou /// use crate::arch::CurrentIrqArch; 68f678331aShanjiezhou /// 69f678331aShanjiezhou /// // disable irq and save irq state (这是唯一的获取IrqFlagsGuard的方法) 70f678331aShanjiezhou /// let guard = unsafe{CurrentIrqArch::save_and_disable_irq()}; 71f678331aShanjiezhou /// 72f678331aShanjiezhou /// // do something 73f678331aShanjiezhou /// 74f678331aShanjiezhou /// // 销毁guard时,会恢复之前的中断状态 75f678331aShanjiezhou /// drop(guard); 76f678331aShanjiezhou /// 77f678331aShanjiezhou /// ``` 78f678331aShanjiezhou #[derive(Debug)] 79f678331aShanjiezhou pub struct IrqFlagsGuard { 80f678331aShanjiezhou flags: IrqFlags, 81f678331aShanjiezhou } 82f678331aShanjiezhou 83f678331aShanjiezhou impl IrqFlagsGuard { 84f678331aShanjiezhou /// @brief 创建IrqFlagsGuard对象 85f678331aShanjiezhou /// 86f678331aShanjiezhou /// # Safety 87f678331aShanjiezhou /// 88f678331aShanjiezhou /// 该函数不安全,因为它不会检查flags是否是一个有效的IrqFlags对象, 而当它被drop时,会恢复flags中的中断状态 89f678331aShanjiezhou /// 90f678331aShanjiezhou /// 该函数只应被`CurrentIrqArch::save_and_disable_irq`调用 91f678331aShanjiezhou pub unsafe fn new(flags: IrqFlags) -> Self { 92f678331aShanjiezhou IrqFlagsGuard { flags } 93f678331aShanjiezhou } 94f678331aShanjiezhou } 95f678331aShanjiezhou impl Drop for IrqFlagsGuard { 96f678331aShanjiezhou fn drop(&mut self) { 97f678331aShanjiezhou unsafe { 98f678331aShanjiezhou CurrentIrqArch::restore_irq(self.flags); 99f678331aShanjiezhou } 100f678331aShanjiezhou } 101f678331aShanjiezhou } 102ce5850adSLoGin 103ce5850adSLoGin // 定义中断号结构体 104ce5850adSLoGin // 用于表示软件逻辑视角的中断号,全局唯一 105ce5850adSLoGin int_like!(IrqNumber, u32); 106ce5850adSLoGin 107*e2841179SLoGin impl IrqNumber { 108*e2841179SLoGin /// 如果一个(PCI)设备中断没有被连接,我们将设置irqnumber为IRQ_NOTCONNECTED。 109*e2841179SLoGin /// 这导致request_irq()失败,返回-ENOTCONN,这样我们就可以区分这种情况和其他错误返回。 110*e2841179SLoGin pub const IRQ_NOTCONNECTED: IrqNumber = IrqNumber::new(u32::MAX); 111*e2841179SLoGin } 112*e2841179SLoGin 113ce5850adSLoGin // 硬件中断号 114ce5850adSLoGin // 用于表示在某个IrqDomain中的中断号 115ce5850adSLoGin int_like!(HardwareIrqNumber, u32); 116*e2841179SLoGin 117*e2841179SLoGin impl Add<u32> for HardwareIrqNumber { 118*e2841179SLoGin type Output = HardwareIrqNumber; 119*e2841179SLoGin 120*e2841179SLoGin fn add(self, rhs: u32) -> HardwareIrqNumber { 121*e2841179SLoGin HardwareIrqNumber::new(self.0 + rhs) 122*e2841179SLoGin } 123*e2841179SLoGin } 124*e2841179SLoGin 125*e2841179SLoGin impl Add<u32> for IrqNumber { 126*e2841179SLoGin type Output = IrqNumber; 127*e2841179SLoGin 128*e2841179SLoGin fn add(self, rhs: u32) -> IrqNumber { 129*e2841179SLoGin IrqNumber::new(self.0 + rhs) 130*e2841179SLoGin } 131*e2841179SLoGin } 132