1098ca2bdSWarner Losh /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni *
4fce5d19dSStefan Eßer * Copyright 1997, Stefan Esser <se@freebsd.org>
55bec6157SStefan Eßer *
65bec6157SStefan Eßer * Redistribution and use in source and binary forms, with or without
75bec6157SStefan Eßer * modification, are permitted provided that the following conditions
85bec6157SStefan Eßer * are met:
95bec6157SStefan Eßer * 1. Redistributions of source code must retain the above copyright
105bec6157SStefan Eßer * notice unmodified, this list of conditions, and the following
115bec6157SStefan Eßer * disclaimer.
125bec6157SStefan Eßer * 2. Redistributions in binary form must reproduce the above copyright
135bec6157SStefan Eßer * notice, this list of conditions and the following disclaimer in the
145bec6157SStefan Eßer * documentation and/or other materials provided with the distribution.
155bec6157SStefan Eßer *
165bec6157SStefan Eßer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
175bec6157SStefan Eßer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
185bec6157SStefan Eßer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
195bec6157SStefan Eßer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
205bec6157SStefan Eßer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
215bec6157SStefan Eßer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
225bec6157SStefan Eßer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
235bec6157SStefan Eßer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
245bec6157SStefan Eßer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
255bec6157SStefan Eßer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265bec6157SStefan Eßer *
275e705738SStefan Eßer */
285e705738SStefan Eßer
2906915ea6SJustin T. Gibbs #ifndef _PCIVAR_H_
3006915ea6SJustin T. Gibbs #define _PCIVAR_H_
3106915ea6SJustin T. Gibbs
3206915ea6SJustin T. Gibbs #include <sys/queue.h>
33e2e050c8SConrad Meyer #include <sys/_eventhandler.h>
3406915ea6SJustin T. Gibbs
355bec6157SStefan Eßer /* some PCI bus constants */
365bec6157SStefan Eßer #define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */
375bec6157SStefan Eßer #define PCI_MAXMAPS_1 2 /* max. no. of maps for PCI to PCI bridge */
385bec6157SStefan Eßer #define PCI_MAXMAPS_2 1 /* max. no. of maps for CardBus bridge */
395e705738SStefan Eßer
40b0a2d4b8SWarner Losh typedef uint64_t pci_addr_t;
415e705738SStefan Eßer
42ad6f36f8SJohn Baldwin /* Config registers for PCI-PCI and PCI-Cardbus bridges. */
43ad6f36f8SJohn Baldwin struct pcicfg_bridge {
44ad6f36f8SJohn Baldwin uint8_t br_seclat;
45ad6f36f8SJohn Baldwin uint8_t br_subbus;
46ad6f36f8SJohn Baldwin uint8_t br_secbus;
47ad6f36f8SJohn Baldwin uint8_t br_pribus;
48ad6f36f8SJohn Baldwin uint16_t br_control;
49ad6f36f8SJohn Baldwin };
50ad6f36f8SJohn Baldwin
51ec40a9f9SScott Long /* Interesting values for PCI power management */
52ec40a9f9SScott Long struct pcicfg_pp {
53ec40a9f9SScott Long uint16_t pp_cap; /* PCI power management capabilities */
5486dd379dSJohn Baldwin uint8_t pp_location; /* Offset of power management registers */
55ec40a9f9SScott Long };
56ec40a9f9SScott Long
57a90dd577SJohn Baldwin struct pci_map {
58a90dd577SJohn Baldwin pci_addr_t pm_value; /* Raw BAR value */
59a90dd577SJohn Baldwin pci_addr_t pm_size;
60e9309eacSRyan Stone uint16_t pm_reg;
61a90dd577SJohn Baldwin STAILQ_ENTRY(pci_map) pm_link;
62a90dd577SJohn Baldwin };
63a90dd577SJohn Baldwin
64667dc26eSJohn-Mark Gurney struct vpd_readonly {
65667dc26eSJohn-Mark Gurney char keyword[2];
66667dc26eSJohn-Mark Gurney char *value;
6784b755dfSJohn Baldwin int len;
68667dc26eSJohn-Mark Gurney };
69667dc26eSJohn-Mark Gurney
70667dc26eSJohn-Mark Gurney struct vpd_write {
71667dc26eSJohn-Mark Gurney char keyword[2];
72667dc26eSJohn-Mark Gurney char *value;
73667dc26eSJohn-Mark Gurney int start;
74667dc26eSJohn-Mark Gurney int len;
75667dc26eSJohn-Mark Gurney };
76667dc26eSJohn-Mark Gurney
77667dc26eSJohn-Mark Gurney struct pcicfg_vpd {
78667dc26eSJohn-Mark Gurney uint8_t vpd_reg; /* base register, + 2 for addr, + 4 data */
79b2bfac4cSJohn Baldwin char vpd_cached;
80667dc26eSJohn-Mark Gurney char *vpd_ident; /* string identifier */
81667dc26eSJohn-Mark Gurney int vpd_rocnt;
82667dc26eSJohn-Mark Gurney struct vpd_readonly *vpd_ros;
83667dc26eSJohn-Mark Gurney int vpd_wcnt;
84667dc26eSJohn-Mark Gurney struct vpd_write *vpd_w;
85667dc26eSJohn-Mark Gurney };
86667dc26eSJohn-Mark Gurney
87ec40a9f9SScott Long /* Interesting values for PCI MSI */
88ec40a9f9SScott Long struct pcicfg_msi {
89ec40a9f9SScott Long uint16_t msi_ctrl; /* Message Control */
909bf4c9c1SJohn Baldwin uint8_t msi_location; /* Offset of MSI capability registers. */
919bf4c9c1SJohn Baldwin int msi_alloc; /* Number of allocated messages. */
929bf4c9c1SJohn Baldwin uint64_t msi_addr; /* Contents of address register. */
939bf4c9c1SJohn Baldwin uint16_t msi_data; /* Contents of data register. */
94e706f7f0SJohn Baldwin u_int msi_handlers;
959bf4c9c1SJohn Baldwin };
969bf4c9c1SJohn Baldwin
9760b9b197SJohn Baldwin /* Interesting values for PCI MSI-X */
98e706f7f0SJohn Baldwin struct msix_vector {
99e706f7f0SJohn Baldwin uint64_t mv_address; /* Contents of address register. */
100e706f7f0SJohn Baldwin uint32_t mv_data; /* Contents of data register. */
101e706f7f0SJohn Baldwin int mv_irq;
102e706f7f0SJohn Baldwin };
103e706f7f0SJohn Baldwin
104e706f7f0SJohn Baldwin struct msix_table_entry {
105e706f7f0SJohn Baldwin u_int mte_vector; /* 1-based index into msix_vectors array. */
106e706f7f0SJohn Baldwin u_int mte_handlers;
107e706f7f0SJohn Baldwin };
108e706f7f0SJohn Baldwin
1099bf4c9c1SJohn Baldwin struct pcicfg_msix {
1109bf4c9c1SJohn Baldwin uint16_t msix_ctrl; /* Message Control */
111e706f7f0SJohn Baldwin uint8_t msix_location; /* Offset of MSI-X capability registers. */
1129bf4c9c1SJohn Baldwin uint8_t msix_table_bar; /* BAR containing vector table. */
1139bf4c9c1SJohn Baldwin uint8_t msix_pba_bar; /* BAR containing PBA. */
1149bf4c9c1SJohn Baldwin uint32_t msix_table_offset;
1159bf4c9c1SJohn Baldwin uint32_t msix_pba_offset;
116a3835cceSJohn Baldwin u_int msix_alloc; /* Number of allocated vectors. */
117a3835cceSJohn Baldwin u_int msix_table_len; /* Length of virtual table. */
118e706f7f0SJohn Baldwin struct msix_table_entry *msix_table; /* Virtual table. */
119e706f7f0SJohn Baldwin struct msix_vector *msix_vectors; /* Array of allocated vectors. */
1209bf4c9c1SJohn Baldwin struct resource *msix_table_res; /* Resource containing vector table. */
1219bf4c9c1SJohn Baldwin struct resource *msix_pba_res; /* Resource containing PBA. */
122ec40a9f9SScott Long };
123ec40a9f9SScott Long
124b7672a70SRuslan Bukin struct pci_id_ofw_iommu {
125*451f0333SAndrew Turner uintptr_t xref;
126b7672a70SRuslan Bukin uint32_t id;
127b7672a70SRuslan Bukin };
128b7672a70SRuslan Bukin
1294522ac77SLuoqi Chen /* Interesting values for HyperTransport */
1304522ac77SLuoqi Chen struct pcicfg_ht {
1318081bab7SJohn Baldwin uint8_t ht_slave; /* Non-zero if device is an HT slave. */
1324522ac77SLuoqi Chen uint8_t ht_msimap; /* Offset of MSI mapping cap registers. */
1334522ac77SLuoqi Chen uint16_t ht_msictrl; /* MSI mapping control */
1344522ac77SLuoqi Chen uint64_t ht_msiaddr; /* MSI mapping base address */
1354522ac77SLuoqi Chen };
1364522ac77SLuoqi Chen
137c668000bSJohn Baldwin /* Interesting values for PCI-express */
138c668000bSJohn Baldwin struct pcicfg_pcie {
139c668000bSJohn Baldwin uint8_t pcie_location; /* Offset of PCI-e capability registers. */
140c668000bSJohn Baldwin uint8_t pcie_type; /* Device type. */
1416e9dcee4SAlexander Kabaev uint16_t pcie_flags; /* Device capabilities register. */
1426e9dcee4SAlexander Kabaev uint16_t pcie_device_ctl; /* Device control register. */
1436e9dcee4SAlexander Kabaev uint16_t pcie_link_ctl; /* Link control register. */
1446e9dcee4SAlexander Kabaev uint16_t pcie_slot_ctl; /* Slot control register. */
1456e9dcee4SAlexander Kabaev uint16_t pcie_root_ctl; /* Root control register. */
1466e9dcee4SAlexander Kabaev uint16_t pcie_device_ctl2; /* Second device control register. */
1476e9dcee4SAlexander Kabaev uint16_t pcie_link_ctl2; /* Second link control register. */
1486e9dcee4SAlexander Kabaev uint16_t pcie_slot_ctl2; /* Second slot control register. */
1496e9dcee4SAlexander Kabaev };
1506e9dcee4SAlexander Kabaev
1516e9dcee4SAlexander Kabaev struct pcicfg_pcix {
1526e9dcee4SAlexander Kabaev uint16_t pcix_command;
1536e9dcee4SAlexander Kabaev uint8_t pcix_location; /* Offset of PCI-X capability registers. */
154c668000bSJohn Baldwin };
155c668000bSJohn Baldwin
1569bfb1e36SRyan Stone struct pcicfg_vf {
1579bfb1e36SRyan Stone int index;
1589bfb1e36SRyan Stone };
1599bfb1e36SRyan Stone
1604d185754SWojciech Macek struct pci_ea_entry {
1614d185754SWojciech Macek int eae_bei;
1624d185754SWojciech Macek uint32_t eae_flags;
1634d185754SWojciech Macek uint64_t eae_base;
1644d185754SWojciech Macek uint64_t eae_max_offset;
1654d185754SWojciech Macek uint32_t eae_cfg_offset;
1664d185754SWojciech Macek STAILQ_ENTRY(pci_ea_entry) eae_link;
1674d185754SWojciech Macek };
1684d185754SWojciech Macek
1694d185754SWojciech Macek struct pcicfg_ea {
1704d185754SWojciech Macek int ea_location; /* Structure offset in Configuration Header */
1714d185754SWojciech Macek STAILQ_HEAD(, pci_ea_entry) ea_entries; /* EA entries */
1724d185754SWojciech Macek };
1734d185754SWojciech Macek
1749bfb1e36SRyan Stone #define PCICFG_VF 0x0001 /* Device is an SR-IOV Virtual Function */
1759bfb1e36SRyan Stone
1765bec6157SStefan Eßer /* config header information common to all header types */
1775bec6157SStefan Eßer typedef struct pcicfg {
178bd937497SJean-Sébastien Pédron device_t dev; /* device which owns this */
1795e705738SStefan Eßer
180a90dd577SJohn Baldwin STAILQ_HEAD(, pci_map) maps; /* BARs */
181f36cfd49SWarner Losh
182b0cb115fSWarner Losh uint16_t subvendor; /* card vendor ID */
183b0cb115fSWarner Losh uint16_t subdevice; /* card device ID, assigned by card vendor */
184b0cb115fSWarner Losh uint16_t vendor; /* chip vendor ID */
185b0cb115fSWarner Losh uint16_t device; /* chip device ID, assigned by chip vendor */
1865e705738SStefan Eßer
187b0cb115fSWarner Losh uint16_t cmdreg; /* disable/enable chip and PCI options */
188b0cb115fSWarner Losh uint16_t statreg; /* supported PCI features and error state */
1898673e05aSStefan Eßer
190b0cb115fSWarner Losh uint8_t baseclass; /* chip PCI class */
191b0cb115fSWarner Losh uint8_t subclass; /* chip PCI subclass */
192b0cb115fSWarner Losh uint8_t progif; /* chip PCI programming interface */
193b0cb115fSWarner Losh uint8_t revid; /* chip revision ID */
1945bec6157SStefan Eßer
195b0cb115fSWarner Losh uint8_t hdrtype; /* chip config header type */
196b0cb115fSWarner Losh uint8_t cachelnsz; /* cache line size in 4byte units */
197b0cb115fSWarner Losh uint8_t intpin; /* PCI interrupt pin */
198b0cb115fSWarner Losh uint8_t intline; /* interrupt line (IRQ for PC arch) */
1995bec6157SStefan Eßer
200b0cb115fSWarner Losh uint8_t mingnt; /* min. useful bus grant time in 250ns units */
201b0cb115fSWarner Losh uint8_t maxlat; /* max. tolerated bus grant latency in 250ns */
202b0cb115fSWarner Losh uint8_t lattimer; /* latency timer in units of 30ns bus cycles */
2035bec6157SStefan Eßer
204b0cb115fSWarner Losh uint8_t mfdev; /* multi-function device (from hdrtype reg) */
205b0cb115fSWarner Losh uint8_t nummaps; /* actual number of PCI maps used */
2065bec6157SStefan Eßer
20755aaf894SMarius Strobl uint32_t domain; /* PCI domain */
208b0cb115fSWarner Losh uint8_t bus; /* config space bus address */
209b0cb115fSWarner Losh uint8_t slot; /* config space slot address */
210b0cb115fSWarner Losh uint8_t func; /* config space function number */
2115bec6157SStefan Eßer
2129bfb1e36SRyan Stone uint32_t flags; /* flags defined above */
2139bfb1e36SRyan Stone
214ad6f36f8SJohn Baldwin struct pcicfg_bridge bridge; /* Bridges */
21535db1e6dSJohn Baldwin struct pcicfg_pp pp; /* Power management */
21635db1e6dSJohn Baldwin struct pcicfg_vpd vpd; /* Vital product data */
21735db1e6dSJohn Baldwin struct pcicfg_msi msi; /* PCI MSI */
21835db1e6dSJohn Baldwin struct pcicfg_msix msix; /* PCI MSI-X */
2194522ac77SLuoqi Chen struct pcicfg_ht ht; /* HyperTransport */
220c668000bSJohn Baldwin struct pcicfg_pcie pcie; /* PCI Express */
2216e9dcee4SAlexander Kabaev struct pcicfg_pcix pcix; /* PCI-X */
2229bfb1e36SRyan Stone struct pcicfg_iov *iov; /* SR-IOV */
2239bfb1e36SRyan Stone struct pcicfg_vf vf; /* SR-IOV Virtual Function */
2244d185754SWojciech Macek struct pcicfg_ea ea; /* Enhanced Allocation */
2255bec6157SStefan Eßer } pcicfgregs;
2265bec6157SStefan Eßer
2275bec6157SStefan Eßer /* additional type 1 device config header information (PCI to PCI bridge) */
2285bec6157SStefan Eßer
2295bec6157SStefan Eßer typedef struct {
2305bec6157SStefan Eßer pci_addr_t pmembase; /* base address of prefetchable memory */
2315bec6157SStefan Eßer pci_addr_t pmemlimit; /* topmost address of prefetchable memory */
232b0cb115fSWarner Losh uint32_t membase; /* base address of memory window */
233b0cb115fSWarner Losh uint32_t memlimit; /* topmost address of memory window */
234b0cb115fSWarner Losh uint32_t iobase; /* base address of port window */
235b0cb115fSWarner Losh uint32_t iolimit; /* topmost address of port window */
236b0cb115fSWarner Losh uint16_t secstat; /* secondary bus status register */
237b0cb115fSWarner Losh uint16_t bridgectl; /* bridge control register */
238b0cb115fSWarner Losh uint8_t seclat; /* CardBus latency timer */
2395bec6157SStefan Eßer } pcih1cfgregs;
2405bec6157SStefan Eßer
2415bec6157SStefan Eßer /* additional type 2 device config header information (CardBus bridge) */
2425bec6157SStefan Eßer
2435bec6157SStefan Eßer typedef struct {
244b0cb115fSWarner Losh uint32_t membase0; /* base address of memory window */
245b0cb115fSWarner Losh uint32_t memlimit0; /* topmost address of memory window */
246b0cb115fSWarner Losh uint32_t membase1; /* base address of memory window */
247b0cb115fSWarner Losh uint32_t memlimit1; /* topmost address of memory window */
248b0cb115fSWarner Losh uint32_t iobase0; /* base address of port window */
249b0cb115fSWarner Losh uint32_t iolimit0; /* topmost address of port window */
250b0cb115fSWarner Losh uint32_t iobase1; /* base address of port window */
251b0cb115fSWarner Losh uint32_t iolimit1; /* topmost address of port window */
252b0cb115fSWarner Losh uint32_t pccardif; /* PC Card 16bit IF legacy more base addr. */
253b0cb115fSWarner Losh uint16_t secstat; /* secondary bus status register */
254b0cb115fSWarner Losh uint16_t bridgectl; /* bridge control register */
255b0cb115fSWarner Losh uint8_t seclat; /* CardBus latency timer */
2565bec6157SStefan Eßer } pcih2cfgregs;
2575bec6157SStefan Eßer
258b0cb115fSWarner Losh extern uint32_t pci_numdevs;
2594cee4598SAlexander Motin extern int pci_enable_aspm;
26006915ea6SJustin T. Gibbs
26135613d10SWarner Losh /*
26231243781SWarner Losh * The bitfield has to be stable and match the fields below (so that
26331243781SWarner Losh * match_flag_vendor must be bit 0) so we have to do the endian dance. We can't
26431243781SWarner Losh * use enums or #define constants because then the macros for subsetting matches
26531243781SWarner Losh * wouldn't work. These tables are parsed by devmatch and others to connect
26631243781SWarner Losh * modules with devices on the PCI bus.
26735613d10SWarner Losh */
268971b5f76SWarner Losh struct pci_device_table {
269971b5f76SWarner Losh #if BYTE_ORDER == LITTLE_ENDIAN
270971b5f76SWarner Losh uint16_t
271971b5f76SWarner Losh match_flag_vendor:1,
272971b5f76SWarner Losh match_flag_device:1,
273971b5f76SWarner Losh match_flag_subvendor:1,
274971b5f76SWarner Losh match_flag_subdevice:1,
275971b5f76SWarner Losh match_flag_class:1,
276971b5f76SWarner Losh match_flag_subclass:1,
277971b5f76SWarner Losh match_flag_revid:1,
278971b5f76SWarner Losh match_flag_unused:9;
279971b5f76SWarner Losh #else
280971b5f76SWarner Losh uint16_t
281971b5f76SWarner Losh match_flag_unused:9,
282971b5f76SWarner Losh match_flag_revid:1,
283971b5f76SWarner Losh match_flag_subclass:1,
284971b5f76SWarner Losh match_flag_class:1,
285971b5f76SWarner Losh match_flag_subdevice:1,
286971b5f76SWarner Losh match_flag_subvendor:1,
287971b5f76SWarner Losh match_flag_device:1,
288971b5f76SWarner Losh match_flag_vendor:1;
289971b5f76SWarner Losh #endif
290971b5f76SWarner Losh uint16_t vendor;
291971b5f76SWarner Losh uint16_t device;
292971b5f76SWarner Losh uint16_t subvendor;
293971b5f76SWarner Losh uint16_t subdevice;
294971b5f76SWarner Losh uint16_t class_id;
295971b5f76SWarner Losh uint16_t subclass;
296971b5f76SWarner Losh uint16_t revid;
297971b5f76SWarner Losh uint16_t unused;
298971b5f76SWarner Losh uintptr_t driver_data;
299971b5f76SWarner Losh char *descr;
300971b5f76SWarner Losh };
301971b5f76SWarner Losh
302971b5f76SWarner Losh #define PCI_DEV(v, d) \
303971b5f76SWarner Losh .match_flag_vendor = 1, .vendor = (v), \
304971b5f76SWarner Losh .match_flag_device = 1, .device = (d)
305971b5f76SWarner Losh #define PCI_SUBDEV(sv, sd) \
306971b5f76SWarner Losh .match_flag_subvendor = 1, .subvendor = (sv), \
307971b5f76SWarner Losh .match_flag_subdevice = 1, .subdevice = (sd)
308971b5f76SWarner Losh #define PCI_CLASS(x) \
309971b5f76SWarner Losh .match_flag_class = 1, .class_id = (x)
310971b5f76SWarner Losh #define PCI_SUBCLASS(x) \
311971b5f76SWarner Losh .match_flag_subclass = 1, .subclass = (x)
312971b5f76SWarner Losh #define PCI_REVID(x) \
313971b5f76SWarner Losh .match_flag_revid = 1, .revid = (x)
314971b5f76SWarner Losh #define PCI_DESCR(x) \
315971b5f76SWarner Losh .descr = (x)
316971b5f76SWarner Losh #define PCI_PNP_STR \
317971b5f76SWarner Losh "M16:mask;U16:vendor;U16:device;U16:subvendor;U16:subdevice;" \
318971b5f76SWarner Losh "U16:class;U16:subclass;U16:revid;"
319971b5f76SWarner Losh #define PCI_PNP_INFO(table) \
320329e817fSWarner Losh MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, \
321971b5f76SWarner Losh sizeof(table) / sizeof(table[0]))
322971b5f76SWarner Losh
323971b5f76SWarner Losh const struct pci_device_table *pci_match_device(device_t child,
324971b5f76SWarner Losh const struct pci_device_table *id, size_t nelt);
325971b5f76SWarner Losh #define PCI_MATCH(child, table) \
326971b5f76SWarner Losh pci_match_device(child, (table), nitems(table));
327971b5f76SWarner Losh
32830d1c11eSPeter Wemm /* Only if the prerequisites are present */
32930d1c11eSPeter Wemm #if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_)
33030d1c11eSPeter Wemm struct pci_devinfo {
33130d1c11eSPeter Wemm STAILQ_ENTRY(pci_devinfo) pci_links;
33230d1c11eSPeter Wemm struct resource_list resources;
33330d1c11eSPeter Wemm pcicfgregs cfg;
33430d1c11eSPeter Wemm struct pci_conf conf;
33530d1c11eSPeter Wemm };
33630d1c11eSPeter Wemm #endif
33706915ea6SJustin T. Gibbs
3386182fdbdSPeter Wemm #ifdef _SYS_BUS_H_
3396182fdbdSPeter Wemm
3406182fdbdSPeter Wemm #include "pci_if.h"
3416182fdbdSPeter Wemm
3426182fdbdSPeter Wemm enum pci_device_ivars {
3436182fdbdSPeter Wemm PCI_IVAR_SUBVENDOR,
3446182fdbdSPeter Wemm PCI_IVAR_SUBDEVICE,
3456182fdbdSPeter Wemm PCI_IVAR_VENDOR,
3466182fdbdSPeter Wemm PCI_IVAR_DEVICE,
3476182fdbdSPeter Wemm PCI_IVAR_DEVID,
3486182fdbdSPeter Wemm PCI_IVAR_CLASS,
3496182fdbdSPeter Wemm PCI_IVAR_SUBCLASS,
3506182fdbdSPeter Wemm PCI_IVAR_PROGIF,
3516182fdbdSPeter Wemm PCI_IVAR_REVID,
3526182fdbdSPeter Wemm PCI_IVAR_INTPIN,
3536182fdbdSPeter Wemm PCI_IVAR_IRQ,
35455aaf894SMarius Strobl PCI_IVAR_DOMAIN,
3556182fdbdSPeter Wemm PCI_IVAR_BUS,
3566182fdbdSPeter Wemm PCI_IVAR_SLOT,
3576182fdbdSPeter Wemm PCI_IVAR_FUNCTION,
358ba5fc4eeSWarner Losh PCI_IVAR_ETHADDR,
3596de560abSWarner Losh PCI_IVAR_CMDREG,
3606de560abSWarner Losh PCI_IVAR_CACHELNSZ,
3616de560abSWarner Losh PCI_IVAR_MINGNT,
3626de560abSWarner Losh PCI_IVAR_MAXLAT,
3633b33782aSPoul-Henning Kamp PCI_IVAR_LATTIMER
3646182fdbdSPeter Wemm };
3656182fdbdSPeter Wemm
3666182fdbdSPeter Wemm /*
3676182fdbdSPeter Wemm * Simplified accessors for pci devices
3686182fdbdSPeter Wemm */
369b7c69fe4SThomas Moestl #define PCI_ACCESSOR(var, ivar, type) \
370b7c69fe4SThomas Moestl __BUS_ACCESSOR(pci, var, PCI, ivar, type)
3716182fdbdSPeter Wemm
PCI_ACCESSOR(subvendor,SUBVENDOR,uint16_t)372b0cb115fSWarner Losh PCI_ACCESSOR(subvendor, SUBVENDOR, uint16_t)
373b0cb115fSWarner Losh PCI_ACCESSOR(subdevice, SUBDEVICE, uint16_t)
374b0cb115fSWarner Losh PCI_ACCESSOR(vendor, VENDOR, uint16_t)
375b0cb115fSWarner Losh PCI_ACCESSOR(device, DEVICE, uint16_t)
376b0cb115fSWarner Losh PCI_ACCESSOR(devid, DEVID, uint32_t)
377b0cb115fSWarner Losh PCI_ACCESSOR(class, CLASS, uint8_t)
378b0cb115fSWarner Losh PCI_ACCESSOR(subclass, SUBCLASS, uint8_t)
379b0cb115fSWarner Losh PCI_ACCESSOR(progif, PROGIF, uint8_t)
380b0cb115fSWarner Losh PCI_ACCESSOR(revid, REVID, uint8_t)
381b0cb115fSWarner Losh PCI_ACCESSOR(intpin, INTPIN, uint8_t)
382b0cb115fSWarner Losh PCI_ACCESSOR(irq, IRQ, uint8_t)
38355aaf894SMarius Strobl PCI_ACCESSOR(domain, DOMAIN, uint32_t)
384b0cb115fSWarner Losh PCI_ACCESSOR(bus, BUS, uint8_t)
385b0cb115fSWarner Losh PCI_ACCESSOR(slot, SLOT, uint8_t)
386b0cb115fSWarner Losh PCI_ACCESSOR(function, FUNCTION, uint8_t)
387b0cb115fSWarner Losh PCI_ACCESSOR(ether, ETHADDR, uint8_t *)
3886de560abSWarner Losh PCI_ACCESSOR(cmdreg, CMDREG, uint8_t)
3896de560abSWarner Losh PCI_ACCESSOR(cachelnsz, CACHELNSZ, uint8_t)
3906de560abSWarner Losh PCI_ACCESSOR(mingnt, MINGNT, uint8_t)
3916de560abSWarner Losh PCI_ACCESSOR(maxlat, MAXLAT, uint8_t)
3926de560abSWarner Losh PCI_ACCESSOR(lattimer, LATTIMER, uint8_t)
3936182fdbdSPeter Wemm
394b6c84078SPeter Wemm #undef PCI_ACCESSOR
395b6c84078SPeter Wemm
3968983cfbfSMike Smith /*
3978983cfbfSMike Smith * Operations on configuration space.
3988983cfbfSMike Smith */
399b0cb115fSWarner Losh static __inline uint32_t
4006182fdbdSPeter Wemm pci_read_config(device_t dev, int reg, int width)
4016182fdbdSPeter Wemm {
4026182fdbdSPeter Wemm return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width);
4036182fdbdSPeter Wemm }
4046182fdbdSPeter Wemm
4056182fdbdSPeter Wemm static __inline void
pci_write_config(device_t dev,int reg,uint32_t val,int width)406b0cb115fSWarner Losh pci_write_config(device_t dev, int reg, uint32_t val, int width)
4076182fdbdSPeter Wemm {
4086182fdbdSPeter Wemm PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width);
4096182fdbdSPeter Wemm }
4106182fdbdSPeter Wemm
411aa6de8e0SAndrew Gallatin /*
412aa6de8e0SAndrew Gallatin * Ivars for pci bridges.
413aa6de8e0SAndrew Gallatin */
414aa6de8e0SAndrew Gallatin
415aa6de8e0SAndrew Gallatin /*typedef enum pci_device_ivars pcib_device_ivars;*/
416aa6de8e0SAndrew Gallatin enum pcib_device_ivars {
41755aaf894SMarius Strobl PCIB_IVAR_DOMAIN,
41821c3015aSDoug Rabson PCIB_IVAR_BUS
419aa6de8e0SAndrew Gallatin };
420aa6de8e0SAndrew Gallatin
421e9cf2ddbSMaxime Henrion #define PCIB_ACCESSOR(var, ivar, type) \
422e9cf2ddbSMaxime Henrion __BUS_ACCESSOR(pcib, var, PCIB, ivar, type)
423aa6de8e0SAndrew Gallatin
PCIB_ACCESSOR(domain,DOMAIN,uint32_t)42455aaf894SMarius Strobl PCIB_ACCESSOR(domain, DOMAIN, uint32_t)
425b0cb115fSWarner Losh PCIB_ACCESSOR(bus, BUS, uint32_t)
426aa6de8e0SAndrew Gallatin
427b6c84078SPeter Wemm #undef PCIB_ACCESSOR
428b6c84078SPeter Wemm
4298983cfbfSMike Smith /*
430a1e85ec6SWarner Losh * PCI interrupt validation. Invalid interrupt values such as 0 or 128
431a1e85ec6SWarner Losh * on i386 or other platforms should be mapped out in the MD pcireadconf
432a1e85ec6SWarner Losh * code and not here, since the only MI invalid IRQ is 255.
4338046c4b9SMike Smith */
434f60115a3SWarner Losh #define PCI_INVALID_IRQ 255
435a1e85ec6SWarner Losh #define PCI_INTERRUPT_VALID(x) ((x) != PCI_INVALID_IRQ)
4368046c4b9SMike Smith
4378046c4b9SMike Smith /*
4388983cfbfSMike Smith * Convenience functions.
4398983cfbfSMike Smith *
4408983cfbfSMike Smith * These should be used in preference to manually manipulating
4418983cfbfSMike Smith * configuration space.
4428983cfbfSMike Smith */
443c047e5b1SMatthew N. Dodd static __inline int
4449eb13b39SPeter Wemm pci_enable_busmaster(device_t dev)
4459eb13b39SPeter Wemm {
446c047e5b1SMatthew N. Dodd return(PCI_ENABLE_BUSMASTER(device_get_parent(dev), dev));
4479eb13b39SPeter Wemm }
4489eb13b39SPeter Wemm
449c047e5b1SMatthew N. Dodd static __inline int
pci_disable_busmaster(device_t dev)4509eb13b39SPeter Wemm pci_disable_busmaster(device_t dev)
4519eb13b39SPeter Wemm {
452c047e5b1SMatthew N. Dodd return(PCI_DISABLE_BUSMASTER(device_get_parent(dev), dev));
4539eb13b39SPeter Wemm }
4549eb13b39SPeter Wemm
455c047e5b1SMatthew N. Dodd static __inline int
pci_enable_io(device_t dev,int space)4569eb13b39SPeter Wemm pci_enable_io(device_t dev, int space)
4579eb13b39SPeter Wemm {
458c047e5b1SMatthew N. Dodd return(PCI_ENABLE_IO(device_get_parent(dev), dev, space));
4599eb13b39SPeter Wemm }
4609eb13b39SPeter Wemm
461c047e5b1SMatthew N. Dodd static __inline int
pci_disable_io(device_t dev,int space)4629eb13b39SPeter Wemm pci_disable_io(device_t dev, int space)
4639eb13b39SPeter Wemm {
464c047e5b1SMatthew N. Dodd return(PCI_DISABLE_IO(device_get_parent(dev), dev, space));
4659eb13b39SPeter Wemm }
4666182fdbdSPeter Wemm
467667dc26eSJohn-Mark Gurney static __inline int
pci_get_vpd_ident(device_t dev,const char ** identptr)468667dc26eSJohn-Mark Gurney pci_get_vpd_ident(device_t dev, const char **identptr)
469667dc26eSJohn-Mark Gurney {
470667dc26eSJohn-Mark Gurney return(PCI_GET_VPD_IDENT(device_get_parent(dev), dev, identptr));
471667dc26eSJohn-Mark Gurney }
472667dc26eSJohn-Mark Gurney
473667dc26eSJohn-Mark Gurney static __inline int
pci_get_vpd_readonly(device_t dev,const char * kw,const char ** vptr)47437bf8b5fSJohn Baldwin pci_get_vpd_readonly(device_t dev, const char *kw, const char **vptr)
475667dc26eSJohn-Mark Gurney {
47637bf8b5fSJohn Baldwin return(PCI_GET_VPD_READONLY(device_get_parent(dev), dev, kw, vptr));
477667dc26eSJohn-Mark Gurney }
478667dc26eSJohn-Mark Gurney
4798983cfbfSMike Smith /*
4809929ff6bSMarcel Moolenaar * Check if the address range falls within the VGA defined address range(s)
4819929ff6bSMarcel Moolenaar */
4829929ff6bSMarcel Moolenaar static __inline int
pci_is_vga_ioport_range(rman_res_t start,rman_res_t end)4832dd1bdf1SJustin Hibbits pci_is_vga_ioport_range(rman_res_t start, rman_res_t end)
4849929ff6bSMarcel Moolenaar {
4859929ff6bSMarcel Moolenaar
4869929ff6bSMarcel Moolenaar return (((start >= 0x3b0 && end <= 0x3bb) ||
4879929ff6bSMarcel Moolenaar (start >= 0x3c0 && end <= 0x3df)) ? 1 : 0);
4889929ff6bSMarcel Moolenaar }
4899929ff6bSMarcel Moolenaar
4909929ff6bSMarcel Moolenaar static __inline int
pci_is_vga_memory_range(rman_res_t start,rman_res_t end)4912dd1bdf1SJustin Hibbits pci_is_vga_memory_range(rman_res_t start, rman_res_t end)
4929929ff6bSMarcel Moolenaar {
4939929ff6bSMarcel Moolenaar
4949929ff6bSMarcel Moolenaar return ((start >= 0xa0000 && end <= 0xbffff) ? 1 : 0);
4959929ff6bSMarcel Moolenaar }
4969929ff6bSMarcel Moolenaar
4979929ff6bSMarcel Moolenaar /*
4988983cfbfSMike Smith * PCI power states are as defined by ACPI:
4998983cfbfSMike Smith *
5008983cfbfSMike Smith * D0 State in which device is on and running. It is receiving full
5018983cfbfSMike Smith * power from the system and delivering full functionality to the user.
5028983cfbfSMike Smith * D1 Class-specific low-power state in which device context may or may not
5038983cfbfSMike Smith * be lost. Buses in D1 cannot do anything to the bus that would force
504776fc0e9SYaroslav Tykhiy * devices on that bus to lose context.
5058983cfbfSMike Smith * D2 Class-specific low-power state in which device context may or may
5068983cfbfSMike Smith * not be lost. Attains greater power savings than D1. Buses in D2
507776fc0e9SYaroslav Tykhiy * can cause devices on that bus to lose some context. Devices in D2
5088983cfbfSMike Smith * must be prepared for the bus to be in D2 or higher.
5098983cfbfSMike Smith * D3 State in which the device is off and not running. Device context is
5108983cfbfSMike Smith * lost. Power can be removed from the device.
5118983cfbfSMike Smith */
5128983cfbfSMike Smith #define PCI_POWERSTATE_D0 0
5138983cfbfSMike Smith #define PCI_POWERSTATE_D1 1
5148983cfbfSMike Smith #define PCI_POWERSTATE_D2 2
5158983cfbfSMike Smith #define PCI_POWERSTATE_D3 3
5168983cfbfSMike Smith #define PCI_POWERSTATE_UNKNOWN -1
5175bec6157SStefan Eßer
5189eb13b39SPeter Wemm static __inline int
pci_set_powerstate(device_t dev,int state)5199eb13b39SPeter Wemm pci_set_powerstate(device_t dev, int state)
5209eb13b39SPeter Wemm {
5219eb13b39SPeter Wemm return PCI_SET_POWERSTATE(device_get_parent(dev), dev, state);
5229eb13b39SPeter Wemm }
5239eb13b39SPeter Wemm
5249eb13b39SPeter Wemm static __inline int
pci_get_powerstate(device_t dev)5259eb13b39SPeter Wemm pci_get_powerstate(device_t dev)
5269eb13b39SPeter Wemm {
5279eb13b39SPeter Wemm return PCI_GET_POWERSTATE(device_get_parent(dev), dev);
5289eb13b39SPeter Wemm }
52980060e88SPeter Wemm
5304f9795b9SJohn Baldwin static __inline int
pci_find_cap(device_t dev,int capability,int * capreg)531e786cbfdSJohn Baldwin pci_find_cap(device_t dev, int capability, int *capreg)
532e786cbfdSJohn Baldwin {
533c668000bSJohn Baldwin return (PCI_FIND_CAP(device_get_parent(dev), dev, capability, capreg));
534e786cbfdSJohn Baldwin }
535e786cbfdSJohn Baldwin
536e786cbfdSJohn Baldwin static __inline int
pci_find_next_cap(device_t dev,int capability,int start,int * capreg)5377a16dacdSBryan Venteicher pci_find_next_cap(device_t dev, int capability, int start, int *capreg)
5387a16dacdSBryan Venteicher {
5397a16dacdSBryan Venteicher return (PCI_FIND_NEXT_CAP(device_get_parent(dev), dev, capability, start,
5407a16dacdSBryan Venteicher capreg));
5417a16dacdSBryan Venteicher }
5427a16dacdSBryan Venteicher
5437a16dacdSBryan Venteicher static __inline int
pci_find_extcap(device_t dev,int capability,int * capreg)5444f9795b9SJohn Baldwin pci_find_extcap(device_t dev, int capability, int *capreg)
5454f9795b9SJohn Baldwin {
546e786cbfdSJohn Baldwin return (PCI_FIND_EXTCAP(device_get_parent(dev), dev, capability, capreg));
5474f9795b9SJohn Baldwin }
5484f9795b9SJohn Baldwin
5499bf4c9c1SJohn Baldwin static __inline int
pci_find_next_extcap(device_t dev,int capability,int start,int * capreg)5507a16dacdSBryan Venteicher pci_find_next_extcap(device_t dev, int capability, int start, int *capreg)
5517a16dacdSBryan Venteicher {
5527a16dacdSBryan Venteicher return (PCI_FIND_NEXT_EXTCAP(device_get_parent(dev), dev, capability,
5537a16dacdSBryan Venteicher start, capreg));
5547a16dacdSBryan Venteicher }
5557a16dacdSBryan Venteicher
5567a16dacdSBryan Venteicher static __inline int
pci_find_htcap(device_t dev,int capability,int * capreg)557c668000bSJohn Baldwin pci_find_htcap(device_t dev, int capability, int *capreg)
558c668000bSJohn Baldwin {
559c668000bSJohn Baldwin return (PCI_FIND_HTCAP(device_get_parent(dev), dev, capability, capreg));
560c668000bSJohn Baldwin }
561c668000bSJohn Baldwin
562c668000bSJohn Baldwin static __inline int
pci_find_next_htcap(device_t dev,int capability,int start,int * capreg)5637a16dacdSBryan Venteicher pci_find_next_htcap(device_t dev, int capability, int start, int *capreg)
5647a16dacdSBryan Venteicher {
5657a16dacdSBryan Venteicher return (PCI_FIND_NEXT_HTCAP(device_get_parent(dev), dev, capability,
5667a16dacdSBryan Venteicher start, capreg));
5677a16dacdSBryan Venteicher }
5687a16dacdSBryan Venteicher
5697a16dacdSBryan Venteicher static __inline int
pci_alloc_msi(device_t dev,int * count)5709bf4c9c1SJohn Baldwin pci_alloc_msi(device_t dev, int *count)
5719bf4c9c1SJohn Baldwin {
5729bf4c9c1SJohn Baldwin return (PCI_ALLOC_MSI(device_get_parent(dev), dev, count));
5739bf4c9c1SJohn Baldwin }
5749bf4c9c1SJohn Baldwin
5759bf4c9c1SJohn Baldwin static __inline int
pci_alloc_msix(device_t dev,int * count)5765fe82bcaSJohn Baldwin pci_alloc_msix(device_t dev, int *count)
5775fe82bcaSJohn Baldwin {
5785fe82bcaSJohn Baldwin return (PCI_ALLOC_MSIX(device_get_parent(dev), dev, count));
5795fe82bcaSJohn Baldwin }
5805fe82bcaSJohn Baldwin
581073bf9ddSRoger Pau Monné static __inline void
pci_enable_msi(device_t dev,uint64_t address,uint16_t data)582073bf9ddSRoger Pau Monné pci_enable_msi(device_t dev, uint64_t address, uint16_t data)
583073bf9ddSRoger Pau Monné {
584073bf9ddSRoger Pau Monné PCI_ENABLE_MSI(device_get_parent(dev), dev, address, data);
585073bf9ddSRoger Pau Monné }
586073bf9ddSRoger Pau Monné
587073bf9ddSRoger Pau Monné static __inline void
pci_enable_msix(device_t dev,u_int index,uint64_t address,uint32_t data)588073bf9ddSRoger Pau Monné pci_enable_msix(device_t dev, u_int index, uint64_t address, uint32_t data)
589073bf9ddSRoger Pau Monné {
590073bf9ddSRoger Pau Monné PCI_ENABLE_MSIX(device_get_parent(dev), dev, index, address, data);
591073bf9ddSRoger Pau Monné }
592073bf9ddSRoger Pau Monné
593073bf9ddSRoger Pau Monné static __inline void
pci_disable_msi(device_t dev)594073bf9ddSRoger Pau Monné pci_disable_msi(device_t dev)
595073bf9ddSRoger Pau Monné {
596073bf9ddSRoger Pau Monné PCI_DISABLE_MSI(device_get_parent(dev), dev);
597073bf9ddSRoger Pau Monné }
598073bf9ddSRoger Pau Monné
5995fe82bcaSJohn Baldwin static __inline int
pci_remap_msix(device_t dev,int count,const u_int * vectors)600e706f7f0SJohn Baldwin pci_remap_msix(device_t dev, int count, const u_int *vectors)
6015fe82bcaSJohn Baldwin {
602e706f7f0SJohn Baldwin return (PCI_REMAP_MSIX(device_get_parent(dev), dev, count, vectors));
6035fe82bcaSJohn Baldwin }
6045fe82bcaSJohn Baldwin
6055fe82bcaSJohn Baldwin static __inline int
pci_release_msi(device_t dev)6069bf4c9c1SJohn Baldwin pci_release_msi(device_t dev)
6079bf4c9c1SJohn Baldwin {
6089bf4c9c1SJohn Baldwin return (PCI_RELEASE_MSI(device_get_parent(dev), dev));
6099bf4c9c1SJohn Baldwin }
6109bf4c9c1SJohn Baldwin
6119bf4c9c1SJohn Baldwin static __inline int
pci_msi_count(device_t dev)6129bf4c9c1SJohn Baldwin pci_msi_count(device_t dev)
6139bf4c9c1SJohn Baldwin {
6149bf4c9c1SJohn Baldwin return (PCI_MSI_COUNT(device_get_parent(dev), dev));
6159bf4c9c1SJohn Baldwin }
6169bf4c9c1SJohn Baldwin
6175fe82bcaSJohn Baldwin static __inline int
pci_msix_count(device_t dev)6185fe82bcaSJohn Baldwin pci_msix_count(device_t dev)
6195fe82bcaSJohn Baldwin {
6205fe82bcaSJohn Baldwin return (PCI_MSIX_COUNT(device_get_parent(dev), dev));
6215fe82bcaSJohn Baldwin }
6225fe82bcaSJohn Baldwin
623ce204e1bSJohn Baldwin static __inline int
pci_msix_pba_bar(device_t dev)624ce204e1bSJohn Baldwin pci_msix_pba_bar(device_t dev)
625ce204e1bSJohn Baldwin {
626ce204e1bSJohn Baldwin return (PCI_MSIX_PBA_BAR(device_get_parent(dev), dev));
627ce204e1bSJohn Baldwin }
628ce204e1bSJohn Baldwin
629ce204e1bSJohn Baldwin static __inline int
pci_msix_table_bar(device_t dev)630ce204e1bSJohn Baldwin pci_msix_table_bar(device_t dev)
631ce204e1bSJohn Baldwin {
632ce204e1bSJohn Baldwin return (PCI_MSIX_TABLE_BAR(device_get_parent(dev), dev));
633ce204e1bSJohn Baldwin }
634ce204e1bSJohn Baldwin
635d7be980dSAndrew Turner static __inline int
pci_get_id(device_t dev,enum pci_id_type type,uintptr_t * id)636d7be980dSAndrew Turner pci_get_id(device_t dev, enum pci_id_type type, uintptr_t *id)
637d7be980dSAndrew Turner {
638d7be980dSAndrew Turner return (PCI_GET_ID(device_get_parent(dev), dev, type, id));
639d7be980dSAndrew Turner }
640d7be980dSAndrew Turner
641d7be980dSAndrew Turner /*
642d7be980dSAndrew Turner * This is the deprecated interface, there is no way to tell the difference
643d7be980dSAndrew Turner * between a failure and a valid value that happens to be the same as the
644d7be980dSAndrew Turner * failure value.
645d7be980dSAndrew Turner */
6465605a99eSRyan Stone static __inline uint16_t
pci_get_rid(device_t dev)6475605a99eSRyan Stone pci_get_rid(device_t dev)
6485605a99eSRyan Stone {
649d7be980dSAndrew Turner uintptr_t rid;
650d7be980dSAndrew Turner
651d7be980dSAndrew Turner if (pci_get_id(dev, PCI_ID_RID, &rid) != 0)
652d7be980dSAndrew Turner return (0);
653d7be980dSAndrew Turner
654d7be980dSAndrew Turner return (rid);
6555605a99eSRyan Stone }
6565605a99eSRyan Stone
657cd407ca2SRoger Pau Monné static __inline void
pci_child_added(device_t dev)658cd407ca2SRoger Pau Monné pci_child_added(device_t dev)
659cd407ca2SRoger Pau Monné {
660cd407ca2SRoger Pau Monné
661cd407ca2SRoger Pau Monné return (PCI_CHILD_ADDED(device_get_parent(dev), dev));
662cd407ca2SRoger Pau Monné }
663cd407ca2SRoger Pau Monné
664b0cb115fSWarner Losh device_t pci_find_bsf(uint8_t, uint8_t, uint8_t);
66555aaf894SMarius Strobl device_t pci_find_dbsf(uint32_t, uint8_t, uint8_t, uint8_t);
666b0cb115fSWarner Losh device_t pci_find_device(uint16_t, uint16_t);
667141c08f9SKonstantin Belousov device_t pci_find_class(uint8_t class, uint8_t subclass);
6688517a547SEmmanuel Vadot device_t pci_find_class_from(uint8_t class, uint8_t subclass, device_t devfrom);
669c118e4daSJean-Sébastien Pédron device_t pci_find_base_class_from(uint8_t class, device_t devfrom);
6709bf4c9c1SJohn Baldwin
671e706f7f0SJohn Baldwin /* Can be used by drivers to manage the MSI-X table. */
6729bf4c9c1SJohn Baldwin int pci_pending_msix(device_t dev, u_int index);
673e706f7f0SJohn Baldwin
674e31182d9SJohn Baldwin int pci_msi_device_blacklisted(device_t dev);
67568e9cbd3SMarius Strobl int pci_msix_device_blacklisted(device_t dev);
6769bf4c9c1SJohn Baldwin
6774522ac77SLuoqi Chen void pci_ht_map_msi(device_t dev, uint64_t addr);
6784522ac77SLuoqi Chen
67987dd2f95SJohn Baldwin device_t pci_find_pcie_root_port(device_t dev);
6801acf24a0SHans Petter Selasky int pci_get_relaxed_ordering_enabled(device_t dev);
6812ab0398dSJohn Baldwin int pci_get_max_payload(device_t dev);
68224d6a5edSAlexander Motin int pci_get_max_read_req(device_t dev);
6839415d1e0SJohn Baldwin void pci_restore_state(device_t dev);
6849415d1e0SJohn Baldwin void pci_save_state(device_t dev);
68524d6a5edSAlexander Motin int pci_set_max_read_req(device_t dev, int size);
6865db2a4a8SKonstantin Belousov int pci_power_reset(device_t dev);
68782d69277SJohn Baldwin void pci_clear_pme(device_t dev);
688e5cbf0e8SJohn Baldwin void pci_enable_pme(device_t dev);
689e5cbf0e8SJohn Baldwin bool pci_has_pm(device_t dev);
690ec603c72SJohn Baldwin uint32_t pcie_read_config(device_t dev, int reg, int width);
691ec603c72SJohn Baldwin void pcie_write_config(device_t dev, int reg, uint32_t value, int width);
692ec603c72SJohn Baldwin uint32_t pcie_adjust_config(device_t dev, int reg, uint32_t mask,
693ec603c72SJohn Baldwin uint32_t value, int width);
694855e49f3SAlexander Motin void pcie_apei_error(device_t dev, int sev, uint8_t *aer);
695da0fc925SJohn Baldwin bool pcie_flr(device_t dev, u_int max_delay, bool force);
696da0fc925SJohn Baldwin int pcie_get_max_completion_timeout(device_t dev);
697da0fc925SJohn Baldwin bool pcie_wait_for_pending_transactions(device_t dev, u_int max_delay);
6985db2a4a8SKonstantin Belousov int pcie_link_reset(device_t port, int pcie_location);
699feb96b46SKonstantin Belousov
7001ace6e5bSKonstantin Belousov void pci_print_faulted_dev(void);
7011ace6e5bSKonstantin Belousov
7028983cfbfSMike Smith #endif /* _SYS_BUS_H_ */
70330d1c11eSPeter Wemm
7048983cfbfSMike Smith /*
7058983cfbfSMike Smith * cdev switch for control device, initialised in generic PCI code
7068983cfbfSMike Smith */
7078983cfbfSMike Smith extern struct cdevsw pcicdev;
70880060e88SPeter Wemm
7098983cfbfSMike Smith /*
7108983cfbfSMike Smith * List of all PCI devices, generation count for the list.
7118983cfbfSMike Smith */
71247676b53SMatthew N. Dodd STAILQ_HEAD(devlist, pci_devinfo);
71347676b53SMatthew N. Dodd
71447676b53SMatthew N. Dodd extern struct devlist pci_devq;
715b0cb115fSWarner Losh extern uint32_t pci_generation;
71646f40af0SPeter Wemm
717a90dd577SJohn Baldwin struct pci_map *pci_find_bar(device_t dev, int reg);
71816bedf53SJohn Baldwin struct pci_map *pci_first_bar(device_t dev);
71916bedf53SJohn Baldwin struct pci_map *pci_next_bar(struct pci_map *pm);
720a90dd577SJohn Baldwin int pci_bar_enabled(device_t dev, struct pci_map *pm);
72184b755dfSJohn Baldwin struct pcicfg_vpd *pci_fetch_vpd_list(device_t dev);
722a90dd577SJohn Baldwin
723509a8ff6SJean-Sébastien Pédron #define VGA_PCI_BIOS_SHADOW_ADDR 0xC0000
724509a8ff6SJean-Sébastien Pédron #define VGA_PCI_BIOS_SHADOW_SIZE 131072
725509a8ff6SJean-Sébastien Pédron
726509a8ff6SJean-Sébastien Pédron int vga_pci_is_boot_display(device_t dev);
727509a8ff6SJean-Sébastien Pédron void * vga_pci_map_bios(device_t dev, size_t *size);
728509a8ff6SJean-Sébastien Pédron void vga_pci_unmap_bios(device_t dev, void *bios);
729be440d68SJean-Sébastien Pédron int vga_pci_repost(device_t dev);
730509a8ff6SJean-Sébastien Pédron
73164414cc0SJohn Baldwin /**
73264414cc0SJohn Baldwin * Global eventhandlers invoked when PCI devices are added or removed
73364414cc0SJohn Baldwin * from the system.
73464414cc0SJohn Baldwin */
73564414cc0SJohn Baldwin typedef void (*pci_event_fn)(void *arg, device_t dev);
73664414cc0SJohn Baldwin EVENTHANDLER_DECLARE(pci_add_device, pci_event_fn);
73764414cc0SJohn Baldwin EVENTHANDLER_DECLARE(pci_delete_device, pci_event_fn);
73864414cc0SJohn Baldwin
73906915ea6SJustin T. Gibbs #endif /* _PCIVAR_H_ */
740