📄 dospci.c
字号:
/*----------------------------------------------------------------------------
COPYRIGHT (c) 1996 by Philips Semiconductors
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED AND COPIED IN
ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH A LICENSE AND WITH THE
INCLUSION OF THE THIS COPY RIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES
OF THIS SOFTWARE MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER
PERSON. THE OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ANY PRIOR NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY Philips Semiconductor.
PHILIPS ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE
ON PLATFORMS OTHER THAN THE ONE ON WHICH THIS SOFTWARE IS FURNISHED.
----------------------------------------------------------------------------*/
/*
FILE dospci.c
HISTORY
960224 Tilakraj Roy (Created) (troy@trimedia.scs.philips.com)
960429 Tilakraj Roy (Modified the -w option for terse output)
960603 Tilakraj Roy (Added comments removed stale code)
960722 Tilakraj Roy (Added -a and -c options)
980716 Tilakraj Roy (Complete rewite for dealing with multiple busses)
COMMENTS
This is a 16 bit DOS program - requires MSVC 1.5 version to compile.
Dospci configures the PCI registers for a PCI bus hosted card.
This program uses the TriMedia Vendor and Device ID by default.
Dospci can read and write configuration settings.
For more information see the PCI BIOS specifications Revision 2.1.
Device:5[7..3]
Function:3[2..0]
*/
#pragma pack (1)
#include "stdio.h"
#include "stdarg.h"
#include "ctype.h"
#include "dos.h"
/* use NT/CE data types */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef VOID
#define VOID void
typedef char CHAR;
typedef short SHORT;
typedef long LONG;
typedef void* PVOID;
#endif
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned long ULONG;
typedef UCHAR *PUCHAR;
typedef USHORT *PUSHORT;
typedef ULONG *PULONG;
typedef UCHAR BOOLEAN;
typedef BOOLEAN *PBOOLEAN;
typedef struct _LARGE_INTEGER
{
ULONG LowPart;
LONG HighPart;
} LARGE_INTEGER;
typedef LARGE_INTEGER *PLARGE_INTEGER;
/* CONATANTS */
#define VENDOR_ID 0x1131 /* TriMedia Vendor ID */
#define DEVICE_ID 0x5400 /* TriMedia Device ID */
#define DevFunc2BYTE(Device, Function)(char)( ( ( (char)(Device) << 3 ) & 0xf8 ) | ( (char)(Function) & 0x7 ) )
#define PCI_ERR_OK 0x0
#define PCI_ERR_NOMOREDEVICES 0xff
#define PCI_MAX_FUNCTIONS 8
#define PCI_MAX_DEVICES 32
#define PCI_MAX_REGISTERS 0x10
//#define PRINTF(_x_) printf _x_
#define PRINTF(_x_)
/* TYPEDEFS */
typedef struct _IRQROUTINGBUFFER
{
USHORT wBufferSize;
USHORT wDataOffset;
USHORT wDataSegment;
} IRQROUTINGBUFFER, *PIRQROUTINGBUFFER;
typedef struct _IRQROUTINGTABLE
{
UCHAR bBusNumber;
UCHAR bDeviceNumber;
struct
{
UCHAR bLink;
USHORT wBitmap;
} IRQ[4];
UCHAR bSlotNumber;
UCHAR bReserved;
} IRQROUTINGTABLE, *PIRQROUTINGTABLE;
typedef struct _PCIREGISTERS
{
USHORT wVendorID;
USHORT wDeviceID;
USHORT wCommand;
USHORT wStatus;
UCHAR bRevisionID;
UCHAR bProgClass;
UCHAR bSubClass;
UCHAR bBaseClass;
UCHAR bCacheLineSize;
UCHAR bLatencyTimer;
UCHAR bHeaderType;
UCHAR bBIST;
ULONG dwBaseAddr[6];
ULONG dwCardbusCIS;
USHORT wSubVendorID;
USHORT wSubSystemID;
ULONG dwExpansionROM;
ULONG dwReserved[2];
UCHAR bInterruptLine;
UCHAR bInterruptPin;
UCHAR bMinGrant;
UCHAR bMaxLatency;
} PCIREGISTERS, *PPCIREGISTERS;
/* PROTOTYPES */
UCHAR PCIBIOSPresent (
PUCHAR HardwareMechanism,
PUSHORT InterfaceVersion,
PUCHAR BusCount );
UCHAR PCIReadDevice (
UCHAR BusNumber,
UCHAR DeviceNumber,
UCHAR FunctionNumber,
PULONG PCIRegisterArray );
UCHAR PCIFindDevice (
USHORT VendorID,
USHORT DeviceID,
CHAR MaximumBusses,
PUCHAR BusNumberPtr,
PUCHAR DevNumberPtr,
PUCHAR FuncNumberPtr );
UCHAR PCIReadULONG (
UCHAR Bus,
UCHAR Device,
UCHAR Function,
USHORT Offset,
PULONG RegisterPtr );
UCHAR PCIWriteULONG (
UCHAR Bus,
UCHAR Device,
UCHAR Function,
USHORT Offset,
ULONG Register );
UCHAR PCIIRQRouting (
USHORT wRouteBufferSegment,
USHORT wRouteBufferOffset );
/* INSTANCIATION */
IRQROUTINGTABLE RoutingTable[0x10]; // space for 16 PCI slots
IRQROUTINGBUFFER RoutingBuffer;
/* IMPLEMENTATION */
UCHAR PCIBIOSPresent (
PUCHAR HardwareMechanism,
PUSHORT InterfaceVersion,
PUCHAR BusCount )
{
UCHAR Return;
UCHAR RegAL, RegCL;
USHORT RegBX;
__asm
{
mov ax, 0xb101
int 0x1a
mov Return, ah
mov RegAL, al
mov RegBX, bx
mov RegCL, cl
}
*HardwareMechanism = RegAL;
*InterfaceVersion = RegBX;
*BusCount = (RegCL+1);
return Return;
}
UCHAR PCIIRQRouting (
USHORT wRouteBufferSegment,
USHORT wRouteBufferOffset )
{
UCHAR bReturn;
__asm
{
xor bx, bx;
mov cx, 0xf000;
mov di, wRouteBufferOffset
mov ax, wRouteBufferSegment
push ax
pop es
push ds
push cx
pop ds
mov ax, 0xb10e
int 0x1a
pop ds
mov bReturn, ah
}
return bReturn;
}
UCHAR PCIReadULONG (
UCHAR Bus,
UCHAR Device,
UCHAR Function,
USHORT RegisterOffset,
PULONG RegisterPtr )
{
UCHAR Return;
USHORT ValueLo;
USHORT ValueHi;
UCHAR DevFunc = DevFunc2BYTE(Device, Function);
__asm
{
mov ah, 0xb1
mov al, 0x09
mov bh, Bus
mov bl, DevFunc
mov di, RegisterOffset
int 0x1a
mov Return, ah
mov ValueLo, cx
}
if ( Return != 0x00 )
return Return;
RegisterOffset += 2;
__asm
{
mov ah, 0xb1;
mov al, 0x09;
mov bh, Bus;
mov bl, DevFunc;
mov di, RegisterOffset;
int 0x1a
mov ValueHi, cx
mov Return, ah
}
((PUSHORT)(RegisterPtr))[0] = ValueLo;
((PUSHORT)(RegisterPtr))[1] = ValueHi;
return Return;
}
UCHAR PCIWriteULONG (
UCHAR Bus,
UCHAR Device,
UCHAR Function,
USHORT RegisterOffset,
ULONG Register )
{
UCHAR Return;
USHORT ValueLo;
USHORT ValueHi;
UCHAR DevFunc = DevFunc2BYTE(Device, Function);
ValueLo = ((USHORT *)(&Register))[0];
ValueHi = ((USHORT *)(&Register))[1];
__asm
{
mov ah, 0xb1;
mov al, 0x0c;
mov bh, Bus;
mov bl, DevFunc;
mov di, RegisterOffset;
mov cx, ValueLo;
int 0x1a
mov Return, ah;
}
if ( Return != 0x00 )
return Return;
RegisterOffset += 2;
__asm
{
mov ah, 0xb1;
mov al, 0x0c;
mov bh, Bus;
mov bl, DevFunc;
mov di, RegisterOffset;
mov cx, ValueHi;
int 0x1a
mov Return, ah;
}
return Return;
}
UCHAR PCIReadDevice (
UCHAR BusNumber,
UCHAR DeviceNumber,
UCHAR FunctionNumber,
PULONG PCIRegisterArray )
{
UCHAR RegisterIndex;
UCHAR Return;
for ( RegisterIndex = 0 ; RegisterIndex <= 0x10 ; RegisterIndex ++ )
{
if ( ( Return = PCIReadULONG (
BusNumber,
DeviceNumber,
FunctionNumber,
RegisterIndex * 4,
&PCIRegisterArray[RegisterIndex] )) != 0x00 )
{
return Return;
}
}
return PCI_ERR_OK;
}
UCHAR PCIFindDevice (
USHORT VendorID,
USHORT DeviceID,
CHAR MaximumBusses,
PUCHAR BusNumberPtr,
PUCHAR DeviceNumberPtr,
PUCHAR FunctionNumberPtr )
{
ULONG Value;
UCHAR Return;
for ( ; *BusNumberPtr < MaximumBusses ; (*BusNumberPtr)++ )
{
for ( ; *DeviceNumberPtr < PCI_MAX_DEVICES ; (*DeviceNumberPtr)++ )
{
*FunctionNumberPtr = 0;
PRINTF(("dospci:DEBUG:PCIFindDevice:Bus#[%x] Dev#[%x] Func#[%x]\n",
*BusNumberPtr, *DeviceNumberPtr, *FunctionNumberPtr ));
if ( (Return = PCIReadULONG (
*BusNumberPtr,
*DeviceNumberPtr,
*FunctionNumberPtr,
0x0,
&Value )) != 0x00 )
{
PRINTF(("dospci:DEBUG:PCIFindDevice:PCIReadULONG:FAIL[%x]\n",
Return ));
return Return;
}
if ( ( DeviceID == 0xffff ) && ( VendorID == 0xffff ) )
{
if ( Value != 0xffffffff )
{
PRINTF(("dospci:DEBUG:PCIFindDevice:Value[%lx]:VendorID[%x], DeviceID[%x]\n",
Value, VendorID, DeviceID ));
return PCI_ERR_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -