1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#ifndef __PCI_H
#define __PCI_H
#include "types.h" // u32
static inline u8 pci_bdf_to_bus(u16 bdf) {
return bdf >> 8;
}
static inline u8 pci_bdf_to_devfn(u16 bdf) {
return bdf & 0xff;
}
static inline u16 pci_bdf_to_busdev(u16 bdf) {
return bdf & ~0x07;
}
static inline u8 pci_bdf_to_dev(u16 bdf) {
return (bdf >> 3) & 0x1f;
}
static inline u8 pci_bdf_to_fn(u16 bdf) {
return bdf & 0x07;
}
static inline u16 pci_to_bdf(int bus, int dev, int fn) {
return (bus<<8) | (dev<<3) | fn;
}
static inline u16 pci_bus_devfn_to_bdf(int bus, u16 devfn) {
return (bus << 8) | devfn;
}
static inline u32 pci_vd(u16 vendor, u16 device) {
return (device << 16) | vendor;
}
static inline u16 pci_vd_to_ven(u32 vd) {
return vd & 0xffff;
}
static inline u16 pci_vd_to_dev(u32 vd) {
return vd >> 16;
}
void pci_config_writel(u16 bdf, u32 addr, u32 val);
void pci_config_writew(u16 bdf, u32 addr, u16 val);
void pci_config_writeb(u16 bdf, u32 addr, u8 val);
u32 pci_config_readl(u16 bdf, u32 addr);
u16 pci_config_readw(u16 bdf, u32 addr);
u8 pci_config_readb(u16 bdf, u32 addr);
void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on);
int pci_find_vga(void);
int pci_find_device(u16 vendid, u16 devid);
int pci_find_class(u16 classid);
int pci_next(int bdf, int *pmax);
#define foreachpci(BDF, MAX) \
for (MAX=0x0100, BDF=pci_next(0, &MAX) \
; BDF >= 0 \
; BDF=pci_next(BDF+1, &MAX))
#define foreachpci_in_bus(BDF, MAX, BUS) \
for (MAX = pci_bus_devfn_to_bdf(BUS, 0) + 0x0100, \
BDF = pci_next(pci_bus_devfn_to_bdf(BUS, 0), &MAX) \
; BDF >= 0 && BDF < pci_bus_devfn_to_bdf(BUS, 0) + 0x0100 \
; MAX = pci_bus_devfn_to_bdf(BUS, 0) + 0x0100, \
BDF = pci_next(BDF + 1, &MAX))
#define PCI_ANY_ID (~0)
struct pci_device_id {
u32 vendid;
u32 devid;
u32 class;
u32 class_mask;
void (*func)(u16 bdf, void *arg);
};
#define PCI_DEVICE(vendor_id, device_id, init_func) \
{ \
.vendid = (vendor_id), \
.devid = (device_id), \
.class = PCI_ANY_ID, \
.class_mask = 0, \
.func = (init_func) \
}
#define PCI_DEVICE_CLASS(vendor_id, device_id, class_code, init_func) \
{ \
.vendid = (vendor_id), \
.devid = (device_id), \
.class = (class_code), \
.class_mask = ~0, \
.func = (init_func) \
}
#define PCI_DEVICE_END \
{ \
.vendid = 0, \
}
int pci_init_device(const struct pci_device_id *table, u16 bdf, void *arg);
int pci_find_init_device(const struct pci_device_id *ids, void *arg);
// pirtable.c
void create_pirtable(void);
/****************************************************************
* PIR table
****************************************************************/
extern u16 PirOffset;
struct link_info {
u8 link;
u16 bitmap;
} PACKED;
struct pir_slot {
u8 bus;
u8 dev;
struct link_info links[4];
u8 slot_nr;
u8 reserved;
} PACKED;
struct pir_header {
u32 signature;
u16 version;
u16 size;
u8 router_bus;
u8 router_devfunc;
u16 exclusive_irqs;
u32 compatible_devid;
u32 miniport_data;
u8 reserved[11];
u8 checksum;
struct pir_slot slots[0];
} PACKED;
#define PIR_SIGNATURE 0x52495024 // $PIR
#endif
|