xref: /DragonOS/kernel/src/driver/virtio/irq.rs (revision 911132c4b8ea0e9c49a4e84b9fa1db114102acbb)
1 use alloc::sync::Arc;
2 use hashbrown::HashMap;
3 use system_error::SystemError;
4 use unified_init::macros::unified_init;
5 
6 use crate::{driver::base::device::DeviceId, init::initcall::INITCALL_CORE, libs::rwlock::RwLock};
7 
8 use super::VirtIODevice;
9 
10 static mut VIRTIO_IRQ_MANAGER: Option<VirtIOIrqManager> = None;
11 
12 #[inline(always)]
13 pub fn virtio_irq_manager() -> &'static VirtIOIrqManager {
14     unsafe { VIRTIO_IRQ_MANAGER.as_ref().unwrap() }
15 }
16 
17 pub struct VirtIOIrqManager {
18     map: RwLock<HashMap<Arc<DeviceId>, Arc<dyn VirtIODevice>>>,
19 }
20 
21 impl VirtIOIrqManager {
22     fn new() -> Self {
23         VirtIOIrqManager {
24             map: RwLock::new(HashMap::new()),
25         }
26     }
27 
28     /// 注册一个新的设备到virtio中断请求(IRQ)映射中。
29     ///
30     /// # 参数
31     ///
32     /// - `device` - 实现了 `VirtIODevice` trait 的设备对象,被封装在 `Arc` 智能指针中。
33     ///
34     /// # 返回值
35     ///
36     /// - 如果设备成功注册,返回 `Ok(())`。
37     /// - 如果设备ID已经存在于映射中,返回 `Err(SystemError::EEXIST)`。
38     pub fn register_device(&self, device: Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
39         let mut map = self.map.write_irqsave();
40 
41         if map.contains_key(device.dev_id()) {
42             return Err(SystemError::EEXIST);
43         }
44 
45         map.insert(device.dev_id().clone(), device);
46 
47         return Ok(());
48     }
49 
50     /// 取消注册设备
51     ///
52     /// 这个函数会从内部映射中移除指定的设备。设备是通过设备ID来识别的。
53     ///
54     /// # 参数
55     ///
56     /// - `device` - 需要被取消注册的设备,它是一个实现了 `VirtIODevice` trait 的智能指针。
57     #[allow(dead_code)]
58     pub fn unregister_device(&self, dev_id: &Arc<DeviceId>) {
59         let mut map = self.map.write_irqsave();
60         map.remove(dev_id);
61     }
62 
63     /// 查找并返回指定设备ID的设备。
64     ///
65     /// # 参数
66     /// - `dev_id` - 我们要查找的设备的设备ID。
67     ///
68     /// # 返回
69     /// - 如果找到了设备,返回一个包含设备的`Option<Arc<dyn VirtIODevice>>`。
70     /// - 如果没有找到设备,返回`None`。
71 
72     pub fn lookup_device(&self, dev_id: &Arc<DeviceId>) -> Option<Arc<dyn VirtIODevice>> {
73         let map = self.map.read_irqsave();
74         map.get(dev_id).cloned()
75     }
76 }
77 
78 #[unified_init(INITCALL_CORE)]
79 fn init_virtio_irq_manager() -> Result<(), SystemError> {
80     let manager = VirtIOIrqManager::new();
81     unsafe {
82         VIRTIO_IRQ_MANAGER = Some(manager);
83     }
84     return Ok(());
85 }
86