aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c')
-rw-r--r--nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c1453
1 files changed, 0 insertions, 1453 deletions
diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
deleted file mode 100644
index 4e71eb614..000000000
--- a/nx-X11/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
+++ /dev/null
@@ -1,1453 +0,0 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.82 2004/01/16 15:39:04 tsi Exp $ */
-/*
- * 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
- * garyb@gate.net
- *
- */
-
-/*
- * Copyright 1998 by Concurrent Computer Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Concurrent Computer
- * Corporation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Concurrent Computer Corporation makes no representations
- * about the suitability of this software for any purpose. It is
- * provided "as is" without express or implied warranty.
- *
- * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
- * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- *
- * Copyright 1998 by Metro Link Incorporated
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Metro Link
- * Incorporated not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission. Metro Link Incorporated makes no representations
- * about the suitability of this software for any purpose. It is
- * provided "as is" without express or implied warranty.
- *
- * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
- * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- *
- * This software is derived from the original XFree86 PCI code
- * which includes the following copyright notices as well:
- *
- * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the names of the above listed copyright holder(s)
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. The above listed
- * copyright holder(s) make(s) no representations about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- *
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
- * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * This code is also based heavily on the code in FreeBSD-current, which was
- * written by Wolfgang Stanglmeier, and contains the following copyright:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-/*
- * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#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, };
-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, };
-
-/*
- * 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
-}
-
-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)());
-}
-
-PCITAG
-pciFindNext(void)
-{
-#ifdef DEBUGPCI
- ErrorF("pciFindNext(), pciInit = %d\n", pciInitialized);
-#endif
- pciInit();
-
- return((*pciFindNextFP)());
-}
-
-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);
-}
-
-CARD16
-pciReadWord(PCITAG tag, int offset)
-{
- CARD32 tmp;
- int shift = (offset & 3) * 8;
- int aligned_offset = offset & ~3;
- int bus = PCI_BUS_FROM_TAG(tag);
-
- if (shift != 0 && shift != 16)
- FatalError("pciReadWord: Alignment error: Cannot read 16 bits "
- "at offset %d\n", offset);
-
- pciInit();
-
- if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciReadWord) {
- CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadWord)(tag, offset);
-
- return(rv);
- } else {
- tmp = pciReadLong(tag, aligned_offset);
-
- return((CARD16)((tmp >> shift) & 0xffff));
- }
-}
-
-CARD8
-pciReadByte(PCITAG tag, int offset)
-{
- CARD32 tmp;
- int shift = (offset & 3) * 8;
- int aligned_offset = offset & ~3;
- int bus = PCI_BUS_FROM_TAG(tag);
-
- pciInit();
-
- if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciReadByte) {
- CARD8 rv = (*pciBusInfo[bus]->funcs->pciReadByte)(tag, offset);
-
- return(rv);
- } else {
- tmp = pciReadLong(tag, aligned_offset);
-
- return((CARD8)((tmp >> shift) & 0xff));
- }
-}
-
-void
-pciWriteLong(PCITAG tag, int offset, CARD32 val)
-{
- int bus = PCI_BUS_FROM_TAG(tag);
-
- pciInit();
-
- if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciWriteLong)
- (*pciBusInfo[bus]->funcs->pciWriteLong)(tag, offset, val);
-}
-
-void
-pciWriteWord(PCITAG tag, int offset, CARD16 val)
-{
- CARD32 tmp;
- int aligned_offset = offset & ~3;
- int shift = (offset & 3) * 8;
- int bus = PCI_BUS_FROM_TAG(tag);
-
- if (shift != 0 && shift != 16)
- FatalError("pciWriteWord: Alignment Error: Cannot read 16 bits "
- "from offset %d\n", offset);
-
- pciInit();
-
- if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciWriteWord) {
- (*pciBusInfo[bus]->funcs->pciWriteWord)(tag, offset, val);
- } else {
- tmp = pciReadLong(tag, aligned_offset);
-
- tmp &= ~(0xffffL << shift);
- tmp |= (((CARD32)val) << shift);
-
- pciWriteLong(tag, aligned_offset, tmp);
- }
-}
-
-void
-pciWriteByte(PCITAG tag, int offset, CARD8 val)
-{
- CARD32 tmp;
- int aligned_offset = offset & ~3;
- int shift = (offset & 3) *8 ;
- int bus = PCI_BUS_FROM_TAG(tag);
-
- pciInit();
-
- if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciWriteByte) {
- (*pciBusInfo[bus]->funcs->pciWriteByte)(tag, offset, val);
- } else {
-
- tmp = pciReadLong(tag, aligned_offset);
-
- tmp &= ~(0xffL << shift);
- tmp |= (((CARD32)val) << shift);
-
- pciWriteLong(tag, aligned_offset, tmp);
- }
-}
-
-void
-pciSetBitsLong(PCITAG tag, int offset, CARD32 mask, CARD32 val)
-{
- int bus = PCI_BUS_FROM_TAG(tag);
-
-#ifdef DEBUGPCI
- ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset);
-#endif
- pciInit();
-
- if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciSetBitsLong) {
- (*pciBusInfo[bus]->funcs->pciSetBitsLong)(tag, offset, mask, val);
- }
-}
-
-void
-pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val)
-{
- CARD32 tmp_mask, tmp_val;
- int aligned_offset = offset & ~3;
- int shift = (offset & 3) *8 ;
-
- tmp_mask = mask << shift;
- tmp_val = val << shift;
- pciSetBitsLong(tag, aligned_offset, tmp_mask, tmp_val);
-}
-
-ADDRESS
-pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr)
-{
- int bus = PCI_BUS_FROM_TAG(tag);
-
- pciInit();
-
- if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciAddrBusToHost)
- return (*pciBusInfo[bus]->funcs->pciAddrBusToHost)(tag, type, addr);
- else
- return(addr);
-}
-
-ADDRESS
-pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr)
-{
- int bus = PCI_BUS_FROM_TAG(tag);
-
- pciInit();
-
- if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] &&
- pciBusInfo[bus]->funcs->pciAddrHostToBus)
- return (*pciBusInfo[bus]->funcs->pciAddrHostToBus)(tag, type, addr);
- else
- return(addr);
-}
-
-/*
- * pciGetBaseSize() returns the size of a PCI base address mapping in bits.
- * The index identifies the base register: 0-5 are the six standard registers,
- * and 6 is the ROM base register. If destructive is TRUE, it will write
- * to the base address register to get an accurate result. Otherwise it
- * makes a conservative guess based on the alignment of the already allocated
- * address. If the result is accurate (ie, not an over-estimate), this is
- * indicated by setting *min to TRUE (when min is non-NULL). This happens
- * when either the destructive flag is set, the information is supplied by
- * the OS if the OS supports this.
- */
-
-int
-pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min)
-{
- int offset;
- CARD32 addr1;
- CARD32 addr2;
- CARD32 mask1;
- CARD32 mask2;
- int bits = 0;
-
- /*
- * Eventually a function for this should be added to pciBusFuncs_t, but for
- * now we'll just use a simple method based on the alignment of the already
- * allocated address.
- */
-
- /*
- * silently ignore bogus index values. Valid values are 0-6. 0-5 are
- * the 6 base address registers, and 6 is the ROM base address register.
- */
- if (index < 0 || index > 6)
- return 0;
-
- pciInit();
-
- if (xf86GetPciSizeFromOS(tag, index, &bits)) {
- if (min)
- *min = TRUE;
- return bits;
- }
-
- if (min)
- *min = destructive;
-
- /* Get the PCI offset */
- if (index == 6)
- offset = PCI_MAP_ROM_REG;
- else
- offset = PCI_MAP_REG_START + (index << 2);
-
- addr1 = pciReadLong(tag, offset);
- /*
- * Check if this is the second part of a 64 bit address.
- * XXX need to check how endianness affects 64 bit addresses.
- */
- if (index > 0 && index < 6) {
- addr2 = pciReadLong(tag, offset - 4);
- if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
- return 0;
- }
-
- if (destructive) {
- pciWriteLong(tag, offset, 0xffffffff);
- mask1 = pciReadLong(tag, offset);
- pciWriteLong(tag, offset, addr1);
- } else {
- mask1 = addr1;
- }
-
- /* Check if this is the first part of a 64 bit address. */
- if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1)) {
- if (PCIGETMEMORY(mask1) == 0) {
- addr2 = pciReadLong(tag, offset + 4);
- if (destructive) {
- pciWriteLong(tag, offset + 4, 0xffffffff);
- mask2 = pciReadLong(tag, offset + 4);
- pciWriteLong(tag, offset + 4, addr2);
- } else {
- mask2 = addr2;
- }
- if (mask2 == 0)
- return 0;
- bits = 32;
- while ((mask2 & 1) == 0) {
- bits++;
- mask2 >>= 1;
- }
- if (bits > 32)
- return bits;
- }
- }
- if (index < 6)
- if (PCI_MAP_IS_MEM(mask1))
- mask1 = PCIGETMEMORY(mask1);
- else
- mask1 = PCIGETIO(mask1);
- else
- mask1 = PCIGETROM(mask1);
- if (mask1 == 0)
- return 0;
- bits = 0;
- while ((mask1 & 1) == 0) {
- bits++;
- mask1 >>= 1;
- }
- /* I/O maps can be no larger than 8 bits */
-
- if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
- bits = 8;
- /* ROM maps can be no larger than 24 bits */
- if (index == 6 && bits > 24)
- bits = 24;
- return bits;
-}
-
-PCITAG
-pciTag(int busnum, int devnum, int funcnum)
-{
- return(PCI_MAKE_TAG(busnum,devnum,funcnum));
-}
-
-#if defined(PCI_MFDEV_SUPPORT) || defined(PowerMAX_OS)
-
-Bool
-pciMfDev(int busnum, int devnum)
-{
- PCITAG tag0, tag1;
- CARD32 id0, id1, val;
-
- /* Detect a multi-function device that complies to the PCI 2.0 spec */
-
- tag0 = PCI_MAKE_TAG(busnum, devnum, 0);
- id0 = pciReadLong(tag0, PCI_ID_REG);
- if ((CARD16)(id0 + 1) <= (CARD16)1UL)
- return FALSE;
-
- val = pciReadLong(tag0, PCI_HEADER_MISC) & 0x00ff0000;
- if ((val != 0x00ff0000) && (val & PCI_HEADER_MULTIFUNCTION))
- return TRUE;
-
- /*
- * Now, to find non-compliant devices...
- * If there is a valid ID for function 1 and the ID for func 0 and 1
- * are different, or the base0 values of func 0 and 1 are differend,
- * then assume there is a multi-function device.
- */
- tag1 = PCI_MAKE_TAG(busnum, devnum, 1);
- id1 = pciReadLong(tag1, PCI_ID_REG);
- if ((CARD16)(id1 + 1) <= (CARD16)1UL)
- return FALSE;
-
- /* Vendor IDs should match */
- if ((id0 ^ id1) & 0x0000ffff)
- return FALSE;
-
- if ((id0 != id1) ||
- /* Note the following test is valid for header types 0, 1 and 2 */
- (pciReadLong(tag0, PCI_MAP_REG_START) !=
- pciReadLong(tag1, PCI_MAP_REG_START)))
- return TRUE;
-
- return FALSE;
-}
-
-#endif
-
-/*
- * Generic find/read/write functions
- */
-PCITAG
-pciGenFindNext(void)
-{
- CARD32 devid, tmp;
- int sec_bus, pri_bus;
- static int previousBus = 0;
- Bool speculativeProbe = FALSE;
- unsigned char base_class, sub_class;
-
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext\n");
-#endif
-
- for (;;) {
-
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: pciBusNum %d\n", pciBusNum);
-#endif
- if (pciBusNum == -1) {
- /*
- * Start at top of the order
- */
- if (pciNumBuses <= 0)
- return(PCI_NOT_FOUND);
-
- /* Skip ahead to the first bus defined by pciInit() */
- for (pciBusNum = 0; !pciBusInfo[pciBusNum]; ++pciBusNum);
- pciFuncNum = 0;
- pciDevNum = 0;
- previousBus = pciBusNum; /* make sure previousBus exists */
- } else {
-#ifdef PCI_MFDEV_SUPPORT
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: pciFuncNum %d\n", pciFuncNum);
-#endif
- /*
- * Somewhere in middle of order. Determine who's
- * next up
- */
- if (pciFuncNum == 0) {
- /*
- * Is current dev a multifunction device?
- */
- if (!speculativeProbe && pciMfDev(pciBusNum, pciDevNum))
- /* Probe for other functions */
- pciFuncNum = 1;
- else
- /*
- * No more functions this device. Next
- * device please
- */
- pciDevNum ++;
- } else if (++pciFuncNum >= 8) {
- /* No more functions for this device. Next device please */
- pciFuncNum = 0;
- pciDevNum ++;
- }
-#else
- pciDevNum ++;
-#endif
- if (pciDevNum >= 32 ||
- !pciBusInfo[pciBusNum] ||
- pciDevNum >= pciBusInfo[pciBusNum]->numDevices) {
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: next bus\n");
-#endif
- /*
- * No more devices for this bus. Next bus please
- */
- if (speculativeProbe) {
- NextSpeculativeBus:
- xfree(pciBusInfo[pciBusNum]);
- pciBusInfo[pciBusNum] = NULL;
- speculativeProbe = FALSE;
- }
-
- if (++pciBusNum >= pciMaxBusNum) {
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: out of buses\n");
-#endif
- /* No more buses. All done for now */
- return(PCI_NOT_FOUND);
- }
-
- pciDevNum = 0;
- }
- }
-
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: pciBusInfo[%d] = 0x%lx\n", pciBusNum, pciBusInfo[pciBusNum]);
-#endif
- if (!pciBusInfo[pciBusNum]) {
- pciBusInfo[pciBusNum] = xnfalloc(sizeof(pciBusInfo_t));
- *pciBusInfo[pciBusNum] = *pciBusInfo[previousBus];
-
- speculativeProbe = TRUE;
- }
-
- /*
- * At this point, pciBusNum, pciDevNum, and pciFuncNum have been
- * advanced to the next device. Compute the tag, and read the
- * device/vendor ID field.
- */
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: [%d, %d, %d]\n", pciBusNum, pciDevNum, pciFuncNum);
-#endif
- pciDeviceTag = PCI_MAKE_TAG(pciBusNum, pciDevNum, pciFuncNum);
- inProbe = TRUE;
- devid = pciReadLong(pciDeviceTag, PCI_ID_REG);
- inProbe = FALSE;
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: pciDeviceTag = 0x%lx, devid = 0x%lx\n", pciDeviceTag, devid);
-#endif
- if ((CARD16)(devid + 1U) <= (CARD16)1UL)
- continue; /* Nobody home. Next device please */
-
- /*
- * Some devices mis-decode configuration cycles in such a way as to
- * create phantom buses.
- */
- if (speculativeProbe && (pciDevNum == 0) && (pciFuncNum == 0) &&
- (PCI_BUS_NO_DOMAIN(pciBusNum) > 0)) {
- for (;;) {
- if (++pciDevNum >= pciBusInfo[pciBusNum]->numDevices)
- goto NextSpeculativeBus;
- if (devid !=
- pciReadLong(PCI_MAKE_TAG(pciBusNum, pciDevNum, 0),
- PCI_ID_REG))
- break;
- }
-
- pciDevNum = 0;
- }
-
- if (pciNumBuses <= pciBusNum)
- pciNumBuses = pciBusNum + 1;
-
- speculativeProbe = FALSE;
- previousBus = pciBusNum;
-
-#ifdef PCI_BRIDGE_SUPPORT
- /*
- * Before checking for a specific devid, look for enabled
- * PCI to PCI bridge devices. If one is found, create and
- * initialize a bus info record (if one does not already exist).
- */
- tmp = pciReadLong(pciDeviceTag, PCI_CLASS_REG);
- base_class = PCI_CLASS_EXTRACT(tmp);
- sub_class = PCI_SUBCLASS_EXTRACT(tmp);
- if ((base_class == PCI_CLASS_BRIDGE) &&
- ((sub_class == PCI_SUBCLASS_BRIDGE_PCI) ||
- (sub_class == PCI_SUBCLASS_BRIDGE_CARDBUS))) {
- tmp = pciReadLong(pciDeviceTag, PCI_PCI_BRIDGE_BUS_REG);
- sec_bus = PCI_SECONDARY_BUS_EXTRACT(tmp, pciDeviceTag);
- pri_bus = PCI_PRIMARY_BUS_EXTRACT(tmp, pciDeviceTag);
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: pri_bus %d sec_bus %d\n",
- pri_bus, sec_bus);
-#endif
- if (pciBusNum != pri_bus) {
- /* Some bridges do not implement the primary bus register */
- if ((PCI_BUS_NO_DOMAIN(pri_bus) != 0) ||
- (sub_class != PCI_SUBCLASS_BRIDGE_CARDBUS))
- xf86Msg(X_WARNING,
- "pciGenFindNext: primary bus mismatch on PCI"
- " bridge 0x%08lx (0x%02x, 0x%02x)\n",
- pciDeviceTag, pciBusNum, pri_bus);
- pri_bus = pciBusNum;
- }
- if ((pri_bus < sec_bus) && (sec_bus < pciMaxBusNum) &&
- pciBusInfo[pri_bus]) {
- /*
- * Found a secondary PCI bus
- */
- if (!pciBusInfo[sec_bus]) {
- pciBusInfo[sec_bus] = xnfalloc(sizeof(pciBusInfo_t));
-
- /* Copy parents settings... */
- *pciBusInfo[sec_bus] = *pciBusInfo[pri_bus];
- }
-
- /* ...but not everything same as parent */
- pciBusInfo[sec_bus]->primary_bus = pri_bus;
- pciBusInfo[sec_bus]->secondary = TRUE;
- pciBusInfo[sec_bus]->numDevices = 32;
-
- if (pciNumBuses <= sec_bus)
- pciNumBuses = sec_bus + 1;
- }
- }
-#endif
-
- /*
- * Does this device match the requested devid after
- * applying mask?
- */
-#ifdef DEBUGPCI
- ErrorF("pciGenFindNext: pciDevidMask = 0x%lx, pciDevid = 0x%lx\n", pciDevidMask, pciDevid);
-#endif
- if ((devid & pciDevidMask) == pciDevid)
- /* Yes - Return it. Otherwise, next device */
- return(pciDeviceTag); /* got a match */
-
- } /* for */
- /*NOTREACHED*/
-}
-
-PCITAG
-pciGenFindFirst(void)
-{
- /* Reset PCI bus number to start from top */
- pciBusNum = -1;
-
- return pciGenFindNext();
-}
-
-CARD32
-pciByteSwap(CARD32 u)
-{
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-# if defined(__powerpc__) && defined(PowerMAX_OS)
- CARD32 tmp;
-
- __inst_stwbrx(u, &tmp, 0);
-
- return(tmp);
-
-# else /* !PowerMAX_OS */
-
- return lswapl(u);
-
-# endif /* !PowerMAX_OS */
-
-#else /* !BIG_ENDIAN */
-
- return(u);
-
-#endif
-}
-
-ADDRESS
-pciAddrNOOP(PCITAG tag, PciAddrType type, ADDRESS addr)
-{
- return(addr);
-}
-
-pciConfigPtr *
-xf86scanpci(int flags)
-{
- pciConfigPtr devp;
- pciBusInfo_t *busp;
- int idx = 0, i;
- PCITAG tag;
- static Bool done = FALSE;
-
- /*
- * if we haven't found PCI devices checking for pci_devp may
- * result in an endless recursion if platform/OS specific PCI
- * bus probing code calls this function from with in it.
- */
- if (done || pci_devp[0])
- return pci_devp;
-
- done = TRUE;
-
- pciInit();
-
-#ifdef XF86SCANPCI_WRAPPER
- XF86SCANPCI_WRAPPER(SCANPCI_INIT);
-#endif
-
- tag = pciFindFirst(0,0); /* 0 mask means match any valid device */
- /* Check if no devices, return now */
- if (tag == PCI_NOT_FOUND) {
-#ifdef XF86SCANPCI_WRAPPER
- XF86SCANPCI_WRAPPER(SCANPCI_TERM);
-#endif
- return NULL;
- }
-
-#ifdef DEBUGPCI
- ErrorF("xf86scanpci: tag = 0x%lx\n", tag);
-#endif
-#ifndef OLD_FORMAT
- xf86MsgVerb(X_INFO, 2, "PCI: PCI scan (all values are in hex)\n");
-#endif
-
- while (idx < MAX_PCI_DEVICES && tag != PCI_NOT_FOUND) {
- devp = xcalloc(1, sizeof(pciDevice));
- if (!devp) {
- xf86Msg(X_ERROR,
- "xf86scanpci: Out of memory after %d devices!!\n", idx);
- return (pciConfigPtr *)NULL;
- }
-
- /* Identify pci device by bus, dev, func, and tag */
- devp->tag = tag;
- devp->busnum = PCI_BUS_FROM_TAG(tag);
- devp->devnum = PCI_DEV_FROM_TAG(tag);
- devp->funcnum = PCI_FUNC_FROM_TAG(tag);
-
- /* Read config space for this device */
- for (i = 0; i < 17; i++) /* PCI hdr plus 1st dev spec dword */
- devp->cfgspc.dwords[i] = pciReadLong(tag, i * sizeof(CARD32));
-
- /* Some broken devices don't implement this field... */
- if (devp->pci_header_type == 0xff)
- devp->pci_header_type = 0;
-
- switch (devp->pci_header_type & 0x7f) {
- case 0:
- /* Get base address sizes for type 0 headers */
- for (i = 0; i < 7; i++)
- devp->basesize[i] =
- pciGetBaseSize(tag, i, FALSE, &devp->minBasesize);
- break;
-
- case 1:
- case 2:
- /* Allow master aborts to complete normally on secondary buses */
- if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN))
- break;
- pciWriteByte(tag, PCI_PCI_BRIDGE_CONTROL_REG,
- devp->pci_bridge_control &
- ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN |
- PCI_PCI_BRIDGE_SECONDARY_RESET));
- break;
-
- default:
- break;
- }
-
-#ifdef OLD_FORMAT
- xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%.2x,0x%02x,0x%1x "
- "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n",
- devp->busnum, devp->devnum, devp->funcnum,
- devp->pci_vendor, devp->pci_device, devp->pci_rev_id,
- devp->pci_base_class, devp->pci_sub_class);
-#else
- xf86MsgVerb(X_INFO, 2, "PCI: %.2x:%02x:%1x: chip %04x,%04x"
- " card %04x,%04x rev %02x class %02x,%02x,%02x hdr %02x\n",
- devp->busnum, devp->devnum, devp->funcnum,
- devp->pci_vendor, devp->pci_device,
- devp->pci_subsys_vendor, devp->pci_subsys_card,
- devp->pci_rev_id, devp->pci_base_class,
- devp->pci_sub_class, devp->pci_prog_if,
- devp->pci_header_type);
-#endif
-
- pci_devp[idx++] = devp;
- tag = pciFindNext();
-
-#ifdef DEBUGPCI
- ErrorF("xf86scanpci: tag = pciFindNext = 0x%lx\n", tag);
-#endif
- }
-
- /* Restore modified data (in reverse order), and link buses */
- while (--idx >= 0) {
- devp = pci_devp[idx];
- switch (devp->pci_header_type & 0x7f) {
- case 0:
- if ((devp->pci_base_class != PCI_CLASS_BRIDGE) ||
- (devp->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST))
- break;
- pciBusInfo[devp->busnum]->bridge = devp;
- pciBusInfo[devp->busnum]->primary_bus = devp->busnum;
- break;
-
- case 1:
- case 2:
- i = PCI_SECONDARY_BUS_EXTRACT(devp->pci_pp_bus_register, devp->tag);
- if (i > devp->busnum) {
- if (pciBusInfo[i]) {
- pciBusInfo[i]->bridge = devp;
- /*
- * The back link needs to be set here, and is unlikely to
- * change.
- */
- devp->businfo = pciBusInfo[i];
- }
-#ifdef ARCH_PCI_PCI_BRIDGE
- ARCH_PCI_PCI_BRIDGE(devp);
-#endif
- }
- if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN))
- break;
- pciWriteByte(devp->tag, PCI_PCI_BRIDGE_CONTROL_REG,
- devp->pci_bridge_control & ~PCI_PCI_BRIDGE_SECONDARY_RESET);
- break;
-
- default:
- break;
- }
- }
-
-#ifdef XF86SCANPCI_WRAPPER
- XF86SCANPCI_WRAPPER(SCANPCI_TERM);
-#endif
-
- /*
- * Lastly, link bridges to their secondary bus, after the architecture has
- * had a chance to modify these assignments.
- */
- for (idx = 0; idx < pciNumBuses; idx++) {
- if (!(busp = pciBusInfo[idx]) || !(devp = busp->bridge))
- continue;
- devp->businfo = busp;
- }
-
-#ifndef OLD_FORMAT
- xf86MsgVerb(X_INFO, 2, "PCI: End of PCI scan\n");
-#endif
-
- return pci_devp;
-}
-
-CARD32
-pciCheckForBrokenBase(PCITAG Tag,int basereg)
-{
- pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), 0xffffffff);
- return pciReadLong(Tag, PCI_MAP_REG_START + (basereg << 2));
-}
-
-#if defined(INCLUDE_XF86_MAP_PCI_MEM)
-
-pointer
-xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, ADDRESS Base,
- unsigned long Size)
-{
- ADDRESS hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM,Base);
- pointer base;
- CARD32 save = 0;
-
- /*
- * If there are possible read side-effects, disable memory while
- * doing the mapping.
- */
- if (Flags & VIDMEM_READSIDEEFFECT) {
- save = pciReadLong(Tag, PCI_CMD_STAT_REG);
- pciWriteLong(Tag, PCI_CMD_STAT_REG,
- save & ~PCI_CMD_MEM_ENABLE);
- }
- base = xf86MapDomainMemory(ScreenNum, Flags, Tag, hostbase, Size);
- if (!base) {
- FatalError("xf86MapPciMem: Could not mmap PCI memory "
- "[base=0x%lx,hostbase=0x%lx,size=%lx] (%s)\n",
- Base, hostbase, Size, strerror(errno));
- }
- /*
- * If read side-effects, do whatever might be needed to prevent
- * unintended reads, then restore PCI_CMD_STAT_REG.
- */
- if (Flags & VIDMEM_READSIDEEFFECT) {
- xf86MapReadSideEffects(ScreenNum, Flags, base, Size);
- pciWriteLong(Tag, PCI_CMD_STAT_REG, save);
- }
- return((pointer)base);
-}
-
-static int
-handlePciBIOS(PCITAG Tag, int basereg,
- int (*func)(PCITAG, CARD8*, ADDRESS, pointer),
- pointer args)
-{
- CARD32 romsave = 0;
- int i;
- romBaseSource b_reg;
- ADDRESS hostbase;
- CARD8 tmp[64];
- int ret = 0;
-
- romsave = pciReadLong(Tag, PCI_MAP_ROM_REG);
-
- for (i = ROM_BASE_PRESET; i <= ROM_BASE_FIND; i++) {
- memType savebase = 0, newbase, romaddr;
-
- switch (i) {
- case ROM_BASE_PRESET:
- /* Does the driver have a preference? */
- if (basereg > ROM_BASE_PRESET && basereg <= ROM_BASE_FIND)
- b_reg = basereg;
- else
- b_reg = ++i;
- break;
- case ROM_BASE_FIND:
- /*
- * If we have something that looks like a valid address
- * in romsave, it's probably not going to help to try
- * to guess a new address and reprogram it.
- */
- if (PCIGETROM(romsave)) {
- pciWriteLong(Tag, PCI_MAP_ROM_REG, PCI_MAP_ROM_ADDRESS_MASK);
- if (romsave != pciReadLong(Tag, PCI_MAP_ROM_REG)) {
- pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave);
- continue;
- }
- }
- default:
- b_reg = i;
- }
-
- if (!(newbase = getValidBIOSBase(Tag, b_reg)))
- continue; /* no valid address found */
-
- romaddr = PCIGETROM(newbase);
-
- /* if we use a mem base save it and move it out of the way */
- if (b_reg >= 0 && b_reg <= 5) {
- savebase = pciReadLong(Tag, PCI_MAP_REG_START+(b_reg<<2));
- xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]"
- " for device %i:%i:%i\n", basereg,
- (int)PCI_BUS_FROM_TAG(Tag), (int)PCI_DEV_FROM_TAG(Tag),
- (int)PCI_FUNC_FROM_TAG(Tag));
- pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2),
- (CARD32)~0);
- }
- /* Set ROM base address and enable ROM address decoding */
- pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr
- | PCI_MAP_ROM_DECODE_ENABLE);
-
- hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM, PCIGETROM(romaddr));
-
- if ((xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) !=
- sizeof(tmp)) ||
- (tmp[0] != 0x55) || (tmp[1] != 0xaa) || !tmp[2] ) {
- /* Restore the base registers if they were changed. */
- pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave);
- if (savebase) pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2),
- (CARD32) savebase);
-
- /* No BIOS found: try another address */
- continue;
- }
-
- ret = (*func)(Tag, tmp, hostbase, args);
-
- /* Restore the base register if it was changed. */
- if (savebase) pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2),
- (CARD32) savebase);
- /* Restore ROM address decoding */
- pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave);
-
- return ret;
- }
- /* Restore ROM address decoding */
- pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave);
- return 0;
-}
-
-typedef struct {
- unsigned long Offset;
- int Len;
- unsigned char *Buf;
- PciBiosType BiosType;
-} readBios, *readBiosPtr;
-
-static int
-readPciBios(PCITAG Tag, CARD8* tmp, ADDRESS hostbase, pointer args)
-{
- unsigned int image_length = 0;
- readBiosPtr rd = args;
- int ret;
-
- /* We found a PCI BIOS Image. Now we look for the correct type */
- while ((tmp[0] == 0x55) && (tmp[1] == 0xAA)) {
- unsigned short data_off = tmp[0x18] | (tmp[0x19] << 8);
- unsigned char data[0x18];
- unsigned char type;
-
- if ((xf86ReadDomainMemory(Tag, hostbase + data_off, sizeof(data), data)
- != sizeof(data)) ||
- (data[0] != 'P') ||
- (data[1] != 'C') ||
- (data[2] != 'I') ||
- (data[3] != 'R'))
- break;
- type = data[0x14];
-#ifdef PRINT_PCI
- ErrorF("data segment in BIOS: 0x%x, type: 0x%x\n", data_off, type);
-#endif
- if (type != rd->BiosType) { /* not correct image: find next one */
- unsigned char indicator = data[0x15];
- unsigned int i_length;
- if (indicator & 0x80) /* last image */
- break;
- i_length = (data[0x10] | (data[0x11] << 8)) << 9;
-#ifdef PRINT_PCI
- ErrorF("data image length: 0x%x, ind: 0x%x\n",
- image_length, indicator);
-#endif
- hostbase += i_length;
- if (xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp)
- != sizeof(tmp))
- break;
- continue;
- }
- /* OK, we have a PCI BIOS Image of the correct type */
-
- if (rd->BiosType == PCI_BIOS_PC)
- image_length = tmp[2] << 9;
- else
- image_length = (data[0x10] | (data[0x11] << 8)) << 9;
-#ifdef PRINT_PCI
- ErrorF("BIOS length: 0x%x\n", image_length);
-#endif
- break;
- }
-
- ret = 0;
- if (image_length) {
-
- /*
- * if no length is given return the full lenght,
- * Offset 0. Beware: Area pointed to by Buf must
- * be large enough!
- */
- if (rd->Len == 0) {
- rd->Len = image_length;
- rd->Offset = 0;
- }
- if ((rd->Offset) > (image_length)) {
- xf86Msg(X_WARNING,"xf86ReadPciBios: requesting data past "
- "end of BIOS %li > %i\n",(rd->Offset) , (image_length));
- } else {
- if ((rd->Offset + rd->Len) > (image_length)) {
- rd->Len = (image_length) - rd->Offset;
- xf86MsgVerb(X_INFO,3,"Truncating PCI BIOS Length to %i\n",rd->Len);
- }
- }
-
- /* Read BIOS */
- ret = xf86ReadDomainMemory(Tag, hostbase + rd->Offset, rd->Len, rd->Buf);
- }
-
- return ret;
-}
-
-static int
-getPciBIOSTypes(PCITAG Tag, CARD8* tmp, ADDRESS hostbase, pointer arg)
-{
- int n = 0;
- PciBiosType *Buf = arg;
-
- /* We found a PCI BIOS Image. Now we collect the types type */
- do {
- unsigned short data_off = tmp[0x18] | (tmp[0x19] << 8);
- unsigned char data[0x16];
- unsigned int i_length;
-
- if ((xf86ReadDomainMemory(Tag, hostbase + data_off, sizeof(data), data)
- != sizeof(data)) ||
- (data[0] != 'P') ||
- (data[1] != 'C') ||
- (data[2] != 'I') ||
- (data[3] != 'R'))
- break;
-
- if (data[0x14] >= PCI_BIOS_OTHER)
- *Buf++ = PCI_BIOS_OTHER;
- else
- *Buf++ = data[0x14];
-
- n++;
- if (data[0x15] & 0x80) /* last image */
- break;
-#ifdef PRINT_PCI
- ErrorF("data segment in BIOS: 0x%x, type: 0x%x\n", data_off, type);
-#endif
- i_length = (data[0x10] | (data[0x11] << 8)) << 9;
-#ifdef PRINT_PCI
- ErrorF("data image length: 0x%x, ind: 0x%x\n",
- image_length, indicator);
-#endif
- hostbase += i_length;
- if (xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp)
- != sizeof(tmp))
- break;
- continue;
- } while ((tmp[0] == 0x55) && (tmp[1] == 0xAA));
- return n;
-}
-
-typedef CARD32 (*ReadProcPtr)(PCITAG, int);
-typedef void (*WriteProcPtr)(PCITAG, int, CARD32);
-
-static int
-HandlePciBios(PCITAG Tag, int basereg,
- int (*func)(PCITAG, CARD8*, ADDRESS, pointer),
- pointer ptr)
-{
- int n, num;
- CARD32 Acc1, Acc2;
- PCITAG *pTag;
- int i;
-
- n = handlePciBIOS(Tag,basereg,func,ptr);
- if (n)
- return n;
-
- num = pciTestMultiDeviceCard(PCI_BUS_FROM_TAG(Tag),
- PCI_DEV_FROM_TAG(Tag),
- PCI_FUNC_FROM_TAG(Tag),&pTag);
-
- if (!num) return 0;
-
-#define PCI_ENA (PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE)
- Acc1 = pciReadLong(Tag, PCI_CMD_STAT_REG);
- pciWriteLong(Tag, PCI_CMD_STAT_REG, (Acc1 & ~PCI_ENA));
-
- for (i = 0; i < num; i++) {
- Acc2 = pciReadLong(pTag[i], PCI_CMD_STAT_REG);
- pciWriteLong(pTag[i], PCI_CMD_STAT_REG, (Acc2 | PCI_ENA));
-
- n = handlePciBIOS(pTag[i],0,func,ptr);
-
- pciWriteLong(pTag[i], PCI_CMD_STAT_REG, Acc2);
- if (n)
- break;
- }
- pciWriteLong(Tag, PCI_CMD_STAT_REG, Acc1);
- return n;
-}
-
-int
-xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
- unsigned char *Buf, int Len)
-{
- return xf86ReadPciBIOSByType(Offset, Tag, basereg, Buf, Len, PCI_BIOS_PC);
-}
-
-int
-xf86ReadPciBIOSByType(unsigned long Offset, PCITAG Tag, int basereg,
- unsigned char *Buf, int Len, PciBiosType Type)
-{
-
- readBios rb;
- rb.Offset = Offset;
- rb.Len = Len;
- rb.Buf = Buf;
- rb.BiosType = Type;
-
- return HandlePciBios(Tag, basereg, readPciBios, &rb);
-}
-
-int
-xf86GetAvailablePciBIOSTypes(PCITAG Tag, int basereg, PciBiosType *Buf)
-{
- return HandlePciBios(Tag, basereg, getPciBIOSTypes, (pointer) Buf);
-}
-
-#endif /* INCLUDE_XF86_MAP_PCI_MEM */
-
-#ifdef INCLUDE_XF86_NO_DOMAIN
-
-int
-xf86GetPciDomain(PCITAG Tag)
-{
- return 0;
-}
-
-pointer
-xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag,
- ADDRESS Base, unsigned long Size)
-{
- return xf86MapVidMem(ScreenNum, Flags, Base, Size);
-}
-
-IOADDRESS
-xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag,
- IOADDRESS Base, unsigned long Size)
-{
- return Base;
-}
-
-int
-xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf)
-{
- int ret, length, rlength;
-
- /* Read in 64kB chunks */
- ret = 0;
- while ((length = Len) > 0) {
- if (length > 0x010000) length = 0x010000;
- rlength = xf86ReadBIOS(Base, 0, Buf, length);
- if (rlength < 0) {
- ret = rlength;
- break;
- }
- ret += rlength;
- if (rlength < length) break;
- Base += rlength;
- Buf += rlength;
- Len -= rlength;
- }
-
- return ret;
-}
-
-#endif /* INCLUDE_XF86_NO_DOMAIN */