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