1*26d84a31SYJwu2023 use super::transport_pci::PciTransport; 2*26d84a31SYJwu2023 use super::virtio_impl::HalImpl; 3*26d84a31SYJwu2023 use crate::driver::pci::pci::DeviceFunction; 4*26d84a31SYJwu2023 use crate::include::bindings::bindings::get_virtio_net_device; 5*26d84a31SYJwu2023 use crate::{kdebug, kerror, kwarn}; 6*26d84a31SYJwu2023 use alloc::{boxed::Box, collections::LinkedList}; 7*26d84a31SYJwu2023 use virtio_drivers::device::net::VirtIONet; 8*26d84a31SYJwu2023 use virtio_drivers::transport::{DeviceType, Transport}; 9*26d84a31SYJwu2023 10*26d84a31SYJwu2023 //Virtio设备寻找过程中出现的问题 11*26d84a31SYJwu2023 enum VirtioError { 12*26d84a31SYJwu2023 VirtioNetNotFound, 13*26d84a31SYJwu2023 } 14*26d84a31SYJwu2023 15*26d84a31SYJwu2023 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加)(for c) 16*26d84a31SYJwu2023 #[no_mangle] 17*26d84a31SYJwu2023 pub extern "C" fn c_virtio_probe() { 18*26d84a31SYJwu2023 if let Ok(virtio_list) = virtio_device_search() { 19*26d84a31SYJwu2023 for device_function in virtio_list { 20*26d84a31SYJwu2023 match PciTransport::new::<HalImpl>(*device_function) { 21*26d84a31SYJwu2023 Ok(mut transport) => { 22*26d84a31SYJwu2023 kdebug!( 23*26d84a31SYJwu2023 "Detected virtio PCI device with device type {:?}, features {:#018x}", 24*26d84a31SYJwu2023 transport.device_type(), 25*26d84a31SYJwu2023 transport.read_device_features(), 26*26d84a31SYJwu2023 ); 27*26d84a31SYJwu2023 virtio_device(transport); 28*26d84a31SYJwu2023 } 29*26d84a31SYJwu2023 Err(err) => { 30*26d84a31SYJwu2023 kerror!("Pci transport create failed because of error: {}", err); 31*26d84a31SYJwu2023 } 32*26d84a31SYJwu2023 } 33*26d84a31SYJwu2023 } 34*26d84a31SYJwu2023 } else { 35*26d84a31SYJwu2023 kerror!("Error occured when finding virtio device!"); 36*26d84a31SYJwu2023 } 37*26d84a31SYJwu2023 } 38*26d84a31SYJwu2023 39*26d84a31SYJwu2023 ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加) 40*26d84a31SYJwu2023 fn virtio_probe() { 41*26d84a31SYJwu2023 if let Ok(virtio_list) = virtio_device_search() { 42*26d84a31SYJwu2023 for device_function in virtio_list { 43*26d84a31SYJwu2023 match PciTransport::new::<HalImpl>(*device_function) { 44*26d84a31SYJwu2023 Ok(mut transport) => { 45*26d84a31SYJwu2023 kdebug!( 46*26d84a31SYJwu2023 "Detected virtio PCI device with device type {:?}, features {:#018x}", 47*26d84a31SYJwu2023 transport.device_type(), 48*26d84a31SYJwu2023 transport.read_device_features(), 49*26d84a31SYJwu2023 ); 50*26d84a31SYJwu2023 virtio_device(transport); 51*26d84a31SYJwu2023 } 52*26d84a31SYJwu2023 Err(err) => { 53*26d84a31SYJwu2023 kerror!("Pci transport create failed because of error: {}", err); 54*26d84a31SYJwu2023 } 55*26d84a31SYJwu2023 } 56*26d84a31SYJwu2023 } 57*26d84a31SYJwu2023 } else { 58*26d84a31SYJwu2023 kerror!("Error occured when finding virtio device!"); 59*26d84a31SYJwu2023 } 60*26d84a31SYJwu2023 } 61*26d84a31SYJwu2023 62*26d84a31SYJwu2023 ///@brief 为virtio设备寻找对应的驱动进行初始化 63*26d84a31SYJwu2023 fn virtio_device(transport: impl Transport) { 64*26d84a31SYJwu2023 match transport.device_type() { 65*26d84a31SYJwu2023 DeviceType::Block => { 66*26d84a31SYJwu2023 kwarn!("Not support virtio_block device for now"); 67*26d84a31SYJwu2023 } 68*26d84a31SYJwu2023 DeviceType::GPU => { 69*26d84a31SYJwu2023 kwarn!("Not support virtio_gpu device for now"); 70*26d84a31SYJwu2023 } 71*26d84a31SYJwu2023 DeviceType::Input => { 72*26d84a31SYJwu2023 kwarn!("Not support virtio_input device for now"); 73*26d84a31SYJwu2023 } 74*26d84a31SYJwu2023 DeviceType::Network => virtio_net(transport), 75*26d84a31SYJwu2023 t => { 76*26d84a31SYJwu2023 kwarn!("Unrecognized virtio device: {:?}", t); 77*26d84a31SYJwu2023 } 78*26d84a31SYJwu2023 } 79*26d84a31SYJwu2023 } 80*26d84a31SYJwu2023 81*26d84a31SYJwu2023 ///@brief virtio-net 驱动的初始化与测试 82*26d84a31SYJwu2023 fn virtio_net<T: Transport>(transport: T) { 83*26d84a31SYJwu2023 let mut driver_net = match VirtIONet::<HalImpl, T>::new(transport) { 84*26d84a31SYJwu2023 Ok(mut net) => { 85*26d84a31SYJwu2023 kdebug!("Virtio-net driver init successfully."); 86*26d84a31SYJwu2023 net 87*26d84a31SYJwu2023 } 88*26d84a31SYJwu2023 Err(_) => { 89*26d84a31SYJwu2023 kerror!("VirtIONet init failed"); 90*26d84a31SYJwu2023 return; 91*26d84a31SYJwu2023 } 92*26d84a31SYJwu2023 }; 93*26d84a31SYJwu2023 // let mut buf = [0u8; 0x100]; 94*26d84a31SYJwu2023 // let len = match driver_net.recv(&mut buf) 95*26d84a31SYJwu2023 // { 96*26d84a31SYJwu2023 // Ok(len) =>{len}, 97*26d84a31SYJwu2023 // Err(_) =>{kerror!("virtio_net recv failed");return;} 98*26d84a31SYJwu2023 // }; 99*26d84a31SYJwu2023 // kdebug!("recv: {:?}", &buf[..len]); 100*26d84a31SYJwu2023 // match driver_net.send(&buf[..len]) 101*26d84a31SYJwu2023 // { 102*26d84a31SYJwu2023 // Ok(_) =>{kdebug!("virtio_net send success");}, 103*26d84a31SYJwu2023 // Err(_) =>{kerror!("virtio_net send failed");return;}, 104*26d84a31SYJwu2023 // } 105*26d84a31SYJwu2023 let mac = driver_net.mac(); 106*26d84a31SYJwu2023 kdebug!("virtio_net MAC={:?}", mac); 107*26d84a31SYJwu2023 kdebug!("virtio-net test finished"); 108*26d84a31SYJwu2023 } 109*26d84a31SYJwu2023 110*26d84a31SYJwu2023 /// @brief 寻找所有的virtio设备 111*26d84a31SYJwu2023 /// @return Result<LinkedList<Box<DeviceFunction>>,VirtioError> 成功则返回包含所有virtio设备的链表,失败则返回err 112*26d84a31SYJwu2023 /// 该函数主要是为其他virtio设备预留支持 113*26d84a31SYJwu2023 fn virtio_device_search() -> Result<LinkedList<Box<DeviceFunction>>, VirtioError> { 114*26d84a31SYJwu2023 let mut virtio_list: LinkedList<Box<DeviceFunction>> = LinkedList::new(); 115*26d84a31SYJwu2023 let (bus, device, function) = unsafe { 116*26d84a31SYJwu2023 let mut bus: u8 = 0; 117*26d84a31SYJwu2023 let mut device: u8 = 0; 118*26d84a31SYJwu2023 let mut function: u8 = 0; 119*26d84a31SYJwu2023 let bus_ptr = &mut bus as *mut u8; 120*26d84a31SYJwu2023 let device_ptr = &mut device as *mut u8; 121*26d84a31SYJwu2023 let function_ptr = &mut function as *mut u8; 122*26d84a31SYJwu2023 get_virtio_net_device(bus_ptr, device_ptr, function_ptr); 123*26d84a31SYJwu2023 (bus, device, function) 124*26d84a31SYJwu2023 }; 125*26d84a31SYJwu2023 if bus == 0 && device == 0 && function == 0 { 126*26d84a31SYJwu2023 kdebug!("get_virtio_net_device failed"); 127*26d84a31SYJwu2023 return Err(VirtioError::VirtioNetNotFound); 128*26d84a31SYJwu2023 } 129*26d84a31SYJwu2023 let device_function = DeviceFunction { 130*26d84a31SYJwu2023 bus: bus, 131*26d84a31SYJwu2023 device: device, 132*26d84a31SYJwu2023 function: function, 133*26d84a31SYJwu2023 }; 134*26d84a31SYJwu2023 virtio_list.push_back(Box::new(device_function)); 135*26d84a31SYJwu2023 Ok(virtio_list) 136*26d84a31SYJwu2023 } 137