xref: /DragonOS/kernel/src/driver/virtio/irq.rs (revision 9fa0e95eeed8630a8a69c874090af2f10e8eee02)
1e2841179SLoGin use alloc::sync::Arc;
2e2841179SLoGin use hashbrown::HashMap;
3e2841179SLoGin use system_error::SystemError;
4e2841179SLoGin use unified_init::macros::unified_init;
5e2841179SLoGin 
60102d69fSLoGin use crate::{
70102d69fSLoGin     driver::base::device::DeviceId,
80102d69fSLoGin     exception::{
90102d69fSLoGin         irqdata::IrqHandlerData,
100102d69fSLoGin         irqdesc::{IrqHandler, IrqReturn},
110102d69fSLoGin         IrqNumber,
120102d69fSLoGin     },
130102d69fSLoGin     init::initcall::INITCALL_CORE,
140102d69fSLoGin     libs::rwlock::RwLock,
150102d69fSLoGin };
16e2841179SLoGin 
17e2841179SLoGin use super::VirtIODevice;
18e2841179SLoGin 
19e2841179SLoGin static mut VIRTIO_IRQ_MANAGER: Option<VirtIOIrqManager> = None;
20e2841179SLoGin 
21e2841179SLoGin #[inline(always)]
virtio_irq_manager() -> &'static VirtIOIrqManager22e2841179SLoGin pub fn virtio_irq_manager() -> &'static VirtIOIrqManager {
23e2841179SLoGin     unsafe { VIRTIO_IRQ_MANAGER.as_ref().unwrap() }
24e2841179SLoGin }
25e2841179SLoGin 
26e2841179SLoGin pub struct VirtIOIrqManager {
27e2841179SLoGin     map: RwLock<HashMap<Arc<DeviceId>, Arc<dyn VirtIODevice>>>,
28e2841179SLoGin }
29e2841179SLoGin 
30e2841179SLoGin impl VirtIOIrqManager {
new() -> Self31e2841179SLoGin     fn new() -> Self {
32e2841179SLoGin         VirtIOIrqManager {
33e2841179SLoGin             map: RwLock::new(HashMap::new()),
34e2841179SLoGin         }
35e2841179SLoGin     }
36e2841179SLoGin 
37e2841179SLoGin     /// 注册一个新的设备到virtio中断请求(IRQ)映射中。
38e2841179SLoGin     ///
39e2841179SLoGin     /// # 参数
40e2841179SLoGin     ///
41e2841179SLoGin     /// - `device` - 实现了 `VirtIODevice` trait 的设备对象,被封装在 `Arc` 智能指针中。
42e2841179SLoGin     ///
43e2841179SLoGin     /// # 返回值
44e2841179SLoGin     ///
45e2841179SLoGin     /// - 如果设备成功注册,返回 `Ok(())`。
46e2841179SLoGin     /// - 如果设备ID已经存在于映射中,返回 `Err(SystemError::EEXIST)`。
register_device(&self, device: Arc<dyn VirtIODevice>) -> Result<(), SystemError>47e2841179SLoGin     pub fn register_device(&self, device: Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
48e2841179SLoGin         let mut map = self.map.write_irqsave();
49e2841179SLoGin 
50e2841179SLoGin         if map.contains_key(device.dev_id()) {
51e2841179SLoGin             return Err(SystemError::EEXIST);
52e2841179SLoGin         }
53e2841179SLoGin 
54e2841179SLoGin         map.insert(device.dev_id().clone(), device);
55e2841179SLoGin 
56e2841179SLoGin         return Ok(());
57e2841179SLoGin     }
58e2841179SLoGin 
59e2841179SLoGin     /// 取消注册设备
60e2841179SLoGin     ///
61e2841179SLoGin     /// 这个函数会从内部映射中移除指定的设备。设备是通过设备ID来识别的。
62e2841179SLoGin     ///
63e2841179SLoGin     /// # 参数
64e2841179SLoGin     ///
65e2841179SLoGin     /// - `device` - 需要被取消注册的设备,它是一个实现了 `VirtIODevice` trait 的智能指针。
66e2841179SLoGin     #[allow(dead_code)]
unregister_device(&self, dev_id: &Arc<DeviceId>)67e2841179SLoGin     pub fn unregister_device(&self, dev_id: &Arc<DeviceId>) {
68e2841179SLoGin         let mut map = self.map.write_irqsave();
69e2841179SLoGin         map.remove(dev_id);
70e2841179SLoGin     }
71e2841179SLoGin 
72e2841179SLoGin     /// 查找并返回指定设备ID的设备。
73e2841179SLoGin     ///
74e2841179SLoGin     /// # 参数
75e2841179SLoGin     /// - `dev_id` - 我们要查找的设备的设备ID。
76e2841179SLoGin     ///
77e2841179SLoGin     /// # 返回
78e2841179SLoGin     /// - 如果找到了设备,返回一个包含设备的`Option<Arc<dyn VirtIODevice>>`。
79e2841179SLoGin     /// - 如果没有找到设备,返回`None`。
80e2841179SLoGin 
lookup_device(&self, dev_id: &Arc<DeviceId>) -> Option<Arc<dyn VirtIODevice>>81e2841179SLoGin     pub fn lookup_device(&self, dev_id: &Arc<DeviceId>) -> Option<Arc<dyn VirtIODevice>> {
82e2841179SLoGin         let map = self.map.read_irqsave();
83b5b571e0SLoGin         map.get(dev_id).cloned()
84e2841179SLoGin     }
85e2841179SLoGin }
86e2841179SLoGin 
87e2841179SLoGin #[unified_init(INITCALL_CORE)]
init_virtio_irq_manager() -> Result<(), SystemError>88e2841179SLoGin fn init_virtio_irq_manager() -> Result<(), SystemError> {
89e2841179SLoGin     let manager = VirtIOIrqManager::new();
90e2841179SLoGin     unsafe {
91e2841179SLoGin         VIRTIO_IRQ_MANAGER = Some(manager);
92e2841179SLoGin     }
93e2841179SLoGin     return Ok(());
94e2841179SLoGin }
950102d69fSLoGin 
960102d69fSLoGin /// `DefaultVirtioIrqHandler` 是一个默认的virtio设备中断处理程序。
970102d69fSLoGin ///
980102d69fSLoGin /// 当虚拟设备产生中断时,该处理程序会被调用。
990102d69fSLoGin ///
1000102d69fSLoGin /// 它首先检查设备ID是否存在,然后尝试查找与设备ID关联的设备。
1010102d69fSLoGin /// 如果找到设备,它会调用设备的 `handle_irq` 方法来处理中断。
1020102d69fSLoGin /// 如果没有找到设备,它会记录一条警告并返回 `IrqReturn::NotHandled`,表示中断未被处理。
1030102d69fSLoGin #[derive(Debug)]
1040102d69fSLoGin pub(super) struct DefaultVirtioIrqHandler;
1050102d69fSLoGin 
1060102d69fSLoGin impl IrqHandler for DefaultVirtioIrqHandler {
handle( &self, irq: IrqNumber, _static_data: Option<&dyn IrqHandlerData>, dev_id: Option<Arc<dyn IrqHandlerData>>, ) -> Result<IrqReturn, SystemError>1070102d69fSLoGin     fn handle(
1080102d69fSLoGin         &self,
1090102d69fSLoGin         irq: IrqNumber,
1100102d69fSLoGin         _static_data: Option<&dyn IrqHandlerData>,
1110102d69fSLoGin         dev_id: Option<Arc<dyn IrqHandlerData>>,
1120102d69fSLoGin     ) -> Result<IrqReturn, SystemError> {
1130102d69fSLoGin         let dev_id = dev_id.ok_or(SystemError::EINVAL)?;
1140102d69fSLoGin         let dev_id = dev_id
1150102d69fSLoGin             .arc_any()
1160102d69fSLoGin             .downcast::<DeviceId>()
1170102d69fSLoGin             .map_err(|_| SystemError::EINVAL)?;
1180102d69fSLoGin 
1190102d69fSLoGin         if let Some(dev) = virtio_irq_manager().lookup_device(&dev_id) {
1200102d69fSLoGin             return dev.handle_irq(irq);
1210102d69fSLoGin         } else {
1220102d69fSLoGin             // 未绑定具体设备,因此无法处理中断
123*9fa0e95eSLoGin             // warn!("No device found for IRQ: {:?}", irq);
1240102d69fSLoGin             return Ok(IrqReturn::NotHandled);
1250102d69fSLoGin         }
1260102d69fSLoGin     }
1270102d69fSLoGin }
128