xref: /DragonOS/kernel/src/driver/virtio/virtio.rs (revision 26d84a31393c50063ff416bc509316e8d342028c)
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