1 #include "virtio.h"
2 #include <common/kprint.h>
3 #include <common/errno.h>
4 #include <driver/pci/pci.h>
5 
6 #define MAX_NET_NUM 8 // pci总线上的net设备的最大数量
7 
8 // 在pci总线上寻找到net设备控制器的header
9 static struct pci_device_structure_header_t *net_pdevs[MAX_NET_NUM];
10 static int net_pdevs_count = 0;
11 static struct pci_device_structure_header_t *virtio_net_pdev;
12 static int virtio_net_pdev_count = 0;
13 static uint8_t NETWORK_CLASS = 0x2;
14 static uint8_t ETHERNET_SUBCLASS = 0x0;
15 
16 /**
17  * @brief 获取virtio-net MMIO映射的虚拟地址
18  * @param virt_addr 外部传入的虚拟地址指针
19  * @return 获取成功,返回0,失败,返回错误码
20  */
get_virtio_net_device(uint8_t * bus,uint8_t * device,uint8_t * function)21 uint8_t get_virtio_net_device(uint8_t * bus, uint8_t *device,uint8_t * function)
22 {
23     // 获取所有net-pci设备的列表
24     pci_get_device_structure(NETWORK_CLASS, ETHERNET_SUBCLASS, net_pdevs, &net_pdevs_count);
25     //检测其中的virt-io-net设备
26     for(int i = 0; i < net_pdevs_count;i++) {
27         struct pci_device_structure_general_device_t *dev = net_pdevs[i];
28         if(net_pdevs[i]->Vendor_ID==0x1AF4 && net_pdevs[i]->Device_ID>=0x1000 && net_pdevs[i]->Device_ID<=0x103F && dev->Subsystem_ID==1)
29         {
30             virtio_net_pdev=net_pdevs[i];
31             virtio_net_pdev_count++;
32             break;
33         }
34     }
35     if (virtio_net_pdev_count == 0) {
36         kwarn("There is no virtio-net device in this computer!");
37         return NOT_FOUND_DEVICE;
38     }
39       if (virtio_net_pdev->Command==0) {
40         kwarn("The virtio-net device isn't support mmio!");
41         return NOT_SUPPORTE_MMIO;
42     }
43     *bus=virtio_net_pdev->bus;
44     *device=virtio_net_pdev->device;
45     *function=virtio_net_pdev->func;
46 }