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