1 #ifndef _SYS_PCI_H 2 #define _SYS_PCI_H 3 4 #include <inttypes.h> 5 #include <sys/io.h> 6 7 #define MAX_PCI_FUNC 8 8 #define MAX_PCI_DEVICES 32 9 #define MAX_PCI_BUSES 256 10 #define LINUX_KERNEL_MODULE_SIZE 64 11 #define PCI_VENDOR_NAME_SIZE 256 12 #define PCI_PRODUCT_NAME_SIZE 256 13 #define PCI_CLASS_NAME_SIZE 256 14 #define MAX_KERNEL_MODULES_PER_PCI_DEVICE 10 15 #define MAX_PCI_CLASSES 256 16 17 typedef uint32_t pciaddr_t; 18 19 enum { 20 ENOPCIIDS = 100, 21 ENOMODULESPCIMAP, 22 ENOMODULESALIAS 23 }; 24 25 /* a structure for extended pci information */ 26 /* XXX: use pointers for these? */ 27 struct pci_dev_info { 28 char vendor_name[PCI_VENDOR_NAME_SIZE]; 29 char product_name[PCI_PRODUCT_NAME_SIZE]; 30 char linux_kernel_module[LINUX_KERNEL_MODULE_SIZE] 31 [MAX_KERNEL_MODULES_PER_PCI_DEVICE]; 32 int linux_kernel_module_count; 33 char class_name[PCI_CLASS_NAME_SIZE]; /* The most precise class name */ 34 char category_name[PCI_CLASS_NAME_SIZE]; /*The general category */ 35 uint8_t irq; 36 uint8_t latency; 37 }; 38 39 /* PCI device (really, function) */ 40 struct pci_device { 41 union { 42 struct { 43 uint16_t vendor; 44 uint16_t product; 45 uint16_t sub_vendor; 46 uint16_t sub_product; 47 uint8_t revision; 48 uint8_t class[3]; 49 }; 50 struct { 51 uint32_t vid_did; 52 uint32_t svid_sdid; 53 uint32_t rid_class; 54 }; 55 }; 56 struct pci_dev_info *dev_info; 57 struct pci_device *next; 58 }; 59 60 /* PCI device ("slot") structure */ 61 struct pci_slot { 62 struct pci_device *func[MAX_PCI_FUNC]; 63 }; 64 65 /* PCI bus structure */ 66 struct pci_bus { 67 struct pci_slot *slot[MAX_PCI_DEVICES]; 68 }; 69 70 /* PCI domain structure */ 71 struct pci_domain { 72 struct pci_bus *bus[MAX_PCI_BUSES]; 73 }; 74 75 /* Iterate over a PCI domain */ 76 #define for_each_pci_func(funcp, domain) \ 77 for (int __pci_bus = 0; __pci_bus < MAX_PCI_BUSES; __pci_bus++) \ 78 if ((domain)->bus[__pci_bus]) \ 79 for (int __pci_slot = 0; __pci_slot < MAX_PCI_DEVICES; __pci_slot++) \ 80 if ((domain)->bus[__pci_bus]->slot[__pci_slot]) \ 81 for (int __pci_func = 0; __pci_func < MAX_PCI_FUNC; __pci_func++) \ 82 if (((funcp) = (domain)->bus[__pci_bus]->slot[__pci_slot]-> \ 83 func[__pci_func])) 84 85 #define for_each_pci_func3(funcp, domain, addr) \ 86 for (int __pci_bus = 0; __pci_bus < MAX_PCI_BUSES; __pci_bus++) \ 87 if ((domain)->bus[__pci_bus]) \ 88 for (int __pci_slot = 0; __pci_slot < MAX_PCI_DEVICES; __pci_slot++) \ 89 if ((domain)->bus[__pci_bus]->slot[__pci_slot]) \ 90 for (int __pci_func = 0; __pci_func < MAX_PCI_FUNC; __pci_func++) \ 91 if (((addr) = pci_mkaddr(__pci_bus, __pci_slot, __pci_func, 0)), \ 92 ((funcp) = (domain)->bus[__pci_bus]->slot[__pci_slot]-> \ 93 func[__pci_func])) 94 95 struct match { 96 struct match *next; 97 uint32_t did; 98 uint32_t did_mask; 99 uint32_t sid; 100 uint32_t sid_mask; 101 uint8_t rid_min, rid_max; 102 char *filename; 103 }; 104 105 static inline pciaddr_t pci_mkaddr(uint32_t bus, uint32_t dev, 106 uint32_t func, uint32_t reg) 107 { 108 return 0x80000000 | ((bus & 0xff) << 16) | ((dev & 0x1f) << 11) | 109 ((func & 0x07) << 8) | (reg & 0xff); 110 } 111 112 static inline int pci_bus(pciaddr_t addr) 113 { 114 return (addr >> 16) & 0xff; 115 } 116 117 static inline int pci_dev(pciaddr_t addr) 118 { 119 return (addr >> 11) & 0x1f; 120 } 121 122 static inline int pci_func(pciaddr_t addr) 123 { 124 return (addr >> 8) & 0x07; 125 } 126 127 enum pci_config_type { 128 PCI_CFG_NONE = -1, /* badness */ 129 PCI_CFG_AUTO = 0, /* autodetect */ 130 PCI_CFG_TYPE1 = 1, 131 PCI_CFG_TYPE2 = 2, 132 PCI_CFG_BIOS = 3, 133 }; 134 135 enum pci_config_type pci_set_config_type(enum pci_config_type); 136 137 uint8_t pci_readb(pciaddr_t); 138 uint16_t pci_readw(pciaddr_t); 139 uint32_t pci_readl(pciaddr_t); 140 void pci_writeb(uint8_t, pciaddr_t); 141 void pci_writew(uint16_t, pciaddr_t); 142 void pci_writel(uint32_t, pciaddr_t); 143 144 struct pci_domain *pci_scan(void); 145 void free_pci_domain(struct pci_domain *domain); 146 struct match *find_pci_device(const struct pci_domain *pci_domain, 147 struct match *list); 148 int get_name_from_pci_ids(struct pci_domain *pci_domain, char *pciids_path); 149 int get_module_name_from_pcimap(struct pci_domain *pci_domain, char *modules_pcimap_path); 150 int get_module_name_from_alias(struct pci_domain *pci_domain, char *modules_alias_path); 151 int get_class_name_from_pci_ids(struct pci_domain *pci_domain, char *pciids_path); 152 void gather_additional_pci_config(struct pci_domain *domain); 153 #endif /* _SYS_PCI_H */ 154