xref: /DragonOS/kernel/src/driver/virtio/sysfs.rs (revision 013ffb708fab7760ea999c1edf462c69ac68f0ac)
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)]
virtio_bus() -> Arc<VirtIOBus>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 {
new() -> Arc<Self>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 {
name(&self) -> String63     fn name(&self) -> String {
64         self.private.name()
65     }
66 
dev_name(&self) -> String67     fn dev_name(&self) -> String {
68         return self.name();
69     }
70 
dev_groups(&self) -> &'static [&'static dyn AttributeGroup]71     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
72         // todo: VirtIODeviceAttrGroup
73         return &[];
74     }
75 
subsystem(&self) -> &SubSysPrivate76     fn subsystem(&self) -> &SubSysPrivate {
77         return &self.private;
78     }
79 
probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError>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 
remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>101     fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
102         todo!()
103     }
104 
sync_state(&self, _device: &Arc<dyn Device>)105     fn sync_state(&self, _device: &Arc<dyn Device>) {
106         todo!()
107     }
108 
shutdown(&self, _device: &Arc<dyn Device>)109     fn shutdown(&self, _device: &Arc<dyn Device>) {
110         todo!()
111     }
112 
resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>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
match_device( &self, _device: &Arc<dyn Device>, _driver: &Arc<dyn Driver>, ) -> Result<bool, SystemError>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)]
virtio_init() -> Result<(), SystemError>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)]
virtio_driver_manager() -> &'static VirtIODriverManager165 pub fn virtio_driver_manager() -> &'static VirtIODriverManager {
166     &VirtIODriverManager
167 }
168 
169 pub struct VirtIODriverManager;
170 
171 impl VirtIODriverManager {
register(&self, driver: Arc<dyn VirtIODriver>) -> Result<(), SystemError>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)]
unregister(&self, driver: &Arc<dyn VirtIODriver>)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)]
virtio_device_manager() -> &'static VirtIODeviceManager184 pub fn virtio_device_manager() -> &'static VirtIODeviceManager {
185     &VirtIODeviceManager
186 }
187 
188 pub struct VirtIODeviceManager;
189 
190 impl VirtIODeviceManager {
device_add(&self, dev: Arc<dyn VirtIODevice>) -> Result<(), SystemError>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设备设置中断。
setup_irq(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError>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)]
device_remove(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError>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值。
new() -> Self267     const fn new() -> Self {
268         Self {
269             ida: SpinLock::new(IdAllocator::new(0, usize::MAX).unwrap()),
270         }
271     }
272 
273     /// 分配一个新的VirtIO设备索引
274     ///
275     /// 分配一个唯一的索引给VirtIO设备。
alloc(&self) -> VirtIODeviceIndex276     pub fn alloc(&self) -> VirtIODeviceIndex {
277         VirtIODeviceIndex(self.ida.lock().alloc().unwrap())
278     }
279 
280     // 释放一个VirtIO设备索引
281     ///
282     /// 释放之前分配的VirtIO设备索引,使其可以被重新使用。
283     #[allow(dead_code)]
free(&self, index: VirtIODeviceIndex)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 {
name(&self) -> Option<&str>296     fn name(&self) -> Option<&str> {
297         None
298     }
299 
attrs(&self) -> &[&'static dyn Attribute]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 {
name(&self) -> &str309     fn name(&self) -> &str {
310         "device"
311     }
312 
mode(&self) -> ModeType313     fn mode(&self) -> ModeType {
314         SYSFS_ATTR_MODE_RO
315     }
316 
support(&self) -> SysFSOpsSupport317     fn support(&self) -> SysFSOpsSupport {
318         SysFSOpsSupport::ATTR_SHOW
319     }
320 
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>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 {
name(&self) -> &str336     fn name(&self) -> &str {
337         "vendor"
338     }
339 
mode(&self) -> ModeType340     fn mode(&self) -> ModeType {
341         SYSFS_ATTR_MODE_RO
342     }
343 
support(&self) -> SysFSOpsSupport344     fn support(&self) -> SysFSOpsSupport {
345         SysFSOpsSupport::ATTR_SHOW
346     }
347 
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>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