📄 amcclib.c
字号:
/****************************************************************************/
/* */
/* Module: AMCCLIB.C */
/* */
/* Purpose: Define a C interface to the PCI BIOS */
/* */
/* Functions Defined: */
/* */
/* PCI_BIOS_PRESENT */
/* FIND_PCI_DEVICE */
/* FIND_PCI_CLASS_CODE */
/* GENERATE_SPECIAL_CYCLE */
/* READ_CONFIGURATION_BYTE */
/* READ_CONFIGURATION_WORD */
/* READ_CONFIGURATION_DWORD */
/* WRITE_CONFIGURATION_BYTE */
/* WRITE_CONFIGURATION_WORD */
/* WRITE_CONFIGURATION_DWORD */
/* OUTPD */
/* INPD */
/* INSB */
/* INSW */
/* INSD */
/* OUTSB */
/* OUTSW */
/* OUTSD */
/* */
/* Local Functions */
/* */
/* READ_CONFIGURATION_AREA */
/* WRITE_CONFIGURATION_AREA */
/* */
/****************************************************************************/
/****************************************************************************/
/* */
/* Include Files */
/* */
/****************************************************************************/
#include <stddef.h>
#include "amcc.h"
#include "pharlap.h"
#include "pldos32.h"
/****************************************************************************/
/* */
/* Local Prototypes */
/* */
/****************************************************************************/
static int read_configuration_area(byte function,
byte bus_number,
byte device_and_function,
byte register_number,
dword *data);
static int write_configuration_area(byte function,
byte bus_number,
byte device_and_function,
byte register_number,
dword value);
/****************************************************************************/
/* */
/* Define macros to obtain individual bytes from a word register */
/* */
/****************************************************************************/
#define HIGH_BYTE(ax) (ax >> 8)
#define LOW_BYTE(ax) (ax & 0xff)
/****************************************************************************/
/* */
/* PCI_BIOS_PRESENT */
/* */
/* Purpose: Determine the presence of the PCI BIOS */
/* */
/* Inputs: None */
/* */
/* Outputs: */
/* */
/* byte *hardware_mechanism */
/* Identifies the hardware characteristics used by the platform. */
/* Value not assigned if NULL pointer. */
/* Bit 0 - Mechanism #1 supported */
/* Bit 1 - Mechanism #2 supported */
/* */
/* word *interface_level_version */
/* PCI BIOS Version - Value not assigned if NULL pointer. */
/* High Byte - Major version number */
/* Low Byte - Minor version number */
/* */
/* byte *last_pci_bus_number */
/* Number of last PCI bus in the system. Value not assigned if NULL*/
/* pointer */
/* */
/* Return Value - Indicates presence of PCI BIOS */
/* SUCCESSFUL - PCI BIOS Present */
/* NOT_SUCCESSFUL - PCI BIOS Not Present */
/* */
/****************************************************************************/
int pci_bios_present(byte *hardware_mechanism,
word *interface_level_version,
byte *last_pci_bus_number)
{
int ret_status = NOT_SUCCESSFUL; /* Function Return Status. */
byte bios_present_status;/* Indicates if PCI bios present */
dword pci_signature; /* PCI Signature ('P', 'C', 'I', ' ') */
word ax, bx, cx, flags; /* Temporary variables to hold register values */
SWI_REGS regs;
#ifdef DEBUG
printf("In pci_bios_present\n");
#endif
/* Load entry registers for PCI BIOS */
regs.eax = PCI_BIOS_PRESENT | (PCI_FUNCTION_ID << 8);
/* Call PCI BIOS Int 1Ah interface */
_dx_real_int(0x1a, ®s);
/* Save registers before overwritten by compiler usage of registers */
ax = regs.eax & 0xffff;
bx = regs.ebx & 0xffff;
cx = regs.ecx & 0xffff;
pci_signature = regs.edx;
flags = regs.flags;
bios_present_status = HIGH_BYTE(ax);
/* First check if CARRY FLAG Set, if so, BIOS not present */
if ((flags & CARRY_FLAG) == 0) {
/* Next, must check that AH (BIOS Present Status) == 0 */
if (bios_present_status == 0) {
/* Check bytes in pci_signature for PCI Signature */
if ((pci_signature & 0xff) == 'P' &&
((pci_signature >> 8) & 0xff) == 'C' &&
((pci_signature >> 16) & 0xff) == 'I' &&
((pci_signature >> 24) & 0xff) == ' ') {
/* Indicate to caller that PCI bios present */
ret_status = SUCCESSFUL;
/* Extract calling parameters from saved registers */
if (hardware_mechanism != NULL) {
*hardware_mechanism = LOW_BYTE(ax);
}
if (hardware_mechanism != NULL) {
*interface_level_version = bx;
}
if (hardware_mechanism != NULL) {
*last_pci_bus_number = LOW_BYTE(cx);
}
}
else {
#ifdef DEBUG
printf("Not successful, pci_signature != 'PCI ' %x(%c) %x(%c) %x(%c) %x(%c)\n",
(pci_signature & 0xff), (pci_signature & 0xff),
((pci_signature >> 8) & 0xff), ((pci_signature >> 8) & 0xff),
((pci_signature >> 16) & 0xff),((pci_signature >> 16) & 0xff),
((pci_signature >> 24) & 0xff),((pci_signature >> 24) & 0xff)
);
#endif
ret_status = NOT_SUCCESSFUL;
}
}
else {
#ifdef DEBUG
printf("Not successful, AH != 0 (%x)\n", bios_present_status);
#endif
ret_status = NOT_SUCCESSFUL;
}
}
else {
#ifdef DEBUG
printf("Not successful, CARRY flag is set, flags=%x\n", flags);
#endif
ret_status = NOT_SUCCESSFUL;
}
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: */
/* */
/* word device_id */
/* Device ID of PCI device desired */
/* */
/* word vendor_id */
/* Vendor ID of PCI device desired */
/* */
/* word index */
/* Device number to find (0 - (N-1)) */
/* */
/* Outputs: */
/* */
/* byte *bus_number */
/* PCI Bus in which this device is found */
/* */
/* byte *device_and_function */
/* Device Number in upper 5 bits, Function Number in lower 3 bits */
/* */
/* Return Value - Indicates presence of device */
/* SUCCESSFUL - Device found */
/* NOT_SUCCESSFUL - BIOS error */
/* DEVICE_NOT_FOUND - Device not found */
/* BAD_VENDOR_ID - Illegal Vendor ID (0xffff) */
/* */
/****************************************************************************/
int find_pci_device(word device_id,
word vendor_id,
word index,
byte *bus_number,
byte *device_and_function)
{
int ret_status; /* Function Return Status */
word ax, bx, flags; /* Temporary variables to hold register values */
SWI_REGS regs;
/* Load entry registers for PCI BIOS */
regs.ecx = device_id;
regs.edx = vendor_id;
regs.esi = index;
regs.eax = (PCI_FUNCTION_ID << 8) | FIND_PCI_DEVICE;
/* Call PCI BIOS Int 1Ah interface */
_dx_real_int(0x1a, ®s);
/* Save registers before overwritten by compiler usage of registers */
ax = regs.eax & 0xffff;
bx = regs.ebx & 0xffff;
flags = regs.flags;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -