1e2841179SLoGin use alloc::sync::Arc; 2e2841179SLoGin use hashbrown::HashMap; 3e2841179SLoGin use system_error::SystemError; 4e2841179SLoGin use unified_init::macros::unified_init; 5e2841179SLoGin 6*0102d69fSLoGin use crate::{ 7*0102d69fSLoGin driver::base::device::DeviceId, 8*0102d69fSLoGin exception::{ 9*0102d69fSLoGin irqdata::IrqHandlerData, 10*0102d69fSLoGin irqdesc::{IrqHandler, IrqReturn}, 11*0102d69fSLoGin IrqNumber, 12*0102d69fSLoGin }, 13*0102d69fSLoGin init::initcall::INITCALL_CORE, 14*0102d69fSLoGin libs::rwlock::RwLock, 15*0102d69fSLoGin }; 16e2841179SLoGin 17e2841179SLoGin use super::VirtIODevice; 18e2841179SLoGin 19e2841179SLoGin static mut VIRTIO_IRQ_MANAGER: Option<VirtIOIrqManager> = None; 20e2841179SLoGin 21e2841179SLoGin #[inline(always)] 22e2841179SLoGin 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 { 31e2841179SLoGin 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)`。 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)] 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 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)] 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 } 95*0102d69fSLoGin 96*0102d69fSLoGin /// `DefaultVirtioIrqHandler` 是一个默认的virtio设备中断处理程序。 97*0102d69fSLoGin /// 98*0102d69fSLoGin /// 当虚拟设备产生中断时,该处理程序会被调用。 99*0102d69fSLoGin /// 100*0102d69fSLoGin /// 它首先检查设备ID是否存在,然后尝试查找与设备ID关联的设备。 101*0102d69fSLoGin /// 如果找到设备,它会调用设备的 `handle_irq` 方法来处理中断。 102*0102d69fSLoGin /// 如果没有找到设备,它会记录一条警告并返回 `IrqReturn::NotHandled`,表示中断未被处理。 103*0102d69fSLoGin #[derive(Debug)] 104*0102d69fSLoGin pub(super) struct DefaultVirtioIrqHandler; 105*0102d69fSLoGin 106*0102d69fSLoGin impl IrqHandler for DefaultVirtioIrqHandler { 107*0102d69fSLoGin fn handle( 108*0102d69fSLoGin &self, 109*0102d69fSLoGin irq: IrqNumber, 110*0102d69fSLoGin _static_data: Option<&dyn IrqHandlerData>, 111*0102d69fSLoGin dev_id: Option<Arc<dyn IrqHandlerData>>, 112*0102d69fSLoGin ) -> Result<IrqReturn, SystemError> { 113*0102d69fSLoGin let dev_id = dev_id.ok_or(SystemError::EINVAL)?; 114*0102d69fSLoGin let dev_id = dev_id 115*0102d69fSLoGin .arc_any() 116*0102d69fSLoGin .downcast::<DeviceId>() 117*0102d69fSLoGin .map_err(|_| SystemError::EINVAL)?; 118*0102d69fSLoGin 119*0102d69fSLoGin if let Some(dev) = virtio_irq_manager().lookup_device(&dev_id) { 120*0102d69fSLoGin return dev.handle_irq(irq); 121*0102d69fSLoGin } else { 122*0102d69fSLoGin // 未绑定具体设备,因此无法处理中断 123*0102d69fSLoGin kwarn!("No device found for IRQ: {:?}", irq); 124*0102d69fSLoGin return Ok(IrqReturn::NotHandled); 125*0102d69fSLoGin } 126*0102d69fSLoGin } 127*0102d69fSLoGin } 128