#include "pci.h" #include #include #include #include pci_dev_common_info** pci_devs; static size_t max_devs; size_t pci_num_devs; static uint32_t read_config(int bus,int device,int func,int offset) { uint32_t address; uint32_t lbus=(uint32_t)bus; uint32_t ldev=(uint32_t)device; uint32_t lfunc=(uint32_t)func; address=(uint32_t)((lbus << 16)|(ldev << 11)|(lfunc<<8)|(offset&0xfc)|((uint32_t)0x80000000)); port_long_out(PCI_CONFIG_ADDRESS,address); uint32_t data=port_long_in(PCI_CONFIG_DATA); return data; } static void write_config(int bus,int device,int func,int offset,uint32_t data) { uint32_t address; uint32_t lbus=(uint32_t)bus; uint32_t ldev=(uint32_t)device; uint32_t lfunc=(uint32_t)func; address=(uint32_t)((lbus << 16)|(ldev << 11)|(lfunc<<8)|(offset&0xfc)|((uint32_t)0x80000000)); port_long_out(PCI_CONFIG_ADDRESS,address); port_long_out(PCI_CONFIG_DATA,data); } pci_dev_common_info* pci_get_dev_info(int bus,int device,int func) { uint32_t* info=malloc(sizeof(uint32_t)*5); info[0]=read_config(bus,device,func,0); info[1]=read_config(bus,device,func,4); info[2]=read_config(bus,device,func,8); info[3]=read_config(bus,device,func,0xC); pci_dev_common_info* pci_info=(pci_dev_common_info*)info; return pci_info; } void pci_set_dev_info(int bus,int device,int func, pci_dev_common_info* inf) { uint32_t* info=(uint32_t*)inf; write_config(bus,device,func,0,info[0]); write_config(bus,device,func,4,info[1]); write_config(bus,device,func,8,info[2]); write_config(bus,device,func,0xC,info[3]); } static void checkFunction(int bus,int device,int func, pci_dev_common_info* info); static void checkDevice(int bus, int device) { pci_dev_common_info* info=pci_get_dev_info(bus,device,0); if(info->vend_id==0xFFFF||info->class_code==0xFF) { return; } checkFunction(bus, device, 0, info); if((info->header_type&0x80)!=0) { for(int function=1;function<8;function++) { pci_dev_common_info* info=pci_get_dev_info(bus,device,function); if(info->vend_id!=0xFFFF&&info->class_code!=0xFF) { checkFunction(bus,device,function,info); } } } } static void printBAR(uint32_t bar,int num) { if (bar!=0) { if (bar&0x1) { printf("[INFO] IO BAR%d:%x\n",num,bar&0xFFFFFFFC); } else { printf("[INFO] MEM BAR%d:%x\n",num,bar&0xFFFFFFF0); } } } static void checkFunction(int bus,int device,int func,pci_dev_common_info* info) { if (pci_num_devs==max_devs) { max_devs+=32; pci_devs=malloc(sizeof(pci_dev_common_info)*max_devs); } pci_devs[pci_num_devs]=info; if ((info->header_type&0x7f)==0) { pci_dev_type0* dev=realloc(info,sizeof(pci_dev_type0)); uint32_t* dev_word_array=(uint32_t*)dev; for (int i=0;i<16;i++) { dev_word_array[i]=read_config(bus,device,func,i*4); } pci_devs[pci_num_devs]=(pci_dev_common_info*)dev; } pci_num_devs++; } void pci_init() { pci_devs=malloc(sizeof(pci_dev_common_info)*32); max_devs=32; pci_num_devs=0; for(uint16_t bus=0;bus<1; bus++) { for(uint8_t device=0;device<32; device++) { checkDevice(bus, device); } } for (int i=0;iclass_code,info->subclass,info->prog_if); printf("[INFO] Vendor ID:%x, Device ID:%x\n",info->vend_id,info->dev_id); if ((info->header_type&0x7f)==0) { pci_dev_type0* dev=(pci_dev_type0*)info; printBAR(dev->bar0,0); printBAR(dev->bar1,1); printBAR(dev->bar2,2); printBAR(dev->bar3,3); printBAR(dev->bar4,4); printBAR(dev->bar5,5); } } }