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