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