os/device/irq/
mod.rs

1//! 中断管理模块
2//!
3//! 包含中断管理器和中断控制器驱动接口的定义
4
5use alloc::{
6    collections::btree_map::{BTreeMap, Entry},
7    sync::Arc,
8    vec::Vec,
9};
10
11pub mod plic;
12
13use crate::{arch::intr::enable_irq, device::Driver};
14
15/// 中断管理器结构体
16pub struct IrqManager {
17    /// 是否为根中断管理器
18    root: bool,
19    /// 中断号到驱动程序列表的映射
20    /// 每个中断号可以对应多个驱动程序
21    mapping: BTreeMap<usize, Vec<Arc<dyn Driver>>>,
22    /// 全局驱动程序列表
23    /// 这些驱动程序会处理所有中断
24    all: Vec<Arc<dyn Driver>>,
25}
26
27impl IrqManager {
28    /// 创建一个新的中断管理器
29    /// # 参数:
30    /// * `root` - 是否为根中断管理器
31    /// # 返回值:
32    /// 新创建的中断管理器实例
33    pub fn new(root: bool) -> IrqManager {
34        IrqManager {
35            root,
36            mapping: BTreeMap::new(),
37            all: Vec::new(),
38        }
39    }
40
41    /// 注册中断号与驱动程序的映射
42    /// # 参数:
43    /// * `irq` - 中断号
44    /// * `driver` - 要注册的驱动程序
45    pub fn register_irq(&mut self, irq: usize, driver: Arc<dyn Driver>) {
46        // 对于根中断管理器,在架构层启用中断
47        // 对于其他中断控制器,在调用此函数之前启用中断
48        if self.root {
49            enable_irq(irq);
50        }
51        match self.mapping.entry(irq) {
52            Entry::Occupied(mut e) => {
53                e.get_mut().push(driver);
54            }
55            Entry::Vacant(e) => {
56                let mut v = Vec::new();
57                v.push(driver);
58                e.insert(v);
59            }
60        }
61    }
62
63    /// 注册全局驱动程序
64    /// # 参数:
65    /// * `driver` - 要注册的驱动程序
66    pub fn register_all(&mut self, driver: Arc<dyn Driver>) {
67        self.all.push(driver);
68    }
69
70    /// 注册可选的中断号与驱动程序的映射
71    /// # 参数:
72    /// * `irq_opt` - 可选的中断号
73    /// * `driver` - 要注册的驱动程序
74    pub fn register_opt(&mut self, irq_opt: Option<usize>, driver: Arc<dyn Driver>) {
75        if let Some(irq) = irq_opt {
76            self.register_irq(irq, driver);
77        } else {
78            self.register_all(driver);
79        }
80    }
81
82    /// 注销中断号与驱动程序的映射
83    /// # 参数:
84    /// * `irq` - 要注销的中断号
85    /// * `driver` - 要注销的驱动程序
86    pub fn deregister_irq(&mut self, irq: usize, driver: Arc<dyn Driver>) {
87        if let Some(e) = self.mapping.get_mut(&irq) {
88            e.retain(|d| !Arc::ptr_eq(d, &driver));
89        }
90    }
91
92    /// 注销全局驱动程序
93    /// # 参数:
94    /// * `driver` - 要注销的驱动程序
95    pub fn deregister_all(&mut self, driver: Arc<dyn Driver>) {
96        self.all.retain(|d| !Arc::ptr_eq(d, &driver));
97    }
98
99    /// 处理中断
100    /// # 参数:
101    /// * `irq_opt` - 可选的中断号
102    /// # 返回值:
103    /// 如果中断被处理则返回 true,否则返回 false
104    pub fn try_handle_interrupt(&self, irq_opt: Option<usize>) -> bool {
105        if let Some(irq) = irq_opt {
106            if let Some(e) = self.mapping.get(&irq) {
107                for dri in e.iter() {
108                    if dri.try_handle_interrupt(Some(irq)) {
109                        return true;
110                    }
111                }
112            }
113        }
114
115        for dri in self.all.iter() {
116            if dri.try_handle_interrupt(irq_opt) {
117                return true;
118            }
119        }
120        false
121    }
122}
123
124/// 中断控制器驱动接口
125pub trait IntcDriver: Driver {
126    /// 注册本地中断处理程序
127    /// # 参数:
128    /// * `irq` - 中断号
129    /// * `driver` - 要注册的驱动程序
130    fn register_local_irq(&self, irq: usize, driver: Arc<dyn Driver>);
131}