Files
glide/swlibs/newpci/pcilib/fxfreebsd.c
2003-07-10 12:30:35 +00:00

366 lines
8.6 KiB
C

/*
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
**
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
** THE UNITED STATES.
**
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
*/
#include <stdlib.h>
#include <stdio.h>
#include <3dfx.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <machine/cpufunc.h>
#include <fcntl.h>
#include "fxpci.h"
#include "pcilib.h"
static const char* pciIdentifyFreeBSD(void);
static FxBool pciOutputStringFreeBSD(const char *msg);
static FxBool pciInitializeFreeBSD(void);
static FxBool pciShutdownFreeBSD(void);
static FxBool pciMapLinearFreeBSD(FxU32, FxU32 physical_addr, FxU32 *linear_addr,
FxU32 *length);
static FxBool pciUnmapLinearFreeBSD(FxU32 linear_addr, FxU32 length);
static FxBool pciSetPermissionFreeBSD(const FxU32, const FxU32, const FxBool);
static FxU8 pciPortInByteFreeBSD(unsigned short port);
static FxU16 pciPortInWordFreeBSD(unsigned short port);
static FxU32 pciPortInLongFreeBSD(unsigned short port);
static FxBool pciPortOutByteFreeBSD(unsigned short port, FxU8 data);
static FxBool pciPortOutWordFreeBSD(unsigned short port, FxU16 data);
static FxBool pciPortOutLongFreeBSD(unsigned short port, FxU32 data);
static FxBool pciMsrGetFreeBSD(MSRInfo *, MSRInfo *);
static FxBool pciMsrSetFreeBSD(MSRInfo *, MSRInfo *);
static FxBool pciSetPassThroughBaseFreeBSD(FxU32 *, FxU32);
const FxPlatformIOProcs ioProcsFreeBSD = {
pciInitializeFreeBSD,
pciShutdownFreeBSD,
pciIdentifyFreeBSD,
pciPortInByteFreeBSD,
pciPortInWordFreeBSD,
pciPortInLongFreeBSD,
pciPortOutByteFreeBSD,
pciPortOutWordFreeBSD,
pciPortOutLongFreeBSD,
pciMapLinearFreeBSD,
pciUnmapLinearFreeBSD,
pciSetPermissionFreeBSD,
pciMsrGetFreeBSD,
pciMsrSetFreeBSD,
pciOutputStringFreeBSD,
pciSetPassThroughBaseFreeBSD
};
const FxU32 PCI_VENDOR_ID_FREEBSD = 0x0;
const FxU32 PCI_DEVICE_ID_FREEBSD = 0x2;
const FxU32 PCI_COMMAND_FREEBSD = 0x4;
const FxU32 PCI_BASE_ADDRESS_0_FREEBSD = 0x10;
const FxU32 SST1_PCI_INIT_ENABLE_FREEBSD = 0x40;
const FxU32 SST1_PCI_BUS_SNOOP0_FREEBSD = 0x44;
const FxU32 SST1_PCI_BUS_SNOOP1_FREEBSD = 0x48;
static int freebsdDevFd=-1;
static int freebsdIoFd=-1;
struct pioData {
short port;
short size;
int device;
void *value;
};
FxBool
pciPlatformInit(void)
{
gCurPlatformIO = &ioProcsFreeBSD;
return FXTRUE;
}
FxBool
hasDev3DfxLinux(void)
{
if (freebsdDevFd==-1) return FXFALSE;
return FXTRUE;
}
FxU32
pciFetchRegisterLinux(FxU32 cmd, FxU32 size, FxU32 device)
{
struct pioData desc;
char cval;
short sval;
int ival;
if (freebsdDevFd==-1) return -1;
desc.port=cmd;
desc.size=size;
desc.device=device;
switch (size) {
case 1:
desc.value=&cval;
break;
case 2:
desc.value=&sval;
break;
case 4:
desc.value=&ival;
break;
default:
return 0;
}
if (ioctl(freebsdDevFd, _IOR('3', 3, sizeof(struct pioData)), &desc)==-1)
return 0;
switch (size) {
case 1:
return cval;
case 2:
return sval;
case 4:
return ival;
default:
return 0;
}
}
FxBool
pciUpdateRegisterLinux(FxU32 cmd, FxU32 data, FxU32 size, FxU32 device)
{
struct pioData desc;
if (freebsdDevFd==-1) return -1;
desc.port=cmd;
desc.size=size;
desc.device=device;
desc.value=&data;
if (ioctl(freebsdDevFd, _IOW('3', 4, sizeof(struct pioData)), &desc)==-1)
return FXFALSE;
return FXTRUE;
}
int
getNumDevicesLinux(void)
{
if (freebsdDevFd==-1) return -1;
return ioctl(freebsdDevFd, _IO('3', 2));
}
static const char*
pciIdentifyFreeBSD(void)
{
return "fxPCI for FreeBSD";
}
static FxBool
pciOutputStringFreeBSD(const char *msg)
{
printf(msg);
return FXTRUE;
}
static FxBool
pciInitializeFreeBSD(void)
{
if (geteuid()) freebsdDevFd=open("/dev/3dfx", O_RDWR, 0);
if (freebsdDevFd==-1) {
freebsdIoFd=open("/dev/io", O_RDWR, 0);
if (freebsdIoFd<0) {
pciErrorCode = PCI_ERR_NO_IO_PERM;
return FXFALSE;
}
}
return FXTRUE;
}
static FxBool
pciShutdownFreeBSD(void)
{
if (freebsdDevFd!=-1) close(freebsdDevFd);
freebsdDevFd=-1;
if (freebsdIoFd!=-1) close(freebsdIoFd);
freebsdIoFd=-1;
return FXTRUE;
}
static FxBool
pciMapLinearFreeBSD(FxU32 bus, FxU32 physical_addr,
FxU32 *linear_addr, FxU32 *length)
{
int fd;
if (freebsdDevFd!=-1) {
fd=freebsdDevFd;
} else {
if ((fd=open("/dev/mem", O_RDWR))<0) {
pciErrorCode=PCI_ERR_NO_MEM_PERM;
return FXFALSE;
}
}
if (((*linear_addr)=(FxU32)mmap(0, *length, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, physical_addr))<0) {
if (fd!=freebsdDevFd) close(fd);
return FXFALSE;
}
if (fd!=freebsdDevFd) close(fd);
return FXTRUE;
}
static FxBool
pciUnmapLinearFreeBSD( FxU32 linear_addr, FxU32 length ) {
munmap((void*)linear_addr, length);
return FXTRUE;
}
static FxBool
pciSetPermissionFreeBSD(const FxU32 addrBase, const FxU32 addrLen,
const FxBool writePermP)
{
return FXTRUE;
}
static FxU8
pciPortInByteFreeBSD(unsigned short port)
{
char tmp;
struct pioData desc;
if (freebsdDevFd==-1) {
tmp=inb(port);
/* fprintf(stderr, "Read byte at %x got %d\n", port, tmp); */
return tmp;
}
desc.port=port;
desc.size=sizeof(tmp);
desc.value=&tmp;
/* fprintf(stderr, "Read byte desc at %x tmp at %x\n", &desc, &tmp); */
ioctl(freebsdDevFd, _IOR(0, 0, sizeof(struct pioData)), &desc);
/* fprintf(stderr, "Got byte %d versus %d\n", tmp, inb(port)); */
return tmp;
}
static FxU16
pciPortInWordFreeBSD(unsigned short port)
{
short tmp;
struct pioData desc;
if (freebsdDevFd==-1) {
tmp=inw(port);
/* fprintf(stderr, "Read word at %x got %x\n", port, tmp); */
return tmp;
}
desc.port=port;
desc.size=sizeof(tmp);
desc.value=&tmp;
/* fprintf(stderr, "Read word desc at %x tmp at %x\n", &desc, &tmp); */
ioctl(freebsdDevFd, _IOR(0, 0, sizeof(struct pioData)), &desc);
/* fprintf(stderr, "Got word %d versus %d\n", tmp, inw(port)); */
return tmp;
}
static FxU32
pciPortInLongFreeBSD(unsigned short port)
{
int tmp;
struct pioData desc;
if (freebsdDevFd==-1) {
tmp=inl(port);
/* fprintf(stderr, "Read long at %x got %x\n", port, tmp); */
return tmp;
}
desc.port=port;
desc.size=sizeof(tmp);
desc.value=&tmp;
/* fprintf(stderr, "Read long desc at %x tmp at %x\n", &desc, &tmp); */
ioctl(freebsdDevFd, _IOR(0, 0, sizeof(struct pioData)), &desc);
/* fprintf(stderr, "Got long %x versus %x\n", tmp, inl(port)); */
return tmp;
}
static FxBool
pciPortOutByteFreeBSD(unsigned short port, FxU8 data)
{
struct pioData desc;
/* fprintf(stderr, "write byte=%d desc at %x data at %x\n", data,
&desc, &data); */
if (freebsdDevFd==-1) {
outb(port, data);
return FXTRUE;
}
desc.port=port;
desc.size=sizeof(data);
desc.value=&data;
return ioctl(freebsdDevFd, _IOW(0, 1, sizeof(struct pioData)), &desc)!=-1;
}
static FxBool
pciPortOutWordFreeBSD(unsigned short port, FxU16 data)
{
struct pioData desc;
/* fprintf(stderr, "write word=%x to port=%x desc at %x data at %x\n",
data, port, &desc, &data); */
if (freebsdDevFd==-1) {
outw(port, data);
return FXTRUE;
}
desc.port=port;
desc.size=sizeof(data);
desc.value=&data;
return ioctl(freebsdDevFd, _IOW(0, 1, sizeof(struct pioData)), &desc)!=-1;
}
static FxBool
pciPortOutLongFreeBSD(unsigned short port, FxU32 data)
{
struct pioData desc;
/* fprintf(stderr, "write long=%x to port=%x desc at %x data at %x\n",
data, port, &desc, &data); */
if (freebsdDevFd==-1) {
outl(port, data);
return FXTRUE;
}
desc.port=port;
desc.size=sizeof(data);
desc.value=&data;
return ioctl(freebsdDevFd, _IOW(0, 1, sizeof(struct pioData)), &desc)!=-1;
}
static FxBool
pciMsrGetFreeBSD(MSRInfo *in, MSRInfo *out)
{
return FXTRUE;
}
static FxBool
pciMsrSetFreeBSD(MSRInfo *in, MSRInfo *out)
{
return FXTRUE;
}
static FxBool
pciSetPassThroughBaseFreeBSD(FxU32 *baseAddr, FxU32 baseAddrLen)
{
return FXTRUE;
}