pcivar.h revision 163163
11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 31556Srgrimes * All rights reserved. 41556Srgrimes * 51556Srgrimes * Redistribution and use in source and binary forms, with or without 61556Srgrimes * modification, are permitted provided that the following conditions 71556Srgrimes * are met: 81556Srgrimes * 1. Redistributions of source code must retain the above copyright 91556Srgrimes * notice unmodified, this list of conditions, and the following 101556Srgrimes * disclaimer. 111556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121556Srgrimes * notice, this list of conditions and the following disclaimer in the 131556Srgrimes * documentation and/or other materials provided with the distribution. 141556Srgrimes * 151556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161556Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171556Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181556Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191556Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201556Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211556Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221556Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231556Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241556Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251556Srgrimes * 261556Srgrimes * $FreeBSD: head/sys/dev/pci/pcivar.h 163163 2006-10-09 16:15:56Z jmg $ 271556Srgrimes * 281556Srgrimes */ 291556Srgrimes 301556Srgrimes#ifndef _PCIVAR_H_ 311556Srgrimes#define _PCIVAR_H_ 321556Srgrimes 331556Srgrimes#include <sys/queue.h> 3436150Scharnier 3536150Scharnier/* some PCI bus constants */ 3636150Scharnier 371556Srgrimes#define PCI_BUSMAX 255 /* highest supported bus number */ 3899110Sobrien#define PCI_SLOTMAX 31 /* highest supported slot number */ 3999110Sobrien#define PCI_FUNCMAX 7 /* highest supported function number */ 401556Srgrimes#define PCI_REGMAX 255 /* highest supported config register addr. */ 4117987Speter 4217987Speter#define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */ 4317987Speter#define PCI_MAXMAPS_1 2 /* max. no. of maps for PCI to PCI bridge */ 4420425Ssteve#define PCI_MAXMAPS_2 1 /* max. no. of maps for CardBus bridge */ 4517987Speter 4617987Speter/* pci_addr_t covers this system's PCI bus address space: 32 or 64 bit */ 47100661Stjr 4817987Speter#ifdef PCI_A64 491556Srgrimestypedef uint64_t pci_addr_t; /* uint64_t for system with 64bit addresses */ 501556Srgrimes#else 511556Srgrimestypedef uint32_t pci_addr_t; /* uint64_t for system with 64bit addresses */ 521556Srgrimes#endif 531556Srgrimes 541556Srgrimes/* Interesting values for PCI power management */ 551556Srgrimesstruct pcicfg_pp { 561556Srgrimes uint16_t pp_cap; /* PCI power management capabilities */ 571556Srgrimes uint8_t pp_status; /* config space address of PCI power status reg */ 581556Srgrimes uint8_t pp_pmcsr; /* config space address of PMCSR reg */ 591556Srgrimes uint8_t pp_data; /* config space address of PCI power data reg */ 601556Srgrimes}; 6120425Ssteve 6217987Speterstruct vpd_readonly { 631556Srgrimes char keyword[2]; 6417987Speter char *value; 6520425Ssteve}; 66223060Sjilles 671556Srgrimesstruct vpd_write { 68213811Sobrien char keyword[2]; 69213811Sobrien char *value; 70213811Sobrien int start; 71213811Sobrien int len; 72213811Sobrien}; 73213811Sobrien 74213811Sobrienstruct pcicfg_vpd { 75213811Sobrien uint8_t vpd_reg; /* base register, + 2 for addr, + 4 data */ 761556Srgrimes char *vpd_ident; /* string identifier */ 77213760Sobrien int vpd_rocnt; 78213760Sobrien struct vpd_readonly *vpd_ros; 79213760Sobrien int vpd_wcnt; 801556Srgrimes struct vpd_write *vpd_w; 811556Srgrimes}; 8297092Stjr 8317987Speter/* Interesting values for PCI MSI */ 84201053Sjillesstruct pcicfg_msi { 85200956Sjilles uint16_t msi_ctrl; /* Message Control */ 861556Srgrimes uint8_t msi_msgnum; /* Number of messages */ 871556Srgrimes uint16_t msi_data; /* Location of MSI data word */ 88222154Sjilles}; 89222154Sjilles 90222292Sjilles/* config header information common to all header types */ 911556Srgrimestypedef struct pcicfg { 92100663Stjr struct device *dev; /* device which owns this */ 93100664Stjr 94222154Sjilles uint32_t bar[PCI_MAXMAPS_0]; /* BARs */ 9597092Stjr uint32_t bios; /* BIOS mapping */ 96222154Sjilles 97222154Sjilles uint16_t subvendor; /* card vendor ID */ 98222154Sjilles uint16_t subdevice; /* card device ID, assigned by card vendor */ 9997092Stjr uint16_t vendor; /* chip vendor ID */ 10097092Stjr uint16_t device; /* chip device ID, assigned by chip vendor */ 10197092Stjr 10297092Stjr uint16_t cmdreg; /* disable/enable chip and PCI options */ 10397092Stjr uint16_t statreg; /* supported PCI features and error state */ 10497092Stjr 10597092Stjr uint8_t baseclass; /* chip PCI class */ 10697092Stjr uint8_t subclass; /* chip PCI subclass */ 10797092Stjr uint8_t progif; /* chip PCI programming interface */ 10897092Stjr uint8_t revid; /* chip revision ID */ 10997092Stjr 11097092Stjr uint8_t hdrtype; /* chip config header type */ 11197092Stjr uint8_t cachelnsz; /* cache line size in 4byte units */ 11297092Stjr uint8_t intpin; /* PCI interrupt pin */ 11397092Stjr uint8_t intline; /* interrupt line (IRQ for PC arch) */ 11497092Stjr 11597092Stjr uint8_t mingnt; /* min. useful bus grant time in 250ns units */ 11697092Stjr uint8_t maxlat; /* max. tolerated bus grant latency in 250ns */ 1171556Srgrimes uint8_t lattimer; /* latency timer in units of 30ns bus cycles */ 1185234Sbde 1195234Sbde uint8_t mfdev; /* multi-function device (from hdrtype reg) */ 1201556Srgrimes uint8_t nummaps; /* actual number of PCI maps used */ 1211556Srgrimes 12212273Speter uint8_t bus; /* config space bus address */ 12312273Speter uint8_t slot; /* config space slot address */ 12412273Speter uint8_t func; /* config space function number */ 12512273Speter 1261556Srgrimes struct pcicfg_pp pp; /* pci power management */ 127222381Sjilles struct pcicfg_vpd vpd; /* pci vital product data */ 128222381Sjilles struct pcicfg_msi msi; /* pci msi */ 129222381Sjilles} pcicfgregs; 130222381Sjilles 1311556Srgrimes/* additional type 1 device config header information (PCI to PCI bridge) */ 1321556Srgrimes 13317987Speter#ifdef PCI_A64 1341556Srgrimes#define PCI_PPBMEMBASE(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) & ~0xfffff) 1351556Srgrimes#define PCI_PPBMEMLIMIT(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) | 0xfffff) 1361556Srgrimes#else 1371556Srgrimes#define PCI_PPBMEMBASE(h,l) (((l)<<16) & ~0xfffff) 13838886Stegge#define PCI_PPBMEMLIMIT(h,l) (((l)<<16) | 0xfffff) 139159551Sstefanf#endif /* PCI_A64 */ 140159551Sstefanf 141159551Sstefanf#define PCI_PPBIOBASE(h,l) ((((h)<<16) + ((l)<<8)) & ~0xfff) 1421556Srgrimes#define PCI_PPBIOLIMIT(h,l) ((((h)<<16) + ((l)<<8)) | 0xfff) 143222154Sjilles 144222154Sjillestypedef struct { 145222154Sjilles pci_addr_t pmembase; /* base address of prefetchable memory */ 146222292Sjilles pci_addr_t pmemlimit; /* topmost address of prefetchable memory */ 147222292Sjilles uint32_t membase; /* base address of memory window */ 1481556Srgrimes uint32_t memlimit; /* topmost address of memory window */ 1491556Srgrimes uint32_t iobase; /* base address of port window */ 150222292Sjilles uint32_t iolimit; /* topmost address of port window */ 15117987Speter uint16_t secstat; /* secondary bus status register */ 15217987Speter uint16_t bridgectl; /* bridge control register */ 1531556Srgrimes uint8_t seclat; /* CardBus latency timer */ 1541556Srgrimes} pcih1cfgregs; 1551556Srgrimes 1561556Srgrimes/* additional type 2 device config header information (CardBus bridge) */ 15797092Stjr 15820774Sstevetypedef struct { 1591556Srgrimes uint32_t membase0; /* base address of memory window */ 160213811Sobrien uint32_t memlimit0; /* topmost address of memory window */ 16197092Stjr uint32_t membase1; /* base address of memory window */ 16220425Ssteve uint32_t memlimit1; /* topmost address of memory window */ 163222154Sjilles uint32_t iobase0; /* base address of port window */ 16497092Stjr uint32_t iolimit0; /* topmost address of port window */ 16597092Stjr uint32_t iobase1; /* base address of port window */ 16697092Stjr uint32_t iolimit1; /* topmost address of port window */ 16797092Stjr uint32_t pccardif; /* PC Card 16bit IF legacy more base addr. */ 168222154Sjilles uint16_t secstat; /* secondary bus status register */ 16997092Stjr uint16_t bridgectl; /* bridge control register */ 17097092Stjr uint8_t seclat; /* CardBus latency timer */ 17197092Stjr} pcih2cfgregs; 17297092Stjr 17397092Stjrextern uint32_t pci_numdevs; 174222154Sjilles 17597092Stjr/* Only if the prerequisites are present */ 17697092Stjr#if defined(_SYS_BUS_H_) && defined(_SYS_PCIIO_H_) 177213811Sobrienstruct pci_devinfo { 17897092Stjr STAILQ_ENTRY(pci_devinfo) pci_links; 17997092Stjr struct resource_list resources; 18038886Stegge pcicfgregs cfg; 18138886Stegge struct pci_conf conf; 18238886Stegge}; 18338886Stegge#endif 18438886Stegge 18538886Stegge#ifdef _SYS_BUS_H_ 18620425Ssteve 18738886Stegge#include "pci_if.h" 18838886Stegge 18938886Stegge/* 19038886Stegge * Define pci-specific resource flags for accessing memory via dense 19138886Stegge * or bwx memory spaces. These flags are ignored on i386. 19238886Stegge */ 19338886Stegge#define PCI_RF_DENSE 0x10000 19438886Stegge#define PCI_RF_BWX 0x20000 19538886Stegge 19638886Steggeenum pci_device_ivars { 19738886Stegge PCI_IVAR_SUBVENDOR, 19838886Stegge PCI_IVAR_SUBDEVICE, 19938886Stegge PCI_IVAR_VENDOR, 20038886Stegge PCI_IVAR_DEVICE, 20138886Stegge PCI_IVAR_DEVID, 20238886Stegge PCI_IVAR_CLASS, 20338886Stegge PCI_IVAR_SUBCLASS, 20438886Stegge PCI_IVAR_PROGIF, 20538886Stegge PCI_IVAR_REVID, 20638886Stegge PCI_IVAR_INTPIN, 20738886Stegge PCI_IVAR_IRQ, 208215783Sjilles PCI_IVAR_BUS, 20938886Stegge PCI_IVAR_SLOT, 21038886Stegge PCI_IVAR_FUNCTION, 21138886Stegge PCI_IVAR_ETHADDR, 21297092Stjr PCI_IVAR_CMDREG, 21338886Stegge PCI_IVAR_CACHELNSZ, 21438886Stegge PCI_IVAR_MINGNT, 21538886Stegge PCI_IVAR_MAXLAT, 21638886Stegge PCI_IVAR_LATTIMER, 21738886Stegge}; 2181556Srgrimes 219176521Sstefanf/* 2201556Srgrimes * Simplified accessors for pci devices 22197092Stjr */ 2221556Srgrimes#define PCI_ACCESSOR(var, ivar, type) \ 223176521Sstefanf __BUS_ACCESSOR(pci, var, PCI, ivar, type) 2241556Srgrimes 22597092StjrPCI_ACCESSOR(subvendor, SUBVENDOR, uint16_t) 2261556SrgrimesPCI_ACCESSOR(subdevice, SUBDEVICE, uint16_t) 2271556SrgrimesPCI_ACCESSOR(vendor, VENDOR, uint16_t) 228213811SobrienPCI_ACCESSOR(device, DEVICE, uint16_t) 22997092StjrPCI_ACCESSOR(devid, DEVID, uint32_t) 23097092StjrPCI_ACCESSOR(class, CLASS, uint8_t) 231176521SstefanfPCI_ACCESSOR(subclass, SUBCLASS, uint8_t) 232222154SjillesPCI_ACCESSOR(progif, PROGIF, uint8_t) 2331556SrgrimesPCI_ACCESSOR(revid, REVID, uint8_t) 23497092StjrPCI_ACCESSOR(intpin, INTPIN, uint8_t) 235215727SjillesPCI_ACCESSOR(irq, IRQ, uint8_t) 23697092StjrPCI_ACCESSOR(bus, BUS, uint8_t) 23797092StjrPCI_ACCESSOR(slot, SLOT, uint8_t) 23897092StjrPCI_ACCESSOR(function, FUNCTION, uint8_t) 239215727SjillesPCI_ACCESSOR(ether, ETHADDR, uint8_t *) 240222154SjillesPCI_ACCESSOR(cmdreg, CMDREG, uint8_t) 241216622SjillesPCI_ACCESSOR(cachelnsz, CACHELNSZ, uint8_t) 242222154SjillesPCI_ACCESSOR(mingnt, MINGNT, uint8_t) 243222154SjillesPCI_ACCESSOR(maxlat, MAXLAT, uint8_t) 244176521SstefanfPCI_ACCESSOR(lattimer, LATTIMER, uint8_t) 24597092Stjr 246222154Sjilles#undef PCI_ACCESSOR 24797092Stjr 24897092Stjr/* 2491556Srgrimes * Operations on configuration space. 2501556Srgrimes */ 2511556Srgrimesstatic __inline uint32_t 2521556Srgrimespci_read_config(device_t dev, int reg, int width) 253213811Sobrien{ 25490111Simp return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width); 25520774Ssteve} 25625222Ssteve 2571556Srgrimesstatic __inline void 2581556Srgrimespci_write_config(device_t dev, int reg, uint32_t val, int width) 2591556Srgrimes{ 2601556Srgrimes PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width); 2611556Srgrimes} 2621556Srgrimes 2631556Srgrimes/* 2641556Srgrimes * Ivars for pci bridges. 2651556Srgrimes */ 2661556Srgrimes 2671556Srgrimes/*typedef enum pci_device_ivars pcib_device_ivars;*/ 2681556Srgrimesenum pcib_device_ivars { 2691556Srgrimes PCIB_IVAR_BUS 2701556Srgrimes}; 2711556Srgrimes 2721556Srgrimes#define PCIB_ACCESSOR(var, ivar, type) \ 2731556Srgrimes __BUS_ACCESSOR(pcib, var, PCIB, ivar, type) 274213811Sobrien 275176521SstefanfPCIB_ACCESSOR(bus, BUS, uint32_t) 27620774Ssteve 2771556Srgrimes#undef PCIB_ACCESSOR 2781556Srgrimes 2791556Srgrimes/* 28038886Stegge * PCI interrupt validation. Invalid interrupt values such as 0 or 128 28138886Stegge * on i386 or other platforms should be mapped out in the MD pcireadconf 28238886Stegge * code and not here, since the only MI invalid IRQ is 255. 28338886Stegge */ 28438886Stegge#define PCI_INVALID_IRQ 255 285199631Sstefanf#define PCI_INTERRUPT_VALID(x) ((x) != PCI_INVALID_IRQ) 286199631Sstefanf 2871556Srgrimes/* 2881556Srgrimes * Convenience functions. 2891556Srgrimes * 2901556Srgrimes * These should be used in preference to manually manipulating 291215783Sjilles * configuration space. 292215783Sjilles */ 2931556Srgrimesstatic __inline int 2941556Srgrimespci_enable_busmaster(device_t dev) 2951556Srgrimes{ 2961556Srgrimes return(PCI_ENABLE_BUSMASTER(device_get_parent(dev), dev)); 2971556Srgrimes} 2981556Srgrimes 2991556Srgrimesstatic __inline int 300215783Sjillespci_disable_busmaster(device_t dev) 3011556Srgrimes{ 3021556Srgrimes return(PCI_DISABLE_BUSMASTER(device_get_parent(dev), dev)); 3031556Srgrimes} 3041556Srgrimes 3051556Srgrimesstatic __inline int 306176521Sstefanfpci_enable_io(device_t dev, int space) 307176521Sstefanf{ 308176521Sstefanf return(PCI_ENABLE_IO(device_get_parent(dev), dev, space)); 309176521Sstefanf} 310176521Sstefanf 311176521Sstefanfstatic __inline int 312176521Sstefanfpci_disable_io(device_t dev, int space) 313176521Sstefanf{ 314213811Sobrien return(PCI_DISABLE_IO(device_get_parent(dev), dev, space)); 315176521Sstefanf} 316176521Sstefanf 317176521Sstefanfstatic __inline int 318176521Sstefanfpci_get_vpd_ident(device_t dev, const char **identptr) 31938886Stegge{ 32038886Stegge return(PCI_GET_VPD_IDENT(device_get_parent(dev), dev, identptr)); 32138886Stegge} 322215727Sjilles 32386176Steggestatic __inline int 32486176Steggepci_get_vpd_readonly(device_t dev, const char *kw, const char **identptr) 3251556Srgrimes{ 3261556Srgrimes return(PCI_GET_VPD_READONLY(device_get_parent(dev), dev, kw, identptr)); 3271556Srgrimes} 328100660Stjr 32917987Speter/* 330199631Sstefanf * Check if the address range falls within the VGA defined address range(s) 33197092Stjr */ 3321556Srgrimesstatic __inline int 333100663Stjrpci_is_vga_ioport_range(u_long start, u_long end) 334100664Stjr{ 33597092Stjr 33697092Stjr return (((start >= 0x3b0 && end <= 0x3bb) || 33797092Stjr (start >= 0x3c0 && end <= 0x3df)) ? 1 : 0); 33897092Stjr} 33997092Stjr 34097092Stjrstatic __inline int 34197092Stjrpci_is_vga_memory_range(u_long start, u_long end) 34297092Stjr{ 34397092Stjr 34497092Stjr return ((start >= 0xa0000 && end <= 0xbffff) ? 1 : 0); 34597092Stjr} 34697092Stjr 34797092Stjr/* 34897092Stjr * PCI power states are as defined by ACPI: 34997092Stjr * 3501556Srgrimes * D0 State in which device is on and running. It is receiving full 35197092Stjr * power from the system and delivering full functionality to the user. 35297092Stjr * D1 Class-specific low-power state in which device context may or may not 35338886Stegge * be lost. Buses in D1 cannot do anything to the bus that would force 35497092Stjr * devices on that bus to lose context. 35597092Stjr * D2 Class-specific low-power state in which device context may or may 35697092Stjr * not be lost. Attains greater power savings than D1. Buses in D2 35797092Stjr * can cause devices on that bus to lose some context. Devices in D2 358199631Sstefanf * must be prepared for the bus to be in D2 or higher. 35997092Stjr * D3 State in which the device is off and not running. Device context is 360199631Sstefanf * lost. Power can be removed from the device. 36197092Stjr */ 36297092Stjr#define PCI_POWERSTATE_D0 0 36338886Stegge#define PCI_POWERSTATE_D1 1 36497092Stjr#define PCI_POWERSTATE_D2 2 36597092Stjr#define PCI_POWERSTATE_D3 3 36638886Stegge#define PCI_POWERSTATE_UNKNOWN -1 3671556Srgrimes 368176521Sstefanfstatic __inline int 3691556Srgrimespci_set_powerstate(device_t dev, int state) 370213811Sobrien{ 37190111Simp return PCI_SET_POWERSTATE(device_get_parent(dev), dev, state); 37220425Ssteve} 373176521Sstefanf 37438886Steggestatic __inline int 3751556Srgrimespci_get_powerstate(device_t dev) 37638886Stegge{ 377176521Sstefanf return PCI_GET_POWERSTATE(device_get_parent(dev), dev); 378199631Sstefanf} 379176521Sstefanf 380176521Sstefanfstatic __inline int 381176521Sstefanfpci_find_extcap(device_t dev, int capability, int *capreg) 382176521Sstefanf{ 383176521Sstefanf return PCI_FIND_EXTCAP(device_get_parent(dev), dev, capability, capreg); 384176521Sstefanf} 385199631Sstefanf 386199631Sstefanfdevice_t pci_find_bsf(uint8_t, uint8_t, uint8_t); 387176521Sstefanfdevice_t pci_find_device(uint16_t, uint16_t); 388176521Sstefanf#endif /* _SYS_BUS_H_ */ 389176521Sstefanf 390213811Sobrien/* 391199631Sstefanf * cdev switch for control device, initialised in generic PCI code 392176521Sstefanf */ 393199631Sstefanfextern struct cdevsw pcicdev; 394199631Sstefanf 39538886Stegge/* 396199631Sstefanf * List of all PCI devices, generation count for the list. 397199631Sstefanf */ 398199631SstefanfSTAILQ_HEAD(devlist, pci_devinfo); 399176521Sstefanf 400199631Sstefanfextern struct devlist pci_devq; 401199631Sstefanfextern uint32_t pci_generation; 402199631Sstefanf 40338886Stegge#endif /* _PCIVAR_H_ */ 404199631Sstefanf