1 use alloc::{ 2 string::{String, ToString}, 3 sync::{Arc, Weak}, 4 }; 5 use ida::IdAllocator; 6 use intertrait::cast::CastArc; 7 use log::error; 8 use system_error::SystemError; 9 use unified_init::macros::unified_init; 10 11 use crate::{ 12 driver::{ 13 base::{ 14 device::{ 15 bus::{bus_manager, Bus}, 16 device_manager, 17 driver::{driver_manager, Driver}, 18 Device, 19 }, 20 kobject::KObject, 21 subsys::SubSysPrivate, 22 }, 23 virtio::irq::{virtio_irq_manager, DefaultVirtioIrqHandler}, 24 }, 25 exception::{irqdesc::IrqHandleFlags, manage::irq_manager}, 26 filesystem::{ 27 sysfs::{ 28 file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO, 29 }, 30 vfs::syscall::ModeType, 31 }, 32 init::initcall::INITCALL_CORE, 33 libs::spinlock::SpinLock, 34 }; 35 36 use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_DEV_ANY_ID}; 37 38 static mut VIRTIO_BUS: Option<Arc<VirtIOBus>> = None; 39 40 #[inline(always)] 41 pub fn virtio_bus() -> Arc<VirtIOBus> { 42 unsafe { VIRTIO_BUS.as_ref().unwrap().clone() } 43 } 44 45 #[derive(Debug)] 46 pub struct VirtIOBus { 47 private: SubSysPrivate, 48 } 49 50 impl VirtIOBus { 51 pub fn new() -> Arc<Self> { 52 let w: Weak<Self> = Weak::new(); 53 let private = SubSysPrivate::new("virtio".to_string(), Some(w), None, &[]); 54 let bus = Arc::new(Self { private }); 55 bus.subsystem() 56 .set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>)))); 57 58 return bus; 59 } 60 } 61 62 impl Bus for VirtIOBus { 63 fn name(&self) -> String { 64 self.private.name() 65 } 66 67 fn dev_name(&self) -> String { 68 return self.name(); 69 } 70 71 fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { 72 // todo: VirtIODeviceAttrGroup 73 return &[]; 74 } 75 76 fn subsystem(&self) -> &SubSysPrivate { 77 return &self.private; 78 } 79 80 fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> { 81 let drv = device.driver().ok_or(SystemError::EINVAL)?; 82 let virtio_drv = drv.cast::<dyn VirtIODriver>().map_err(|_| { 83 error!( 84 "VirtIOBus::probe() failed: device.driver() is not a VirtioDriver. Device: '{:?}'", 85 device.name() 86 ); 87 SystemError::EINVAL 88 })?; 89 90 let virtio_dev = device.clone().cast::<dyn VirtIODevice>().map_err(|_| { 91 error!( 92 "VirtIOBus::probe() failed: device is not a VirtIODevice. Device: '{:?}'", 93 device.name() 94 ); 95 SystemError::EINVAL 96 })?; 97 98 return virtio_drv.probe(&virtio_dev); 99 } 100 101 fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> { 102 todo!() 103 } 104 105 fn sync_state(&self, _device: &Arc<dyn Device>) { 106 todo!() 107 } 108 109 fn shutdown(&self, _device: &Arc<dyn Device>) { 110 todo!() 111 } 112 113 fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> { 114 todo!() 115 } 116 117 // 参考:https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#85 118 fn match_device( 119 &self, 120 _device: &Arc<dyn Device>, 121 _driver: &Arc<dyn Driver>, 122 ) -> Result<bool, SystemError> { 123 let virtio_device = _device.clone().cast::<dyn VirtIODevice>().map_err(|_| { 124 error!( 125 "VirtIOBus::match_device() failed: device is not a VirtIODevice. Device: '{:?}'", 126 _device.name() 127 ); 128 SystemError::EINVAL 129 })?; 130 let virtio_driver = _driver.clone().cast::<dyn VirtIODriver>().map_err(|_| { 131 error!( 132 "VirtIOBus::match_device() failed: driver is not a VirtioDriver. Driver: '{:?}'", 133 _driver.name() 134 ); 135 SystemError::EINVAL 136 })?; 137 138 let ids = virtio_driver.virtio_id_table(); 139 for id in &ids { 140 if id.device != virtio_device.device_type_id() && id.vendor != VIRTIO_DEV_ANY_ID { 141 continue; 142 } 143 if id.vendor == VIRTIO_DEV_ANY_ID || id.vendor == virtio_device.vendor() { 144 return Ok(true); 145 } 146 } 147 148 return Ok(false); 149 } 150 } 151 152 #[unified_init(INITCALL_CORE)] 153 fn virtio_init() -> Result<(), SystemError> { 154 let bus = VirtIOBus::new(); 155 unsafe { 156 VIRTIO_BUS = Some(bus.clone()); 157 } 158 bus_manager() 159 .register(bus) 160 .expect("Failed to register virtio bus!"); 161 Ok(()) 162 } 163 164 #[inline(always)] 165 pub fn virtio_driver_manager() -> &'static VirtIODriverManager { 166 &VirtIODriverManager 167 } 168 169 pub struct VirtIODriverManager; 170 171 impl VirtIODriverManager { 172 pub fn register(&self, driver: Arc<dyn VirtIODriver>) -> Result<(), SystemError> { 173 driver.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>)))); 174 return driver_manager().register(driver as Arc<dyn Driver>); 175 } 176 177 #[allow(dead_code)] 178 pub fn unregister(&self, driver: &Arc<dyn VirtIODriver>) { 179 driver_manager().unregister(&(driver.clone() as Arc<dyn Driver>)); 180 } 181 } 182 183 #[inline(always)] 184 pub fn virtio_device_manager() -> &'static VirtIODeviceManager { 185 &VirtIODeviceManager 186 } 187 188 pub struct VirtIODeviceManager; 189 190 impl VirtIODeviceManager { 191 pub fn device_add(&self, dev: Arc<dyn VirtIODevice>) -> Result<(), SystemError> { 192 dev.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>)))); 193 device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>)); 194 195 let virtio_index = VIRTIO_DEVICE_INDEX_MANAGER.alloc(); 196 dev.set_virtio_device_index(virtio_index); 197 dev.set_device_name(format!("virtio{}", virtio_index.data())); 198 199 device_manager().add_device(dev.clone() as Arc<dyn Device>)?; 200 let r = device_manager() 201 .add_groups(&(dev.clone() as Arc<dyn Device>), &[&VirtIODeviceAttrGroup]); 202 203 self.setup_irq(&dev).ok(); 204 205 return r; 206 } 207 208 /// # setup_irq - 设置中断 209 /// 210 /// 为virtio设备设置中断。 211 fn setup_irq(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> { 212 let irq = dev.irq().ok_or(SystemError::EINVAL)?; 213 if let Err(e) = irq_manager().request_irq( 214 irq, 215 dev.device_name(), 216 &DefaultVirtioIrqHandler, 217 IrqHandleFlags::IRQF_SHARED, 218 Some(dev.dev_id().clone()), 219 ) { 220 error!( 221 "Failed to request irq for virtio device '{}': irq: {:?}, error {:?}", 222 dev.device_name(), 223 irq, 224 e 225 ); 226 return Err(e); 227 } 228 229 virtio_irq_manager() 230 .register_device(dev.clone()) 231 .map_err(|e| { 232 error!( 233 "Failed to register virtio device's irq, dev: '{}', irq: {:?}, error {:?}", 234 dev.device_name(), 235 irq, 236 e 237 ); 238 e 239 })?; 240 return Ok(()); 241 } 242 243 #[allow(dead_code)] 244 pub fn device_remove(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> { 245 device_manager().remove(&(dev.clone() as Arc<dyn Device>)); 246 return Ok(()); 247 } 248 } 249 250 static VIRTIO_DEVICE_INDEX_MANAGER: VirtIODeviceIndexManager = VirtIODeviceIndexManager::new(); 251 252 /// VirtIO设备索引管理器 253 /// 254 /// VirtIO设备索引管理器用于分配和管理VirtIO设备的唯一索引。 255 pub struct VirtIODeviceIndexManager { 256 // ID分配器 257 /// 258 /// ID分配器用于分配唯一的索引给VirtIO设备。 259 ida: SpinLock<IdAllocator>, 260 } 261 262 // VirtIO设备索引管理器的新建实例 263 impl VirtIODeviceIndexManager { 264 /// 创建新的VirtIO设备索引管理器实例 265 /// 266 /// 创建一个新的VirtIO设备索引管理器实例,初始时分配器从0开始,直到最大usize值。 267 const fn new() -> Self { 268 Self { 269 ida: SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap()), 270 } 271 } 272 273 /// 分配一个新的VirtIO设备索引 274 /// 275 /// 分配一个唯一的索引给VirtIO设备。 276 pub fn alloc(&self) -> VirtIODeviceIndex { 277 VirtIODeviceIndex(self.ida.lock().alloc().unwrap()) 278 } 279 280 // 释放一个VirtIO设备索引 281 /// 282 /// 释放之前分配的VirtIO设备索引,使其可以被重新使用。 283 #[allow(dead_code)] 284 pub fn free(&self, index: VirtIODeviceIndex) { 285 self.ida.lock().free(index.0); 286 } 287 } 288 289 /// VirtIO设备属性组 290 /// 291 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#64 292 #[derive(Debug)] 293 pub struct VirtIODeviceAttrGroup; 294 295 impl AttributeGroup for VirtIODeviceAttrGroup { 296 fn name(&self) -> Option<&str> { 297 None 298 } 299 300 fn attrs(&self) -> &[&'static dyn Attribute] { 301 &[&AttrDevice, &AttrVendor] 302 } 303 } 304 305 #[derive(Debug)] 306 struct AttrDevice; 307 308 impl Attribute for AttrDevice { 309 fn name(&self) -> &str { 310 "device" 311 } 312 313 fn mode(&self) -> ModeType { 314 SYSFS_ATTR_MODE_RO 315 } 316 317 fn support(&self) -> SysFSOpsSupport { 318 SysFSOpsSupport::ATTR_SHOW 319 } 320 321 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 322 let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| { 323 error!("AttrDevice::show() failed: kobj is not a VirtIODevice"); 324 SystemError::EINVAL 325 })?; 326 let device_type_id = dev.device_type_id(); 327 328 return sysfs_emit_str(buf, &format!("0x{:04x}\n", device_type_id)); 329 } 330 } 331 332 #[derive(Debug)] 333 struct AttrVendor; 334 335 impl Attribute for AttrVendor { 336 fn name(&self) -> &str { 337 "vendor" 338 } 339 340 fn mode(&self) -> ModeType { 341 SYSFS_ATTR_MODE_RO 342 } 343 344 fn support(&self) -> SysFSOpsSupport { 345 SysFSOpsSupport::ATTR_SHOW 346 } 347 348 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 349 let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| { 350 error!("AttrVendor::show() failed: kobj is not a VirtIODevice"); 351 SystemError::EINVAL 352 })?; 353 let vendor = dev.vendor(); 354 355 return sysfs_emit_str(buf, &format!("0x{:04x}\n", vendor)); 356 } 357 } 358