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