2006-11-26 11:13:41 -07:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_XORG_CONFIG_H
|
|
|
|
#include <xorg-config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "compiler.h"
|
|
|
|
#include "xf86.h"
|
|
|
|
#include "xf86Priv.h"
|
|
|
|
#include "xf86_OSlib.h"
|
|
|
|
#include "Pci.h"
|
|
|
|
|
|
|
|
#include <sys/pciio.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* freebsd platform specific PCI access functions -- using /dev/pci
|
|
|
|
* needs kernel version 2.2.x
|
|
|
|
*/
|
|
|
|
static CARD32 freebsdPciCfgRead(PCITAG tag, int off);
|
|
|
|
static void freebsdPciCfgWrite(PCITAG, int off, CARD32 val);
|
|
|
|
static void freebsdPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits);
|
|
|
|
|
|
|
|
static pciBusFuncs_t freebsdFuncs0 = {
|
|
|
|
/* pciReadLong */ freebsdPciCfgRead,
|
|
|
|
/* pciWriteLong */ freebsdPciCfgWrite,
|
|
|
|
/* pciSetBitsLong */ freebsdPciCfgSetBits,
|
|
|
|
/* pciAddrHostToBus */ pciAddrNOOP,
|
|
|
|
/* pciAddrBusToHost */ pciAddrNOOP
|
|
|
|
};
|
|
|
|
|
|
|
|
static pciBusInfo_t freebsdPci0 = {
|
|
|
|
/* configMech */ PCI_CFG_MECH_OTHER,
|
|
|
|
/* numDevices */ 32,
|
|
|
|
/* secondary */ FALSE,
|
|
|
|
/* primary_bus */ 0,
|
|
|
|
/* funcs */ &freebsdFuncs0,
|
|
|
|
/* pciBusPriv */ NULL,
|
|
|
|
/* bridge */ NULL
|
|
|
|
};
|
|
|
|
|
2008-06-14 18:17:32 -06:00
|
|
|
#if !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__DragonFly__)
|
2006-11-26 11:13:41 -07:00
|
|
|
#if X_BYTE_ORDER == X_BIG_ENDIAN
|
|
|
|
#ifdef __sparc__
|
|
|
|
#ifndef ASI_PL
|
|
|
|
#define ASI_PL 0x88
|
|
|
|
#endif
|
|
|
|
#define PCI_CPU(val) ({ \
|
|
|
|
int __ret; \
|
|
|
|
__asm__ __volatile__("lduwa [%1] %2, %0" : "=r" (__ret) : "r" (&val), "i" (ASI_PL)); \
|
|
|
|
__ret; \
|
|
|
|
})
|
|
|
|
#else
|
|
|
|
#define PCI_CPU(val) (((val >> 24) & 0x000000ff) | \
|
|
|
|
((val >> 8) & 0x0000ff00) | \
|
|
|
|
((val << 8) & 0x00ff0000) | \
|
|
|
|
((val << 24) & 0xff000000))
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#define PCI_CPU(val) (val)
|
|
|
|
#endif
|
|
|
|
#else /* ! OpenBSD */
|
|
|
|
/* OpenBSD has already the bytes in the right order
|
|
|
|
for all architectures */
|
|
|
|
#define PCI_CPU(val) (val)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define BUS(tag) (((tag)>>16)&0xff)
|
|
|
|
#define DFN(tag) (((tag)>>8)&0xff)
|
|
|
|
|
|
|
|
static int pciFd = -1;
|
|
|
|
|
|
|
|
void
|
|
|
|
freebsdPciInit()
|
|
|
|
{
|
2006-11-28 13:29:31 -07:00
|
|
|
#ifndef X_PRIVSEP
|
2006-11-26 11:13:41 -07:00
|
|
|
pciFd = open("/dev/pci", O_RDWR);
|
2006-11-28 13:29:31 -07:00
|
|
|
#else
|
|
|
|
pciFd = priv_open_device("/dev/pci");
|
|
|
|
#endif
|
2006-11-26 11:13:41 -07:00
|
|
|
if (pciFd < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pciNumBuses = 1;
|
|
|
|
pciBusInfo[0] = &freebsdPci0;
|
|
|
|
pciFindFirstFP = pciGenFindFirst;
|
|
|
|
pciFindNextFP = pciGenFindNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CARD32
|
|
|
|
freebsdPciCfgRead(PCITAG tag, int off)
|
|
|
|
{
|
|
|
|
struct pci_io io;
|
|
|
|
int error;
|
|
|
|
io.pi_sel.pc_bus = BUS(tag);
|
|
|
|
io.pi_sel.pc_dev = DFN(tag) >> 3;
|
|
|
|
io.pi_sel.pc_func = DFN(tag) & 7;
|
|
|
|
io.pi_reg = off;
|
|
|
|
io.pi_width = 4;
|
|
|
|
error = ioctl(pciFd, PCIOCREAD, &io);
|
|
|
|
if (error)
|
|
|
|
return ~0;
|
|
|
|
return PCI_CPU(io.pi_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
freebsdPciCfgWrite(PCITAG tag, int off, CARD32 val)
|
|
|
|
{
|
|
|
|
struct pci_io io;
|
|
|
|
io.pi_sel.pc_bus = BUS(tag);
|
|
|
|
io.pi_sel.pc_dev = DFN(tag) >> 3;
|
|
|
|
io.pi_sel.pc_func = DFN(tag) & 7;
|
|
|
|
io.pi_reg = off;
|
|
|
|
io.pi_width = 4;
|
|
|
|
io.pi_data = PCI_CPU(val);
|
|
|
|
ioctl(pciFd, PCIOCWRITE, &io);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
freebsdPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits)
|
|
|
|
{
|
|
|
|
CARD32 val = freebsdPciCfgRead(tag, off);
|
|
|
|
val = (val & ~mask) | (bits & mask);
|
|
|
|
freebsdPciCfgWrite(tag, off, val);
|
|
|
|
}
|