📄 lib.c
字号:
/*
lib.c
common 5920 testboard library functions
*/
/*
Note well: 'testboard' refers to a board used to verify the S5920 at AMCC.
It is unfortunately not, nor is it likely to ever be, available to our customers.
For one thing, the testboard is non-PCI compliant because it has a 5933 *and* a 5920 on
the PCI bus, and two PCI loads per add in board is forbidden for normal PCI boards.
*/
#include <stdtypes.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* non-standard includes... */
#include <clib1.h>
#include <lib.h>
#include <amcclib.h>
#include <nvram.h>
#include <main.h>
extern struct _chip chip_control, chip_uut;
extern VUINT32 control; /* shadow of testboard control register */
extern CHAR errstring[];
extern CHAR text[];
static void check_base ( struct _chip *chip, int region );
static int dword_compare( const void *data0, const void *data1 );
static int find_region( UINT32 base );
#define CHECKPCI if ( status != PCI_SUCCESSFUL ) \
return pci_bios_fail( status );
UINT8 read_md_bus( VOID )
/*
Return: value of the MD bus (bits 7:0 of status reg on
the 5920 testcard pcb).
*/
{
UINT32 data32;
data32 = region_read32( &chip_control, CTRL_CONTROL_REGION, 0L );
data32 &= 0xFFL;
return (UINT8)( data32 );
}
UINT8 region_read8( struct _chip *chip, int region, UINT32 offset )
/*
Reads data from a region.
Entry: chip - which chip structure to use
region #0+
offset - into the region 0+
data - where to put the data
Return: value requested
*/
{
UINT8 data;
check_base ( chip, region ); /* see if base != 0 */
if (chip->reg[region].base & BASE_IO) /* I/O ? */
data = (UINT8)inp( (unsigned)(offset + (chip->reg[region].base & 0xFFFFFFFCL)) );
else
data = xpeek8( (UINT32)( (chip->reg[region].base & 0xFFFFFFF0L) + offset) );
return( data );
}
UINT16 region_read16( struct _chip *chip, int region, UINT32 offset )
/*
Entry: see read8
Return: see read8
*/
{
UINT16 data;
check_base ( chip, region ); /* see if base != 0 */
if (chip->reg[region].base & BASE_IO) /* I/O ? */
data = inpw( (unsigned)(offset + (chip->reg[region].base & 0xFFFFFFFCL)) );
else
data = xpeek16( (UINT32)( (chip->reg[region].base & 0xFFFFFFF0L) + offset) );
return( data );
}
UINT32 region_read32( struct _chip *chip, int region, UINT32 offset )
/*
Entry: see read8
Return: see read8
*/
{
UINT32 data;
check_base ( chip, region ); /* see if base != 0 */
if (chip->reg[region].base & BASE_IO) /* I/O ? */
data = inpl( (unsigned)(offset + (chip->reg[region].base & 0xFFFFFFFCL)) );
else
data = xpeek32( (UINT32)( (chip->reg[region].base & 0xFFFFFFF0L) + offset) );
return( data );
}
int check_sized( int region, UINT32 sbdata, UINT32 wsdata )
/*
Check data based on size of region.
Return: TRUE if compare OK.
*/
{
switch ( region_width( region ) )
{
case 8: if ( (UINT8)sbdata != (UINT8)wsdata ) return FALSE;
return TRUE;
case 16: if ( (UINT16)sbdata != (UINT16)wsdata ) return FALSE;
return TRUE;
case 32: if ( sbdata != wsdata ) return FALSE;
return TRUE;
default:
fprintf( stderr, "Illegal call to check_sized.\n" );
exit(1);
}
return FALSE;
}
VOID region_write_sized( struct _chip *chip, int region, UINT32 offset, UINT32 data )
/*
Write byte/word/long based on region width.
*/
{
switch ( region_width( region ) )
{
case 8: region_write8( chip, region, offset, (UINT8) data );
break;
case 16: region_write16( chip, region, offset, (UINT16) data );
break;
case 32: region_write32( chip, region, offset, data );
break;
default:
fprintf( stderr, "Illegal call to region_write_sized.\n" );
exit(1);
break;
}
}
UINT32 region_read_sized( struct _chip *chip, int region, UINT32 offset )
/*
Write byte/word/long based on region width.
*/
{
switch ( region_width( region ) )
{
case 8:
return (UINT32)region_read8( chip, region, offset );
case 16:
return (UINT32)region_read16( chip, region, offset );
case 32:
return region_read32( chip, region, offset );
default:
return 0L;
}
}
VOID region_write8( struct _chip *chip, int region, UINT32 offset, UINT8 data )
/*
Reads data from a region.
Entry: chip - which chip structure to use
region #0+
offset - into the region 0+
data - where to put the data
Return: TRUE if OK, else <> and error string added to ????
*/
{
check_base ( chip, region ); /* see if base != 0 */
if (chip->reg[region].base & BASE_IO) /* I/O */
outp((unsigned)offset + (unsigned)(chip->reg[region].base & 0xFFFFFFFCL), (int)data );
else
xpoke8( (UINT32)((chip->reg[region].base & 0xFFFFFFF0L) + offset), data );
}
VOID region_write16( struct _chip *chip, int region, UINT32 offset, UINT16 data )
/*
Entry: see write8
Return: see write8
*/
{
check_base ( chip, region ); /* see if base != 0 */
if (chip->reg[region].base & BASE_IO) /* I/O */
outp((unsigned)offset + (unsigned)(chip->reg[region].base & 0xFFFFFFFCL), (int)data );
else
xpoke16( (UINT32)((chip->reg[region].base & 0xFFFFFFF0L) + offset), data );
}
VOID region_write32( struct _chip *chip, int region, UINT32 offset, UINT32 data )
/*
Entry: see write8
Return: see write8
*/
{
check_base ( chip, region ); /* see if base != 0 */
if (chip->reg[region].base & BASE_IO) /* I/O */
outpl((unsigned)offset + (unsigned)(chip->reg[region].base & 0xFFFFFFFCL), data );
else
xpoke32( (UINT32)((chip->reg[region].base & 0xFFFFFFF0L) + offset), data );
}
UINT8 pci_config_read8( struct _chip *chip, UINT32 offset, UINT8 *data )
/*
Entry: chip - which chip structure to use
offset - into the region 0+
data - where to put the data
Return: "ah" register from BIOS call
defines are (see lib.h for most recent list):
PCI_SUCCESSFUL
PCI_FUNC_NOT_SUPPORTED
PCI_BAD_VENDOR_ID
PCI_DEVICE_NOT_FOUND
PCI_BAD_REGISTER_NUMBER
*/
{
return( pciConfigRead8(chip->bus, chip->device, (UINT8)offset, data) );
}
UINT8 pci_config_read16( struct _chip *chip, UINT32 offset, UINT16 *data )
/* see pci_config_read8 for description */
{
return( pciConfigRead16(chip->bus, chip->device, (UINT8)offset, data) );
}
UINT8 pci_config_read32( struct _chip *chip, UINT32 offset, UINT32 *data )
/* see pci_config_read8 for description */
{
return( pciConfigRead32(chip->bus, chip->device, (UINT8)offset, data) );
}
UINT8 pci_config_write8( struct _chip *chip, UINT32 offset, UINT8 data )
/*
Entry: chip - which chip structure to use
offset - into the region 0+
data - what to write
Return: "ah" register from BIOS call
*/
{
return( pciConfigWrite8( chip->bus, chip->device, (UINT8)offset, data) );
}
UINT8 pci_config_write16( struct _chip *chip, UINT32 offset, UINT16 data )
{
return( pciConfigWrite16( chip->bus, chip->device, (UINT8)offset, data) );
}
UINT8 pci_config_write32( struct _chip *chip, UINT32 offset, UINT32 data )
{
return( pciConfigWrite32( chip->bus, chip->device, (UINT8)offset, data) );
}
UINT8 bset_config8( struct _chip *chip, UINT32 offset, UINT8 mask )
/* set bits based on mask
return: PCI_X
*/
{
int status;
UINT8 data;
status = pci_config_read8( chip, offset, &data );
if ( status != PCI_SUCCESSFUL ) return status;
data |= mask;
return ( pci_config_write8( chip, offset, data ) );
}
UINT8 bset_config16( struct _chip *chip, UINT32 offset, UINT16 mask )
/* set bits based on mask
return: PCI_X
*/
{
UINT16 data;
int status;
status = pci_config_read16( chip, offset, &data );
if ( status != PCI_SUCCESSFUL ) return status;
data |= mask;
return ( pci_config_write16( chip, offset, data ) );
}
UINT8 bset_config32( struct _chip *chip, UINT32 offset, UINT32 mask )
/* set bits based on mask
return: PCI_X
*/
{
UINT32 data;
int status;
status = pci_config_read32( chip, offset, &data );
if ( status != PCI_SUCCESSFUL ) return status;
data |= mask;
return ( pci_config_write32( chip, offset, data ) );
}
UINT8 bclr_config8( struct _chip *chip, UINT32 offset, UINT8 mask )
/* clear bits based on mask
return: PCI_X
*/
{
UINT8 data;
int status;
status = pci_config_read8( chip, offset, &data );
if ( status != PCI_SUCCESSFUL ) return status;
data &= ~mask;
return ( pci_config_write8( chip, offset, data ) );
}
UINT8 bclr_config16( struct _chip *chip, UINT32 offset, UINT16 mask )
/* clear bits based on mask
return: PCI_X
*/
{
UINT16 data;
int status;
status = pci_config_read16( chip, offset, &data );
if ( status != PCI_SUCCESSFUL ) return status;
data &= ~mask;
return ( pci_config_write16( chip, offset, data ) );
}
UINT8 bclr_config32( struct _chip *chip, UINT32 offset, UINT32 mask )
/* clear bits based on mask
return: PCI_X
*/
{
UINT32 data;
int status;
status = pci_config_read32( chip, offset, &data );
if ( status != PCI_SUCCESSFUL ) return status;
data &= ~mask;
return ( pci_config_write32( chip, offset, data ) );
}
int pci_enable_memory( void )
/*
enable memory space for UUT
Return: "ah" register from BIOS call
*/
{
UINT16 data16;
int status;
status = pci_config_read16( &chip_uut, PCI_CS_COMMAND, &data16 );
if ( status != PCI_SUCCESSFUL )
return status;
data16 |= 2;
status = pci_config_write16( &chip_uut, PCI_CS_COMMAND, data16 );
return status;
}
int pci_disable_memory( void )
/*
disable memory space for UUT
Return: "ah" register from BIOS call
*/
{
UINT16 data16;
int status;
status = pci_config_read16( &chip_uut, PCI_CS_COMMAND, &data16 );
if ( status != PCI_SUCCESSFUL )
return status;
data16 &= !2;
status = pci_config_write16( &chip_uut, PCI_CS_COMMAND, data16 );
return status;
}
int pci_enable_io( void )
/*
enable I/O space for UUT
Return: "ah" register from BIOS call
*/
{
UINT16 data16;
int status;
status = pci_config_read16( &chip_uut, PCI_CS_COMMAND, &data16 );
if ( status != PCI_SUCCESSFUL )
return status;
data16 |= 1;
status = pci_config_write16( &chip_uut, PCI_CS_COMMAND, data16 );
return status;
}
int pci_disable_io( void )
/*
disable I/O space for UUT
Return: "ah" register from BIOS call
*/
{
UINT16 data16;
int status;
status = pci_config_read16( &chip_uut, PCI_CS_COMMAND, &data16 );
if ( status != PCI_SUCCESSFUL )
return status;
data16 &= !1;
status = pci_config_write16( &chip_uut, PCI_CS_COMMAND, data16 );
return status;
}
UINT8 addon_read8( UINT32 offset )
/* These functions are used to access UUT addon opregs because the UUT may
be in 16-bit addon mode. In 16-bit addon mode, the testboard must
set A1 and then access the byte/word.
Also, it takes two word accesses to build a long.
Return: value read
*/
{
if ( addon_width_16() )
{
if( offset & 0x2L ) /* A1 should be high... */
bset_control_reg( CTRL_A1 );
else
bclr_control_reg( CTRL_A1 );
return region_read8( &chip_control, CTRL_UUT_ADDON_REGION, \
offset & ~0x2L ); // drop out high word
}
return region_read8( &chip_control, CTRL_UUT_ADDON_REGION, offset );
}
UINT16 addon_read16( UINT32 offset )
/*
See opreg8.
*/
{
if ( addon_width_16() )
{
if( offset & 0x2L ) /* A1 should be high... */
bset_control_reg( CTRL_A1 );
else
bclr_control_reg( CTRL_A1 );
return region_read16( &chip_control, CTRL_UUT_ADDON_REGION, \
offset & ~0x2L ); // drop out high word
}
return region_read16( &chip_control, CTRL_UUT_ADDON_REGION, offset );
}
UINT32 addon_read32( UINT32 offset )
/*
See opreg8.
*/
{
UINT32 data, hdata;
if ( addon_width_16() )
{
/* low word... */
bclr_control_reg( CTRL_A1 ); /* A1 low */
data = (UINT32)region_read16( &chip_control, CTRL_UUT_ADDON_REGION, offset );
/* high word */
bset_control_reg( CTRL_A1 ); /* A1 high */
hdata = (UINT32)region_read16( &chip_control, CTRL_UUT_ADDON_REGION, offset );
hdata = hdata << 16;
return( data | hdata );
}
return region_read32( &chip_control, CTRL_UUT_ADDON_REGION, offset );
}
int addon_write8( UINT32 offset, UINT8 data )
/*
See opreg8.
Return: TRUE if done OK.
*/
{
if ( addon_width_16() )
{
if( offset & 0x2 ) /* A1 should be high... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -