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