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 
pci_mkaddr(uint32_t bus,uint32_t dev,uint32_t func,uint32_t reg)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 
pci_bus(pciaddr_t addr)112 static inline int pci_bus(pciaddr_t addr)
113 {
114     return (addr >> 16) & 0xff;
115 }
116 
pci_dev(pciaddr_t addr)117 static inline int pci_dev(pciaddr_t addr)
118 {
119     return (addr >> 11) & 0x1f;
120 }
121 
pci_func(pciaddr_t addr)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