📄 pci.c
字号:
#include <dos.h>
#include <stddef.h>
/*---PCI Functions---*/
#define PCI_BIOS_PRESENT 0x01
#define FIND_PCI_DEVICE 0x02
#define READ_CONFIG_DWORD 0x0a
#define PCI_FUNCTION_ID 0xb1
/*---Return Code ---*/
#define SUCCESSFUL 0x00
#define NOT_SUCCESSFUL 0x01
/*---PCI Configuration Space Registers---*/
#define PCI_CS_VENDOR_ID 0x00
#define PCI_CS_DEVICE_ID 0x02
#define PCI_CS_COMMAND 0x04
#define PCI_CS_STATUS 0x06
#define PCI_CS_REVISION_ID 0x08
#define PCI_CS_CLASS_CODE 0x09
#define PCI_CS_CACHE_LINE_SIZE 0x0c
#define PCI_CS_MASTER_LATENCY 0x0d
#define PCI_CS_HEADER_TYPE 0x0e
#define PCI_CS_BIST 0x0f
#define PCI_CS_BASE_ADDRESS_0 0x10
#define PCI_CS_BASE_ADDRESS_1 0x14
#define PCI_CS_BASE_ADDRESS_2 0x18
#define PCI_CS_BASE_ADDRESS_3 0x1c
#define PCI_CS_BASE_ADDRESS_4 0x20
#define PCI_CS_BASE_ADDRESS_5 0x24
#define PCI_CS_SUBSYSTEM_ID 0x2c
#define PCI_CS_EXPANSION_ROM 0x30
#define PCI_CS_INTERRUPT_LINE 0x3c
#define PCI_CS_INTERRUPT_PIN 0x3d
/*---Define macros to obtain individual bytes from a word register---*/
#define TRUE 1
#define FALSE 0
#define HIGH_BYTE(ax) (ax >> 8)
#define LOW_BYTE(ax) (ax & 0xff)
#define CARRY_FLAG 0x01 /* 80x86 Flags Register Carry Flag bit */
typedef unsigned char byte; /* byte data type */
typedef unsigned short word; /* word data type */
typedef unsigned long dword; /* double word data type */
/* Function Prototypes */
static int read_configuration_area(byte function, byte bus_number,
byte device_and_function,
byte register_number, dword *data);
int find_pci_device(word device_id, word vendor_id, word index,
byte *bus_number, byte *device_and_function);
int read_configuration_dword(byte bus_number, byte device_and_function,
byte register_number, dword *dword_read);
/* Function source code */
int find_pci_device(word device_id,
word vendor_id,
word index,
byte *bus_number,
byte *device_and_function)
{
int ret_status;
word ax, bx, flags;
/* Set registers for PCI BIOS call */
_CX = device_id;
_DX = vendor_id;
_SI = index;
_AH = PCI_FUNCTION_ID;
_AL = FIND_PCI_DEVICE;
/* Call PCI BIOS Int 1Ah */
geninterrupt(0x1a);
ax = _AX;
bx = _BX;
flags = _FLAGS;
/* if carry flag set, error has occurred */
if ((flags & CARRY_FLAG) == 0)
{
/* Get Return code from BIOS */
ret_status = HIGH_BYTE(ax);
if (ret_status == SUCCESSFUL)
{
/* Assign Bus Number, Device & Function if successful */
if (bus_number != NULL)
{ *bus_number = HIGH_BYTE(bx); }
if (device_and_function != NULL)
{ *device_and_function = LOW_BYTE(bx); }
}
}
else
{ ret_status = NOT_SUCCESSFUL; }
return (ret_status);
}
int read_configuration_dword(byte bus_number, byte device_and_function,
byte register_number, dword *dword_read)
{
int ret_status;
dword data;
/* Read PCI configuration register data */
ret_status = read_configuration_area(READ_CONFIG_DWORD, bus_number,
device_and_function,
register_number, &data);
if (ret_status == SUCCESSFUL)
{ *dword_read = data; }
return (ret_status);
}
static int read_configuration_area(byte function, byte bus_number,
byte device_and_function,
byte register_number, dword *data)
{
int ret_status;
word ax, flags;
dword ecx;
/* Load entry registers for PCI BIOS */
_BH = bus_number;
_BL = device_and_function;
_DI = register_number;
_AH = PCI_FUNCTION_ID;
_AL = function;
/* Call PCI BIOS Int 1Ah interface */
geninterrupt(0x1a);
ecx = _ECX;
ax = _AX;
flags = _FLAGS;
/* if carry flag Set, error has occurred */
if ((flags & CARRY_FLAG) == 0)
{
/* Get Return code from BIOS */
ret_status = HIGH_BYTE(ax);
/* If successful, return data */
if (ret_status == SUCCESSFUL)
{ *data = ecx; }
}
else
{ ret_status = NOT_SUCCESSFUL; }
return (ret_status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -