pcivar.h revision 45720
1160814Ssimon/* 2160814Ssimon * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3160814Ssimon * All rights reserved. 4160814Ssimon * 5160814Ssimon * Redistribution and use in source and binary forms, with or without 6160814Ssimon * modification, are permitted provided that the following conditions 7160814Ssimon * are met: 8160814Ssimon * 1. Redistributions of source code must retain the above copyright 9160814Ssimon * notice unmodified, this list of conditions, and the following 10160814Ssimon * disclaimer. 11160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 12160814Ssimon * notice, this list of conditions and the following disclaimer in the 13160814Ssimon * documentation and/or other materials provided with the distribution. 14160814Ssimon * 15160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16160814Ssimon * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17160814Ssimon * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18160814Ssimon * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19160814Ssimon * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21160814Ssimon * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22160814Ssimon * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23160814Ssimon * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24160814Ssimon * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25160814Ssimon * 26160814Ssimon * $Id: pcivar.h,v 1.25 1999/01/19 23:29:20 se Exp $ 27160814Ssimon * 28160814Ssimon */ 29160814Ssimon 30160814Ssimon#ifndef _PCIVAR_H_ 31160814Ssimon#define _PCIVAR_H_ 32160814Ssimon 33160814Ssimon#ifndef PCI_COMPAT 34160814Ssimon#define PCI_COMPAT 35160814Ssimon#endif 36160814Ssimon 37160814Ssimon#include <pci/pci_ioctl.h> /* XXX KDM */ 38160814Ssimon#include <sys/queue.h> 39160814Ssimon 40160814Ssimon/* some PCI bus constants */ 41160814Ssimon 42160814Ssimon#define PCI_BUSMAX 255 /* highest supported bus number */ 43160814Ssimon#define PCI_SLOTMAX 31 /* highest supported slot number */ 44160814Ssimon#define PCI_FUNCMAX 7 /* highest supported function number */ 45160814Ssimon#define PCI_REGMAX 255 /* highest supported config register addr. */ 46160814Ssimon 47160814Ssimon#define PCI_MAXMAPS_0 6 /* max. no. of memory/port maps */ 48160814Ssimon#define PCI_MAXMAPS_1 2 /* max. no. of maps for PCI to PCI bridge */ 49160814Ssimon#define PCI_MAXMAPS_2 1 /* max. no. of maps for CardBus bridge */ 50160814Ssimon 51160814Ssimon/* pci_addr_t covers this system's PCI bus address space: 32 or 64 bit */ 52160814Ssimon 53160814Ssimon#ifdef PCI_A64 54160814Ssimontypedef u_int64_t pci_addr_t; /* u_int64_t for system with 64bit addresses */ 55160814Ssimon#else 56160814Ssimontypedef u_int32_t pci_addr_t; /* u_int64_t for system with 64bit addresses */ 57160814Ssimon#endif 58160814Ssimon 59160814Ssimon/* map register information */ 60160814Ssimon 61160814Ssimontypedef struct { 62160814Ssimon u_int32_t base; 63160814Ssimon u_int8_t type; 64160814Ssimon#define PCI_MAPMEM 0x01 /* memory map */ 65160814Ssimon#define PCI_MAPMEMP 0x02 /* prefetchable memory map */ 66160814Ssimon#define PCI_MAPPORT 0x04 /* port map */ 67160814Ssimon u_int8_t ln2size; 68160814Ssimon u_int8_t ln2range; 69160814Ssimon u_int8_t reg; /* offset of map register in config space */ 70160814Ssimon/* u_int8_t dummy;*/ 71160814Ssimon struct resource *res; /* handle from resource manager */ 72160814Ssimon} pcimap; 73160814Ssimon 74160814Ssimon/* config header information common to all header types */ 75160814Ssimon 76160814Ssimontypedef struct pcicfg { 77160814Ssimon struct device *dev; /* device which owns this */ 78160814Ssimon pcimap *map; /* pointer to array of PCI maps */ 79160814Ssimon void *hdrspec; /* pointer to header type specific data */ 80160814Ssimon struct resource *irqres; /* resource descriptor for interrupt mapping */ 81160814Ssimon 82160814Ssimon u_int16_t subvendor; /* card vendor ID */ 83160814Ssimon u_int16_t subdevice; /* card device ID, assigned by card vendor */ 84160814Ssimon u_int16_t vendor; /* chip vendor ID */ 85160814Ssimon u_int16_t device; /* chip device ID, assigned by chip vendor */ 86160814Ssimon 87160814Ssimon u_int16_t cmdreg; /* disable/enable chip and PCI options */ 88160814Ssimon u_int16_t statreg; /* supported PCI features and error state */ 89160814Ssimon 90160814Ssimon u_int8_t baseclass; /* chip PCI class */ 91160814Ssimon u_int8_t subclass; /* chip PCI subclass */ 92160814Ssimon u_int8_t progif; /* chip PCI programming interface */ 93160814Ssimon u_int8_t revid; /* chip revision ID */ 94160814Ssimon 95160814Ssimon u_int8_t hdrtype; /* chip config header type */ 96160814Ssimon u_int8_t cachelnsz; /* cache line size in 4byte units */ 97160814Ssimon u_int8_t intpin; /* PCI interrupt pin */ 98160814Ssimon u_int8_t intline; /* interrupt line (IRQ for PC arch) */ 99160814Ssimon 100160814Ssimon u_int8_t mingnt; /* min. useful bus grant time in 250ns units */ 101160814Ssimon u_int8_t maxlat; /* max. tolerated bus grant latency in 250ns */ 102160814Ssimon u_int8_t lattimer; /* latency timer in units of 30ns bus cycles */ 103160814Ssimon 104160814Ssimon u_int8_t mfdev; /* multi-function device (from hdrtype reg) */ 105160814Ssimon u_int8_t nummaps; /* actual number of PCI maps used */ 106160814Ssimon 107160814Ssimon u_int8_t bus; /* config space bus address */ 108160814Ssimon u_int8_t slot; /* config space slot address */ 109160814Ssimon u_int8_t func; /* config space function number */ 110160814Ssimon 111160814Ssimon u_int8_t secondarybus; /* bus on secondary side of bridge, if any */ 112160814Ssimon u_int8_t subordinatebus; /* topmost bus number behind bridge, if any */ 113160814Ssimon} pcicfgregs; 114160814Ssimon 115160814Ssimon/* additional type 1 device config header information (PCI to PCI bridge) */ 116160814Ssimon 117160814Ssimon#ifdef PCI_A64 118160814Ssimon#define PCI_PPBMEMBASE(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) & ~0xfffff) 119160814Ssimon#define PCI_PPBMEMLIMIT(h,l) ((((pci_addr_t)(h) << 32) + ((l)<<16)) | 0xfffff) 120160814Ssimon#else 121160814Ssimon#define PCI_PPBMEMBASE(h,l) (((l)<<16) & ~0xfffff) 122160814Ssimon#define PCI_PPBMEMLIMIT(h,l) (((l)<<16) | 0xfffff) 123160814Ssimon#endif /* PCI_A64 */ 124160814Ssimon 125160814Ssimon#define PCI_PPBIOBASE(h,l) ((((h)<<16) + ((l)<<8)) & ~0xfff) 126160814Ssimon#define PCI_PPBIOLIMIT(h,l) ((((h)<<16) + ((l)<<8)) | 0xfff) 127160814Ssimon 128160814Ssimontypedef struct { 129160814Ssimon pci_addr_t pmembase; /* base address of prefetchable memory */ 130160814Ssimon pci_addr_t pmemlimit; /* topmost address of prefetchable memory */ 131160814Ssimon u_int32_t membase; /* base address of memory window */ 132160814Ssimon u_int32_t memlimit; /* topmost address of memory window */ 133160814Ssimon u_int32_t iobase; /* base address of port window */ 134160814Ssimon u_int32_t iolimit; /* topmost address of port window */ 135160814Ssimon u_int16_t secstat; /* secondary bus status register */ 136160814Ssimon u_int16_t bridgectl; /* bridge control register */ 137160814Ssimon u_int8_t seclat; /* CardBus latency timer */ 138160814Ssimon} pcih1cfgregs; 139160814Ssimon 140160814Ssimon/* additional type 2 device config header information (CardBus bridge) */ 141160814Ssimon 142160814Ssimontypedef struct { 143160814Ssimon u_int32_t membase0; /* base address of memory window */ 144160814Ssimon u_int32_t memlimit0; /* topmost address of memory window */ 145160814Ssimon u_int32_t membase1; /* base address of memory window */ 146160814Ssimon u_int32_t memlimit1; /* topmost address of memory window */ 147160814Ssimon u_int32_t iobase0; /* base address of port window */ 148160814Ssimon u_int32_t iolimit0; /* topmost address of port window */ 149160814Ssimon u_int32_t iobase1; /* base address of port window */ 150160814Ssimon u_int32_t iolimit1; /* topmost address of port window */ 151160814Ssimon u_int32_t pccardif; /* PC Card 16bit IF legacy more base addr. */ 152160814Ssimon u_int16_t secstat; /* secondary bus status register */ 153160814Ssimon u_int16_t bridgectl; /* bridge control register */ 154160814Ssimon u_int8_t seclat; /* CardBus latency timer */ 155160814Ssimon} pcih2cfgregs; 156160814Ssimon 157160814Ssimon/* PCI bus attach definitions (there could be multiple PCI bus *trees* ... */ 158160814Ssimon 159160814Ssimontypedef struct pciattach { 160160814Ssimon int unit; 161160814Ssimon int pcibushigh; 162160814Ssimon struct pciattach *next; 163160814Ssimon} pciattach; 164160814Ssimon 165160814Ssimonstruct pci_devinfo { 166160814Ssimon STAILQ_ENTRY(pci_devinfo) pci_links; 167160814Ssimon struct pci_device *device; /* should this be ifdefed? */ 168160814Ssimon pcicfgregs cfg; 169160814Ssimon struct pci_conf conf; 170160814Ssimon}; 171160814Ssimon 172160814Ssimonextern u_int32_t pci_numdevs; 173160814Ssimon 174160814Ssimon 175160814Ssimon/* externally visible functions */ 176160814Ssimon 177160814Ssimonint pci_probe (pciattach *attach); 178160814Ssimonvoid pci_drvattach(struct pci_devinfo *dinfo); 179160814Ssimon 180160814Ssimon/* low level PCI config register functions provided by pcibus.c */ 181160814Ssimon 182160814Ssimonint pci_cfgopen (void); 183160814Ssimonint pci_cfgread (pcicfgregs *cfg, int reg, int bytes); 184160814Ssimonvoid pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes); 185160814Ssimon#ifdef __alpha__ 186160814Ssimonvm_offset_t pci_cvt_to_dense (vm_offset_t); 187160814Ssimonvm_offset_t pci_cvt_to_bwx (vm_offset_t); 188160814Ssimon#endif /* __alpha__ */ 189160814Ssimon 190160814Ssimon#ifdef _SYS_BUS_H_ 191160814Ssimon 192160814Ssimon#include "pci_if.h" 193160814Ssimon 194160814Ssimonenum pci_device_ivars { 195160814Ssimon PCI_IVAR_SUBVENDOR, 196160814Ssimon PCI_IVAR_SUBDEVICE, 197160814Ssimon PCI_IVAR_VENDOR, 198160814Ssimon PCI_IVAR_DEVICE, 199160814Ssimon PCI_IVAR_DEVID, 200160814Ssimon PCI_IVAR_CLASS, 201160814Ssimon PCI_IVAR_SUBCLASS, 202160814Ssimon PCI_IVAR_PROGIF, 203160814Ssimon PCI_IVAR_REVID, 204160814Ssimon PCI_IVAR_INTPIN, 205160814Ssimon PCI_IVAR_IRQ, 206160814Ssimon PCI_IVAR_BUS, 207160814Ssimon PCI_IVAR_SLOT, 208160814Ssimon PCI_IVAR_FUNCTION, 209160814Ssimon PCI_IVAR_SECONDARYBUS, 210160814Ssimon PCI_IVAR_SUBORDINATEBUS, 211160814Ssimon}; 212160814Ssimon 213160814Ssimon/* 214160814Ssimon * Simplified accessors for pci devices 215160814Ssimon */ 216160814Ssimon#define PCI_ACCESSOR(A, B, T) \ 217160814Ssimon \ 218160814Ssimonstatic __inline T pci_get_ ## A(device_t dev) \ 219160814Ssimon{ \ 220160814Ssimon uintptr_t v; \ 221160814Ssimon BUS_READ_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, &v); \ 222160814Ssimon return (T) v; \ 223160814Ssimon} \ 224160814Ssimon \ 225160814Ssimonstatic __inline void pci_set_ ## A(device_t dev, T t) \ 226160814Ssimon{ \ 227160814Ssimon u_long v = (u_long) t; \ 228160814Ssimon BUS_WRITE_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, v); \ 229160814Ssimon} 230160814Ssimon 231160814SsimonPCI_ACCESSOR(subvendor, SUBVENDOR, u_int16_t) 232160814SsimonPCI_ACCESSOR(subdevice, SUBDEVICE, u_int16_t) 233160814SsimonPCI_ACCESSOR(vendor, VENDOR, u_int16_t) 234160814SsimonPCI_ACCESSOR(device, DEVICE, u_int16_t) 235160814SsimonPCI_ACCESSOR(devid, DEVID, u_int32_t) 236160814SsimonPCI_ACCESSOR(class, CLASS, u_int8_t) 237160814SsimonPCI_ACCESSOR(subclass, SUBCLASS, u_int8_t) 238160814SsimonPCI_ACCESSOR(progif, PROGIF, u_int8_t) 239160814SsimonPCI_ACCESSOR(revid, REVID, u_int8_t) 240160814SsimonPCI_ACCESSOR(intpin, INTPIN, u_int8_t) 241160814SsimonPCI_ACCESSOR(irq, IRQ, u_int8_t) 242160814SsimonPCI_ACCESSOR(bus, BUS, u_int8_t) 243160814SsimonPCI_ACCESSOR(slot, SLOT, u_int8_t) 244160814SsimonPCI_ACCESSOR(function, FUNCTION, u_int8_t) 245160814SsimonPCI_ACCESSOR(secondarybus, SECONDARYBUS, u_int8_t) 246160814SsimonPCI_ACCESSOR(subordinatebus, SUBORDINATEBUS, u_int8_t) 247160814Ssimon 248160814Ssimonstatic __inline u_int32_t 249160814Ssimonpci_read_config(device_t dev, int reg, int width) 250160814Ssimon{ 251160814Ssimon return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width); 252160814Ssimon} 253160814Ssimon 254160814Ssimonstatic __inline void 255160814Ssimonpci_write_config(device_t dev, int reg, u_int32_t val, int width) 256160814Ssimon{ 257160814Ssimon PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width); 258160814Ssimon} 259160814Ssimon 260160814Ssimon#endif 261160814Ssimon 262/* for compatibility to FreeBSD-2.2 version of PCI code */ 263 264#ifdef PCI_COMPAT 265 266typedef pcicfgregs *pcici_t; 267typedef unsigned pcidi_t; 268typedef void pci_inthand_t(void *arg); 269 270#define pci_max_burst_len (3) 271 272/* just copied from old PCI code for now ... */ 273 274extern struct linker_set pcidevice_set; 275extern int pci_mechanism; 276 277struct pci_device { 278 char* pd_name; 279 const char* (*pd_probe ) (pcici_t tag, pcidi_t type); 280 void (*pd_attach) (pcici_t tag, int unit); 281 u_long *pd_count; 282 int (*pd_shutdown) (int, int); 283}; 284 285struct pci_lkm { 286 struct pci_device *dvp; 287 struct pci_lkm *next; 288}; 289 290#ifdef __i386__ 291typedef u_short pci_port_t; 292#else 293typedef u_int pci_port_t; 294#endif 295 296u_long pci_conf_read (pcici_t tag, u_long reg); 297void pci_conf_write (pcici_t tag, u_long reg, u_long data); 298void pci_configure (void); 299int pci_map_port (pcici_t tag, u_long reg, pci_port_t* pa); 300int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa); 301int pci_map_dense (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa); 302int pci_map_bwx (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa); 303int pci_map_int (pcici_t tag, pci_inthand_t *handler, void *arg, 304 intrmask_t *maskptr); 305int pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg, 306 intrmask_t *maskptr, u_int flags); 307int pci_unmap_int (pcici_t tag); 308int pci_register_lkm (struct pci_device *dvp, int if_revision); 309 310#endif /* PCI_COMPAT */ 311#endif /* _PCIVAR_H_ */ 312