126d84a31SYJwu2023 use super::transport_pci::PciTransport; 226d84a31SYJwu2023 use super::virtio_impl::HalImpl; 3*78bf93f0SYJwu2023 use crate::driver::pci::pci::PciDeviceStructureGeneralDevice; 4*78bf93f0SYJwu2023 use crate::driver::pci::pci::{ 5*78bf93f0SYJwu2023 get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST, 6*78bf93f0SYJwu2023 }; 7*78bf93f0SYJwu2023 use crate::libs::rwlock::RwLockWriteGuard; 826d84a31SYJwu2023 use crate::{kdebug, kerror, kwarn}; 926d84a31SYJwu2023 use alloc::{boxed::Box, collections::LinkedList}; 1026d84a31SYJwu2023 use virtio_drivers::device::net::VirtIONet; 1126d84a31SYJwu2023 use virtio_drivers::transport::{DeviceType, Transport}; 12*78bf93f0SYJwu2023 const NETWORK_CLASS: u8 = 0x2; 13*78bf93f0SYJwu2023 const ETHERNET_SUBCLASS: u8 = 0x0; 1426d84a31SYJwu2023 1526d84a31SYJwu2023 //Virtio设备寻找过程中出现的问题 1626d84a31SYJwu2023 enum VirtioError { 1726d84a31SYJwu2023 VirtioNetNotFound, 18*78bf93f0SYJwu2023 NetDeviceNotFound, 1926d84a31SYJwu2023 } 2026d84a31SYJwu2023 2126d84a31SYJwu2023 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)(for c) 2226d84a31SYJwu2023 #[no_mangle] 2326d84a31SYJwu2023 pub extern "C" fn c_virtio_probe() { 24*78bf93f0SYJwu2023 virtio_probe(); 2526d84a31SYJwu2023 } 2626d84a31SYJwu2023 2726d84a31SYJwu2023 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加) 28*78bf93f0SYJwu2023 pub fn virtio_probe() { 29*78bf93f0SYJwu2023 let mut list = PCI_DEVICE_LINKEDLIST.write(); 30*78bf93f0SYJwu2023 if let Ok(virtio_list) = virtio_device_search(&mut list) { 31*78bf93f0SYJwu2023 for virtio_device in virtio_list { 32*78bf93f0SYJwu2023 match PciTransport::new::<HalImpl>(virtio_device) { 3326d84a31SYJwu2023 Ok(mut transport) => { 3426d84a31SYJwu2023 kdebug!( 3526d84a31SYJwu2023 "Detected virtio PCI device with device type {:?}, features {:#018x}", 3626d84a31SYJwu2023 transport.device_type(), 3726d84a31SYJwu2023 transport.read_device_features(), 3826d84a31SYJwu2023 ); 39*78bf93f0SYJwu2023 virtio_device_init(transport); 4026d84a31SYJwu2023 } 4126d84a31SYJwu2023 Err(err) => { 4226d84a31SYJwu2023 kerror!("Pci transport create failed because of error: {}", err); 4326d84a31SYJwu2023 } 4426d84a31SYJwu2023 } 4526d84a31SYJwu2023 } 4626d84a31SYJwu2023 } else { 4726d84a31SYJwu2023 kerror!("Error occured when finding virtio device!"); 4826d84a31SYJwu2023 } 4926d84a31SYJwu2023 } 5026d84a31SYJwu2023 5126d84a31SYJwu2023 ///@brief 为virtio设备寻找对应的驱动进行初始化 52*78bf93f0SYJwu2023 fn virtio_device_init(transport: impl Transport) { 5326d84a31SYJwu2023 match transport.device_type() { 5426d84a31SYJwu2023 DeviceType::Block => { 5526d84a31SYJwu2023 kwarn!("Not support virtio_block device for now"); 5626d84a31SYJwu2023 } 5726d84a31SYJwu2023 DeviceType::GPU => { 5826d84a31SYJwu2023 kwarn!("Not support virtio_gpu device for now"); 5926d84a31SYJwu2023 } 6026d84a31SYJwu2023 DeviceType::Input => { 6126d84a31SYJwu2023 kwarn!("Not support virtio_input device for now"); 6226d84a31SYJwu2023 } 6326d84a31SYJwu2023 DeviceType::Network => virtio_net(transport), 6426d84a31SYJwu2023 t => { 6526d84a31SYJwu2023 kwarn!("Unrecognized virtio device: {:?}", t); 6626d84a31SYJwu2023 } 6726d84a31SYJwu2023 } 6826d84a31SYJwu2023 } 6926d84a31SYJwu2023 7026d84a31SYJwu2023 ///@brief virtio-net 驱动的初始化与测试 7126d84a31SYJwu2023 fn virtio_net<T: Transport>(transport: T) { 72bacd691cSlogin let driver_net = match VirtIONet::<HalImpl, T>::new(transport) { 73676b8ef6SMork Ok(net) => { 7426d84a31SYJwu2023 kdebug!("Virtio-net driver init successfully."); 7526d84a31SYJwu2023 net 7626d84a31SYJwu2023 } 7726d84a31SYJwu2023 Err(_) => { 7826d84a31SYJwu2023 kerror!("VirtIONet init failed"); 7926d84a31SYJwu2023 return; 8026d84a31SYJwu2023 } 8126d84a31SYJwu2023 }; 82bacd691cSlogin // let mut buf = [0u8; 0x100]; 83bacd691cSlogin // // let len = match driver_net.recv(&mut buf) 84bacd691cSlogin // // { 85bacd691cSlogin // // Ok(len) =>{len}, 86bacd691cSlogin // // Err(_) =>{kerror!("virtio_net recv failed");return;} 87bacd691cSlogin // // }; 88bacd691cSlogin // match driver_net.can_send() { 8973c607aaSYJwu2023 // true => { 90bacd691cSlogin // kdebug!("Virtio-net can send"); 9126d84a31SYJwu2023 // } 9273c607aaSYJwu2023 // false => { 93bacd691cSlogin // kdebug!("Virtio-net can not send"); 9473c607aaSYJwu2023 // } 9573c607aaSYJwu2023 // } 96bacd691cSlogin // // match driver_net.can_recv() { 97bacd691cSlogin // // true => { 98bacd691cSlogin // // kdebug!("can recv") 99bacd691cSlogin // // } 100bacd691cSlogin // // false => { 101bacd691cSlogin // // kdebug!("can not recv"); 102bacd691cSlogin // // } 103bacd691cSlogin // // } 10473c607aaSYJwu2023 105bacd691cSlogin // let len = 100; 106bacd691cSlogin // //kdebug!("recv: {:?}", &buf[..len]); 107bacd691cSlogin // match driver_net.send(&buf[..len]) { 108bacd691cSlogin // Ok(_) => { 109bacd691cSlogin // kdebug!("virtio_net send success"); 110bacd691cSlogin // } 111bacd691cSlogin // Err(_) => { 112bacd691cSlogin // kerror!("virtio_net send failed"); 113bacd691cSlogin // return; 114bacd691cSlogin // } 115bacd691cSlogin // } 11673c607aaSYJwu2023 11726d84a31SYJwu2023 let mac = driver_net.mac(); 11826d84a31SYJwu2023 kdebug!("virtio_net MAC={:?}", mac); 11926d84a31SYJwu2023 kdebug!("virtio-net test finished"); 12026d84a31SYJwu2023 } 12126d84a31SYJwu2023 12226d84a31SYJwu2023 /// @brief 寻找所有的virtio设备 123*78bf93f0SYJwu2023 /// @param list 链表的写锁 124*78bf93f0SYJwu2023 /// @return Result<LinkedList<&'a mut Pci_Device_Structure_General_Device>, VirtioError> 成功则返回包含所有virtio设备结构体的可变引用的链表,失败则返回err 12526d84a31SYJwu2023 /// 该函数主要是为其他virtio设备预留支持 126*78bf93f0SYJwu2023 fn virtio_device_search<'a>( 127*78bf93f0SYJwu2023 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 128*78bf93f0SYJwu2023 ) -> Result<LinkedList<&'a mut PciDeviceStructureGeneralDevice>, VirtioError> { 129*78bf93f0SYJwu2023 let mut virtio_list: LinkedList<&mut PciDeviceStructureGeneralDevice> = LinkedList::new(); 130*78bf93f0SYJwu2023 let virtio_net_device = get_virtio_net_device(list)?; 131*78bf93f0SYJwu2023 virtio_list.push_back(virtio_net_device); 13226d84a31SYJwu2023 Ok(virtio_list) 13326d84a31SYJwu2023 } 134*78bf93f0SYJwu2023 135*78bf93f0SYJwu2023 /// @brief 寻找virtio-net设备 136*78bf93f0SYJwu2023 /// @param list 链表的写锁 137*78bf93f0SYJwu2023 /// @return Result<&'a mut Pci_Device_Structure_General_Device, VirtioError> 成功则返回virtio设备结构体的可变引用,失败则返回err 138*78bf93f0SYJwu2023 fn get_virtio_net_device<'a>( 139*78bf93f0SYJwu2023 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 140*78bf93f0SYJwu2023 ) -> Result<&'a mut PciDeviceStructureGeneralDevice, VirtioError> { 141*78bf93f0SYJwu2023 let result = get_pci_device_structure_mut(list, NETWORK_CLASS, ETHERNET_SUBCLASS); 142*78bf93f0SYJwu2023 if result.is_empty() { 143*78bf93f0SYJwu2023 return Err(VirtioError::NetDeviceNotFound); 144*78bf93f0SYJwu2023 } 145*78bf93f0SYJwu2023 for device in result { 146*78bf93f0SYJwu2023 let standard_device = device.as_standard_device_mut().unwrap(); 147*78bf93f0SYJwu2023 let header = &standard_device.common_header; 148*78bf93f0SYJwu2023 if header.vendor_id == 0x1AF4 149*78bf93f0SYJwu2023 && header.device_id >= 0x1000 150*78bf93f0SYJwu2023 && header.device_id <= 0x103F 151*78bf93f0SYJwu2023 && standard_device.subsystem_id == 1 152*78bf93f0SYJwu2023 { 153*78bf93f0SYJwu2023 return Ok(standard_device); 154*78bf93f0SYJwu2023 } 155*78bf93f0SYJwu2023 } 156*78bf93f0SYJwu2023 Err(VirtioError::VirtioNetNotFound) 157*78bf93f0SYJwu2023 } 158