xref: /DragonOS/kernel/src/driver/virtio/virtio.rs (revision 28fe4ad2a0b0d8b5abf1f0cb402b1c3204b42242)
1e32effb1SLoGin use super::mmio::virtio_probe_mmio;
226d84a31SYJwu2023 use super::transport_pci::PciTransport;
326d84a31SYJwu2023 use super::virtio_impl::HalImpl;
4*28fe4ad2S黄铭涛 use crate::driver::base::device::bus::Bus;
5*28fe4ad2S黄铭涛 use crate::driver::base::device::{Device, DeviceId};
6731bc2b3SLoGin use crate::driver::block::virtio_blk::virtio_blk;
713776c11Slogin use crate::driver::net::virtio_net::virtio_net;
878bf93f0SYJwu2023 use crate::driver::pci::pci::{
9e32effb1SLoGin     get_pci_device_structures_mut_by_vendor_id, PciDeviceStructure,
10e32effb1SLoGin     PciDeviceStructureGeneralDevice, PCI_DEVICE_LINKEDLIST,
1178bf93f0SYJwu2023 };
12*28fe4ad2S黄铭涛 use crate::driver::pci::subsys::pci_bus;
13e32effb1SLoGin use crate::driver::virtio::transport::VirtIOTransport;
1478bf93f0SYJwu2023 use crate::libs::rwlock::RwLockWriteGuard;
152eab6dd7S曾俊 
16*28fe4ad2S黄铭涛 use alloc::string::String;
17e2841179SLoGin use alloc::sync::Arc;
18e32effb1SLoGin use alloc::vec::Vec;
1926d84a31SYJwu2023 use alloc::{boxed::Box, collections::LinkedList};
202eab6dd7S曾俊 use log::{debug, error, warn};
2126d84a31SYJwu2023 use virtio_drivers::transport::{DeviceType, Transport};
2226d84a31SYJwu2023 
2326d84a31SYJwu2023 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)
virtio_probe()2478bf93f0SYJwu2023 pub fn virtio_probe() {
25731bc2b3SLoGin     #[cfg(not(target_arch = "riscv64"))]
26e32effb1SLoGin     virtio_probe_pci();
27e32effb1SLoGin     virtio_probe_mmio();
28e32effb1SLoGin }
29e32effb1SLoGin 
30731bc2b3SLoGin #[allow(dead_code)]
virtio_probe_pci()31e32effb1SLoGin fn virtio_probe_pci() {
3278bf93f0SYJwu2023     let mut list = PCI_DEVICE_LINKEDLIST.write();
33e32effb1SLoGin     let virtio_list = virtio_device_search(&mut list);
3478bf93f0SYJwu2023     for virtio_device in virtio_list {
35e2841179SLoGin         let dev_id = virtio_device.common_header.device_id;
36e32effb1SLoGin         let dev_id = DeviceId::new(None, Some(format!("{dev_id}"))).unwrap();
37e2841179SLoGin         match PciTransport::new::<HalImpl>(virtio_device, dev_id.clone()) {
3826d84a31SYJwu2023             Ok(mut transport) => {
392eab6dd7S曾俊                 debug!(
4026d84a31SYJwu2023                     "Detected virtio PCI device with device type {:?}, features {:#018x}",
4126d84a31SYJwu2023                     transport.device_type(),
4226d84a31SYJwu2023                     transport.read_device_features(),
4326d84a31SYJwu2023                 );
44e32effb1SLoGin                 let transport = VirtIOTransport::Pci(transport);
45*28fe4ad2S黄铭涛                 // 这里暂时通过设备名称在sysfs中查找设备,但是我感觉用设备ID更好
46*28fe4ad2S黄铭涛                 let bus = pci_bus() as Arc<dyn Bus>;
47*28fe4ad2S黄铭涛                 let name: String = virtio_device.common_header.bus_device_function.into();
48*28fe4ad2S黄铭涛                 let pci_raw_device = bus.find_device_by_name(name.as_str());
49*28fe4ad2S黄铭涛                 virtio_device_init(transport, dev_id, pci_raw_device);
5026d84a31SYJwu2023             }
5126d84a31SYJwu2023             Err(err) => {
522eab6dd7S曾俊                 error!("Pci transport create failed because of error: {}", err);
5326d84a31SYJwu2023             }
5426d84a31SYJwu2023         }
5526d84a31SYJwu2023     }
5626d84a31SYJwu2023 }
5726d84a31SYJwu2023 
5826d84a31SYJwu2023 ///@brief 为virtio设备寻找对应的驱动进行初始化
virtio_device_init( transport: VirtIOTransport, dev_id: Arc<DeviceId>, dev_parent: Option<Arc<dyn Device>>, )59*28fe4ad2S黄铭涛 pub(super) fn virtio_device_init(
60*28fe4ad2S黄铭涛     transport: VirtIOTransport,
61*28fe4ad2S黄铭涛     dev_id: Arc<DeviceId>,
62*28fe4ad2S黄铭涛     dev_parent: Option<Arc<dyn Device>>,
63*28fe4ad2S黄铭涛 ) {
6426d84a31SYJwu2023     match transport.device_type() {
65*28fe4ad2S黄铭涛         DeviceType::Block => virtio_blk(transport, dev_id, dev_parent),
6626d84a31SYJwu2023         DeviceType::GPU => {
672eab6dd7S曾俊             warn!("Not support virtio_gpu device for now");
6826d84a31SYJwu2023         }
6926d84a31SYJwu2023         DeviceType::Input => {
702eab6dd7S曾俊             warn!("Not support virtio_input device for now");
7126d84a31SYJwu2023         }
72*28fe4ad2S黄铭涛         DeviceType::Network => virtio_net(transport, dev_id, dev_parent),
7326d84a31SYJwu2023         t => {
742eab6dd7S曾俊             warn!("Unrecognized virtio device: {:?}", t);
7526d84a31SYJwu2023         }
7626d84a31SYJwu2023     }
7726d84a31SYJwu2023 }
7826d84a31SYJwu2023 
79e32effb1SLoGin /// # virtio_device_search - 在给定的PCI设备列表中搜索符合特定标准的virtio设备
80e32effb1SLoGin ///
81e32effb1SLoGin /// 该函数搜索一个PCI设备列表,找到所有由特定厂商ID(0x1AF4)和设备ID范围(0x1000至0x103F)定义的virtio设备。
82e32effb1SLoGin ///
83e32effb1SLoGin /// ## 参数
84e32effb1SLoGin ///
85e32effb1SLoGin /// - list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>> - 一个可写的PCI设备结构列表的互斥锁。
86e32effb1SLoGin ///
87e32effb1SLoGin /// ## 返回值
88e32effb1SLoGin ///
89e32effb1SLoGin /// 返回一个包含所有找到的virtio设备的数组
virtio_device_search<'a>( list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, ) -> Vec<&'a mut PciDeviceStructureGeneralDevice>9078bf93f0SYJwu2023 fn virtio_device_search<'a>(
9178bf93f0SYJwu2023     list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
92e32effb1SLoGin ) -> Vec<&'a mut PciDeviceStructureGeneralDevice> {
93e32effb1SLoGin     let mut virtio_list = Vec::new();
94e32effb1SLoGin     let result = get_pci_device_structures_mut_by_vendor_id(list, 0x1AF4);
9578bf93f0SYJwu2023 
9678bf93f0SYJwu2023     for device in result {
9778bf93f0SYJwu2023         let standard_device = device.as_standard_device_mut().unwrap();
9878bf93f0SYJwu2023         let header = &standard_device.common_header;
99e32effb1SLoGin         if header.device_id >= 0x1000 && header.device_id <= 0x103F {
100e32effb1SLoGin             virtio_list.push(standard_device);
10178bf93f0SYJwu2023         }
10278bf93f0SYJwu2023     }
103e32effb1SLoGin 
104e32effb1SLoGin     return virtio_list;
10578bf93f0SYJwu2023 }
106