📄 lib.c
字号:
bset_control_reg( CTRL_A1 );
else
bclr_control_reg( CTRL_A1 );
region_write8( &chip_control, CTRL_UUT_ADDON_REGION, offset & ~0x2, data );
}
else
region_write8( &chip_control, CTRL_UUT_ADDON_REGION, offset, data );
return( TRUE );
}
int addon_write16( UINT32 offset, UINT16 data )
/*
See addon_write8.
Return: TRUE if done OK.
*/
{
if ( addon_width_16() )
{
if( offset & 0x2 ) /* A1 should be high... */
bset_control_reg( CTRL_A1 );
else
bclr_control_reg( CTRL_A1 );
region_write16( &chip_control, CTRL_UUT_ADDON_REGION, offset & ~0x2, data );
}
else
region_write16( &chip_control, CTRL_UUT_ADDON_REGION, offset, data );
return( TRUE );
}
int addon_write32( UINT32 offset, UINT32 data )
/*
See addon_write8.
Return: TRUE if done OK.
*/
{
if ( addon_width_16() )
{
/* low word... */
bclr_control_reg( CTRL_A1 ); /* A1 low */
region_write16( &chip_control, CTRL_UUT_ADDON_REGION, offset, (UINT16)data );
/* high word */
bset_control_reg( CTRL_A1 ); /* A1 high */
region_write16( &chip_control, CTRL_UUT_ADDON_REGION, offset, (UINT16)(data>>16) );
}
else
region_write32( &chip_control, CTRL_UUT_ADDON_REGION, offset, data );
return( TRUE );
}
VOID bset_region32( struct _chip *chip, int region, \
UINT32 offset, UINT32 data )
/*
Read/modify/write of location in a region.
Set associated bits in this region.
*/
{
UINT32 data32;
check_base ( chip, region ); /* see if base != 0 */
data32 = region_read32( chip, region, offset );
data32 |= data;
region_write32( chip, region, offset, data32 );
}
VOID bclr_region32( struct _chip *chip, int region, \
UINT32 offset, UINT32 data )
/*
Read/modify/write of location in a region.
Clear associated bits in this region.
*/
{
UINT32 data32;
check_base ( chip, region ); /* see if base != 0 */
data32 = region_read32( chip, region, offset );
data32 &= ~data;
region_write32( chip, region, offset, data32 );
}
VOID bset_control_reg( UINT32 data )
/*
Read/modify/write of control register.
Set associated bits in control register shadow, then write it to reg.
*/
{
control |= data;
write_control_reg( control );
}
VOID bclr_control_reg( UINT32 data )
/*
Read/modify/write of control register.
Clear associated bits in control register shadow, then write it to reg.
*/
{
control &= ~data;
write_control_reg( control );
}
VOID write_control_reg( UINT32 data )
{
region_write32( &chip_control, CTRL_CONTROL_REGION, 0L, data );
}
UINT16 read_status_register( VOID )
/* Read testboard status register (16 bits).
*/
{
return region_read16( &chip_control, CTRL_CONTROL_REGION, 0L );
}
static void check_base ( struct _chip *chip, int region )
{
if ( chip->reg[region].base == 0L )
{
fprintf( stderr, \
"Error - called I/O function with base = 0.\n"
"Probably a programming error - \"chip\" structure not initialized.\n" );
exit(1);
}
}
int add_region_number( int region )
{
sprintf( text, "Region %d.\n", region );
strcat( errstring, text );
return FALSE;
}
int addon_width_16( VOID )
/*
Return: TRUE if UUT addon bus width is 16 bits.
Note: DQMODE high is 16-bit.
*/
{
if ( read_status_register() & STAT_DQMODE ) return( TRUE );
return( FALSE );
}
int dma_mode( VOID )
/*
Returns: TRUE if chip is in DMA mode
!!!!! IMPORTANT !!!!!
Once reset, you must not change the state of any mode pins unless
you are going to reset the chip before testing.
*/
{
if ( read_status_register() & STAT_DQMODE ) return( FALSE );
return( TRUE );
}
int mailbox_comp_mode( VOID )
/*
Return: TRUE if mailboxes are set up in compatible mode (always
inputs).
*/
{
if ( read_status_register() & STAT_MDMODE ) return( TRUE );
return( FALSE );
}
int sb_ws_sized( UINT32 offset, UINT32 sb_data, UINT32 ws_data, int region )
/*
Calls correct sb_ws function based on region width.
*/
{
switch ( region_width( region ) )
{
case 8:
return sb_ws8( offset, (UINT8)sb_data, (UINT8)ws_data );
case 16:
return sb_ws16( offset, (UINT16)sb_data, (UINT16)ws_data );
case 32:
return sb_ws32( offset, sb_data, ws_data );
default:
return FALSE;
}
}
int check_reg_values( struct _chip *chip, struct _reg_values *reg )
/*
Reads operation registers (region 0) and compares values read
against data for the registers. The "_reg_values" structure
contains the offset (address), expected value, and name of register.
Entry: chip - which chip to access
_reg_values - array of structures
Return: TRUE if OK, else errstring with address and data info.
*/
{
UINT32 data;
int i = 0;
while( reg[i].offset < 0x7FFFL )
{
data = region_read32( chip, 0, reg[i].offset );
if ( data != reg[i].value )
{
strcat( errstring, reg[i].regname );
strcat( errstring, " register miscompare.\n" );
return( data_err32( NULL, reg[i].offset, reg[i].value, data ) );
}
i++;
}
return( TRUE );
}
int nvram_access_error( VOID )
{
strcpy( errstring, "NVRAM access error.\n" );
return( FALSE );
}
CHAR waitkey( VOID )
{
return getch(); /* gets directly from keyboard no echo */
}
CHAR pcontinue( VOID )
/* Return: key pressed to continue */
{
CHAR c;
printf( " press key..." );
c = getch();
printf( "\n" );
return c;
}
int addon_int_active( VOID )
/*
Return: TRUE if UUT addon interrupt is active (low).
*/
{
if ( read_status_register() & STAT_IRQ ) return( FALSE );
return( TRUE );
}
int pci_int_active( VOID )
/*
Return: TRUE if UUT addon interrupt is active (low).
*/
{
if ( read_status_register() & STAT_INTA ) return( FALSE );
return( TRUE );
}
/* Define messages that apply to return error codes for
all NVRAM access commands. See lib.h for NVRAM_X defines which
must match.
!!! WARNING !!!
Be sure each line has "," so is not concatenated accidentally!
*/
CHAR *nvfail_message[] = {
"Last NVRAM access was OK.\n",
"5920 indicated NVRAM access error during write.\n",
"5920 indicated NVRAM access error during read.\n",
"NVRAM ready timeout.\n",
"NVRAM ready timeout during write.\n",
"NVRAM ready timeout during read.\n",
"NVRAM non-specific error.\n"
};
int nvfail( int fail_code )
/*
Add error string based on failure code, return FALSE.
*/
{
if ( fail_code >= NVRAM_LAST_INVALID_CODE )
strcat( errstring, "Last Invalid error code in \"nvfail()\".\n" );
else
strcat( errstring, nvfail_message[fail_code] );
return( FALSE );
}
int pci_bios_fail( int fail_code )
/*
Add error string based on failure code PCI_xx failure
from BIOS call (see lib.h).
Return: FALSE
*/
{
sprintf( text, "PCI BIOS return code %2.2x.\n", fail_code );
strcat( errstring, text );
switch( fail_code )
{
case PCI_SUCCESSFUL:
strcat( errstring, "PCI BIOS call OK.\n" );
break;
case PCI_NOT_SUCCESSFUL:
strcat( errstring, "PCI BIOS call failed - no specific error.\n" );
break;
case PCI_FUNC_NOT_SUPPORTED:
strcat( errstring, "PCI BIOS call failed - Function not supported.\n" );
break;
case PCI_BAD_VENDOR_ID:
strcat( errstring, "PCI BIOS call failed - Bad Vendor ID.\n" );
break;
case PCI_DEVICE_NOT_FOUND:
strcat( errstring, "PCI BIOS call failed - Device not Found.\n" );
break;
case PCI_BAD_REGISTER_NUMBER:
strcat( errstring, "PCI BIOS call failed - Bad Register Number.\n" );
break;
default:
strcat( errstring, "PCI BIOS call failed - unknown return code.\n" );
break;
}
return( FALSE );
}
VOID bclr_addon32( UINT32 address, UINT32 data )
/*
Take data and clear those bits (the ones that are set in "data") in the
destination register.
This is a 32-bit operation.
*/
{
UINT32 data32;
data32 = addon_read32( address );
data32 &= ~data;
addon_write32( address, data32 );
}
VOID bset_addon32( UINT32 address, UINT32 data )
/*
Take data and set those bits in the destination register.
(logical "or").
This is a 32-bit operation.
*/
{
UINT32 data32;
data32 = addon_read32( address );
data32 |= data;
addon_write32( address, data32 );
}
UINT32 region_size( int region )
/*
Return: current region size in bytes
0 if region is disabled
Use this function instead of getting directly from the structure.
This encapsulates the method used for easier mods.
*/
{
if ( !region_enabled(region) ) return 0L;
return chip_uut.reg[region].size;
}
int region_enabled( int region )
// Return: TRUE if this region is enabled
// Does not check memory enable bit
{
if (chip_uut.reg[region].base & 0xFFFFFFF0L) return TRUE;
return FALSE;
}
int write_fifo_enabled( int region )
// Return: TRUE if this region has its write FIFO enabled
// Does not check memory enable bit
{
UINT32 data32;
data32 = region_read32( &chip_uut, 0, PTCR );
data32 = data32 >> ((region-1) * 8);
if ( data32 & 0x20L )
return FALSE;
return TRUE;
}
int region_is_valid( struct _chip *chip, int region )
// Return: TRUE if region has a base address <> 0
{
if ( chip->reg[region].base ) return TRUE;
return FALSE;
}
int region_is_memory( int region )
// Return: TRUE if this region is in memory space (not I/O)
{
if (chip_uut.reg[region].base & 1L) return FALSE;
return TRUE;
}
int region_width( int region )
/*
Return: width of UUT region (8/16/32) based on current nvram contents.
0 if region disabled
exit(1) if error reading nvram
Note: The two MSBits of the 32-bit Base Address Register for
a region define its size. This can only be gotten from
nvram.
*/
{
int status;
UINT8 data;
if ( region == 0 ) return 32; // opregs
// read MSbyte of region - bit 31:30 are the width
status = nvram_read8( chip_uut.reg[0].base, \
0x50 + (4 * region) + 3, &data, chip_uut.type );
if ( status != NVRAM_OK )
{
nvfail( status );
fprintf( stderr, errstring );
exit(1);
}
switch ( data & 0xC0 )
{
case 0x40: return 8;
case 0x80: return 16;
case 0xC0: return 32;
default: ;
}
return 0; /* disabled */
}
int region_widths( void )
/*
Return: number of different region widths based on nvRAM contents
exit(1) if error reading nvram
Note: The two MSBits of the 32-bit Base Address Register for
a region define its size. This can only be gotten from
nvram.
*/
{
int region, size8 = FALSE, size16 = FALSE, size32 = FALSE;
int num_regions = 0;
for ( region = MIN_PT_REGION; region <= MAX_PT_REGION; region++ )
{
switch ( region_width(region) )
{
case 8:
if ( !size8 )
{
num_regions++;
size8 = TRUE;
}
break;
case 16:
if ( !size16 )
{
num_regions++;
size16 = TRUE;
}
break;
case 32:
if ( !size32 )
{
num_regions++;
size32 = TRUE;
}
break;
default:
fprintf( stderr, "Error getting region width.\n" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -