Xorg and PCI bus access: http://www.google.com/codesearch/p?hl=en&sa=N&cd=5&ct=rc#yK0X4qAocC8/xorg-server-X11R7.1-1.1.0/hw/xfree86/os-support/bus/Pci.c&q=ARCH_PCI_INIT * Pci.c - New server PCI access functions * * The XFree86 server PCI access functions have been reimplemented as a * framework that allows each supported platform/OS to have their own * platform/OS specific pci driver. * * All of the public PCI access functions exported to the other parts of * the server are declared in Pci.h and defined herein. These include: * pciInit() - Initialize PCI access functions * pciFindFirst() - Find a PCI device by dev/vend id * pciFindNext() - Find another PCI device by dev/vend id * pciReadLong() - Read a 32 bit value from a device's cfg space * pciReadWord() - Read a 16 bit value from a device's cfg space * pciReadByte() - Read an 8 bit value from a device's cfg space * pciWriteLong() - Write a 32 bit value to a device's cfg space * pciWriteWord() - Write a 16 bit value to a device's cfg space * pciWriteByte() - Write an 8 bit value to a device's cfg space * pciSetBitsLong() - Write a 32 bit value against a mask * pciSetBitsByte() - Write an 8 bit value against a mask * pciTag() - Return tag for a given PCI bus, device, & * function * pciBusAddrToHostAddr() - Convert a PCI address to a host address * pciHostAddrToBusAddr() - Convert a host address to a PCI address * pciGetBaseSize() - Returns the number of bits in a PCI base * addr mapping * xf86MapPciMem() - Like xf86MapVidMem() except function expects * a PCI address and a PCITAG that identifies * a PCI device * xf86ReadPciBIOS() - Like xf86ReadBIOS() but can handle PCI/host * address translation and BIOS decode enabling * xf86scanpci() - Return info about all PCI devices * xf86GetPciDomain() - Return domain number from a PCITAG * xf86MapDomainMemory() - Like xf86MapPciMem() but can handle * domain/host address translation * xf86MapDomainIO() - Maps PCI I/O spaces * xf86ReadDomainMemory() - Like xf86ReadPciBIOS() but can handle * domain/host address translation * * The actual PCI backend driver is selected by the pciInit() function * (see below) using either compile time definitions, run-time checks, * or both. * * Certain generic functions are provided that make the implementation * of certain well behaved platforms (e.g. those supporting PCI config * mechanism 1 or some thing close to it) very easy. * * Less well behaved platforms/OS's can roll their own functions. * * To add support for another platform/OS, add a call to fooPciInit() within * pciInit() below under the correct compile time definition or run-time * conditional. * * The fooPciInit() procedure must do three things: * 1) Initialize the pciBusTable[] for all primary PCI buses including * the per domain PCI access functions (readLong, writeLong, * addrBusToHost, and addrHostToBus). * * 2) Add entries to pciBusTable[] for configured secondary buses. This * step may be skipped if a platform is using the generic findFirst/ * findNext functions because these procedures will automatically * discover and add secondary buses dynamically. * * 3) Overide default settings for global PCI access functions if * required. These include pciFindFirstFP, pciFindNextFP, * Of course, if you choose not to use one of the generic * functions, you will need to provide a platform specifc replacement. * * Gary Barton * Concurrent Computer Corporation * ga...@gate.net * */ #ifdef HAVE_XORG_CONFIG_H #include <xorg-config.h> #endif #include <errno.h> #include <signal.h> #include <X11/Xarch.h> #include "compiler.h" #include "xf86.h" #include "xf86Priv.h" #define XF86_OS_PRIVS #include "xf86_OSproc.h" #include "Pci.h" #define PCI_MFDEV_SUPPORT 1 /* Include PCI multifunction device support */ #define PCI_BRIDGE_SUPPORT 1 /* Include support for PCI-to-PCI bridges */ /* * Global data */ static int pciInitialized = 0; CARD32 pciDevid; /* Requested device/vendor ID (after mask) */ CARD32 pciDevidMask; /* Bit mask applied (AND) before comparison */ /* of real devid's with requested */ int pciBusNum; /* Bus Number of current device */ int pciDevNum; /* Device number of current device */ int pciFuncNum; /* Function number of current device */ PCITAG pciDeviceTag; /* Tag for current device */ pciBusInfo_t *pciBusInfo[MAX_PCI_BUSES] = { NULL, }; _X_EXPORT int pciNumBuses = 0; /* Actual number of PCI buses */ int pciMaxBusNum = MAX_PCI_BUSES; static Bool inProbe = FALSE; static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, }; static int readPciBios( PCITAG Tag, CARD8* tmp, ADDRESS hostbase, unsigned char * buf, int len, PciBiosType BiosType ); static int (*pciOSHandleBIOS)(PCITAG Tag, int basereg, unsigned char *buf, int len); /* * Platform specific PCI function pointers. * * NOTE: A platform/OS specific pci init procedure can override these defaults * by setting them to the appropriate platform dependent functions. */ PCITAG (*pciFindFirstFP)(void) = pciGenFindFirst; PCITAG (*pciFindNextFP)(void) = pciGenFindNext; /* * pciInit - choose correct platform/OS specific PCI init routine */ void pciInit() { if (pciInitialized) return; pciInitialized = 1; /* XXX */ #if defined(DEBUGPCI) if (DEBUGPCI >= xf86Verbose) xf86Verbose = DEBUGPCI; #endif ARCH_PCI_INIT(); #if defined(ARCH_PCI_OS_INIT) if (pciNumBuses <= 0) ARCH_PCI_OS_INIT(); #endif } void pciSetOSBIOSPtr(int (*bios_fn)(PCITAG Tag, int basereg, unsigned char * buf, int len)) { pciOSHandleBIOS = bios_fn; } _X_EXPORT PCITAG pciFindFirst(CARD32 id, CARD32 mask) { #ifdef DEBUGPCI ErrorF("pciFindFirst(0x%lx, 0x%lx), pciInit = %d\n", id, mask, pciInitialized); #endif pciInit(); pciDevid = id & mask; pciDevidMask = mask; return((*pciFindFirstFP)()); } _X_EXPORT PCITAG pciFindNext(void) { #ifdef DEBUGPCI ErrorF("pciFindNext(), pciInit = %d\n", pciInitialized); #endif pciInit(); return((*pciFindNextFP)()); } _X_EXPORT CARD32 pciReadLong(PCITAG tag, int offset) { int bus = PCI_BUS_FROM_TAG(tag); #ifdef DEBUGPCI ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset); #endif pciInit(); if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] && pciBusInfo[bus]->funcs->pciReadLong) { CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadLong)(tag, offset); PCITRACE(1, ("pciReadLong: tag=0x%x [b=%d,d=%d,f=%d] returns 0x%08x\n", tag, bus, PCI_DEV_FROM_TAG(tag), PCI_FUNC_FROM_TAG(tag), rv)); return(rv); } return(PCI_NOT_FOUND); } |