pcivar.h revision 153560
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 153560 2005-12-20 19:57:47Z jhb $ 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, 195149972Simp PCI_IVAR_CMDREG, 196149972Simp PCI_IVAR_CACHELNSZ, 197149972Simp PCI_IVAR_MINGNT, 198149972Simp PCI_IVAR_MAXLAT, 199149972Simp PCI_IVAR_LATTIMER, 20045720Speter}; 20145720Speter 20245720Speter/* 20345720Speter * Simplified accessors for pci devices 20445720Speter */ 205102145Smux#define PCI_ACCESSOR(var, ivar, type) \ 20688375Stmm __BUS_ACCESSOR(pci, var, PCI, ivar, type) 20745720Speter 208119266SimpPCI_ACCESSOR(subvendor, SUBVENDOR, uint16_t) 209119266SimpPCI_ACCESSOR(subdevice, SUBDEVICE, uint16_t) 210119266SimpPCI_ACCESSOR(vendor, VENDOR, uint16_t) 211119266SimpPCI_ACCESSOR(device, DEVICE, uint16_t) 212119266SimpPCI_ACCESSOR(devid, DEVID, uint32_t) 213119266SimpPCI_ACCESSOR(class, CLASS, uint8_t) 214119266SimpPCI_ACCESSOR(subclass, SUBCLASS, uint8_t) 215119266SimpPCI_ACCESSOR(progif, PROGIF, uint8_t) 216119266SimpPCI_ACCESSOR(revid, REVID, uint8_t) 217119266SimpPCI_ACCESSOR(intpin, INTPIN, uint8_t) 218119266SimpPCI_ACCESSOR(irq, IRQ, uint8_t) 219119266SimpPCI_ACCESSOR(bus, BUS, uint8_t) 220119266SimpPCI_ACCESSOR(slot, SLOT, uint8_t) 221119266SimpPCI_ACCESSOR(function, FUNCTION, uint8_t) 222119266SimpPCI_ACCESSOR(ether, ETHADDR, uint8_t *) 223149972SimpPCI_ACCESSOR(cmdreg, CMDREG, uint8_t) 224149972SimpPCI_ACCESSOR(cachelnsz, CACHELNSZ, uint8_t) 225149972SimpPCI_ACCESSOR(mingnt, MINGNT, uint8_t) 226149972SimpPCI_ACCESSOR(maxlat, MAXLAT, uint8_t) 227149972SimpPCI_ACCESSOR(lattimer, LATTIMER, uint8_t) 22845720Speter 22966416Speter#undef PCI_ACCESSOR 23066416Speter 23169953Smsmith/* 23269953Smsmith * Operations on configuration space. 23369953Smsmith */ 234119266Simpstatic __inline uint32_t 23545720Speterpci_read_config(device_t dev, int reg, int width) 23645720Speter{ 23745720Speter return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width); 23845720Speter} 23945720Speter 24045720Speterstatic __inline void 241119266Simppci_write_config(device_t dev, int reg, uint32_t val, int width) 24245720Speter{ 24345720Speter PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width); 24445720Speter} 24545720Speter 24647339Sgallatin/* 24747339Sgallatin * Ivars for pci bridges. 24847339Sgallatin */ 24947339Sgallatin 25047339Sgallatin/*typedef enum pci_device_ivars pcib_device_ivars;*/ 25147339Sgallatinenum pcib_device_ivars { 25265176Sdfr PCIB_IVAR_BUS 25347339Sgallatin}; 25447339Sgallatin 255102144Smux#define PCIB_ACCESSOR(var, ivar, type) \ 256102144Smux __BUS_ACCESSOR(pcib, var, PCIB, ivar, type) 25747339Sgallatin 258119266SimpPCIB_ACCESSOR(bus, BUS, uint32_t) 25947339Sgallatin 26066416Speter#undef PCIB_ACCESSOR 26166416Speter 26269953Smsmith/* 26398017Simp * PCI interrupt validation. Invalid interrupt values such as 0 or 128 26498017Simp * on i386 or other platforms should be mapped out in the MD pcireadconf 26598017Simp * code and not here, since the only MI invalid IRQ is 255. 26690554Smsmith */ 26797695Simp#define PCI_INVALID_IRQ 255 26898017Simp#define PCI_INTERRUPT_VALID(x) ((x) != PCI_INVALID_IRQ) 26990554Smsmith 27090554Smsmith/* 27169953Smsmith * Convenience functions. 27269953Smsmith * 27369953Smsmith * These should be used in preference to manually manipulating 27469953Smsmith * configuration space. 27569953Smsmith */ 276113544Smdoddstatic __inline int 27773185Speterpci_enable_busmaster(device_t dev) 27873185Speter{ 279113544Smdodd return(PCI_ENABLE_BUSMASTER(device_get_parent(dev), dev)); 28073185Speter} 28145720Speter 282113544Smdoddstatic __inline int 28373185Speterpci_disable_busmaster(device_t dev) 28473185Speter{ 285113544Smdodd return(PCI_DISABLE_BUSMASTER(device_get_parent(dev), dev)); 28673185Speter} 28773185Speter 288113544Smdoddstatic __inline int 28973185Speterpci_enable_io(device_t dev, int space) 29073185Speter{ 291113544Smdodd return(PCI_ENABLE_IO(device_get_parent(dev), dev, space)); 29273185Speter} 29373185Speter 294113544Smdoddstatic __inline int 29573185Speterpci_disable_io(device_t dev, int space) 29673185Speter{ 297113544Smdodd return(PCI_DISABLE_IO(device_get_parent(dev), dev, space)); 29873185Speter} 29973185Speter 30069953Smsmith/* 301145651Smarcel * Check if the address range falls within the VGA defined address range(s) 302145651Smarcel */ 303145651Smarcelstatic __inline int 304145651Smarcelpci_is_vga_ioport_range(u_long start, u_long end) 305145651Smarcel{ 306145651Smarcel 307145651Smarcel return (((start >= 0x3b0 && end <= 0x3bb) || 308145651Smarcel (start >= 0x3c0 && end <= 0x3df)) ? 1 : 0); 309145651Smarcel} 310145651Smarcel 311145651Smarcelstatic __inline int 312145651Smarcelpci_is_vga_memory_range(u_long start, u_long end) 313145651Smarcel{ 314145651Smarcel 315145651Smarcel return ((start >= 0xa0000 && end <= 0xbffff) ? 1 : 0); 316145651Smarcel} 317145651Smarcel 318145651Smarcel/* 31969953Smsmith * PCI power states are as defined by ACPI: 32069953Smsmith * 32169953Smsmith * D0 State in which device is on and running. It is receiving full 32269953Smsmith * power from the system and delivering full functionality to the user. 32369953Smsmith * D1 Class-specific low-power state in which device context may or may not 32469953Smsmith * be lost. Buses in D1 cannot do anything to the bus that would force 32569953Smsmith * devices on that bus to loose context. 32669953Smsmith * D2 Class-specific low-power state in which device context may or may 32769953Smsmith * not be lost. Attains greater power savings than D1. Buses in D2 32869953Smsmith * can cause devices on that bus to loose some context. Devices in D2 32969953Smsmith * must be prepared for the bus to be in D2 or higher. 33069953Smsmith * D3 State in which the device is off and not running. Device context is 33169953Smsmith * lost. Power can be removed from the device. 33269953Smsmith */ 33369953Smsmith#define PCI_POWERSTATE_D0 0 33469953Smsmith#define PCI_POWERSTATE_D1 1 33569953Smsmith#define PCI_POWERSTATE_D2 2 33669953Smsmith#define PCI_POWERSTATE_D3 3 33769953Smsmith#define PCI_POWERSTATE_UNKNOWN -1 33826159Sse 33973185Speterstatic __inline int 34073185Speterpci_set_powerstate(device_t dev, int state) 34173185Speter{ 34273185Speter return PCI_SET_POWERSTATE(device_get_parent(dev), dev, state); 34373185Speter} 34458287Speter 34573185Speterstatic __inline int 34673185Speterpci_get_powerstate(device_t dev) 34773185Speter{ 34873185Speter return PCI_GET_POWERSTATE(device_get_parent(dev), dev); 34973185Speter} 35073185Speter 351153560Sjhbstatic __inline int 352153560Sjhbpci_find_extcap(device_t dev, int capability, int *capreg) 353153560Sjhb{ 354153560Sjhb return PCI_FIND_EXTCAP(device_get_parent(dev), dev, capability, capreg); 355153560Sjhb} 356153560Sjhb 357119266Simpdevice_t pci_find_bsf(uint8_t, uint8_t, uint8_t); 358119266Simpdevice_t pci_find_device(uint16_t, uint16_t); 35969953Smsmith#endif /* _SYS_BUS_H_ */ 36061047Speter 36169953Smsmith/* 36269953Smsmith * cdev switch for control device, initialised in generic PCI code 36369953Smsmith */ 36469953Smsmithextern struct cdevsw pcicdev; 36558287Speter 36669953Smsmith/* 36769953Smsmith * List of all PCI devices, generation count for the list. 36869953Smsmith */ 36988184SmdoddSTAILQ_HEAD(devlist, pci_devinfo); 37012453Sbde 37188184Smdoddextern struct devlist pci_devq; 372119266Simpextern uint32_t pci_generation; 37388184Smdodd 37439231Sgibbs#endif /* _PCIVAR_H_ */ 375