/*** INCLUDES ***/
#include "vkiWrap.h"
#include "mec.h"
#include "dg_mgr.h"
#include "dg_error.h"
#include "dg_pcic.h"
#include "end.h"
#include "dg_pex8632.h"
/*** CONSTANT DEFINITIONS ***/
/*** MACRO DEFINITIONS ***/
#ifdef DEBUG
#define DBG_PRINT(msg) \
printf(msg); printf("\n");
#define DBG_PRINTF(msg, args...) \
printf(msg, ## args);
#else
#define DBG_PRINT(flg, msg)
#define DBG_PRINTF(flg, msg, args...)
#endif
#define PEX8632_WR8(offset, value) \
( *(volatile UINT8 *)((UINT8*)ptrDev->devRegBaseAddr + (offset)) = (value) )
#define PEX8632_RD8(offset, value) \
value = *((volatile UINT8*)((UINT8*)ptrDev->devRegBaseAddr + (offset)))
#define PEX8632_WR32(offset, value) \
( *(volatile UINT32 *)((UINT8*)ptrDev->devRegBaseAddr + (offset)) = (value) )
#define PEX8632_RD32(offset, value) \
value = *((volatile UINT32*)((UINT8*)ptrDev->devRegBaseAddr + (offset)))
/*** TYPE DEFINITIONS ***/
/* A simplified device control structure for the diagnostiocs */
typedef struct device_control
{
volatile void *devRegBaseAddr; /* virtual base address for registers */
} PEX8632_DEV_CTRL;
/*** EXTERNS ***/
/*** LOCALS ***/
LOCAL PEX8632_DEV_CTRL* ptrDev;
/*** Forward Declarations ***/
LOCAL int dg_pex8632 (void);
LOCAL UINT32 get_eeprom_value(UINT32 eepOffset);
LOCAL UINT32 convert_reg_phy_addr(UINT32 ls4Bytes, UINT32 *regAddr);
/*******************************************************************************
* PROCEDURE
*
* NAME: dg_pex8632_2( void )
* SUMMARY: Verify switch configuration test
* VISIBILITY: private
* SCOPE: Diagnostics
*
* DESCRIPTION: This test verifies if the value of the registers which stored in eeprom
are match to the value which stored in the memory addressing space.
*/
LOCAL int dg_pex8632 (void)
{
UINT32 i = 0;
UINT32 num = 0;
UINT32 ms4Bytes = 0;
UINT32 ls4Bytes = 0;
UINT32 regAddr = 0;
UINT32 regValue = 0;
UINT32 eepRegValue = 0;
//Validation signature verification
if ((get_eeprom_value(0x0) & EEPROM_5A_MASK) != 0x5A)
{
printf("external eeprom invalid!\n");
return DIAG_TERMINATION_SKIP;
}
//get pex8632 registers' base address
ptrDev->devRegBaseAddr = BCM_GET_DEVICE_REGION_BASE(Bridge, 0, 0);
printf("\n********base addr=%x********\n", ptrDev->devRegBaseAddr);
//calculate configuration register byte count which stored in eeprom
num = get_eeprom_value(0x0) >> 16;
//calculate if the amount of configuration registers can be divisible by 6, or not.
//Because the 6-byte unit consist of 2 parts, least significant 2-byte and most significant 4-byte,
//least significant 2-byte means the address of the next 4-byte(most significant 4-byte) in the memory addressing space,
//most significant 4-byte means the value which should be loaded into the register when pex8632 reset or power up.
if (num%6)
{
printf("the amount of registers cannot be divisible by 6 !\n");
return DIAG_TERMINATION_SKIP;
}
//scan all 6-byte unit and then compare the registers' value in eeprom with the value in the memory addressing space,
//equal then passed, different then failed.
for (; i < num/6; i++)
{
//the pex8632 eeprom interface only can access 4 bytes at a time, but every unit is 6 bytes,
//the deployment of the value reading from eeprom is
//address0 address0 value0 value0, value0 value0 address1 address1,
//value1 value1 value1 value1, address2 address2 value2 value2,
//value2 value2 address3 address3 ......
//so, the operation is divided to 2 types, odd unit and even unit.
//analyze and compare the 1st, 3rd, 5th, 7th ...... unit value
if (i%2)
{
// 2 times reading can include 6-byte value,
// 0x5A and configuration register byte count are in 0x0-0x3, so start from 0x4
ls4Bytes = get_eeprom_value(EEPROM_VALID_BYTE_START+i*6-2);
ms4Bytes = get_eeprom_value(EEPROM_VALID_BYTE_START+(i*6-2+4));
printf("odd ls4Bytes = %x\n", ls4Bytes);
//convert configuration register address from eeprom format to memory addressing space format
//shift to right by 16 bits for transfer the address from MS 16bits to LS 16bits
if(convert_reg_phy_addr(ls4Bytes >> 16, ®Addr))
{
printf("error port number !\n");
return DIAG_TERMINATION_SKIP;
}
//convert configuration register value
eepRegValue = ms4Bytes;
}
//analyze and compare the 0th, 2nd, 4th, 8th ...... unit value
else
{
// 2 times reading can include 6-byte value
// 0x5A and configuration register byte count are in 0x0-0x3, so start from 0x4
ls4Bytes = get_eeprom_value(EEPROM_VALID_BYTE_START+i*6);
ms4Bytes = get_eeprom_value(EEPROM_VALID_BYTE_START+(i*6+4));
printf("even ls4Bytes = %x\n", ls4Bytes);
//convert configuration register address from eeprom format to memory addressing space format
if(convert_reg_phy_addr(ls4Bytes, ®Addr))
{
printf("error port number !\n");
return DIAG_TERMINATION_SKIP;
}
//convert configuration register value
eepRegValue = (ls4Bytes >> 16) + (ms4Bytes << 16);
}
//get registers' value
PEX8632_RD32(regAddr, regValue);
//compare the configuration register value with the value in eeprom
if (eepRegValue != (regValue & eeprom_reg_valid_bit_mask[i]))
{
printf("register value in eeprom isnot match to the real value!\n");
return DIAG_TERMINATION_SKIP;
}
}
return (DIAG_TERMINATION_NORMAL);
}
/*******************************************************************************
* PROCEDURE
*
* NAME: convert_reg_phy_addr(UINT32 ls4Bytes, UINT32 *regAddr)
* SUMMARY: convert address format
* VISIBILITY: private
* SCOPE: Diagnostics
*
* DESCRIPTION: convert configuration register address
from eeprom format to memory addressing space format
*/
LOCAL UINT32 convert_reg_phy_addr(UINT32 ls4Bytes, UINT32 *regAddr)
{
UINT32 retValue = 0;
//abstract port number from least significant 4 bytes
//the formula is port address + eeprom_register_address << 2
//shifting the address to left by 2 bits means from a 1-int pointer to a 1-byte pointer
switch(ls4Bytes & EEPROM_PORTNUM_MASK)
{
case EEPROM_PORTNUM_0: //port 0 identifier in eeprom
*regAddr = PORT_PHY_ADDR_0 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_1: //port 1 identifier in eeprom
*regAddr = PORT_PHY_ADDR_1 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_2: //port 2 identifier in eeprom
*regAddr = PORT_PHY_ADDR_2 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_3: //port 3 identifier in eeprom
*regAddr = PORT_PHY_ADDR_3 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_4: //port 4 identifier in eeprom
*regAddr = PORT_PHY_ADDR_4 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_5: //port 5 identifier in eeprom
*regAddr = PORT_PHY_ADDR_5 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_6: //port 6 identifier in eeprom
*regAddr = PORT_PHY_ADDR_6 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_7: //port 7 identifier in eeprom
*regAddr = PORT_PHY_ADDR_7 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_8: //port 8 identifier in eeprom
*regAddr = PORT_PHY_ADDR_8 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_9: //port 9 identifier in eeprom
*regAddr = PORT_PHY_ADDR_9 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_10: //port 10 identifier in eeprom
*regAddr = PORT_PHY_ADDR_10 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_11: //port 11 identifier in eeprom
*regAddr = PORT_PHY_ADDR_11 + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
case EEPROM_PORTNUM_LINK: //port link identifier in eeprom
*regAddr = PORT_PHY_ADDR_LINK + ((ls4Bytes & EEPROM_REG_ADDR_MASK) << 2);
break;
default:
retValue = 1;
break;
}
return retValue;
}
/**********************************
评论0