📄 pci.c
字号:
//************************************************************
//
// This file contains the support for the pci interface
//
// ****************** local includes ************************
#include "bios32.h"
#include "pci.h"
// ******************* PCI and chip related defs *******************
#define PCI_FUNCTION_ID 0xb1
#define PCI_BIOS_PRESENT 0x01
#define FIND_PCI_DEVICE 0x02
#define FIND_PCI_CLASS_CODE 0x03
#define GENERATE_SPECIAL_CYCLE 0x06
#define READ_CONFIG_BYTE 0x08
#define READ_CONFIG_WORD 0x09
#define READ_CONFIG_DWORD 0x0a
#define WRITE_CONFIG_BYTE 0x0b
#define WRITE_CONFIG_WORD 0x0c
#define WRITE_CONFIG_DWORD 0x0d
// ******************* Function code *******************
/****************************************************************************/
/* */
/* PCI_BIOS_PRESENT */
/* */
/* Purpose: Determine the presence of the PCI BIOS */
/* */
/* Inputs: None */
/* */
/* Outputs: None */
/* */
/* Return Value - Indicates presence of PCI BIOS */
/* TRUE - PCI BIOS Present */
/* FALSE - PCI BIOS Not Present */
/* */
/****************************************************************************/
int PCIBiosPresent(void)
{
union { /* PCI Signature ('P', 'C', 'I', ' ') */
unsigned long val;
unsigned char id[4];
} pci_signature;
unsigned char ret_status; /* Function Return Status. */
DRegs inregs, outregs;
/* Load entry registers for PCI BIOS */
inregs.h.ah = PCI_FUNCTION_ID;
inregs.h.al = PCI_BIOS_PRESENT;
/* Call PCI BIOS Int 1Ah interface */
Bios32(&inregs, &outregs);
/* save PCI signature */
pci_signature.val = outregs.e.edx; // _EDX;
/* First check if CARRY FLAG Set, if so, BIOS not present */
if (outregs.x.cflag == 0)
{
/* Next, must check that AH (BIOS Present Status) == 0 */
if (outregs.h.ah == 0)
{
/* Check unsigned chars in pci_signature for PCI Signature */
if ( (pci_signature.id[0] == 'P') &&
(pci_signature.id[1] == 'C') &&
(pci_signature.id[2] == 'I') &&
(pci_signature.id[3] == ' ') )
{
/* Indicate to caller that PCI bios present */
ret_status = TRUE;
}
}
else
ret_status = FALSE;
}
else
ret_status = FALSE;
return ret_status;
}
/****************************************************************************/
/* */
/* FIND_PCI_DEVICE */
/* */
/* Purpose: Determine the location of PCI devices given a specific Vendor */
/* Device ID and Index number. To find the first device, specify */
/* 0 for index, 1 in index finds the second device, etc. */
/* */
/* Inputs: */
/* */
/* unsigned int device_id */
/* Device ID of PCI device desired */
/* */
/* unsigned int vendor_id */
/* Vendor ID of PCI device desired */
/* */
/* unsigned int index */
/* Device number to find (0 - (N-1)) */
/* */
/* Outputs: */
/* */
/* unsigned char *bus_number */
/* PCI Bus in which this device is found */
/* */
/* unsigned char *device_and_function */
/* Device Number in upper 5 bits, Function Number in lower 3 bits */
/* */
/* Return Value - Indicates presence of device */
/* TRUE - Device found */
/* FALSE - Device not found or BIOS error */
/* */
/****************************************************************************/
int FindPCIDevice( unsigned int device_id,
unsigned int vendor_id,
unsigned int index,
unsigned char *bus_number,
unsigned char *device_and_function)
{
int ret_status; /* Function Return Status */
DRegs inregs, outregs;
/* Load entry registers for PCI BIOS */
inregs.x.cx = device_id;
inregs.x.dx = vendor_id;
inregs.x.si = index;
inregs.h.ah = PCI_FUNCTION_ID;
inregs.h.al = FIND_PCI_DEVICE;
/* Call PCI BIOS Int 1Ah interface */
Bios32(&inregs, &outregs);
/* First check if CARRY FLAG Set, if so, error has occurred */
if (outregs.x.cflag == 0)
{
/* Get Return code from BIOS */
if (outregs.h.ah == 0)
{
/* Assign Bus Number, Device & Function if successful */
if (bus_number) {
*bus_number = outregs.h.bh;
}
if (device_and_function) {
*device_and_function = outregs.h.bl;
}
ret_status = TRUE;
}
else
ret_status = FALSE;
}
else
ret_status = FALSE;
return ret_status;
}
/****************************************************************************/
/* */
/* READ_CONFIGURATION_AREA */
/* */
/* Purpose: Reads a unsigned char/word/dword from the configuration space */
/* of a specific device */
/* */
/* Inputs: */
/* */
/* unsigned char bus_number */
/* PCI bus to read configuration data from */
/* */
/* unsigned char device_and_function */
/* Device Number in upper 5 bits, Function Number in lower 3 bits */
/* */
/* unsigned char register_number */
/* Register Number of configuration space to read */
/* */
/* Outputs: */
/* */
/* unsigned long *dword_read */
/* Dword read from Configuration Space */
/* */
/* Return Value - Indicates presence of device */
/* TRUE - Device found */
/* FALSE - Invalid Register Number or BIOS error */
/* */
/****************************************************************************/
int ReadConfigurationArea( unsigned char function,
unsigned char bus_number,
unsigned char device_and_function,
unsigned char register_number,
unsigned long *data)
{
int ret_status; /* Function Return Status */
DRegs inregs, outregs;
/* Load entry registers for PCI BIOS */
inregs.h.bh = bus_number;
inregs.h.bl = device_and_function;
inregs.x.di = register_number;
inregs.h.ah = PCI_FUNCTION_ID;
inregs.h.al = function;
/* Call PCI BIOS Int 1Ah interface */
Bios32(&inregs, &outregs);
/* First check if CARRY FLAG Set, if so, error has occurred */
if (outregs.x.cflag == 0)
{
/* If successful, return data */
if (outregs.h.ah == 0) {
*data = outregs.e.ecx;
ret_status = TRUE;
} else
ret_status = FALSE;
} else
ret_status = FALSE;
return ret_status;
}
/****************************************************************************/
/* */
/* READ_CONFIGURATION_BYTE */
/* */
/* Purpose: Reads a unsigned char from the configuration space of a */
/* specific device */
/* */
/* Inputs: */
/* */
/* unsigned char bus_number */
/* PCI bus to read configuration data from */
/* */
/* unsigned char device_and_function */
/* Device Number in upper 5 bits, Function Number in lower 3 bits */
/* */
/* unsigned char register_number */
/* Register Number of configuration space to read */
/* */
/* Outputs: */
/* */
/* unsigned char *unsigned char_read */
/* Byte read from Configuration Space */
/* */
/* Return Value - Indicates presence of device */
/* TRUE - Device found */
/* FALSE - Invalid Register Number or BIOS error */
/* */
/****************************************************************************/
int ReadConfigurationByte( unsigned char bus_number,
unsigned char device_and_function,
unsigned char register_number,
unsigned char *byte_read)
{
int ret_status; /* Function Return Status */
unsigned long data;
/* Call read_configuration_area function with unsigned char data */
ret_status = ReadConfigurationArea( READ_CONFIG_BYTE,
bus_number,
device_and_function,
register_number,
&data);
if (ret_status) {
/* Extract unsigned char */
*byte_read = (unsigned char)(data & 0x000000ff);
}
return ret_status;
}
/****************************************************************************/
/* */
/* READ_CONFIGURATION_WORD */
/* */
/* Purpose: Reads a word from the configuration space of a specific device */
/* */
/* Inputs: */
/* */
/* unsigned char bus_number */
/* PCI bus to read configuration data from */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -