414 lines
12 KiB
C
414 lines
12 KiB
C
|
/****************************************************************************
|
||
|
*
|
||
|
* SciTech OS Portability Manager Library
|
||
|
*
|
||
|
* ========================================================================
|
||
|
*
|
||
|
* The contents of this file are subject to the SciTech MGL Public
|
||
|
* License Version 1.0 (the "License"); you may not use this file
|
||
|
* except in compliance with the License. You may obtain a copy of
|
||
|
* the License at http://www.scitechsoft.com/mgl-license.txt
|
||
|
*
|
||
|
* Software distributed under the License is distributed on an
|
||
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||
|
* implied. See the License for the specific language governing
|
||
|
* rights and limitations under the License.
|
||
|
*
|
||
|
* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is SciTech Software, Inc.
|
||
|
* All Rights Reserved.
|
||
|
*
|
||
|
* ========================================================================
|
||
|
*
|
||
|
* Language: ANSI C
|
||
|
* Environment: Any
|
||
|
*
|
||
|
* Description: Header file for interface routines to the PCI bus.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#ifndef __PCILIB_H
|
||
|
#define __PCILIB_H
|
||
|
|
||
|
#include "scitech.h"
|
||
|
|
||
|
/*---------------------- Macros and type definitions ----------------------*/
|
||
|
|
||
|
#pragma pack(1)
|
||
|
|
||
|
/* Defines for PCIDeviceInfo.HeaderType */
|
||
|
|
||
|
typedef enum {
|
||
|
PCI_deviceType = 0x00,
|
||
|
PCI_bridgeType = 0x01,
|
||
|
PCI_cardBusBridgeType = 0x02,
|
||
|
PCI_multiFunctionType = 0x80
|
||
|
} PCIHeaderTypeFlags;
|
||
|
|
||
|
/* Defines for PCIDeviceInfo.Command */
|
||
|
|
||
|
typedef enum {
|
||
|
PCI_enableIOSpace = 0x0001,
|
||
|
PCI_enableMemorySpace = 0x0002,
|
||
|
PCI_enableBusMaster = 0x0004,
|
||
|
PCI_enableSpecialCylces = 0x0008,
|
||
|
PCI_enableWriteAndInvalidate = 0x0010,
|
||
|
PCI_enableVGACompatiblePalette = 0x0020,
|
||
|
PCI_enableParity = 0x0040,
|
||
|
PCI_enableWaitCycle = 0x0080,
|
||
|
PCI_enableSerr = 0x0100,
|
||
|
PCI_enableFastBackToBack = 0x0200
|
||
|
} PCICommandFlags;
|
||
|
|
||
|
/* Defines for PCIDeviceInfo.Status */
|
||
|
|
||
|
typedef enum {
|
||
|
PCI_statusCapabilitiesList = 0x0010,
|
||
|
PCI_status66MhzCapable = 0x0020,
|
||
|
PCI_statusUDFSupported = 0x0040,
|
||
|
PCI_statusFastBackToBack = 0x0080,
|
||
|
PCI_statusDataParityDetected = 0x0100,
|
||
|
PCI_statusDevSel = 0x0600,
|
||
|
PCI_statusSignaledTargetAbort = 0x0800,
|
||
|
PCI_statusRecievedTargetAbort = 0x1000,
|
||
|
PCI_statusRecievedMasterAbort = 0x2000,
|
||
|
PCI_statusSignaledSystemError = 0x4000,
|
||
|
PCI_statusDetectedParityError = 0x8000
|
||
|
} PCIStatusFlags;
|
||
|
|
||
|
/* PCI capability IDs */
|
||
|
|
||
|
typedef enum {
|
||
|
PCI_capsPowerManagement = 0x01,
|
||
|
PCI_capsAGP = 0x02,
|
||
|
PCI_capsMSI = 0x05
|
||
|
} PCICapsType;
|
||
|
|
||
|
/* PCI AGP rate definitions */
|
||
|
|
||
|
typedef enum {
|
||
|
PCI_AGPRate1X = 0x1,
|
||
|
PCI_AGPRate2X = 0x2,
|
||
|
PCI_AGPRate4X = 0x4
|
||
|
} PCIAGPRateType;
|
||
|
|
||
|
/* NOTE: We define all bitfield's as uint's, specifically so that the IBM
|
||
|
* Visual Age C++ compiler does not complain. We need them to be
|
||
|
* 32-bits wide, and this is the width of an unsigned integer, but
|
||
|
* we can't use a ulong to make this explicit or we get errors.
|
||
|
*/
|
||
|
|
||
|
/* Structure defining a PCI slot identifier */
|
||
|
|
||
|
typedef union {
|
||
|
struct {
|
||
|
uint Zero:2;
|
||
|
uint Register:6;
|
||
|
uint Function:3;
|
||
|
uint Device:5;
|
||
|
uint Bus:8;
|
||
|
uint Reserved:7;
|
||
|
uint Enable:1;
|
||
|
} p;
|
||
|
ulong i;
|
||
|
} PCIslot;
|
||
|
|
||
|
/* Structure defining the regular (type 0) PCI configuration register
|
||
|
* layout. We use this in a union below so we can describe all types of
|
||
|
* PCI configuration spaces with a single structure.
|
||
|
*/
|
||
|
|
||
|
typedef struct {
|
||
|
ulong BaseAddress10;
|
||
|
ulong BaseAddress14;
|
||
|
ulong BaseAddress18;
|
||
|
ulong BaseAddress1C;
|
||
|
ulong BaseAddress20;
|
||
|
ulong BaseAddress24;
|
||
|
ulong CardbusCISPointer;
|
||
|
ushort SubSystemVendorID;
|
||
|
ushort SubSystemID;
|
||
|
ulong ROMBaseAddress;
|
||
|
uchar CapabilitiesPointer;
|
||
|
uchar reserved1;
|
||
|
uchar reserved2;
|
||
|
uchar reserved3;
|
||
|
ulong reserved4;
|
||
|
uchar InterruptLine;
|
||
|
uchar InterruptPin;
|
||
|
uchar MinimumGrant;
|
||
|
uchar MaximumLatency;
|
||
|
|
||
|
/* These are not in the actual config space, but we enumerate them */
|
||
|
ulong BaseAddress10Len;
|
||
|
ulong BaseAddress14Len;
|
||
|
ulong BaseAddress18Len;
|
||
|
ulong BaseAddress1CLen;
|
||
|
ulong BaseAddress20Len;
|
||
|
ulong BaseAddress24Len;
|
||
|
ulong ROMBaseAddressLen;
|
||
|
} PCIType0Info;
|
||
|
|
||
|
/* Structure defining PCI to PCI bridge (type 1) PCI configuration register
|
||
|
* layout. We use this in a union below so we can describe all types of
|
||
|
* PCI configuration spaces with a single structure.
|
||
|
*/
|
||
|
|
||
|
typedef struct {
|
||
|
ulong BaseAddress10;
|
||
|
ulong BaseAddress14;
|
||
|
uchar PrimaryBusNumber;
|
||
|
uchar SecondayBusNumber;
|
||
|
uchar SubordinateBusNumber;
|
||
|
uchar SecondaryLatencyTimer;
|
||
|
uchar IOBase;
|
||
|
uchar IOLimit;
|
||
|
ushort SecondaryStatus;
|
||
|
ushort MemoryBase;
|
||
|
ushort MemoryLimit;
|
||
|
ushort PrefetchableMemoryBase;
|
||
|
ushort PrefetchableMemoryLimit;
|
||
|
ulong PrefetchableBaseHi;
|
||
|
ulong PrefetchableLimitHi;
|
||
|
ushort IOBaseHi;
|
||
|
ushort IOLimitHi;
|
||
|
uchar CapabilitiesPointer;
|
||
|
uchar reserved1;
|
||
|
uchar reserved2;
|
||
|
uchar reserved3;
|
||
|
ulong ROMBaseAddress;
|
||
|
uchar InterruptLine;
|
||
|
uchar InterruptPin;
|
||
|
ushort BridgeControl;
|
||
|
} PCIType1Info;
|
||
|
|
||
|
/* PCI to CardBus bridge (type 2) configuration information */
|
||
|
typedef struct {
|
||
|
ulong SocketRegistersBaseAddress;
|
||
|
uchar CapabilitiesPointer;
|
||
|
uchar reserved1;
|
||
|
ushort SecondaryStatus;
|
||
|
uchar PrimaryBus;
|
||
|
uchar SecondaryBus;
|
||
|
uchar SubordinateBus;
|
||
|
uchar SecondaryLatency;
|
||
|
struct {
|
||
|
ulong Base;
|
||
|
ulong Limit;
|
||
|
} Range[4];
|
||
|
uchar InterruptLine;
|
||
|
uchar InterruptPin;
|
||
|
ushort BridgeControl;
|
||
|
} PCIType2Info;
|
||
|
|
||
|
/* Structure defining the PCI configuration space information for a
|
||
|
* single PCI device on the PCI bus. We enumerate all this information
|
||
|
* for all PCI devices on the bus.
|
||
|
*/
|
||
|
|
||
|
typedef struct {
|
||
|
ulong dwSize;
|
||
|
PCIslot slot;
|
||
|
ulong mech1;
|
||
|
ushort VendorID;
|
||
|
ushort DeviceID;
|
||
|
ushort Command;
|
||
|
ushort Status;
|
||
|
uchar RevID;
|
||
|
uchar Interface;
|
||
|
uchar SubClass;
|
||
|
uchar BaseClass;
|
||
|
uchar CacheLineSize;
|
||
|
uchar LatencyTimer;
|
||
|
uchar HeaderType;
|
||
|
uchar BIST;
|
||
|
union {
|
||
|
PCIType0Info type0;
|
||
|
PCIType1Info type1;
|
||
|
PCIType2Info type2;
|
||
|
} u;
|
||
|
} PCIDeviceInfo;
|
||
|
|
||
|
/* PCI Capability header structure. All PCI capabilities have the
|
||
|
* following header.
|
||
|
*
|
||
|
* capsID is used to identify the type of the structure as define above.
|
||
|
*
|
||
|
* next is the offset in PCI configuration space (0x40-0xFC) of the
|
||
|
* next capability structure in the list, or 0x00 if there are no more
|
||
|
* entries.
|
||
|
*/
|
||
|
|
||
|
typedef struct {
|
||
|
uchar capsID;
|
||
|
uchar next;
|
||
|
} PCICapsHeader;
|
||
|
|
||
|
/* Structure defining the PCI AGP status register contents */
|
||
|
|
||
|
typedef struct {
|
||
|
uint rate:3;
|
||
|
uint rsvd1:1;
|
||
|
uint fastWrite:1;
|
||
|
uint fourGB:1;
|
||
|
uint rsvd2:3;
|
||
|
uint sideBandAddressing:1;
|
||
|
uint rsvd3:14;
|
||
|
uint requestQueueDepthMaximum:8;
|
||
|
} PCIAGPStatus;
|
||
|
|
||
|
/* Structure defining the PCI AGP command register contents */
|
||
|
|
||
|
typedef struct {
|
||
|
uint rate:3;
|
||
|
uint rsvd1:1;
|
||
|
uint fastWriteEnable:1;
|
||
|
uint fourGBEnable:1;
|
||
|
uint rsvd2:2;
|
||
|
uint AGPEnable:1;
|
||
|
uint SBAEnable:1;
|
||
|
uint rsvd3:14;
|
||
|
uint requestQueueDepth:8;
|
||
|
} PCIAGPCommand;
|
||
|
|
||
|
/* AGP Capability structure */
|
||
|
|
||
|
typedef struct {
|
||
|
PCICapsHeader h;
|
||
|
ushort majMin;
|
||
|
PCIAGPStatus AGPStatus;
|
||
|
PCIAGPCommand AGPCommand;
|
||
|
} PCIAGPCapability;
|
||
|
|
||
|
/* Structure for obtaining the PCI IRQ routing information */
|
||
|
|
||
|
typedef struct {
|
||
|
uchar bus;
|
||
|
uchar device;
|
||
|
uchar linkA;
|
||
|
ushort mapA;
|
||
|
uchar linkB;
|
||
|
ushort mapB;
|
||
|
uchar linkC;
|
||
|
ushort mapC;
|
||
|
uchar linkD;
|
||
|
ushort mapD;
|
||
|
uchar slot;
|
||
|
uchar reserved;
|
||
|
} PCIRouteInfo;
|
||
|
|
||
|
typedef struct {
|
||
|
ushort BufferSize;
|
||
|
PCIRouteInfo *DataBuffer;
|
||
|
} PCIRoutingOptionsBuffer;
|
||
|
|
||
|
#define NUM_PCI_REG (sizeof(PCIDeviceInfo) / 4) - 10
|
||
|
#define PCI_BRIDGE_CLASS 0x06
|
||
|
#define PCI_HOST_BRIDGE_SUBCLASS 0x00
|
||
|
#define PCI_EARLY_VGA_CLASS 0x00
|
||
|
#define PCI_EARLY_VGA_SUBCLASS 0x01
|
||
|
#define PCI_DISPLAY_CLASS 0x03
|
||
|
#define PCI_DISPLAY_VGA_SUBCLASS 0x00
|
||
|
#define PCI_DISPLAY_XGA_SUBCLASS 0x01
|
||
|
#define PCI_DISPLAY_OTHER_SUBCLASS 0x80
|
||
|
#define PCI_MM_CLASS 0x04
|
||
|
#define PCI_AUDIO_SUBCLASS 0x01
|
||
|
|
||
|
/* Macros to detect specific classes of devices */
|
||
|
|
||
|
#define PCI_IS_3DLABS_NONVGA_CLASS(pci) \
|
||
|
(((pci)->BaseClass == PCI_DISPLAY_CLASS && (pci)->SubClass == PCI_DISPLAY_OTHER_SUBCLASS) \
|
||
|
&& ((pci)->VendorID == 0x3D3D || (pci)->VendorID == 0x104C))
|
||
|
|
||
|
#define PCI_IS_DISPLAY_CLASS(pci) \
|
||
|
(((pci)->BaseClass == PCI_DISPLAY_CLASS && (pci)->SubClass == PCI_DISPLAY_VGA_SUBCLASS) \
|
||
|
|| ((pci)->BaseClass == PCI_DISPLAY_CLASS && (pci)->SubClass == PCI_DISPLAY_XGA_SUBCLASS) \
|
||
|
|| ((pci)->BaseClass == PCI_EARLY_VGA_CLASS && (pci)->SubClass == PCI_EARLY_VGA_SUBCLASS) \
|
||
|
|| PCI_IS_3DLABS_NONVGA_CLASS(pci))
|
||
|
|
||
|
/* Function codes to pass to PCI_accessReg */
|
||
|
|
||
|
#define PCI_READ_BYTE 0
|
||
|
#define PCI_READ_WORD 1
|
||
|
#define PCI_READ_DWORD 2
|
||
|
#define PCI_WRITE_BYTE 3
|
||
|
#define PCI_WRITE_WORD 4
|
||
|
#define PCI_WRITE_DWORD 5
|
||
|
|
||
|
/* Macros to read/write PCI registers. These assume a global PCI array
|
||
|
* of device information.
|
||
|
*/
|
||
|
|
||
|
#define PCI_readPCIRegB(index,device) \
|
||
|
PCI_accessReg(index,0,0,&PCI[DeviceIndex[device]])
|
||
|
|
||
|
#define PCI_readPCIRegW(index,device) \
|
||
|
PCI_accessReg(index,0,1,&PCI[DeviceIndex[device]])
|
||
|
|
||
|
#define PCI_readPCIRegL(index,device) \
|
||
|
PCI_accessReg(index,0,2,&PCI[DeviceIndex[device]])
|
||
|
|
||
|
#define PCI_writePCIRegB(index,value,device) \
|
||
|
PCI_accessReg(index,value,3,&PCI[DeviceIndex[device]])
|
||
|
|
||
|
#define PCI_writePCIRegW(index,value,device) \
|
||
|
PCI_accessReg(index,value,4,&PCI[DeviceIndex[device]])
|
||
|
|
||
|
#define PCI_writePCIRegL(index,value,device) \
|
||
|
PCI_accessReg(index,value,5,&PCI[DeviceIndex[device]])
|
||
|
|
||
|
#pragma pack()
|
||
|
|
||
|
/*-------------------------- Function Prototypes --------------------------*/
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" { /* Use "C" linkage when in C++ mode */
|
||
|
#endif
|
||
|
|
||
|
/* Function to determine the number of PCI devices in the system */
|
||
|
|
||
|
int _ASMAPI PCI_getNumDevices(void);
|
||
|
|
||
|
/* Function to enumerate all device on the PCI bus */
|
||
|
|
||
|
int _ASMAPI PCI_enumerate(PCIDeviceInfo info[]);
|
||
|
|
||
|
/* Function to access PCI configuration registers */
|
||
|
|
||
|
ulong _ASMAPI PCI_accessReg(int index,ulong value,int func,PCIDeviceInfo *info);
|
||
|
|
||
|
/* Function to get PCI IRQ routing options for a card */
|
||
|
|
||
|
int _ASMAPI PCI_getIRQRoutingOptions(int numDevices,PCIRouteInfo *buffer);
|
||
|
|
||
|
/* Function to re-route the PCI IRQ setting for a device */
|
||
|
|
||
|
ibool _ASMAPI PCI_setHardwareIRQ(PCIDeviceInfo *info,uint intPin,uint IRQ);
|
||
|
|
||
|
/* Function to generate a special cyle on the specified PCI bus */
|
||
|
|
||
|
void _ASMAPI PCI_generateSpecialCyle(uint bus,ulong specialCycleData);
|
||
|
|
||
|
/* Function to determine the size of a PCI base address register */
|
||
|
|
||
|
ulong _ASMAPI PCI_findBARSize(int bar,PCIDeviceInfo *pci);
|
||
|
|
||
|
/* Function to read a block of PCI configuration space registers */
|
||
|
|
||
|
void _ASMAPI PCI_readRegBlock(PCIDeviceInfo *info,int index,void *dst,int count);
|
||
|
|
||
|
/* Function to write a block of PCI configuration space registers */
|
||
|
|
||
|
void _ASMAPI PCI_writeRegBlock(PCIDeviceInfo *info,int index,void *src,int count);
|
||
|
|
||
|
/* Function to return the 32-bit PCI BIOS entry point */
|
||
|
|
||
|
ulong _ASMAPI PCIBIOS_getEntry(void);
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
} /* End of "C" linkage for C++ */
|
||
|
#endif
|
||
|
|
||
|
#endif /* __PCILIB_H */
|