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