xref: /DragonOS/kernel/src/driver/virtio/sysfs.rs (revision 28fe4ad2a0b0d8b5abf1f0cb402b1c3204b42242)
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)]
virtio_bus() -> Arc<VirtIOBus>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 {
new() -> Arc<Self>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 {
name(&self) -> String62     fn name(&self) -> String {
63         self.private.name()
64     }
65 
dev_name(&self) -> String66     fn dev_name(&self) -> String {
67         return self.name();
68     }
69 
dev_groups(&self) -> &'static [&'static dyn AttributeGroup]70     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
71         // todo: VirtIODeviceAttrGroup
72         return &[];
73     }
74 
subsystem(&self) -> &SubSysPrivate75     fn subsystem(&self) -> &SubSysPrivate {
76         return &self.private;
77     }
78 
probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError>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 
remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>100     fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
101         todo!()
102     }
103 
sync_state(&self, _device: &Arc<dyn Device>)104     fn sync_state(&self, _device: &Arc<dyn Device>) {
105         todo!()
106     }
107 
shutdown(&self, _device: &Arc<dyn Device>)108     fn shutdown(&self, _device: &Arc<dyn Device>) {
109         todo!()
110     }
111 
resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>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
match_device( &self, _device: &Arc<dyn Device>, _driver: &Arc<dyn Driver>, ) -> Result<bool, SystemError>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)]
virtio_init() -> Result<(), SystemError>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)]
virtio_driver_manager() -> &'static VirtIODriverManager164 pub fn virtio_driver_manager() -> &'static VirtIODriverManager {
165     &VirtIODriverManager
166 }
167 
168 pub struct VirtIODriverManager;
169 
170 impl VirtIODriverManager {
register(&self, driver: Arc<dyn VirtIODriver>) -> Result<(), SystemError>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)]
unregister(&self, driver: &Arc<dyn VirtIODriver>)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)]
virtio_device_manager() -> &'static VirtIODeviceManager183 pub fn virtio_device_manager() -> &'static VirtIODeviceManager {
184     &VirtIODeviceManager
185 }
186 
187 pub struct VirtIODeviceManager;
188 
189 impl VirtIODeviceManager {
device_add(&self, dev: Arc<dyn VirtIODevice>) -> Result<(), SystemError>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设备设置中断。
setup_irq(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError>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)]
device_remove(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError>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值。
new() -> Self266     const fn new() -> Self {
267         Self {
268             ida: IdAllocator::new(0, usize::MAX),
269         }
270     }
271 
272     /// 分配一个新的VirtIO设备索引
273     ///
274     /// 分配一个唯一的索引给VirtIO设备。
alloc(&self) -> VirtIODeviceIndex275     pub fn alloc(&self) -> VirtIODeviceIndex {
276         VirtIODeviceIndex(self.ida.alloc().unwrap())
277     }
278 
279     // 释放一个VirtIO设备索引
280     ///
281     /// 释放之前分配的VirtIO设备索引,使其可以被重新使用。
282     #[allow(dead_code)]
free(&self, index: VirtIODeviceIndex)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 {
name(&self) -> Option<&str>295     fn name(&self) -> Option<&str> {
296         None
297     }
298 
attrs(&self) -> &[&'static dyn Attribute]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 {
name(&self) -> &str308     fn name(&self) -> &str {
309         "device"
310     }
311 
mode(&self) -> ModeType312     fn mode(&self) -> ModeType {
313         SYSFS_ATTR_MODE_RO
314     }
315 
support(&self) -> SysFSOpsSupport316     fn support(&self) -> SysFSOpsSupport {
317         SysFSOpsSupport::ATTR_SHOW
318     }
319 
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>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 {
name(&self) -> &str335     fn name(&self) -> &str {
336         "vendor"
337     }
338 
mode(&self) -> ModeType339     fn mode(&self) -> ModeType {
340         SYSFS_ATTR_MODE_RO
341     }
342 
support(&self) -> SysFSOpsSupport343     fn support(&self) -> SysFSOpsSupport {
344         SysFSOpsSupport::ATTR_SHOW
345     }
346 
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>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