1*f678331aShanjiezhou use crate::arch::CurrentIrqArch; 2*f678331aShanjiezhou 362e46139SGou Ngai pub mod softirq; 4*f678331aShanjiezhou 5*f678331aShanjiezhou /// @brief 中断相关的操作 6*f678331aShanjiezhou pub trait InterruptArch: Send + Sync { 7*f678331aShanjiezhou /// @brief 使能中断 8*f678331aShanjiezhou unsafe fn interrupt_enable(); 9*f678331aShanjiezhou /// @brief 禁止中断 10*f678331aShanjiezhou unsafe fn interrupt_disable(); 11*f678331aShanjiezhou /// @brief 检查中断是否被禁止 12*f678331aShanjiezhou fn is_irq_enabled() -> bool; 13*f678331aShanjiezhou 14*f678331aShanjiezhou /// @brief 保存当前中断状态,并且禁止中断 15*f678331aShanjiezhou unsafe fn save_and_disable_irq() -> IrqFlagsGuard; 16*f678331aShanjiezhou unsafe fn restore_irq(flags: IrqFlags); 17*f678331aShanjiezhou } 18*f678331aShanjiezhou 19*f678331aShanjiezhou #[derive(Debug, Clone, Copy)] 20*f678331aShanjiezhou pub struct IrqFlags { 21*f678331aShanjiezhou flags: u64, 22*f678331aShanjiezhou } 23*f678331aShanjiezhou 24*f678331aShanjiezhou impl IrqFlags { 25*f678331aShanjiezhou pub fn new(flags: u64) -> Self { 26*f678331aShanjiezhou IrqFlags { flags } 27*f678331aShanjiezhou } 28*f678331aShanjiezhou 29*f678331aShanjiezhou pub fn flags(&self) -> u64 { 30*f678331aShanjiezhou self.flags 31*f678331aShanjiezhou } 32*f678331aShanjiezhou } 33*f678331aShanjiezhou 34*f678331aShanjiezhou /// @brief 当前中断状态的保护器,当该对象被drop时,会恢复之前的中断状态 35*f678331aShanjiezhou /// 36*f678331aShanjiezhou /// # Example 37*f678331aShanjiezhou /// 38*f678331aShanjiezhou /// ``` 39*f678331aShanjiezhou /// use crate::arch::CurrentIrqArch; 40*f678331aShanjiezhou /// 41*f678331aShanjiezhou /// // disable irq and save irq state (这是唯一的获取IrqFlagsGuard的方法) 42*f678331aShanjiezhou /// let guard = unsafe{CurrentIrqArch::save_and_disable_irq()}; 43*f678331aShanjiezhou /// 44*f678331aShanjiezhou /// // do something 45*f678331aShanjiezhou /// 46*f678331aShanjiezhou /// // 销毁guard时,会恢复之前的中断状态 47*f678331aShanjiezhou /// drop(guard); 48*f678331aShanjiezhou /// 49*f678331aShanjiezhou /// ``` 50*f678331aShanjiezhou #[derive(Debug)] 51*f678331aShanjiezhou pub struct IrqFlagsGuard { 52*f678331aShanjiezhou flags: IrqFlags, 53*f678331aShanjiezhou } 54*f678331aShanjiezhou 55*f678331aShanjiezhou impl IrqFlagsGuard { 56*f678331aShanjiezhou /// @brief 创建IrqFlagsGuard对象 57*f678331aShanjiezhou /// 58*f678331aShanjiezhou /// # Safety 59*f678331aShanjiezhou /// 60*f678331aShanjiezhou /// 该函数不安全,因为它不会检查flags是否是一个有效的IrqFlags对象, 而当它被drop时,会恢复flags中的中断状态 61*f678331aShanjiezhou /// 62*f678331aShanjiezhou /// 该函数只应被`CurrentIrqArch::save_and_disable_irq`调用 63*f678331aShanjiezhou pub unsafe fn new(flags: IrqFlags) -> Self { 64*f678331aShanjiezhou IrqFlagsGuard { flags } 65*f678331aShanjiezhou } 66*f678331aShanjiezhou } 67*f678331aShanjiezhou impl Drop for IrqFlagsGuard { 68*f678331aShanjiezhou fn drop(&mut self) { 69*f678331aShanjiezhou unsafe { 70*f678331aShanjiezhou CurrentIrqArch::restore_irq(self.flags); 71*f678331aShanjiezhou } 72*f678331aShanjiezhou } 73*f678331aShanjiezhou } 74