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