irq.rs 2.5 KB

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