📄 amcclib.c
字号:
/*
amcclib.c - misc PCI utility and tools routines that can be called from utility programs
The include file for this library is "amcclib.h".
*/
#include <stdtypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <time.h>
#include <sys\timeb.h>
/* non-standard includes... */
#include <lib.h>
#include <clib1.h>
#include <main.h>
#include <amcclib.h>
#include <nvram.h>
#include <display.h>
// delay after write nvram
#define XDELAY_MS 20
#define HIGH_BYTE(ax) (ax >> 8)
#define LOW_BYTE(ax) (ax & 0xFF)
static void check_base( UINT32 base );
static void check_nvram_type( int chip_type );
int read_config_area( UINT8 function, UINT8 bus_number, UINT8 device_and_function, \
UINT8 register_number, UINT32*data32 );
int read_config_dword( UINT8 bus_number, UINT8 device_and_function, \
UINT8 register_number, UINT32*data32 );
/****************************************************************************/
/* pciReadBuf */
/* */
/* Purpose: read config space to buffer */
/* */
/* Inputs: bus number, function, offset, len (in bytes) */
/* */
/* Outputs: read data, BIOS return PCI_xxx (see lib.h) */
/* */
/****************************************************************************/
UINT8 pciReadBuf(UINT8 bus, UINT8 device, UINT8 *data, UINT16 len)
{
UINT16 i;
UINT8 status;
for (i=0;i<len;i++)
{
status = pciConfigRead8 (bus, device, i, data);
if ( status != PCI_SUCCESSFUL )
return( status );
data++;
}
return( status );
}
UINT8 pciReadBuf32(UINT8 bus, UINT8 device, UINT32 *data, UINT16 len)
/* 32-bit version of pciReadBuf32
len - in bytes
*/
{
UINT16 i;
UINT8 status;
for (i=0; i < (len/4); i++)
{
status = pciConfigRead32 (bus, device, i, data);
if ( status != PCI_SUCCESSFUL )
return( status );
data++;
}
return(PCI_SUCCESSFUL);
}
/****************************************************************************/
/* PCIBIOSPRESENT */
/* */
/* 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 */
/* TRUE - PCI BIOS Present */
/* FALSE - PCI BIOS Not Present */
/****************************************************************************/
UINT8 pciBiosPresent(UINT8 *hardware_mechanism,
UINT16 *interface_level_version,
UINT8 *last_pci_bus_number)
{
int ret_status; /* Function Return Status. */
byte bios_present_status;/* Indicates if PCI bios present */
union REGS regs;
regs.h.ah = PCI_FUNCTION_ID;
regs.h.al = PCI_BIOS_PRESENT;
int86( 0x1A, ®s, ®s );
enable();
/* Save registers before overwritten by compiler usage of registers */
bios_present_status = regs.h.ah;
/* First check if CARRY FLAG Set, if so, BIOS not present */
if (!regs.x.cflag)
{
/* Next, must check that AH (BIOS Present Status) == 0 */
if (bios_present_status == 0)
{
/* Check bytes in pci_signature for PCI Signature */
if (regs.x.dx == 0x4350 )
{
/* Indicate to caller that PCI bios present */
ret_status = TRUE;
/* Extract calling parameters from saved registers */
if (hardware_mechanism != NULL)
{
*hardware_mechanism = regs.h.al;
*interface_level_version = regs.x.bx;
*last_pci_bus_number = regs.h.cl;
}
}
}
else /* if (bios_present_status != 0) */
ret_status = FALSE;
}
else /* error since carry flag is set */
ret_status = FALSE;
return (ret_status);
}
/****************************************************************************/
/* */
/* FINDPCIDEVICE */
/* */
/* 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 */
/* bus_number stuffed */
/* devce_and_function stuffed */
/* */
/* PCI_SUCCESSFUL - Device found */
/* PCI_NOT_SUCCESSFUL - BIOS error */
/* PCI_DEVICE_NOT_FOUND - Device not found */
/* PCI_ BAD_VENDOR_ID - Illegal Vendor ID (0xffff) */
/* */
/****************************************************************************/
UINT8 pciFindDevice(UINT16 device_id,
UINT16 vendor_id,
UINT16 index,
UINT8 *bus_number,
UINT8 *device_and_function)
{
union REGS regs;
UINT8 ret_status; /* Function Return Status */
/* Load entry registers for PCI BIOS */
regs.x.cx = device_id;
regs.x.dx = vendor_id;
regs.x.si = index;
regs.h.ah = PCI_FUNCTION_ID;
regs.h.al = FIND_PCI_DEVICE;
/* Call PCI BIOS Int 1Ah interface */
int86( 0x1A, ®s, ®s );
/* First check if CARRY FLAG Set, if so, error has occurred */
if (!regs.x.cflag) {
/* Get Return code from BIOS */
ret_status = regs.h.ah;
if (ret_status == PCI_SUCCESSFUL) {
/* Assign Bus Number, Device & Function if successful */
if (bus_number != NULL) {
*bus_number = regs.h.bh;
}
if (device_and_function != NULL) {
*device_and_function = regs.h.bl;
}
}
}
else
ret_status = PCI_NOT_SUCCESSFUL; /* error - carry is set */
return (ret_status);
}
/****************************************************************************/
/* */
/* PciFindClassCode */
/* */
/* Purpose: Returns the location of PCI devices that have a specific Class */
/* Code. */
/* */
/* Inputs: */
/* */
/* word class_code */
/* Class Code 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 */
/* PCI_SUCCESSFUL - Device found */
/* PCI_NOT_SUCCESSFUL - BIOS error */
/* PCI_DEVICE_NOT_FOUND - Device not found */
/* */
/****************************************************************************/
UINT16 pciFindClassCode(UINT32 class_code,
UINT16 index,
UINT8 *bus_number,
UINT8 *device_and_function)
{
int ret_status; /* Function Return Status */
union REGS regs;
/* Load entry registers for PCI BIOS */
regs.x.cx = (double)class_code;
regs.x.si = index;
regs.h.ah = PCI_FUNCTION_ID;
regs.h.al = FIND_PCI_CLASS_CODE;
/* Call PCI BIOS Int 1Ah interface */
int86( 0x1A, ®s, ®s );
/* First check if CARRY FLAG Set, if so, error has occurred */
if ((regs.x.flags & CARRY_FLAG) == 0) {
/* Get Return code from BIOS */
ret_status = regs.h.ah;
if (ret_status == PCI_SUCCESSFUL) {
/* Assign Bus Number, Device & Function if successful */
if (bus_number != NULL) {
*bus_number = regs.h.bh;
}
if (device_and_function != NULL) {
*device_and_function = regs.h.bh;
}
}
}
else
ret_status = PCI_NOT_SUCCESSFUL; /* carry was set */
return (ret_status);
}
/****************************************************************************/
/* */
/* PCIGENERATESPECIALCYCLE */
/* */
/* Purpose: Generates a PCI special cycle */
/* */
/* Inputs: */
/* */
/* byte bus_number */
/* PCI bus to generate cycle on */
/* */
/* dword special_cycle_data */
/* Special Cycle Data to be generated */
/* */
/* Outputs: */
/* */
/* Return Value - Indicates presence of device */
/* PCI_SUCCESSFUL - Device found */
/* PCI_NOT_SUCCESSFUL - non-specific error */
/* DEVICE_NOT_FOUND - Device not found */
/* */
/****************************************************************************/
UINT8 generate_special_cycle(UINT8 bus_number,
UINT32 special_cycle_data)
{
int ret_status; /* Function Return Status */
union REGS regs;
/* Load entry registers for PCI BIOS */
regs.h.bh = bus_number;
regs.x.dx = (double)special_cycle_data;
regs.h.ah = PCI_FUNCTION_ID;
regs.h.al = FIND_PCI_CLASS_CODE;
/* Call PCI BIOS Int 1Ah interface */
int86( 0x1A, ®s, ®s );
/* Save registers before overwritten by compiler usage of registers */
/* First check if CARRY FLAG Set, if so, error has occurred */
if ((regs.x.flags & CARRY_FLAG) == 0) {
/* Get Return code from BIOS */
ret_status = regs.h.ah;
}
else {
ret_status = PCI_NOT_SUCCESSFUL;
}
return (ret_status);
}
/*
************************************************************************
************************************************************************
** **
** pci device search routines **
** **
************************************************************************
************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -