xref: /DragonOS/kernel/src/exception/mod.rs (revision f678331a3315b7847f08ab32b42d5bf49a9f3a6a)
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