blob: e2d58b0848e6879854d75c4514d97dcf03522b0f [file] [log] [blame]
/****************************************************************************
*
* 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 */