xref: /DragonOS/kernel/src/exception/mod.rs (revision e28411791f090c421fe4b6fa5956fb1bd362a8d9)
1*e2841179SLoGin use core::ops::Add;
2*e2841179SLoGin 
3f2022a8aSLoGin use system_error::SystemError;
4f2022a8aSLoGin 
5f678331aShanjiezhou use crate::arch::CurrentIrqArch;
6f678331aShanjiezhou 
73bc96fa4SLoGin pub mod dummychip;
83bc96fa4SLoGin pub mod handle;
9f2022a8aSLoGin pub mod init;
10aa0367d6SLoGin pub mod ipi;
11ce5850adSLoGin pub mod irqchip;
12ce5850adSLoGin pub mod irqdata;
133bc96fa4SLoGin pub mod irqdesc;
14ce5850adSLoGin pub mod irqdomain;
15*e2841179SLoGin pub mod manage;
16ce5850adSLoGin pub mod msi;
17*e2841179SLoGin mod resend;
1862e46139SGou Ngai pub mod softirq;
193bc96fa4SLoGin pub mod sysfs;
20f678331aShanjiezhou 
21f2022a8aSLoGin /// 中断的架构相关的trait
22f678331aShanjiezhou pub trait InterruptArch: Send + Sync {
23f2022a8aSLoGin     /// 架构相关的中断初始化
24f2022a8aSLoGin     unsafe fn arch_irq_init() -> Result<(), SystemError>;
25f2022a8aSLoGin     /// 使能中断
26f678331aShanjiezhou     unsafe fn interrupt_enable();
27f2022a8aSLoGin     /// 禁止中断
28f678331aShanjiezhou     unsafe fn interrupt_disable();
29f2022a8aSLoGin     /// 检查中断是否被禁止
30f678331aShanjiezhou     fn is_irq_enabled() -> bool;
31f678331aShanjiezhou 
32f2022a8aSLoGin     /// 保存当前中断状态,并且禁止中断
33f678331aShanjiezhou     unsafe fn save_and_disable_irq() -> IrqFlagsGuard;
34f678331aShanjiezhou     unsafe fn restore_irq(flags: IrqFlags);
353bc96fa4SLoGin 
363bc96fa4SLoGin     /// 检测系统支持的中断总数
373bc96fa4SLoGin     fn probe_total_irq_num() -> u32;
383bc96fa4SLoGin 
393bc96fa4SLoGin     fn arch_early_irq_init() -> Result<(), SystemError> {
403bc96fa4SLoGin         Ok(())
413bc96fa4SLoGin     }
423bc96fa4SLoGin 
433bc96fa4SLoGin     /// 响应未注册的中断
443bc96fa4SLoGin     fn ack_bad_irq(irq: IrqNumber);
45f678331aShanjiezhou }
46f678331aShanjiezhou 
47f678331aShanjiezhou #[derive(Debug, Clone, Copy)]
48f678331aShanjiezhou pub struct IrqFlags {
4940fe15e0SLoGin     flags: usize,
50f678331aShanjiezhou }
51f678331aShanjiezhou 
52f678331aShanjiezhou impl IrqFlags {
5340fe15e0SLoGin     pub fn new(flags: usize) -> Self {
54f678331aShanjiezhou         IrqFlags { flags }
55f678331aShanjiezhou     }
56f678331aShanjiezhou 
5740fe15e0SLoGin     pub fn flags(&self) -> usize {
58f678331aShanjiezhou         self.flags
59f678331aShanjiezhou     }
60f678331aShanjiezhou }
61f678331aShanjiezhou 
62f678331aShanjiezhou /// @brief 当前中断状态的保护器,当该对象被drop时,会恢复之前的中断状态
63f678331aShanjiezhou ///
64f678331aShanjiezhou /// # Example
65f678331aShanjiezhou ///
66f678331aShanjiezhou /// ```
67f678331aShanjiezhou /// use crate::arch::CurrentIrqArch;
68f678331aShanjiezhou ///
69f678331aShanjiezhou /// // disable irq and save irq state (这是唯一的获取IrqFlagsGuard的方法)
70f678331aShanjiezhou /// let guard = unsafe{CurrentIrqArch::save_and_disable_irq()};
71f678331aShanjiezhou ///
72f678331aShanjiezhou /// // do something
73f678331aShanjiezhou ///
74f678331aShanjiezhou /// // 销毁guard时,会恢复之前的中断状态
75f678331aShanjiezhou /// drop(guard);
76f678331aShanjiezhou ///
77f678331aShanjiezhou /// ```
78f678331aShanjiezhou #[derive(Debug)]
79f678331aShanjiezhou pub struct IrqFlagsGuard {
80f678331aShanjiezhou     flags: IrqFlags,
81f678331aShanjiezhou }
82f678331aShanjiezhou 
83f678331aShanjiezhou impl IrqFlagsGuard {
84f678331aShanjiezhou     /// @brief 创建IrqFlagsGuard对象
85f678331aShanjiezhou     ///
86f678331aShanjiezhou     /// # Safety
87f678331aShanjiezhou     ///
88f678331aShanjiezhou     /// 该函数不安全,因为它不会检查flags是否是一个有效的IrqFlags对象, 而当它被drop时,会恢复flags中的中断状态
89f678331aShanjiezhou     ///
90f678331aShanjiezhou     /// 该函数只应被`CurrentIrqArch::save_and_disable_irq`调用
91f678331aShanjiezhou     pub unsafe fn new(flags: IrqFlags) -> Self {
92f678331aShanjiezhou         IrqFlagsGuard { flags }
93f678331aShanjiezhou     }
94f678331aShanjiezhou }
95f678331aShanjiezhou impl Drop for IrqFlagsGuard {
96f678331aShanjiezhou     fn drop(&mut self) {
97f678331aShanjiezhou         unsafe {
98f678331aShanjiezhou             CurrentIrqArch::restore_irq(self.flags);
99f678331aShanjiezhou         }
100f678331aShanjiezhou     }
101f678331aShanjiezhou }
102ce5850adSLoGin 
103ce5850adSLoGin // 定义中断号结构体
104ce5850adSLoGin // 用于表示软件逻辑视角的中断号,全局唯一
105ce5850adSLoGin int_like!(IrqNumber, u32);
106ce5850adSLoGin 
107*e2841179SLoGin impl IrqNumber {
108*e2841179SLoGin     /// 如果一个(PCI)设备中断没有被连接,我们将设置irqnumber为IRQ_NOTCONNECTED。
109*e2841179SLoGin     /// 这导致request_irq()失败,返回-ENOTCONN,这样我们就可以区分这种情况和其他错误返回。
110*e2841179SLoGin     pub const IRQ_NOTCONNECTED: IrqNumber = IrqNumber::new(u32::MAX);
111*e2841179SLoGin }
112*e2841179SLoGin 
113ce5850adSLoGin // 硬件中断号
114ce5850adSLoGin // 用于表示在某个IrqDomain中的中断号
115ce5850adSLoGin int_like!(HardwareIrqNumber, u32);
116*e2841179SLoGin 
117*e2841179SLoGin impl Add<u32> for HardwareIrqNumber {
118*e2841179SLoGin     type Output = HardwareIrqNumber;
119*e2841179SLoGin 
120*e2841179SLoGin     fn add(self, rhs: u32) -> HardwareIrqNumber {
121*e2841179SLoGin         HardwareIrqNumber::new(self.0 + rhs)
122*e2841179SLoGin     }
123*e2841179SLoGin }
124*e2841179SLoGin 
125*e2841179SLoGin impl Add<u32> for IrqNumber {
126*e2841179SLoGin     type Output = IrqNumber;
127*e2841179SLoGin 
128*e2841179SLoGin     fn add(self, rhs: u32) -> IrqNumber {
129*e2841179SLoGin         IrqNumber::new(self.0 + rhs)
130*e2841179SLoGin     }
131*e2841179SLoGin }
132