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);
}




Reply via email to