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