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