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