1e32effb1SLoGin use super::mmio::virtio_probe_mmio; 226d84a31SYJwu2023 use super::transport_pci::PciTransport; 326d84a31SYJwu2023 use super::virtio_impl::HalImpl; 4e2841179SLoGin use crate::driver::base::device::DeviceId; 5731bc2b3SLoGin use crate::driver::block::virtio_blk::virtio_blk; 613776c11Slogin use crate::driver::net::virtio_net::virtio_net; 778bf93f0SYJwu2023 use crate::driver::pci::pci::{ 8e32effb1SLoGin get_pci_device_structures_mut_by_vendor_id, PciDeviceStructure, 9e32effb1SLoGin PciDeviceStructureGeneralDevice, PCI_DEVICE_LINKEDLIST, 1078bf93f0SYJwu2023 }; 11e32effb1SLoGin use crate::driver::virtio::transport::VirtIOTransport; 1278bf93f0SYJwu2023 use crate::libs::rwlock::RwLockWriteGuard; 13*2eab6dd7S曾俊 14e2841179SLoGin use alloc::sync::Arc; 15e32effb1SLoGin use alloc::vec::Vec; 1626d84a31SYJwu2023 use alloc::{boxed::Box, collections::LinkedList}; 17*2eab6dd7S曾俊 use log::{debug, error, warn}; 1826d84a31SYJwu2023 use virtio_drivers::transport::{DeviceType, Transport}; 1926d84a31SYJwu2023 2026d84a31SYJwu2023 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加) 2178bf93f0SYJwu2023 pub fn virtio_probe() { 22731bc2b3SLoGin #[cfg(not(target_arch = "riscv64"))] 23e32effb1SLoGin virtio_probe_pci(); 24e32effb1SLoGin virtio_probe_mmio(); 25e32effb1SLoGin } 26e32effb1SLoGin 27731bc2b3SLoGin #[allow(dead_code)] 28e32effb1SLoGin fn virtio_probe_pci() { 2978bf93f0SYJwu2023 let mut list = PCI_DEVICE_LINKEDLIST.write(); 30e32effb1SLoGin let virtio_list = virtio_device_search(&mut list); 3178bf93f0SYJwu2023 for virtio_device in virtio_list { 32e2841179SLoGin let dev_id = virtio_device.common_header.device_id; 33e32effb1SLoGin let dev_id = DeviceId::new(None, Some(format!("{dev_id}"))).unwrap(); 34e2841179SLoGin match PciTransport::new::<HalImpl>(virtio_device, dev_id.clone()) { 3526d84a31SYJwu2023 Ok(mut transport) => { 36*2eab6dd7S曾俊 debug!( 3726d84a31SYJwu2023 "Detected virtio PCI device with device type {:?}, features {:#018x}", 3826d84a31SYJwu2023 transport.device_type(), 3926d84a31SYJwu2023 transport.read_device_features(), 4026d84a31SYJwu2023 ); 41e32effb1SLoGin let transport = VirtIOTransport::Pci(transport); 42e2841179SLoGin virtio_device_init(transport, dev_id); 4326d84a31SYJwu2023 } 4426d84a31SYJwu2023 Err(err) => { 45*2eab6dd7S曾俊 error!("Pci transport create failed because of error: {}", err); 4626d84a31SYJwu2023 } 4726d84a31SYJwu2023 } 4826d84a31SYJwu2023 } 4926d84a31SYJwu2023 } 5026d84a31SYJwu2023 5126d84a31SYJwu2023 ///@brief 为virtio设备寻找对应的驱动进行初始化 52731bc2b3SLoGin pub(super) fn virtio_device_init(transport: VirtIOTransport, dev_id: Arc<DeviceId>) { 5326d84a31SYJwu2023 match transport.device_type() { 54731bc2b3SLoGin DeviceType::Block => virtio_blk(transport, dev_id), 5526d84a31SYJwu2023 DeviceType::GPU => { 56*2eab6dd7S曾俊 warn!("Not support virtio_gpu device for now"); 5726d84a31SYJwu2023 } 5826d84a31SYJwu2023 DeviceType::Input => { 59*2eab6dd7S曾俊 warn!("Not support virtio_input device for now"); 6026d84a31SYJwu2023 } 61e2841179SLoGin DeviceType::Network => virtio_net(transport, dev_id), 6226d84a31SYJwu2023 t => { 63*2eab6dd7S曾俊 warn!("Unrecognized virtio device: {:?}", t); 6426d84a31SYJwu2023 } 6526d84a31SYJwu2023 } 6626d84a31SYJwu2023 } 6726d84a31SYJwu2023 68e32effb1SLoGin /// # virtio_device_search - 在给定的PCI设备列表中搜索符合特定标准的virtio设备 69e32effb1SLoGin /// 70e32effb1SLoGin /// 该函数搜索一个PCI设备列表,找到所有由特定厂商ID(0x1AF4)和设备ID范围(0x1000至0x103F)定义的virtio设备。 71e32effb1SLoGin /// 72e32effb1SLoGin /// ## 参数 73e32effb1SLoGin /// 74e32effb1SLoGin /// - list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>> - 一个可写的PCI设备结构列表的互斥锁。 75e32effb1SLoGin /// 76e32effb1SLoGin /// ## 返回值 77e32effb1SLoGin /// 78e32effb1SLoGin /// 返回一个包含所有找到的virtio设备的数组 7978bf93f0SYJwu2023 fn virtio_device_search<'a>( 8078bf93f0SYJwu2023 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 81e32effb1SLoGin ) -> Vec<&'a mut PciDeviceStructureGeneralDevice> { 82e32effb1SLoGin let mut virtio_list = Vec::new(); 83e32effb1SLoGin let result = get_pci_device_structures_mut_by_vendor_id(list, 0x1AF4); 8478bf93f0SYJwu2023 8578bf93f0SYJwu2023 for device in result { 8678bf93f0SYJwu2023 let standard_device = device.as_standard_device_mut().unwrap(); 8778bf93f0SYJwu2023 let header = &standard_device.common_header; 88e32effb1SLoGin if header.device_id >= 0x1000 && header.device_id <= 0x103F { 89e32effb1SLoGin virtio_list.push(standard_device); 9078bf93f0SYJwu2023 } 9178bf93f0SYJwu2023 } 92e32effb1SLoGin 93e32effb1SLoGin return virtio_list; 9478bf93f0SYJwu2023 } 95