source: rtems-libbsd/freebsd/dev/pci/pcivar.h @ fb4c8a9

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since fb4c8a9 was fb4c8a9, checked in by Jennifer Averett <jennifer.averett@…>, on 05/23/12 at 19:53:12

Added pcib for Nics.

  • Property mode set to 100644
File size: 14.5 KB
Line 
1/*-
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD$
27 *
28 */
29
30#ifndef _PCIVAR_HH_
31#define _PCIVAR_HH_
32
33#include <freebsd/sys/queue.h>
34
35/* some PCI bus constants */
36#define PCI_MAXMAPS_0   6       /* max. no. of memory/port maps */
37#define PCI_MAXMAPS_1   2       /* max. no. of maps for PCI to PCI bridge */
38#define PCI_MAXMAPS_2   1       /* max. no. of maps for CardBus bridge */
39
40typedef uint64_t pci_addr_t;
41
42/* Interesting values for PCI power management */
43struct pcicfg_pp {
44    uint16_t    pp_cap;         /* PCI power management capabilities */
45    uint8_t     pp_status;      /* config space address of PCI power status reg */
46    uint8_t     pp_pmcsr;       /* config space address of PMCSR reg */
47    uint8_t     pp_data;        /* config space address of PCI power data reg */
48};
49 
50struct vpd_readonly {
51    char        keyword[2];
52    char        *value;
53};
54
55struct vpd_write {
56    char        keyword[2];
57    char        *value;
58    int         start;
59    int         len;
60};
61
62struct pcicfg_vpd {
63    uint8_t     vpd_reg;        /* base register, + 2 for addr, + 4 data */
64    char        vpd_cached;
65    char        *vpd_ident;     /* string identifier */
66    int         vpd_rocnt;
67    struct vpd_readonly *vpd_ros;
68    int         vpd_wcnt;
69    struct vpd_write *vpd_w;
70};
71
72/* Interesting values for PCI MSI */
73struct pcicfg_msi {
74    uint16_t    msi_ctrl;       /* Message Control */
75    uint8_t     msi_location;   /* Offset of MSI capability registers. */
76    uint8_t     msi_msgnum;     /* Number of messages */
77    int         msi_alloc;      /* Number of allocated messages. */
78    uint64_t    msi_addr;       /* Contents of address register. */
79    uint16_t    msi_data;       /* Contents of data register. */
80    u_int       msi_handlers;
81};
82
83/* Interesting values for PCI MSI-X */
84struct msix_vector {
85    uint64_t    mv_address;     /* Contents of address register. */
86    uint32_t    mv_data;        /* Contents of data register. */
87    int         mv_irq;
88};
89
90struct msix_table_entry {
91    u_int       mte_vector;     /* 1-based index into msix_vectors array. */
92    u_int       mte_handlers;
93};
94
95struct pcicfg_msix {
96    uint16_t    msix_ctrl;      /* Message Control */
97    uint16_t    msix_msgnum;    /* Number of messages */
98    uint8_t     msix_location;  /* Offset of MSI-X capability registers. */
99    uint8_t     msix_table_bar; /* BAR containing vector table. */
100    uint8_t     msix_pba_bar;   /* BAR containing PBA. */
101    uint32_t    msix_table_offset;
102    uint32_t    msix_pba_offset;
103    int         msix_alloc;     /* Number of allocated vectors. */
104    int         msix_table_len; /* Length of virtual table. */
105    struct msix_table_entry *msix_table; /* Virtual table. */
106    struct msix_vector *msix_vectors;   /* Array of allocated vectors. */
107    struct resource *msix_table_res;    /* Resource containing vector table. */
108    struct resource *msix_pba_res;      /* Resource containing PBA. */
109};
110
111/* Interesting values for HyperTransport */
112struct pcicfg_ht {
113    uint8_t     ht_msimap;      /* Offset of MSI mapping cap registers. */
114    uint16_t    ht_msictrl;     /* MSI mapping control */
115    uint64_t    ht_msiaddr;     /* MSI mapping base address */
116};
117
118/* config header information common to all header types */
119typedef struct pcicfg {
120    struct device *dev;         /* device which owns this */
121
122    uint32_t    bar[PCI_MAXMAPS_0]; /* BARs */
123    uint32_t    bios;           /* BIOS mapping */
124
125    uint16_t    subvendor;      /* card vendor ID */
126    uint16_t    subdevice;      /* card device ID, assigned by card vendor */
127    uint16_t    vendor;         /* chip vendor ID */
128    uint16_t    device;         /* chip device ID, assigned by chip vendor */
129
130    uint16_t    cmdreg;         /* disable/enable chip and PCI options */
131    uint16_t    statreg;        /* supported PCI features and error state */
132
133    uint8_t     baseclass;      /* chip PCI class */
134    uint8_t     subclass;       /* chip PCI subclass */
135    uint8_t     progif;         /* chip PCI programming interface */
136    uint8_t     revid;          /* chip revision ID */
137
138    uint8_t     hdrtype;        /* chip config header type */
139    uint8_t     cachelnsz;      /* cache line size in 4byte units */
140    uint8_t     intpin;         /* PCI interrupt pin */
141    uint8_t     intline;        /* interrupt line (IRQ for PC arch) */
142
143    uint8_t     mingnt;         /* min. useful bus grant time in 250ns units */
144    uint8_t     maxlat;         /* max. tolerated bus grant latency in 250ns */
145    uint8_t     lattimer;       /* latency timer in units of 30ns bus cycles */
146
147    uint8_t     mfdev;          /* multi-function device (from hdrtype reg) */
148    uint8_t     nummaps;        /* actual number of PCI maps used */
149
150    uint32_t    domain;         /* PCI domain */
151    uint8_t     bus;            /* config space bus address */
152    uint8_t     slot;           /* config space slot address */
153    uint8_t     func;           /* config space function number */
154
155    struct pcicfg_pp pp;        /* Power management */
156    struct pcicfg_vpd vpd;      /* Vital product data */
157    struct pcicfg_msi msi;      /* PCI MSI */
158    struct pcicfg_msix msix;    /* PCI MSI-X */
159    struct pcicfg_ht ht;        /* HyperTransport */
160} pcicfgregs;
161
162/* additional type 1 device config header information (PCI to PCI bridge) */
163
164#define PCI_PPBMEMBASE(h,l)  ((((pci_addr_t)(h) << 32) + ((l)<<16)) & ~0xfffff)
165#define PCI_PPBMEMLIMIT(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) | 0xfffff)
166#define PCI_PPBIOBASE(h,l)   ((((h)<<16) + ((l)<<8)) & ~0xfff)
167#define PCI_PPBIOLIMIT(h,l)  ((((h)<<16) + ((l)<<8)) | 0xfff)
168
169typedef struct {
170    pci_addr_t  pmembase;       /* base address of prefetchable memory */
171    pci_addr_t  pmemlimit;      /* topmost address of prefetchable memory */
172    uint32_t    membase;        /* base address of memory window */
173    uint32_t    memlimit;       /* topmost address of memory window */
174    uint32_t    iobase;         /* base address of port window */
175    uint32_t    iolimit;        /* topmost address of port window */
176    uint16_t    secstat;        /* secondary bus status register */
177    uint16_t    bridgectl;      /* bridge control register */
178    uint8_t     seclat;         /* CardBus latency timer */
179} pcih1cfgregs;
180
181/* additional type 2 device config header information (CardBus bridge) */
182
183typedef struct {
184    uint32_t    membase0;       /* base address of memory window */
185    uint32_t    memlimit0;      /* topmost address of memory window */
186    uint32_t    membase1;       /* base address of memory window */
187    uint32_t    memlimit1;      /* topmost address of memory window */
188    uint32_t    iobase0;        /* base address of port window */
189    uint32_t    iolimit0;       /* topmost address of port window */
190    uint32_t    iobase1;        /* base address of port window */
191    uint32_t    iolimit1;       /* topmost address of port window */
192    uint32_t    pccardif;       /* PC Card 16bit IF legacy more base addr. */
193    uint16_t    secstat;        /* secondary bus status register */
194    uint16_t    bridgectl;      /* bridge control register */
195    uint8_t     seclat;         /* CardBus latency timer */
196} pcih2cfgregs;
197
198extern uint32_t pci_numdevs;
199
200/* Only if the prerequisites are present */
201#if defined(_SYS_BUS_HH_) && defined(_SYS_PCIIO_HH_)
202struct pci_devinfo {
203        STAILQ_ENTRY(pci_devinfo) pci_links;
204        struct resource_list resources;
205        pcicfgregs              cfg;
206        struct pci_conf         conf;
207};
208#endif
209
210#ifdef _SYS_BUS_HH_
211
212#include <freebsd/local/pci_if.h>
213
214enum pci_device_ivars {
215    PCI_IVAR_SUBVENDOR,
216    PCI_IVAR_SUBDEVICE,
217    PCI_IVAR_VENDOR,
218    PCI_IVAR_DEVICE,
219    PCI_IVAR_DEVID,
220    PCI_IVAR_CLASS,
221    PCI_IVAR_SUBCLASS,
222    PCI_IVAR_PROGIF,
223    PCI_IVAR_REVID,
224    PCI_IVAR_INTPIN,
225    PCI_IVAR_IRQ,
226    PCI_IVAR_DOMAIN,
227    PCI_IVAR_BUS,
228    PCI_IVAR_SLOT,
229    PCI_IVAR_FUNCTION,
230    PCI_IVAR_ETHADDR,
231    PCI_IVAR_CMDREG,
232    PCI_IVAR_CACHELNSZ,
233    PCI_IVAR_MINGNT,
234    PCI_IVAR_MAXLAT,
235    PCI_IVAR_LATTIMER
236};
237
238/*
239 * Simplified accessors for pci devices
240 */
241#define PCI_ACCESSOR(var, ivar, type)                                   \
242        __BUS_ACCESSOR(pci, var, PCI, ivar, type)
243
244PCI_ACCESSOR(subvendor,         SUBVENDOR,      uint16_t)
245PCI_ACCESSOR(subdevice,         SUBDEVICE,      uint16_t)
246PCI_ACCESSOR(vendor,            VENDOR,         uint16_t)
247PCI_ACCESSOR(device,            DEVICE,         uint16_t)
248PCI_ACCESSOR(devid,             DEVID,          uint32_t)
249PCI_ACCESSOR(class,             CLASS,          uint8_t)
250PCI_ACCESSOR(subclass,          SUBCLASS,       uint8_t)
251PCI_ACCESSOR(progif,            PROGIF,         uint8_t)
252PCI_ACCESSOR(revid,             REVID,          uint8_t)
253PCI_ACCESSOR(intpin,            INTPIN,         uint8_t)
254PCI_ACCESSOR(irq,               IRQ,            uint8_t)
255PCI_ACCESSOR(domain,            DOMAIN,         uint32_t)
256PCI_ACCESSOR(bus,               BUS,            uint8_t)
257PCI_ACCESSOR(slot,              SLOT,           uint8_t)
258PCI_ACCESSOR(function,          FUNCTION,       uint8_t)
259PCI_ACCESSOR(ether,             ETHADDR,        uint8_t *)
260PCI_ACCESSOR(cmdreg,            CMDREG,         uint8_t)
261PCI_ACCESSOR(cachelnsz,         CACHELNSZ,      uint8_t)
262PCI_ACCESSOR(mingnt,            MINGNT,         uint8_t)
263PCI_ACCESSOR(maxlat,            MAXLAT,         uint8_t)
264PCI_ACCESSOR(lattimer,          LATTIMER,       uint8_t)
265
266#undef PCI_ACCESSOR
267
268/*
269 * Operations on configuration space.
270 */
271static __inline uint32_t
272pci_read_config(device_t dev, int reg, int width)
273{
274    return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width);
275}
276
277static __inline void
278pci_write_config(device_t dev, int reg, uint32_t val, int width)
279{
280    PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width);
281}
282
283/*
284 * Ivars for pci bridges.
285 */
286
287/*typedef enum pci_device_ivars pcib_device_ivars;*/
288enum pcib_device_ivars {
289        PCIB_IVAR_DOMAIN,
290        PCIB_IVAR_BUS
291};
292
293#define PCIB_ACCESSOR(var, ivar, type)                                   \
294    __BUS_ACCESSOR(pcib, var, PCIB, ivar, type)
295
296PCIB_ACCESSOR(domain,           DOMAIN,         uint32_t)
297PCIB_ACCESSOR(bus,              BUS,            uint32_t)
298
299#undef PCIB_ACCESSOR
300
301/*
302 * PCI interrupt validation.  Invalid interrupt values such as 0 or 128
303 * on i386 or other platforms should be mapped out in the MD pcireadconf
304 * code and not here, since the only MI invalid IRQ is 255.
305 */
306#define PCI_INVALID_IRQ         255
307#define PCI_INTERRUPT_VALID(x)  ((x) != PCI_INVALID_IRQ)
308
309
310/*
311 * Convenience functions.
312 *
313 * These should be used in preference to manually manipulating
314 * configuration space.
315 */
316static __inline int
317pci_enable_busmaster(device_t dev)
318{
319    return(PCI_ENABLE_BUSMASTER(device_get_parent(dev), dev));
320}
321
322#ifndef __rtems__
323static __inline int
324pci_disable_busmaster(device_t dev)
325{
326    return(PCI_DISABLE_BUSMASTER(device_get_parent(dev), dev));
327}
328
329static __inline int
330pci_enable_io(device_t dev, int space)
331{
332    return(PCI_ENABLE_IO(device_get_parent(dev), dev, space));
333}
334
335static __inline int
336pci_disable_io(device_t dev, int space)
337{
338    return(PCI_DISABLE_IO(device_get_parent(dev), dev, space));
339}
340
341static __inline int
342pci_get_vpd_ident(device_t dev, const char **identptr)
343{
344    return(PCI_GET_VPD_IDENT(device_get_parent(dev), dev, identptr));
345}
346
347static __inline int
348pci_get_vpd_readonly(device_t dev, const char *kw, const char **identptr)
349{
350    return(PCI_GET_VPD_READONLY(device_get_parent(dev), dev, kw, identptr));
351}
352#endif /* __rtems__ */
353
354/*
355 * Check if the address range falls within the VGA defined address range(s)
356 */
357static __inline int
358pci_is_vga_ioport_range(u_long start, u_long end)
359{
360 
361        return (((start >= 0x3b0 && end <= 0x3bb) ||
362            (start >= 0x3c0 && end <= 0x3df)) ? 1 : 0);
363}
364
365static __inline int
366pci_is_vga_memory_range(u_long start, u_long end)
367{
368
369        return ((start >= 0xa0000 && end <= 0xbffff) ? 1 : 0);
370}
371
372/*
373 * PCI power states are as defined by ACPI:
374 *
375 * D0   State in which device is on and running.  It is receiving full
376 *      power from the system and delivering full functionality to the user.
377 * D1   Class-specific low-power state in which device context may or may not
378 *      be lost.  Buses in D1 cannot do anything to the bus that would force
379 *      devices on that bus to lose context.
380 * D2   Class-specific low-power state in which device context may or may
381 *      not be lost.  Attains greater power savings than D1.  Buses in D2
382 *      can cause devices on that bus to lose some context.  Devices in D2
383 *      must be prepared for the bus to be in D2 or higher.
384 * D3   State in which the device is off and not running.  Device context is
385 *      lost.  Power can be removed from the device.
386 */
387#define PCI_POWERSTATE_D0       0
388#define PCI_POWERSTATE_D1       1
389#define PCI_POWERSTATE_D2       2
390#define PCI_POWERSTATE_D3       3
391#define PCI_POWERSTATE_UNKNOWN  -1
392
393static __inline int
394pci_set_powerstate(device_t dev, int state)
395{
396    return PCI_SET_POWERSTATE(device_get_parent(dev), dev, state);
397}
398
399static __inline int
400pci_get_powerstate(device_t dev)
401{
402    return PCI_GET_POWERSTATE(device_get_parent(dev), dev);
403}
404
405static __inline int
406pci_find_extcap(device_t dev, int capability, int *capreg)
407{
408    return PCI_FIND_EXTCAP(device_get_parent(dev), dev, capability, capreg);
409}
410
411static __inline int
412pci_alloc_msi(device_t dev, int *count)
413{
414    return (PCI_ALLOC_MSI(device_get_parent(dev), dev, count));
415}
416
417static __inline int
418pci_alloc_msix(device_t dev, int *count)
419{
420    return (PCI_ALLOC_MSIX(device_get_parent(dev), dev, count));
421}
422
423static __inline int
424pci_remap_msix(device_t dev, int count, const u_int *vectors)
425{
426    return (PCI_REMAP_MSIX(device_get_parent(dev), dev, count, vectors));
427}
428
429static __inline int
430pci_release_msi(device_t dev)
431{
432    return (PCI_RELEASE_MSI(device_get_parent(dev), dev));
433}
434
435static __inline int
436pci_msi_count(device_t dev)
437{
438    return (PCI_MSI_COUNT(device_get_parent(dev), dev));
439}
440
441static __inline int
442pci_msix_count(device_t dev)
443{
444    return (PCI_MSIX_COUNT(device_get_parent(dev), dev));
445}
446
447device_t pci_find_bsf(uint8_t, uint8_t, uint8_t);
448device_t pci_find_dbsf(uint32_t, uint8_t, uint8_t, uint8_t);
449#ifndef __rtems__
450device_t pci_find_device(uint16_t, uint16_t);
451#endif /* __rtems__ */
452
453/* Can be used by drivers to manage the MSI-X table. */
454int     pci_pending_msix(device_t dev, u_int index);
455
456int     pci_msi_device_blacklisted(device_t dev);
457
458void    pci_ht_map_msi(device_t dev, uint64_t addr);
459
460int     pci_get_max_read_req(device_t dev);
461int     pci_set_max_read_req(device_t dev, int size);
462
463#endif  /* _SYS_BUS_HH_ */
464
465/*
466 * cdev switch for control device, initialised in generic PCI code
467 */
468extern struct cdevsw pcicdev;
469
470/*
471 * List of all PCI devices, generation count for the list.
472 */
473STAILQ_HEAD(devlist, pci_devinfo);
474
475extern struct devlist   pci_devq;
476extern uint32_t pci_generation;
477
478#endif /* _PCIVAR_HH_ */
Note: See TracBrowser for help on using the repository browser.