xref: /DragonOS/kernel/src/exception/mod.rs (revision ce5850adbf74ec6c6717bbb5b1749f1fbff4ca0d)
1f2022a8aSLoGin use system_error::SystemError;
2f2022a8aSLoGin 
3f678331aShanjiezhou use crate::arch::CurrentIrqArch;
4f678331aShanjiezhou 
5f2022a8aSLoGin pub mod init;
6aa0367d6SLoGin pub mod ipi;
7*ce5850adSLoGin pub mod irqchip;
8*ce5850adSLoGin pub mod irqdata;
9*ce5850adSLoGin pub mod irqdomain;
10*ce5850adSLoGin pub mod msi;
1162e46139SGou Ngai pub mod softirq;
12f678331aShanjiezhou 
13f2022a8aSLoGin /// 中断的架构相关的trait
14f678331aShanjiezhou pub trait InterruptArch: Send + Sync {
15f2022a8aSLoGin     /// 架构相关的中断初始化
16f2022a8aSLoGin     unsafe fn arch_irq_init() -> Result<(), SystemError>;
17f2022a8aSLoGin     /// 使能中断
18f678331aShanjiezhou     unsafe fn interrupt_enable();
19f2022a8aSLoGin     /// 禁止中断
20f678331aShanjiezhou     unsafe fn interrupt_disable();
21f2022a8aSLoGin     /// 检查中断是否被禁止
22f678331aShanjiezhou     fn is_irq_enabled() -> bool;
23f678331aShanjiezhou 
24f2022a8aSLoGin     /// 保存当前中断状态,并且禁止中断
25f678331aShanjiezhou     unsafe fn save_and_disable_irq() -> IrqFlagsGuard;
26f678331aShanjiezhou     unsafe fn restore_irq(flags: IrqFlags);
27f678331aShanjiezhou }
28f678331aShanjiezhou 
29f678331aShanjiezhou #[derive(Debug, Clone, Copy)]
30f678331aShanjiezhou pub struct IrqFlags {
3140fe15e0SLoGin     flags: usize,
32f678331aShanjiezhou }
33f678331aShanjiezhou 
34f678331aShanjiezhou impl IrqFlags {
3540fe15e0SLoGin     pub fn new(flags: usize) -> Self {
36f678331aShanjiezhou         IrqFlags { flags }
37f678331aShanjiezhou     }
38f678331aShanjiezhou 
3940fe15e0SLoGin     pub fn flags(&self) -> usize {
40f678331aShanjiezhou         self.flags
41f678331aShanjiezhou     }
42f678331aShanjiezhou }
43f678331aShanjiezhou 
44f678331aShanjiezhou /// @brief 当前中断状态的保护器,当该对象被drop时,会恢复之前的中断状态
45f678331aShanjiezhou ///
46f678331aShanjiezhou /// # Example
47f678331aShanjiezhou ///
48f678331aShanjiezhou /// ```
49f678331aShanjiezhou /// use crate::arch::CurrentIrqArch;
50f678331aShanjiezhou ///
51f678331aShanjiezhou /// // disable irq and save irq state (这是唯一的获取IrqFlagsGuard的方法)
52f678331aShanjiezhou /// let guard = unsafe{CurrentIrqArch::save_and_disable_irq()};
53f678331aShanjiezhou ///
54f678331aShanjiezhou /// // do something
55f678331aShanjiezhou ///
56f678331aShanjiezhou /// // 销毁guard时,会恢复之前的中断状态
57f678331aShanjiezhou /// drop(guard);
58f678331aShanjiezhou ///
59f678331aShanjiezhou /// ```
60f678331aShanjiezhou #[derive(Debug)]
61f678331aShanjiezhou pub struct IrqFlagsGuard {
62f678331aShanjiezhou     flags: IrqFlags,
63f678331aShanjiezhou }
64f678331aShanjiezhou 
65f678331aShanjiezhou impl IrqFlagsGuard {
66f678331aShanjiezhou     /// @brief 创建IrqFlagsGuard对象
67f678331aShanjiezhou     ///
68f678331aShanjiezhou     /// # Safety
69f678331aShanjiezhou     ///
70f678331aShanjiezhou     /// 该函数不安全,因为它不会检查flags是否是一个有效的IrqFlags对象, 而当它被drop时,会恢复flags中的中断状态
71f678331aShanjiezhou     ///
72f678331aShanjiezhou     /// 该函数只应被`CurrentIrqArch::save_and_disable_irq`调用
73f678331aShanjiezhou     pub unsafe fn new(flags: IrqFlags) -> Self {
74f678331aShanjiezhou         IrqFlagsGuard { flags }
75f678331aShanjiezhou     }
76f678331aShanjiezhou }
77f678331aShanjiezhou impl Drop for IrqFlagsGuard {
78f678331aShanjiezhou     fn drop(&mut self) {
79f678331aShanjiezhou         unsafe {
80f678331aShanjiezhou             CurrentIrqArch::restore_irq(self.flags);
81f678331aShanjiezhou         }
82f678331aShanjiezhou     }
83f678331aShanjiezhou }
84*ce5850adSLoGin 
85*ce5850adSLoGin // 定义中断号结构体
86*ce5850adSLoGin // 用于表示软件逻辑视角的中断号,全局唯一
87*ce5850adSLoGin int_like!(IrqNumber, u32);
88*ce5850adSLoGin 
89*ce5850adSLoGin // 硬件中断号
90*ce5850adSLoGin // 用于表示在某个IrqDomain中的中断号
91*ce5850adSLoGin int_like!(HardwareIrqNumber, u32);
92