1e32effb1SLoGin use alloc::{
2e32effb1SLoGin string::{String, ToString},
3e32effb1SLoGin sync::{Arc, Weak},
4e32effb1SLoGin };
5e32effb1SLoGin use ida::IdAllocator;
6e32effb1SLoGin use intertrait::cast::CastArc;
72eab6dd7S曾俊 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
35*28fe4ad2S黄铭涛 use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_DEV_ANY_ID};
36e32effb1SLoGin
37e32effb1SLoGin static mut VIRTIO_BUS: Option<Arc<VirtIOBus>> = None;
38e32effb1SLoGin
39e32effb1SLoGin #[inline(always)]
virtio_bus() -> Arc<VirtIOBus>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 {
new() -> Arc<Self>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 {
name(&self) -> String62e32effb1SLoGin fn name(&self) -> String {
63e32effb1SLoGin self.private.name()
64e32effb1SLoGin }
65e32effb1SLoGin
dev_name(&self) -> String66e32effb1SLoGin fn dev_name(&self) -> String {
67e32effb1SLoGin return self.name();
68e32effb1SLoGin }
69e32effb1SLoGin
dev_groups(&self) -> &'static [&'static dyn AttributeGroup]70e32effb1SLoGin fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
71e32effb1SLoGin // todo: VirtIODeviceAttrGroup
72e32effb1SLoGin return &[];
73e32effb1SLoGin }
74e32effb1SLoGin
subsystem(&self) -> &SubSysPrivate75e32effb1SLoGin fn subsystem(&self) -> &SubSysPrivate {
76e32effb1SLoGin return &self.private;
77e32effb1SLoGin }
78e32effb1SLoGin
probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError>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(|_| {
822eab6dd7S曾俊 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(|_| {
902eab6dd7S曾俊 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
remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>100e32effb1SLoGin fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
101e32effb1SLoGin todo!()
102e32effb1SLoGin }
103e32effb1SLoGin
sync_state(&self, _device: &Arc<dyn Device>)104e32effb1SLoGin fn sync_state(&self, _device: &Arc<dyn Device>) {
105e32effb1SLoGin todo!()
106e32effb1SLoGin }
107e32effb1SLoGin
shutdown(&self, _device: &Arc<dyn Device>)108e32effb1SLoGin fn shutdown(&self, _device: &Arc<dyn Device>) {
109e32effb1SLoGin todo!()
110e32effb1SLoGin }
111e32effb1SLoGin
resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError>112e32effb1SLoGin fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
113e32effb1SLoGin todo!()
114e32effb1SLoGin }
115e32effb1SLoGin
116*28fe4ad2S黄铭涛 // 参考: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>117e32effb1SLoGin fn match_device(
118e32effb1SLoGin &self,
119e32effb1SLoGin _device: &Arc<dyn Device>,
120e32effb1SLoGin _driver: &Arc<dyn Driver>,
121e32effb1SLoGin ) -> Result<bool, SystemError> {
122*28fe4ad2S黄铭涛 let virtio_device = _device.clone().cast::<dyn VirtIODevice>().map_err(|_| {
123*28fe4ad2S黄铭涛 error!(
124*28fe4ad2S黄铭涛 "VirtIOBus::match_device() failed: device is not a VirtIODevice. Device: '{:?}'",
125*28fe4ad2S黄铭涛 _device.name()
126*28fe4ad2S黄铭涛 );
127*28fe4ad2S黄铭涛 SystemError::EINVAL
128*28fe4ad2S黄铭涛 })?;
129*28fe4ad2S黄铭涛 let virtio_driver = _driver.clone().cast::<dyn VirtIODriver>().map_err(|_| {
130*28fe4ad2S黄铭涛 error!(
131*28fe4ad2S黄铭涛 "VirtIOBus::match_device() failed: driver is not a VirtioDriver. Driver: '{:?}'",
132*28fe4ad2S黄铭涛 _driver.name()
133*28fe4ad2S黄铭涛 );
134*28fe4ad2S黄铭涛 SystemError::EINVAL
135*28fe4ad2S黄铭涛 })?;
136*28fe4ad2S黄铭涛
137*28fe4ad2S黄铭涛 let ids = virtio_driver.virtio_id_table();
138*28fe4ad2S黄铭涛 for id in &ids {
139*28fe4ad2S黄铭涛 if id.device != virtio_device.device_type_id() && id.vendor != VIRTIO_DEV_ANY_ID {
140*28fe4ad2S黄铭涛 continue;
141*28fe4ad2S黄铭涛 }
142*28fe4ad2S黄铭涛 if id.vendor == VIRTIO_DEV_ANY_ID || id.vendor == virtio_device.vendor() {
143*28fe4ad2S黄铭涛 return Ok(true);
144*28fe4ad2S黄铭涛 }
145*28fe4ad2S黄铭涛 }
146*28fe4ad2S黄铭涛
147*28fe4ad2S黄铭涛 return Ok(false);
148e32effb1SLoGin }
149e32effb1SLoGin }
150e32effb1SLoGin
151e32effb1SLoGin #[unified_init(INITCALL_CORE)]
virtio_init() -> Result<(), SystemError>152e32effb1SLoGin fn virtio_init() -> Result<(), SystemError> {
153e32effb1SLoGin let bus = VirtIOBus::new();
154e32effb1SLoGin unsafe {
155e32effb1SLoGin VIRTIO_BUS = Some(bus.clone());
156e32effb1SLoGin }
157e32effb1SLoGin bus_manager()
158e32effb1SLoGin .register(bus)
159e32effb1SLoGin .expect("Failed to register virtio bus!");
160e32effb1SLoGin Ok(())
161e32effb1SLoGin }
162e32effb1SLoGin
163e32effb1SLoGin #[inline(always)]
virtio_driver_manager() -> &'static VirtIODriverManager164e32effb1SLoGin pub fn virtio_driver_manager() -> &'static VirtIODriverManager {
165e32effb1SLoGin &VirtIODriverManager
166e32effb1SLoGin }
167e32effb1SLoGin
168e32effb1SLoGin pub struct VirtIODriverManager;
169e32effb1SLoGin
170e32effb1SLoGin impl VirtIODriverManager {
register(&self, driver: Arc<dyn VirtIODriver>) -> Result<(), SystemError>171e32effb1SLoGin pub fn register(&self, driver: Arc<dyn VirtIODriver>) -> Result<(), SystemError> {
172e32effb1SLoGin driver.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>))));
173e32effb1SLoGin return driver_manager().register(driver as Arc<dyn Driver>);
174e32effb1SLoGin }
175e32effb1SLoGin
176e32effb1SLoGin #[allow(dead_code)]
unregister(&self, driver: &Arc<dyn VirtIODriver>)177e32effb1SLoGin pub fn unregister(&self, driver: &Arc<dyn VirtIODriver>) {
178e32effb1SLoGin driver_manager().unregister(&(driver.clone() as Arc<dyn Driver>));
179e32effb1SLoGin }
180e32effb1SLoGin }
181e32effb1SLoGin
182e32effb1SLoGin #[inline(always)]
virtio_device_manager() -> &'static VirtIODeviceManager183e32effb1SLoGin pub fn virtio_device_manager() -> &'static VirtIODeviceManager {
184e32effb1SLoGin &VirtIODeviceManager
185e32effb1SLoGin }
186e32effb1SLoGin
187e32effb1SLoGin pub struct VirtIODeviceManager;
188e32effb1SLoGin
189e32effb1SLoGin impl VirtIODeviceManager {
device_add(&self, dev: Arc<dyn VirtIODevice>) -> Result<(), SystemError>190e32effb1SLoGin pub fn device_add(&self, dev: Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
191e32effb1SLoGin dev.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>))));
192e32effb1SLoGin device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
193e32effb1SLoGin
194e32effb1SLoGin let virtio_index = VIRTIO_DEVICE_INDEX_MANAGER.alloc();
195e32effb1SLoGin dev.set_virtio_device_index(virtio_index);
196e32effb1SLoGin dev.set_device_name(format!("virtio{}", virtio_index.data()));
197e32effb1SLoGin
198e32effb1SLoGin device_manager().add_device(dev.clone() as Arc<dyn Device>)?;
1990102d69fSLoGin let r = device_manager()
2000102d69fSLoGin .add_groups(&(dev.clone() as Arc<dyn Device>), &[&VirtIODeviceAttrGroup]);
2010102d69fSLoGin
2020102d69fSLoGin self.setup_irq(&dev).ok();
2030102d69fSLoGin
2040102d69fSLoGin return r;
2050102d69fSLoGin }
2060102d69fSLoGin
2070102d69fSLoGin /// # setup_irq - 设置中断
2080102d69fSLoGin ///
2090102d69fSLoGin /// 为virtio设备设置中断。
setup_irq(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError>2100102d69fSLoGin fn setup_irq(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
2110102d69fSLoGin let irq = dev.irq().ok_or(SystemError::EINVAL)?;
2120102d69fSLoGin if let Err(e) = irq_manager().request_irq(
2130102d69fSLoGin irq,
2140102d69fSLoGin dev.device_name(),
2150102d69fSLoGin &DefaultVirtioIrqHandler,
2160102d69fSLoGin IrqHandleFlags::IRQF_SHARED,
2170102d69fSLoGin Some(dev.dev_id().clone()),
2180102d69fSLoGin ) {
2192eab6dd7S曾俊 error!(
2200102d69fSLoGin "Failed to request irq for virtio device '{}': irq: {:?}, error {:?}",
2210102d69fSLoGin dev.device_name(),
2220102d69fSLoGin irq,
2230102d69fSLoGin e
2240102d69fSLoGin );
2250102d69fSLoGin return Err(e);
2260102d69fSLoGin }
2270102d69fSLoGin
2280102d69fSLoGin virtio_irq_manager()
2290102d69fSLoGin .register_device(dev.clone())
2300102d69fSLoGin .map_err(|e| {
2312eab6dd7S曾俊 error!(
2320102d69fSLoGin "Failed to register virtio device's irq, dev: '{}', irq: {:?}, error {:?}",
2330102d69fSLoGin dev.device_name(),
2340102d69fSLoGin irq,
2350102d69fSLoGin e
2360102d69fSLoGin );
2370102d69fSLoGin e
2380102d69fSLoGin })?;
2390102d69fSLoGin return Ok(());
240e32effb1SLoGin }
241e32effb1SLoGin
242e32effb1SLoGin #[allow(dead_code)]
device_remove(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError>243e32effb1SLoGin pub fn device_remove(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
244e32effb1SLoGin device_manager().remove(&(dev.clone() as Arc<dyn Device>));
245e32effb1SLoGin return Ok(());
246e32effb1SLoGin }
247e32effb1SLoGin }
248e32effb1SLoGin
249e32effb1SLoGin static VIRTIO_DEVICE_INDEX_MANAGER: VirtIODeviceIndexManager = VirtIODeviceIndexManager::new();
250e32effb1SLoGin
251e32effb1SLoGin /// VirtIO设备索引管理器
252e32effb1SLoGin ///
253e32effb1SLoGin /// VirtIO设备索引管理器用于分配和管理VirtIO设备的唯一索引。
254e32effb1SLoGin pub struct VirtIODeviceIndexManager {
255e32effb1SLoGin // ID分配器
256e32effb1SLoGin ///
257e32effb1SLoGin /// ID分配器用于分配唯一的索引给VirtIO设备。
258e32effb1SLoGin ida: IdAllocator,
259e32effb1SLoGin }
260e32effb1SLoGin
261e32effb1SLoGin // VirtIO设备索引管理器的新建实例
262e32effb1SLoGin impl VirtIODeviceIndexManager {
263e32effb1SLoGin /// 创建新的VirtIO设备索引管理器实例
264e32effb1SLoGin ///
265e32effb1SLoGin /// 创建一个新的VirtIO设备索引管理器实例,初始时分配器从0开始,直到最大usize值。
new() -> Self266e32effb1SLoGin const fn new() -> Self {
267e32effb1SLoGin Self {
268e32effb1SLoGin ida: IdAllocator::new(0, usize::MAX),
269e32effb1SLoGin }
270e32effb1SLoGin }
271e32effb1SLoGin
272e32effb1SLoGin /// 分配一个新的VirtIO设备索引
273e32effb1SLoGin ///
274e32effb1SLoGin /// 分配一个唯一的索引给VirtIO设备。
alloc(&self) -> VirtIODeviceIndex275e32effb1SLoGin pub fn alloc(&self) -> VirtIODeviceIndex {
276e32effb1SLoGin VirtIODeviceIndex(self.ida.alloc().unwrap())
277e32effb1SLoGin }
278e32effb1SLoGin
279e32effb1SLoGin // 释放一个VirtIO设备索引
280e32effb1SLoGin ///
281e32effb1SLoGin /// 释放之前分配的VirtIO设备索引,使其可以被重新使用。
282e32effb1SLoGin #[allow(dead_code)]
free(&self, index: VirtIODeviceIndex)283e32effb1SLoGin pub fn free(&self, index: VirtIODeviceIndex) {
284e32effb1SLoGin self.ida.free(index.0);
285e32effb1SLoGin }
286e32effb1SLoGin }
287e32effb1SLoGin
288e32effb1SLoGin /// VirtIO设备属性组
289e32effb1SLoGin ///
290e32effb1SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#64
291e32effb1SLoGin #[derive(Debug)]
292e32effb1SLoGin pub struct VirtIODeviceAttrGroup;
293e32effb1SLoGin
294e32effb1SLoGin impl AttributeGroup for VirtIODeviceAttrGroup {
name(&self) -> Option<&str>295e32effb1SLoGin fn name(&self) -> Option<&str> {
296e32effb1SLoGin None
297e32effb1SLoGin }
298e32effb1SLoGin
attrs(&self) -> &[&'static dyn Attribute]299e32effb1SLoGin fn attrs(&self) -> &[&'static dyn Attribute] {
300e32effb1SLoGin &[&AttrDevice, &AttrVendor]
301e32effb1SLoGin }
302e32effb1SLoGin }
303e32effb1SLoGin
304e32effb1SLoGin #[derive(Debug)]
305e32effb1SLoGin struct AttrDevice;
306e32effb1SLoGin
307e32effb1SLoGin impl Attribute for AttrDevice {
name(&self) -> &str308e32effb1SLoGin fn name(&self) -> &str {
309e32effb1SLoGin "device"
310e32effb1SLoGin }
311e32effb1SLoGin
mode(&self) -> ModeType312e32effb1SLoGin fn mode(&self) -> ModeType {
313e32effb1SLoGin SYSFS_ATTR_MODE_RO
314e32effb1SLoGin }
315e32effb1SLoGin
support(&self) -> SysFSOpsSupport316e32effb1SLoGin fn support(&self) -> SysFSOpsSupport {
317e32effb1SLoGin SysFSOpsSupport::ATTR_SHOW
318e32effb1SLoGin }
319e32effb1SLoGin
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>320e32effb1SLoGin fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
321e32effb1SLoGin let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| {
3222eab6dd7S曾俊 error!("AttrDevice::show() failed: kobj is not a VirtIODevice");
323e32effb1SLoGin SystemError::EINVAL
324e32effb1SLoGin })?;
325e32effb1SLoGin let device_type_id = dev.device_type_id();
326e32effb1SLoGin
327e32effb1SLoGin return sysfs_emit_str(buf, &format!("0x{:04x}\n", device_type_id));
328e32effb1SLoGin }
329e32effb1SLoGin }
330e32effb1SLoGin
331e32effb1SLoGin #[derive(Debug)]
332e32effb1SLoGin struct AttrVendor;
333e32effb1SLoGin
334e32effb1SLoGin impl Attribute for AttrVendor {
name(&self) -> &str335e32effb1SLoGin fn name(&self) -> &str {
336e32effb1SLoGin "vendor"
337e32effb1SLoGin }
338e32effb1SLoGin
mode(&self) -> ModeType339e32effb1SLoGin fn mode(&self) -> ModeType {
340e32effb1SLoGin SYSFS_ATTR_MODE_RO
341e32effb1SLoGin }
342e32effb1SLoGin
support(&self) -> SysFSOpsSupport343e32effb1SLoGin fn support(&self) -> SysFSOpsSupport {
344e32effb1SLoGin SysFSOpsSupport::ATTR_SHOW
345e32effb1SLoGin }
346e32effb1SLoGin
show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>347e32effb1SLoGin fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
348e32effb1SLoGin let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| {
3492eab6dd7S曾俊 error!("AttrVendor::show() failed: kobj is not a VirtIODevice");
350e32effb1SLoGin SystemError::EINVAL
351e32effb1SLoGin })?;
352e32effb1SLoGin let vendor = dev.vendor();
353e32effb1SLoGin
354e32effb1SLoGin return sysfs_emit_str(buf, &format!("0x{:04x}\n", vendor));
355e32effb1SLoGin }
356e32effb1SLoGin }
357