Adds PCI config dump helper
[akaros.git] / kern / arch / x86 / pci.h
1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2  * See LICENSE for details.
3  *
4  * Barret Rhoden <brho@cs.berkeley.edu>
5  * Original by Paul Pearce <pearce@eecs.berkeley.edu> */
6
7 #ifndef ROS_ARCH_PCI_H
8 #define ROS_ARCH_PCI_H
9
10 #include <ros/common.h>
11 #include <sys/queue.h>
12 #include <atomic.h>
13
14 #define pci_debug(...)  printk(__VA_ARGS__)  
15
16 #define PCI_CONFIG_ADDR     0xCF8
17 #define PCI_CONFIG_DATA     0xCFC
18 #define INVALID_VENDOR_ID   0xFFFF
19
20 /* TODO: gut this (when the IOAPIC is fixed) */
21 #define INVALID_BUS                     0xFFFF
22
23 #define PCI_NOINT                       0x00
24 #define PCI_INTA                        0x01
25 #define PCI_INTB                        0x02
26 #define PCI_INTC                        0x03
27 #define PCI_INTD                        0x04
28
29 /* PCI Register Config Space */
30 #define PCI_DEV_VEND_REG        0x00    /* for the 32 bit read of dev/vend */
31 #define PCI_VENDID_REG          0x00
32 #define PCI_DEVID_REG           0x02
33 #define PCI_CMD_REG                     0x04
34 #define PCI_STATUS_REG          0x06
35 #define PCI_REVID_REG           0x08
36 #define PCI_PROGIF_REG          0x09
37 #define PCI_SUBCLASS_REG        0x0a
38 #define PCI_CLASS_REG           0x0b
39 #define PCI_CLSZ_REG            0x0c
40 #define PCI_LATTIM_REG          0x0d
41 #define PCI_HEADER_REG          0x0e
42 #define PCI_BIST_REG            0x0f
43 /* Config space for header type 0x00  (Standard) */
44 #define PCI_BAR0_STD            0x10
45 #define PCI_BAR1_STD            0x14
46 #define PCI_BAR2_STD            0x18
47 #define PCI_BAR3_STD            0x1c
48 #define PCI_BAR4_STD            0x20
49 #define PCI_BAR5_STD            0x24
50 #define PCI_BAR_OFF                     0x04
51 #define PCI_CARDBUS_STD         0x28
52 #define PCI_SUBSYSVEN_STD       0x2c
53 #define PCI_SUBSYSID_STD        0x2e
54 #define PCI_EXPROM_STD          0x30
55 #define PCI_CAPAB_STD           0x34
56 #define PCI_IRQLINE_STD         0x3c
57 #define PCI_IRQPIN_STD          0x3d
58 #define PCI_MINGRNT_STD         0x3e
59 #define PCI_MAXLAT_STD          0x3f
60 /* Config space for header type 0x01 (PCI-PCI bridge) */
61 /* None of these have been used, so if you use them, check them against
62  * http://wiki.osdev.org/PCI#PCI_Device_Structure */
63 #define PCI_BAR0_BR                     0x10
64 #define PCI_BAR1_BR                     0x14
65 #define PCI_BUS1_BR                     0x18
66 #define PCI_BUS2_BR                     0x19
67 #define PCI_SUBBUS_BR           0x1a
68 #define PCI_LATTIM2_BR          0x1b
69 #define PCI_IOBASE_BR           0x1c
70 #define PCI_IOLIM_BR            0x1d
71 #define PCI_STATUS2_BR          0x1e
72 #define PCI_MEMBASE_BR          0x20
73 #define PCI_MEMLIM_BR           0x22
74 #define PCI_PREMEMBASE_BR       0x24
75 #define PCI_PREMEMLIM_BR        0x26
76 #define PCI_PREBASEUP32_BR      0x28
77 #define PCI_PRELIMUP32_BR       0x2c
78 #define PCI_IOBASEUP16_BR       0x30
79 #define PCI_IOLIMUP16_BR        0x32
80 #define PCI_CAPAB_BR            0x34
81 #define PCI_EXPROM_BR           0x38
82 #define PCI_IRQLINE_BR          0x3c
83 #define PCI_IRQPIN_BR           0x3d
84 #define PCI_BDGCTL_BR           0x3e
85 /* Config space for header type 0x02 (PCI-Cardbus bridge) */
86 /* None of these have been used, so if you use them, check them against
87  * http://wiki.osdev.org/PCI#PCI_Device_Structure */
88 #define PCI_SOC_BASE_CB         0x10
89 #define PCI_OFF_CAP_CB          0x14
90 #define PCI_SEC_STAT_CB         0x16
91 #define PCI_BUS_NR_CB           0x18
92 #define PCI_CARDBUS_NR_CB       0x19
93 #define PCI_SUBBUS_NR_CB        0x1a
94 #define PCI_CARD_LAT_CB         0x1b
95 #define PCI_MEM_BASE0_CB        0x1c
96 #define PCI_MEM_LIMIT0_CB       0x20
97 #define PCI_MEM_BASE1_CB        0x24
98 #define PCI_MEM_LIMIT1_CB       0x28
99 #define PCI_IO_BASE0_CB         0x2c
100 #define PCI_IO_LIMIT0_CB        0x30
101 #define PCI_IO_BASE1_CB         0x34
102 #define PCI_IO_LIMIT1_CB        0x38
103 #define PCI_IRQLINE_CB          0x3c
104 #define PCI_IRQPIN_CB           0x3d
105 #define PCI_BDGCTL_CB           0x3e
106 #define PCI_SUBDEVID_CB         0x40
107 #define PCI_SUBVENID_CB         0x42
108 #define PCI_16BIT_CB            0x44
109
110 /* Command Register Flags */
111 #define PCI_CMD_IO_SPC          (1 << 0)
112 #define PCI_CMD_MEM_SPC         (1 << 1)
113 #define PCI_CMD_BUS_MAS         (1 << 2)
114 #define PCI_CMD_SPC_CYC         (1 << 3)
115 #define PCI_CMD_WR_EN           (1 << 4)
116 #define PCI_CMD_VGA                     (1 << 5)
117 #define PCI_CMD_PAR_ERR         (1 << 6)
118 /* #define PCI_CMD_XXX          (1 << 7) Reserved */
119 #define PCI_CMD_SERR            (1 << 8)
120 #define PCI_CMD_FAST_EN         (1 << 9)
121 #define PCI_CMD_IRQ_DIS         (1 << 10)
122
123 /* Status Register Flags (Bits 9 and 10 are one field) */
124 /* Bits 0, 1, and 2 are reserved */
125 #define PCI_ST_IRQ_STAT         (1 << 3)
126 #define PCI_ST_CAP_LIST         (1 << 4)
127 #define PCI_ST_66MHZ            (1 << 5)
128 /* #define PCI_CMD_XXX          (1 << 6)  Reserved */
129 #define PCI_ST_FAST_CAP         (1 << 7)
130 #define PCI_ST_MASPAR_ERR       (1 << 8)
131 #define PCI_ST_DEVSEL_TIM       (3 << 9)        /* 2 bits */
132 #define PCI_ST_SIG_TAR_ABRT     (1 << 11)
133 #define PCI_ST_REC_TAR_ABRT     (1 << 12)
134 #define PCI_ST_REC_MAS_ABRT     (1 << 13)
135 #define PCI_ST_SIG_SYS_ERR      (1 << 14)
136 #define PCI_ST_PAR_ERR          (1 << 15)
137
138 /* BARS: Base Address Registers */
139 #define PCI_BAR_IO                      0x1                     /* 1 == IO, 0 == Mem */
140 #define PCI_BAR_IO_MASK         0xfffffffc
141 #define PCI_BAR_MEM_MASK        0xfffffff0
142 #define PCI_MEMBAR_TYPE         (3 << 1)
143 #define PCI_MEMBAR_32BIT        0x0
144 #define PCI_MEMBAR_RESV         0x2                     /* type 0x1 shifted to MEMBAR_TYPE */
145 #define PCI_MEMBAR_64BIT        0x4                     /* type 0x2 shifted to MEMBAR_TYPE */
146
147 #define PCI_MAX_BUS                     256
148 #define PCI_MAX_DEV                     32
149 #define PCI_MAX_FUNC            8
150
151 // Run the PCI Code to loop over the PCI BARs. For now we don't use the BARs,
152 // dont check em.
153 #define CHECK_BARS                      0
154
155 #define MAX_PCI_BAR                     6
156
157 /* Capability lists */
158
159 #define PCI_CAP_LIST_ID         0       /* Capability ID */
160 #define  PCI_CAP_ID_PM          0x01    /* Power Management */
161 #define  PCI_CAP_ID_AGP         0x02    /* Accelerated Graphics Port */
162 #define  PCI_CAP_ID_VPD         0x03    /* Vital Product Data */
163 #define  PCI_CAP_ID_SLOTID      0x04    /* Slot Identification */
164 #define  PCI_CAP_ID_MSI         0x05    /* Message Signalled Interrupts */
165 #define  PCI_CAP_ID_CHSWP       0x06    /* CompactPCI HotSwap */
166 #define  PCI_CAP_ID_PCIX        0x07    /* PCI-X */
167 #define  PCI_CAP_ID_HT          0x08    /* HyperTransport */
168 #define  PCI_CAP_ID_VNDR        0x09    /* Vendor specific */
169 #define  PCI_CAP_ID_DBG         0x0A    /* Debug port */
170 #define  PCI_CAP_ID_CCRC        0x0B    /* CompactPCI Central Resource Control */
171 #define  PCI_CAP_ID_SHPC        0x0C    /* PCI Standard Hot-Plug Controller */
172 #define  PCI_CAP_ID_SSVID       0x0D    /* Bridge subsystem vendor/device ID */
173 #define  PCI_CAP_ID_AGP3        0x0E    /* AGP Target PCI-PCI bridge */
174 #define  PCI_CAP_ID_SECDEV      0x0F    /* Secure Device */
175 #define  PCI_CAP_ID_EXP         0x10    /* PCI Express */
176 #define  PCI_CAP_ID_MSIX        0x11    /* MSI-X */
177 #define  PCI_CAP_ID_SATA        0x12    /* SATA Data/Index Conf. */
178 #define  PCI_CAP_ID_AF          0x13    /* PCI Advanced Features */
179 #define  PCI_CAP_ID_MAX         PCI_CAP_ID_AF
180 #define PCI_CAP_LIST_NEXT       1       /* Next capability in the list */
181 #define PCI_CAP_FLAGS           2       /* Capability defined flags (16 bits) */
182 #define PCI_CAP_SIZEOF          4
183
184 /* Power Management Registers */
185
186 #define PCI_PM_PMC              2       /* PM Capabilities Register */
187 #define  PCI_PM_CAP_VER_MASK    0x0007  /* Version */
188 #define  PCI_PM_CAP_PME_CLOCK   0x0008  /* PME clock required */
189 #define  PCI_PM_CAP_RESERVED    0x0010  /* Reserved field */
190 #define  PCI_PM_CAP_DSI         0x0020  /* Device specific initialization */
191 #define  PCI_PM_CAP_AUX_POWER   0x01C0  /* Auxiliary power support mask */
192 #define  PCI_PM_CAP_D1          0x0200  /* D1 power state support */
193 #define  PCI_PM_CAP_D2          0x0400  /* D2 power state support */
194 #define  PCI_PM_CAP_PME         0x0800  /* PME pin supported */
195 #define  PCI_PM_CAP_PME_MASK    0xF800  /* PME Mask of all supported states */
196 #define  PCI_PM_CAP_PME_D0      0x0800  /* PME# from D0 */
197 #define  PCI_PM_CAP_PME_D1      0x1000  /* PME# from D1 */
198 #define  PCI_PM_CAP_PME_D2      0x2000  /* PME# from D2 */
199 #define  PCI_PM_CAP_PME_D3      0x4000  /* PME# from D3 (hot) */
200 #define  PCI_PM_CAP_PME_D3cold  0x8000  /* PME# from D3 (cold) */
201 #define  PCI_PM_CAP_PME_SHIFT   11      /* Start of the PME Mask in PMC */
202 #define PCI_PM_CTRL             4       /* PM control and status register */
203 #define  PCI_PM_CTRL_STATE_MASK 0x0003  /* Current power state (D0 to D3) */
204 #define  PCI_PM_CTRL_NO_SOFT_RESET      0x0008  /* No reset for D3hot->D0 */
205 #define  PCI_PM_CTRL_PME_ENABLE 0x0100  /* PME pin enable */
206 #define  PCI_PM_CTRL_DATA_SEL_MASK      0x1e00  /* Data select (??) */
207 #define  PCI_PM_CTRL_DATA_SCALE_MASK    0x6000  /* Data scale (??) */
208 #define  PCI_PM_CTRL_PME_STATUS 0x8000  /* PME pin status */
209 #define PCI_PM_PPB_EXTENSIONS   6       /* PPB support extensions (??) */
210 #define  PCI_PM_PPB_B2_B3       0x40    /* Stop clock when in D3hot (??) */
211 #define  PCI_PM_BPCC_ENABLE     0x80    /* Bus power/clock control enable (??) */
212 #define PCI_PM_DATA_REGISTER    7       /* (??) */
213 #define PCI_PM_SIZEOF           8
214
215 /* AGP registers */
216
217 #define PCI_AGP_VERSION         2       /* BCD version number */
218 #define PCI_AGP_RFU             3       /* Rest of capability flags */
219 #define PCI_AGP_STATUS          4       /* Status register */
220 #define  PCI_AGP_STATUS_RQ_MASK 0xff000000      /* Maximum number of requests - 1 */
221 #define  PCI_AGP_STATUS_SBA     0x0200  /* Sideband addressing supported */
222 #define  PCI_AGP_STATUS_64BIT   0x0020  /* 64-bit addressing supported */
223 #define  PCI_AGP_STATUS_FW      0x0010  /* FW transfers supported */
224 #define  PCI_AGP_STATUS_RATE4   0x0004  /* 4x transfer rate supported */
225 #define  PCI_AGP_STATUS_RATE2   0x0002  /* 2x transfer rate supported */
226 #define  PCI_AGP_STATUS_RATE1   0x0001  /* 1x transfer rate supported */
227 #define PCI_AGP_COMMAND         8       /* Control register */
228 #define  PCI_AGP_COMMAND_RQ_MASK 0xff000000  /* Master: Maximum number of requests */
229 #define  PCI_AGP_COMMAND_SBA    0x0200  /* Sideband addressing enabled */
230 #define  PCI_AGP_COMMAND_AGP    0x0100  /* Allow processing of AGP transactions */
231 #define  PCI_AGP_COMMAND_64BIT  0x0020  /* Allow processing of 64-bit addresses */
232 #define  PCI_AGP_COMMAND_FW     0x0010  /* Force FW transfers */
233 #define  PCI_AGP_COMMAND_RATE4  0x0004  /* Use 4x rate */
234 #define  PCI_AGP_COMMAND_RATE2  0x0002  /* Use 2x rate */
235 #define  PCI_AGP_COMMAND_RATE1  0x0001  /* Use 1x rate */
236 #define PCI_AGP_SIZEOF          12
237
238 /* Vital Product Data */
239
240 #define PCI_VPD_ADDR            2       /* Address to access (15 bits!) */
241 #define  PCI_VPD_ADDR_MASK      0x7fff  /* Address mask */
242 #define  PCI_VPD_ADDR_F         0x8000  /* Write 0, 1 indicates completion */
243 #define PCI_VPD_DATA            4       /* 32-bits of data returned here */
244 #define PCI_CAP_VPD_SIZEOF      8
245
246 /* Slot Identification */
247
248 #define PCI_SID_ESR             2       /* Expansion Slot Register */
249 #define  PCI_SID_ESR_NSLOTS     0x1f    /* Number of expansion slots available */
250 #define  PCI_SID_ESR_FIC        0x20    /* First In Chassis Flag */
251 #define PCI_SID_CHASSIS_NR      3       /* Chassis Number */
252
253 /* Message Signalled Interrupts registers */
254
255 #define PCI_MSI_FLAGS           2       /* Various flags */
256 #define  PCI_MSI_FLAGS_64BIT    0x80    /* 64-bit addresses allowed */
257 #define  PCI_MSI_FLAGS_QSIZE    0x70    /* Message queue size configured */
258 #define  PCI_MSI_FLAGS_QMASK    0x0e    /* Maximum queue size available */
259 #define  PCI_MSI_FLAGS_ENABLE   0x01    /* MSI feature enabled */
260 #define  PCI_MSI_FLAGS_MASKBIT  0x100   /* 64-bit mask bits allowed */
261 #define PCI_MSI_RFU             3       /* Rest of capability flags */
262 #define PCI_MSI_ADDRESS_LO      4       /* Lower 32 bits */
263 #define PCI_MSI_ADDRESS_HI      8       /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
264 #define PCI_MSI_DATA_32         8       /* 16 bits of data for 32-bit devices */
265 #define PCI_MSI_MASK_32         12      /* Mask bits register for 32-bit devices */
266 #define PCI_MSI_PENDING_32      16      /* Pending intrs for 32-bit devices */
267 #define PCI_MSI_DATA_64         12      /* 16 bits of data for 64-bit devices */
268 #define PCI_MSI_MASK_64         16      /* Mask bits register for 64-bit devices */
269 #define PCI_MSI_PENDING_64      20      /* Pending intrs for 64-bit devices */
270
271 /* MSI-X registers */
272 #define PCI_MSIX_FLAGS          2
273 #define  PCI_MSIX_FLAGS_QSIZE   0x7FF
274 #define  PCI_MSIX_FLAGS_ENABLE  (1 << 15)
275 #define  PCI_MSIX_FLAGS_MASKALL (1 << 14)
276 #define PCI_MSIX_TABLE          4
277 #define PCI_MSIX_PBA            8
278 #define  PCI_MSIX_FLAGS_BIRMASK (7 << 0)
279 #define PCI_CAP_MSIX_SIZEOF     12      /* size of MSIX registers */
280
281 /* MSI-X entry's format */
282 #define PCI_MSIX_ENTRY_SIZE             16
283 #define  PCI_MSIX_ENTRY_LOWER_ADDR      0
284 #define  PCI_MSIX_ENTRY_UPPER_ADDR      4
285 #define  PCI_MSIX_ENTRY_DATA            8
286 #define  PCI_MSIX_ENTRY_VECTOR_CTRL     12
287 #define   PCI_MSIX_ENTRY_CTRL_MASKBIT   1
288
289 /* CompactPCI Hotswap Register */
290
291 #define PCI_CHSWP_CSR           2       /* Control and Status Register */
292 #define  PCI_CHSWP_DHA          0x01    /* Device Hiding Arm */
293 #define  PCI_CHSWP_EIM          0x02    /* ENUM# Signal Mask */
294 #define  PCI_CHSWP_PIE          0x04    /* Pending Insert or Extract */
295 #define  PCI_CHSWP_LOO          0x08    /* LED On / Off */
296 #define  PCI_CHSWP_PI           0x30    /* Programming Interface */
297 #define  PCI_CHSWP_EXT          0x40    /* ENUM# status - extraction */
298 #define  PCI_CHSWP_INS          0x80    /* ENUM# status - insertion */
299
300 /* PCI Advanced Feature registers */
301
302 #define PCI_AF_LENGTH           2
303 #define PCI_AF_CAP              3
304 #define  PCI_AF_CAP_TP          0x01
305 #define  PCI_AF_CAP_FLR         0x02
306 #define PCI_AF_CTRL             4
307 #define  PCI_AF_CTRL_FLR        0x01
308 #define PCI_AF_STATUS           5
309 #define  PCI_AF_STATUS_TP       0x01
310 #define PCI_CAP_AF_SIZEOF       6       /* size of AF registers */
311
312 struct pci_bar {
313         uint32_t                                        raw_bar;
314         uint32_t                                        pio_base;
315         uint32_t                                        mmio_base32;
316         uint64_t                                        mmio_base64;
317         uint32_t                                        mmio_sz;
318 };
319
320 struct pci_device {
321         STAILQ_ENTRY(pci_device)        all_dev;        /* list of all devices */
322         SLIST_ENTRY(pci_device)         irq_dev;        /* list of all devs off an irq */
323         spinlock_t                                      lock;
324         bool                                            in_use;         /* prevent double discovery */
325         uint8_t                                         bus;
326         uint8_t                                         dev;
327         uint8_t                                         func;
328         uint16_t                                        dev_id;
329         uint16_t                                        ven_id;
330         uint8_t                                         irqline;
331         uint8_t                                         irqpin;
332         char                                            *header_type;
333         uint8_t                                         class;
334         uint8_t                                         subclass;
335         uint8_t                                         progif;
336         bool                                            msi_ready;
337         uint32_t                                        msi_msg_addr_hi;
338         uint32_t                                        msi_msg_addr_lo;
339         uint32_t                                        msi_msg_data;
340         uint8_t                                         nr_bars;
341         struct pci_bar                          bar[MAX_PCI_BAR];
342         uint32_t                                        caps[PCI_CAP_ID_MAX + 1];
343         uintptr_t                                       msix_tbl_paddr;
344         uintptr_t                                       msix_tbl_vaddr;
345         uintptr_t                                       msix_pba_paddr;
346         uintptr_t                                       msix_pba_vaddr;
347         unsigned int                            msix_nr_vec;
348         bool                                            msix_ready;
349         // Expansion ROM and attached FLASH
350         int                                             flash_size;
351 };
352
353 struct msix_entry {
354         uint32_t addr_lo, addr_hi, data, vector;
355 };
356
357 struct msix_irq_vector {
358         struct pci_device *pcidev;
359         struct msix_entry *entry;
360         uint32_t addr_lo;
361         uint32_t addr_hi;
362         uint32_t data;
363 };
364
365 /* List of all discovered devices */
366 STAILQ_HEAD(pcidev_stailq, pci_device);
367 extern struct pcidev_stailq pci_devices;
368
369 /* Sync rules for PCI: once a device is added to the list, it is never removed,
370  * and its read-only fields can be accessed at any time.  There is no need for
371  * refcnts or things like that.
372  *
373  * The device list is built early on when we're single threaded, so I'm not
374  * bothering with locks for that yet.  Append-only, singly-linked-list reads
375  * don't need a lock either.
376  *
377  * Other per-device accesses (like read-modify-writes to config space or MSI
378  * fields) require the device's lock.  If we ever want to unplug, we'll probably
379  * work out an RCU-like scheme for the pci_devices list.
380  *
381  * Note this is in addition to the config space global locking done by every
382  * pci_read or write call. */
383
384 void pci_init(void);
385 void pcidev_print_info(struct pci_device *pcidev, int verbosity);
386 uint32_t pci_config_addr(uint8_t bus, uint8_t dev, uint8_t func, uint32_t reg);
387
388 /* Read and write helpers (Eventually, we should have these be statics, since no
389  * device should touch PCI config space). */
390 uint32_t pci_read32(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset);
391 void pci_write32(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
392                  uint32_t value);
393 uint16_t pci_read16(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset);
394 void pci_write16(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
395                  uint16_t value);
396 uint8_t pci_read8(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset);
397 void pci_write8(uint8_t bus, uint8_t dev, uint8_t func, uint32_t offset,
398                 uint8_t value);
399 uint32_t pcidev_read32(struct pci_device *pcidev, uint32_t offset);
400 void pcidev_write32(struct pci_device *pcidev, uint32_t offset, uint32_t value);
401 uint16_t pcidev_read16(struct pci_device *pcidev, uint32_t offset);
402 void pcidev_write16(struct pci_device *pcidev, uint32_t offset, uint16_t value);
403 uint8_t pcidev_read8(struct pci_device *pcidev, uint32_t offset);
404 void pcidev_write8(struct pci_device *pcidev, uint32_t offset, uint8_t value);
405
406 /* Other common PCI functions */
407 void pci_set_bus_master(struct pci_device *pcidev);
408 void pci_clr_bus_master(struct pci_device *pcidev);
409 struct pci_device *pci_match_tbdf(int tbdf);
410 uintptr_t pci_get_membar(struct pci_device *pcidev, int bir);
411 uintptr_t pci_get_iobar(struct pci_device *pcidev, int bir);
412 uint16_t pci_get_vendor(struct pci_device *pcidev);
413 uint16_t pci_get_device(struct pci_device *pcidev);
414 uint16_t pci_get_subvendor(struct pci_device *pcidev);
415 uint16_t pci_get_subdevice(struct pci_device *pcidev);
416 void pci_dump_config(struct pci_device *pcidev, size_t len);
417
418 /* MSI functions, msi.c */
419 int pci_msi_enable(struct pci_device *p, uint64_t vec);
420 struct msix_irq_vector *pci_msix_enable(struct pci_device *p, uint64_t vec);
421 void pci_msi_mask(struct pci_device *p);
422 void pci_msi_unmask(struct pci_device *p);
423 void pci_msi_route(struct pci_device *p, int dest);
424 void pci_msix_mask_vector(struct msix_irq_vector *linkage);
425 void pci_msix_unmask_vector(struct msix_irq_vector *linkage);
426 void pci_msix_route_vector(struct msix_irq_vector *linkage, int dest);
427
428 /* TODO: this is quite the Hacke */
429 #define explode_tbdf(tbdf) {pcidev.bus = tbdf >> 16;\
430                 pcidev.dev = (tbdf>>11)&0x1f;\
431                 pcidev.func = (tbdf>>8)&3;}
432
433 #endif /* ROS_ARCH_PCI_H */