| /**************************************************************************** |
| * |
| * 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 */ |
| |