pcivar.h revision 145651
1139749Simp/*- 226159Sse * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 326159Sse * All rights reserved. 426159Sse * 526159Sse * Redistribution and use in source and binary forms, with or without 626159Sse * modification, are permitted provided that the following conditions 726159Sse * are met: 826159Sse * 1. Redistributions of source code must retain the above copyright 926159Sse * notice unmodified, this list of conditions, and the following 1026159Sse * disclaimer. 1126159Sse * 2. Redistributions in binary form must reproduce the above copyright 1226159Sse * notice, this list of conditions and the following disclaimer in the 1326159Sse * documentation and/or other materials provided with the distribution. 1426159Sse * 1526159Sse * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1626159Sse * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1726159Sse * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1826159Sse * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1926159Sse * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2026159Sse * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2126159Sse * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2226159Sse * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2326159Sse * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2426159Sse * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2526159Sse * 2650477Speter * $FreeBSD: head/sys/dev/pci/pcivar.h 145651 2005-04-29 02:03:11Z marcel $ 2726159Sse * 2826159Sse */ 296100Sse 3039231Sgibbs#ifndef _PCIVAR_H_ 3139231Sgibbs#define _PCIVAR_H_ 3239231Sgibbs 3339231Sgibbs#include <sys/queue.h> 3439231Sgibbs 3526159Sse/* some PCI bus constants */ 366767Sse 3726159Sse#define PCI_BUSMAX 255 /* highest supported bus number */ 3826159Sse#define PCI_SLOTMAX 31 /* highest supported slot number */ 3926159Sse#define PCI_FUNCMAX 7 /* highest supported function number */ 4026159Sse#define PCI_REGMAX 255 /* highest supported config register addr. */ 416100Sse 4226159Sse#define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */ 4326159Sse#define PCI_MAXMAPS_1 2 /* max. no. of maps for PCI to PCI bridge */ 4426159Sse#define PCI_MAXMAPS_2 1 /* max. no. of maps for CardBus bridge */ 456100Sse 4626159Sse/* pci_addr_t covers this system's PCI bus address space: 32 or 64 bit */ 476100Sse 4826159Sse#ifdef PCI_A64 49119266Simptypedef uint64_t pci_addr_t; /* uint64_t for system with 64bit addresses */ 5026159Sse#else 51119266Simptypedef uint32_t pci_addr_t; /* uint64_t for system with 64bit addresses */ 5226159Sse#endif 536100Sse 54120063Sscottl/* Interesting values for PCI power management */ 55120063Sscottlstruct pcicfg_pp { 56120063Sscottl uint16_t pp_cap; /* PCI power management capabilities */ 57120063Sscottl uint8_t pp_status; /* config space address of PCI power status reg */ 58120063Sscottl uint8_t pp_pmcsr; /* config space address of PMCSR reg */ 59120063Sscottl uint8_t pp_data; /* config space address of PCI power data reg */ 60120063Sscottl}; 61120063Sscottl 62120063Sscottl/* Interesting values for PCI MSI */ 63120063Sscottlstruct pcicfg_msi { 64120063Sscottl uint16_t msi_ctrl; /* Message Control */ 65120063Sscottl uint8_t msi_msgnum; /* Number of messages */ 66120063Sscottl uint16_t msi_data; /* Location of MSI data word */ 67120063Sscottl}; 68120063Sscottl 6926159Sse/* config header information common to all header types */ 7026159Ssetypedef struct pcicfg { 7145720Speter struct device *dev; /* device which owns this */ 726100Sse 73128019Simp uint32_t bar[PCI_MAXMAPS_0]; /* BARs */ 74128019Simp uint32_t bios; /* BIOS mapping */ 75128019Simp 76119266Simp uint16_t subvendor; /* card vendor ID */ 77119266Simp uint16_t subdevice; /* card device ID, assigned by card vendor */ 78119266Simp uint16_t vendor; /* chip vendor ID */ 79119266Simp uint16_t device; /* chip device ID, assigned by chip vendor */ 806100Sse 81119266Simp uint16_t cmdreg; /* disable/enable chip and PCI options */ 82119266Simp uint16_t statreg; /* supported PCI features and error state */ 837233Sse 84119266Simp uint8_t baseclass; /* chip PCI class */ 85119266Simp uint8_t subclass; /* chip PCI subclass */ 86119266Simp uint8_t progif; /* chip PCI programming interface */ 87119266Simp uint8_t revid; /* chip revision ID */ 886100Sse 89119266Simp uint8_t hdrtype; /* chip config header type */ 90119266Simp uint8_t cachelnsz; /* cache line size in 4byte units */ 91119266Simp uint8_t intpin; /* PCI interrupt pin */ 92119266Simp uint8_t intline; /* interrupt line (IRQ for PC arch) */ 936100Sse 94119266Simp uint8_t mingnt; /* min. useful bus grant time in 250ns units */ 95119266Simp uint8_t maxlat; /* max. tolerated bus grant latency in 250ns */ 96119266Simp uint8_t lattimer; /* latency timer in units of 30ns bus cycles */ 976100Sse 98119266Simp uint8_t mfdev; /* multi-function device (from hdrtype reg) */ 99119266Simp uint8_t nummaps; /* actual number of PCI maps used */ 1007233Sse 101119266Simp uint8_t bus; /* config space bus address */ 102119266Simp uint8_t slot; /* config space slot address */ 103119266Simp uint8_t func; /* config space function number */ 1047233Sse 105120063Sscottl struct pcicfg_pp pp; /* pci power management */ 106120063Sscottl struct pcicfg_msi msi; /* pci msi */ 10726159Sse} pcicfgregs; 1086100Sse 10926159Sse/* additional type 1 device config header information (PCI to PCI bridge) */ 1106100Sse 11126159Sse#ifdef PCI_A64 11226159Sse#define PCI_PPBMEMBASE(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) & ~0xfffff) 11326159Sse#define PCI_PPBMEMLIMIT(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) | 0xfffff) 11426159Sse#else 11526159Sse#define PCI_PPBMEMBASE(h,l) (((l)<<16) & ~0xfffff) 11626159Sse#define PCI_PPBMEMLIMIT(h,l) (((l)<<16) | 0xfffff) 11726159Sse#endif /* PCI_A64 */ 1186100Sse 11926159Sse#define PCI_PPBIOBASE(h,l) ((((h)<<16) + ((l)<<8)) & ~0xfff) 12026159Sse#define PCI_PPBIOLIMIT(h,l) ((((h)<<16) + ((l)<<8)) | 0xfff) 1217233Sse 12226159Ssetypedef struct { 12326159Sse pci_addr_t pmembase; /* base address of prefetchable memory */ 12426159Sse pci_addr_t pmemlimit; /* topmost address of prefetchable memory */ 125119266Simp uint32_t membase; /* base address of memory window */ 126119266Simp uint32_t memlimit; /* topmost address of memory window */ 127119266Simp uint32_t iobase; /* base address of port window */ 128119266Simp uint32_t iolimit; /* topmost address of port window */ 129119266Simp uint16_t secstat; /* secondary bus status register */ 130119266Simp uint16_t bridgectl; /* bridge control register */ 131119266Simp uint8_t seclat; /* CardBus latency timer */ 13226159Sse} pcih1cfgregs; 1336100Sse 13426159Sse/* additional type 2 device config header information (CardBus bridge) */ 13526159Sse 13626159Ssetypedef struct { 137119266Simp uint32_t membase0; /* base address of memory window */ 138119266Simp uint32_t memlimit0; /* topmost address of memory window */ 139119266Simp uint32_t membase1; /* base address of memory window */ 140119266Simp uint32_t memlimit1; /* topmost address of memory window */ 141119266Simp uint32_t iobase0; /* base address of port window */ 142119266Simp uint32_t iolimit0; /* topmost address of port window */ 143119266Simp uint32_t iobase1; /* base address of port window */ 144119266Simp uint32_t iolimit1; /* topmost address of port window */ 145119266Simp uint32_t pccardif; /* PC Card 16bit IF legacy more base addr. */ 146119266Simp uint16_t secstat; /* secondary bus status register */ 147119266Simp uint16_t bridgectl; /* bridge control register */ 148119266Simp uint8_t seclat; /* CardBus latency timer */ 14926159Sse} pcih2cfgregs; 15026159Sse 151119266Simpextern uint32_t pci_numdevs; 15239231Sgibbs 15361047Speter/* Only if the prerequisites are present */ 15461047Speter#if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_) 15561047Speterstruct pci_devinfo { 15661047Speter STAILQ_ENTRY(pci_devinfo) pci_links; 15761047Speter struct resource_list resources; 15861047Speter pcicfgregs cfg; 15961047Speter struct pci_conf conf; 16061047Speter}; 16161047Speter#endif 16239231Sgibbs 16340004Sdfr#ifdef __alpha__ 16440004Sdfrvm_offset_t pci_cvt_to_dense (vm_offset_t); 16540004Sdfrvm_offset_t pci_cvt_to_bwx (vm_offset_t); 16640004Sdfr#endif /* __alpha__ */ 16745720Speter 16845720Speter#ifdef _SYS_BUS_H_ 16945720Speter 17045720Speter#include "pci_if.h" 17145720Speter 17252243Sdfr/* 17352243Sdfr * Define pci-specific resource flags for accessing memory via dense 17452243Sdfr * or bwx memory spaces. These flags are ignored on i386. 17552243Sdfr */ 17652243Sdfr#define PCI_RF_DENSE 0x10000 17752243Sdfr#define PCI_RF_BWX 0x20000 17852243Sdfr 17945720Speterenum pci_device_ivars { 18069953Smsmith PCI_IVAR_SUBVENDOR, 18169953Smsmith PCI_IVAR_SUBDEVICE, 18269953Smsmith PCI_IVAR_VENDOR, 18369953Smsmith PCI_IVAR_DEVICE, 18469953Smsmith PCI_IVAR_DEVID, 18569953Smsmith PCI_IVAR_CLASS, 18669953Smsmith PCI_IVAR_SUBCLASS, 18769953Smsmith PCI_IVAR_PROGIF, 18869953Smsmith PCI_IVAR_REVID, 18969953Smsmith PCI_IVAR_INTPIN, 19069953Smsmith PCI_IVAR_IRQ, 19169953Smsmith PCI_IVAR_BUS, 19269953Smsmith PCI_IVAR_SLOT, 19369953Smsmith PCI_IVAR_FUNCTION, 194107300Simp PCI_IVAR_ETHADDR, 19545720Speter}; 19645720Speter 19745720Speter/* 19845720Speter * Simplified accessors for pci devices 19945720Speter */ 200102145Smux#define PCI_ACCESSOR(var, ivar, type) \ 20188375Stmm __BUS_ACCESSOR(pci, var, PCI, ivar, type) 20245720Speter 203119266SimpPCI_ACCESSOR(subvendor, SUBVENDOR, uint16_t) 204119266SimpPCI_ACCESSOR(subdevice, SUBDEVICE, uint16_t) 205119266SimpPCI_ACCESSOR(vendor, VENDOR, uint16_t) 206119266SimpPCI_ACCESSOR(device, DEVICE, uint16_t) 207119266SimpPCI_ACCESSOR(devid, DEVID, uint32_t) 208119266SimpPCI_ACCESSOR(class, CLASS, uint8_t) 209119266SimpPCI_ACCESSOR(subclass, SUBCLASS, uint8_t) 210119266SimpPCI_ACCESSOR(progif, PROGIF, uint8_t) 211119266SimpPCI_ACCESSOR(revid, REVID, uint8_t) 212119266SimpPCI_ACCESSOR(intpin, INTPIN, uint8_t) 213119266SimpPCI_ACCESSOR(irq, IRQ, uint8_t) 214119266SimpPCI_ACCESSOR(bus, BUS, uint8_t) 215119266SimpPCI_ACCESSOR(slot, SLOT, uint8_t) 216119266SimpPCI_ACCESSOR(function, FUNCTION, uint8_t) 217119266SimpPCI_ACCESSOR(ether, ETHADDR, uint8_t *) 21845720Speter 21966416Speter#undef PCI_ACCESSOR 22066416Speter 22169953Smsmith/* 22269953Smsmith * Operations on configuration space. 22369953Smsmith */ 224119266Simpstatic __inline uint32_t 22545720Speterpci_read_config(device_t dev, int reg, int width) 22645720Speter{ 22745720Speter return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width); 22845720Speter} 22945720Speter 23045720Speterstatic __inline void 231119266Simppci_write_config(device_t dev, int reg, uint32_t val, int width) 23245720Speter{ 23345720Speter PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width); 23445720Speter} 23545720Speter 23647339Sgallatin/* 23747339Sgallatin * Ivars for pci bridges. 23847339Sgallatin */ 23947339Sgallatin 24047339Sgallatin/*typedef enum pci_device_ivars pcib_device_ivars;*/ 24147339Sgallatinenum pcib_device_ivars { 24265176Sdfr PCIB_IVAR_BUS 24347339Sgallatin}; 24447339Sgallatin 245102144Smux#define PCIB_ACCESSOR(var, ivar, type) \ 246102144Smux __BUS_ACCESSOR(pcib, var, PCIB, ivar, type) 24747339Sgallatin 248119266SimpPCIB_ACCESSOR(bus, BUS, uint32_t) 24947339Sgallatin 25066416Speter#undef PCIB_ACCESSOR 25166416Speter 25269953Smsmith/* 25398017Simp * PCI interrupt validation. Invalid interrupt values such as 0 or 128 25498017Simp * on i386 or other platforms should be mapped out in the MD pcireadconf 25598017Simp * code and not here, since the only MI invalid IRQ is 255. 25690554Smsmith */ 25797695Simp#define PCI_INVALID_IRQ 255 25898017Simp#define PCI_INTERRUPT_VALID(x) ((x) != PCI_INVALID_IRQ) 25990554Smsmith 26090554Smsmith/* 26169953Smsmith * Convenience functions. 26269953Smsmith * 26369953Smsmith * These should be used in preference to manually manipulating 26469953Smsmith * configuration space. 26569953Smsmith */ 266113544Smdoddstatic __inline int 26773185Speterpci_enable_busmaster(device_t dev) 26873185Speter{ 269113544Smdodd return(PCI_ENABLE_BUSMASTER(device_get_parent(dev), dev)); 27073185Speter} 27145720Speter 272113544Smdoddstatic __inline int 27373185Speterpci_disable_busmaster(device_t dev) 27473185Speter{ 275113544Smdodd return(PCI_DISABLE_BUSMASTER(device_get_parent(dev), dev)); 27673185Speter} 27773185Speter 278113544Smdoddstatic __inline int 27973185Speterpci_enable_io(device_t dev, int space) 28073185Speter{ 281113544Smdodd return(PCI_ENABLE_IO(device_get_parent(dev), dev, space)); 28273185Speter} 28373185Speter 284113544Smdoddstatic __inline int 28573185Speterpci_disable_io(device_t dev, int space) 28673185Speter{ 287113544Smdodd return(PCI_DISABLE_IO(device_get_parent(dev), dev, space)); 28873185Speter} 28973185Speter 29069953Smsmith/* 291145651Smarcel * Check if the address range falls within the VGA defined address range(s) 292145651Smarcel */ 293145651Smarcelstatic __inline int 294145651Smarcelpci_is_vga_ioport_range(u_long start, u_long end) 295145651Smarcel{ 296145651Smarcel 297145651Smarcel return (((start >= 0x3b0 && end <= 0x3bb) || 298145651Smarcel (start >= 0x3c0 && end <= 0x3df)) ? 1 : 0); 299145651Smarcel} 300145651Smarcel 301145651Smarcelstatic __inline int 302145651Smarcelpci_is_vga_memory_range(u_long start, u_long end) 303145651Smarcel{ 304145651Smarcel 305145651Smarcel return ((start >= 0xa0000 && end <= 0xbffff) ? 1 : 0); 306145651Smarcel} 307145651Smarcel 308145651Smarcel/* 30969953Smsmith * PCI power states are as defined by ACPI: 31069953Smsmith * 31169953Smsmith * D0 State in which device is on and running. It is receiving full 31269953Smsmith * power from the system and delivering full functionality to the user. 31369953Smsmith * D1 Class-specific low-power state in which device context may or may not 31469953Smsmith * be lost. Buses in D1 cannot do anything to the bus that would force 31569953Smsmith * devices on that bus to loose context. 31669953Smsmith * D2 Class-specific low-power state in which device context may or may 31769953Smsmith * not be lost. Attains greater power savings than D1. Buses in D2 31869953Smsmith * can cause devices on that bus to loose some context. Devices in D2 31969953Smsmith * must be prepared for the bus to be in D2 or higher. 32069953Smsmith * D3 State in which the device is off and not running. Device context is 32169953Smsmith * lost. Power can be removed from the device. 32269953Smsmith */ 32369953Smsmith#define PCI_POWERSTATE_D0 0 32469953Smsmith#define PCI_POWERSTATE_D1 1 32569953Smsmith#define PCI_POWERSTATE_D2 2 32669953Smsmith#define PCI_POWERSTATE_D3 3 32769953Smsmith#define PCI_POWERSTATE_UNKNOWN -1 32826159Sse 32973185Speterstatic __inline int 33073185Speterpci_set_powerstate(device_t dev, int state) 33173185Speter{ 33273185Speter return PCI_SET_POWERSTATE(device_get_parent(dev), dev, state); 33373185Speter} 33458287Speter 33573185Speterstatic __inline int 33673185Speterpci_get_powerstate(device_t dev) 33773185Speter{ 33873185Speter return PCI_GET_POWERSTATE(device_get_parent(dev), dev); 33973185Speter} 34073185Speter 341119266Simpdevice_t pci_find_bsf(uint8_t, uint8_t, uint8_t); 342119266Simpdevice_t pci_find_device(uint16_t, uint16_t); 34369953Smsmith#endif /* _SYS_BUS_H_ */ 34461047Speter 34569953Smsmith/* 34669953Smsmith * cdev switch for control device, initialised in generic PCI code 34769953Smsmith */ 34869953Smsmithextern struct cdevsw pcicdev; 34958287Speter 35069953Smsmith/* 35169953Smsmith * List of all PCI devices, generation count for the list. 35269953Smsmith */ 35388184SmdoddSTAILQ_HEAD(devlist, pci_devinfo); 35412453Sbde 35588184Smdoddextern struct devlist pci_devq; 356119266Simpextern uint32_t pci_generation; 35788184Smdodd 35839231Sgibbs#endif /* _PCIVAR_H_ */ 359