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