diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2011-10-18 15:35:31 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2011-10-27 12:58:59 -0500 |
commit | 71564141e3a6c7f023a9484549baf319f0e1807e (patch) | |
tree | 5987d3d51a8e9913973df9929478949bedf93a0d /src/usr/fsi | |
parent | 07c744f567b3d57819992859bca92e525495a5e1 (diff) | |
download | talos-hostboot-71564141e3a6c7f023a9484549baf319f0e1807e.tar.gz talos-hostboot-71564141e3a6c7f023a9484549baf319f0e1807e.zip |
Adding support for remote FSI accesses
RTC Story 3792
- Added 7 more Venice targets and 7 more Centaur targets to the
simics_VENICE.system.xml to match the latest simics config
Note: remove Centaurs are currently disabled due to SW107421
- Modified testcases to be more tolerant of system config differences
- Changes to initialization flow to be more tolerant of missing
chips
- Expanded the size of the HB_DATA section of PNOR to hold the
additional targets (up to 128KB space now, actual is 36KB)
Change-Id: Ic92708ccb147fb18bf992ef3ac318a287d32fafe
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/445
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/fsi')
-rw-r--r-- | src/usr/fsi/fsidd.C | 285 | ||||
-rw-r--r-- | src/usr/fsi/fsidd.H | 50 | ||||
-rw-r--r-- | src/usr/fsi/test/fsiddtest.H | 184 |
3 files changed, 377 insertions, 142 deletions
diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C index 8b8a72a33..5ce7329a0 100644 --- a/src/usr/fsi/fsidd.C +++ b/src/usr/fsi/fsidd.C @@ -57,7 +57,7 @@ TRAC_INIT(&g_trac_fsir, "FSIR", 4096); //4K //@todo - This should come from the target/attribute code somewhere -uint64_t target_to_uint64(TARGETING::Target* i_target) +uint64_t target_to_uint64(const TARGETING::Target* i_target) { uint64_t id = 0; if( i_target == NULL ) @@ -249,18 +249,55 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WRITE, ddOp); -// Initialize all visible FSI masters +/** + * @brief Initialize the FSI hardware + */ errlHndl_t initializeHardware() { return Singleton<FsiDD>::instance().initializeHardware(); } +/** + * @brief Retrieves the status of a given port + */ +bool isSlavePresent( const TARGETING::Target* i_fsiMaster, + TARGETING::FSI_MASTER_TYPE i_type, + uint8_t i_port ) +{ + if( i_fsiMaster == NULL ) + { + // NULL target means it isn't present + return false; + } + else + { + return Singleton<FsiDD>::instance().isSlavePresent(i_fsiMaster, + i_type, + i_port); + } +} + +/** + * @brief Retrieves the FSI status of a given chip + */ +bool isSlavePresent( const TARGETING::Target* i_target ) +{ + if( i_target == NULL ) + { + // NULL target means it isn't present + return false; + } + else + { + return Singleton<FsiDD>::instance().isSlavePresent(i_target); + } +} }; //end FSI namespace /** - * @brief set up _start() task entry procedure for PNOR daemon + * @brief set up _start() task entry procedure for FSI daemon */ TASK_ENTRY_MACRO( FsiDD::init ); @@ -285,7 +322,7 @@ void FsiDD::init( void* i_taskArgs ) /** * @brief Performs an FSI Read Operation to a relative address */ -errlHndl_t FsiDD::read(TARGETING::Target* i_target, +errlHndl_t FsiDD::read(const TARGETING::Target* i_target, uint64_t i_address, uint32_t* o_buffer) { @@ -310,7 +347,7 @@ errlHndl_t FsiDD::read(TARGETING::Target* i_target, /** * @brief Performs an FSI Write Operation to a relative address */ -errlHndl_t FsiDD::write(TARGETING::Target* i_target, +errlHndl_t FsiDD::write(const TARGETING::Target* i_target, uint64_t i_address, uint32_t* o_buffer) { @@ -339,11 +376,11 @@ errlHndl_t FsiDD::write(TARGETING::Target* i_target, ********************/ -// local type used inside FsiDD::initializeHardware() +// local types used inside FsiDD::initializeHardware() // must be declared outside the function to make compiler happy -struct remote_info_t { - TARGETING::Target* master; - uint8_t slave_port; +struct remote_master_t { + TARGETING::Target* cmfsi_master; + uint8_t mfsi_port; }; /** @@ -356,16 +393,21 @@ errlHndl_t FsiDD::initializeHardware() do{ // list of ports off of local MFSI - std::list<uint64_t> local_mfsi; - - // list of ports off of local cMFSI - std::list<uint64_t> local_cmfsi; + std::list<remote_master_t> local_mfsi; - // list of ports off of remote cMFSI - std::list<TARGETING::Target*> remote_masters; + // list of possible ports off of local cMFSI + bool local_cmfsi[MAX_SLAVE_PORTS]; + for( uint8_t cmfsi=0; cmfsi<MAX_SLAVE_PORTS; cmfsi++ ) { + local_cmfsi[cmfsi] = false; + } - // list of ports off of remote cMFSI - std::list<remote_info_t> remote_cmfsi; + // array of possible ports to initialize : [mfsi port][cmfsi port] + bool remote_cmfsi[MAX_SLAVE_PORTS][MAX_SLAVE_PORTS]; + for( uint8_t mfsi=0; mfsi<MAX_SLAVE_PORTS; mfsi++ ) { + for( uint8_t cmfsi=0; cmfsi<MAX_SLAVE_PORTS; cmfsi++ ) { + remote_cmfsi[mfsi][cmfsi] = false; + } + } FsiChipInfo_t info; @@ -386,27 +428,19 @@ errlHndl_t FsiDD::initializeHardware() if( info.type == TARGETING::FSI_MASTER_TYPE_MFSI ) { - local_mfsi.push_back(info.port); + remote_master_t tmp = {*t_itr,info.port}; + local_mfsi.push_back(tmp); } else if( info.type == TARGETING::FSI_MASTER_TYPE_CMFSI ) { if( info.master == iv_master ) { - local_cmfsi.push_back(info.port); + local_cmfsi[info.port] = true; } else { - // add all unique masters to the list - if( remote_masters.end() == - std::find(remote_masters.begin(), - remote_masters.end(), - info.master) ) - { - remote_masters.push_back( info.master ); - } - - remote_info_t tmp = {info.master,info.port}; - remote_cmfsi.push_back( tmp ); + FsiChipInfo_t info2 = getFsiInfo(info.master); + remote_cmfsi[info2.port][info.port] = true; } } } @@ -423,13 +457,15 @@ errlHndl_t FsiDD::initializeHardware() else { // initialize all of the local MFSI ports - for( std::list<uint64_t>::iterator itr = local_mfsi.begin(); + for( std::list<remote_master_t>::iterator itr = local_mfsi.begin(); itr != local_mfsi.end(); ++itr ) { + bool slave_present = false; l_err = initPort( iv_master, TARGETING::FSI_MASTER_TYPE_MFSI, - *itr ); + itr->mfsi_port, + slave_present ); if( l_err ) { //@todo - append the actual slave target to FFDC @@ -439,7 +475,54 @@ errlHndl_t FsiDD::initializeHardware() //if this fails then some of the slaves below won't init, // but that is okay because the detected ports will be // zero which will cause the initPort call to be a NOOP + continue; } + + // the slave wasn't present so we can't do anything with the + // downstream ports + if( !slave_present ) + { + continue; + } + + // initialize all of the remote cMFSI ports off the master + // we just initialized + bool master_init_done = false; + for( uint8_t cmfsi=0; cmfsi<MAX_SLAVE_PORTS; cmfsi++ ) + { + // skip ports that have no possible slaves + if( remote_cmfsi[itr->mfsi_port][cmfsi] == false ) + { + continue; + } + + if( !master_init_done ) + { + // initialize the remote cMFSI master on this MFSI slave + l_err = initMasterControl( itr->cmfsi_master, + TARGETING::FSI_MASTER_TYPE_CMFSI ); + if( l_err ) + { + // commit the log here so that we can move on to next port + errlCommit(l_err); + break; + } + master_init_done = true; + } + + // initialize the port/slave + l_err = initPort( itr->cmfsi_master, + TARGETING::FSI_MASTER_TYPE_CMFSI, + cmfsi, + slave_present ); + if( l_err ) + { + //@todo - append the actual slave target to FFDC + // commit the log here so that we can move on to next port + errlCommit(l_err); + } + } + } } @@ -452,11 +535,19 @@ errlHndl_t FsiDD::initializeHardware() else { // initialize all of the local cMFSI ports - for( std::list<uint64_t>::iterator itr = local_cmfsi.begin(); - itr != local_cmfsi.end(); - ++itr ) + for( uint8_t cmfsi=0; cmfsi<MAX_SLAVE_PORTS; cmfsi++ ) { - l_err = initPort( iv_master, TARGETING::FSI_MASTER_TYPE_CMFSI, *itr ); + // skip ports that have no possible slaves + if( local_cmfsi[cmfsi] == false ) + { + continue; + } + + bool slave_present = false; + l_err = initPort( iv_master, + TARGETING::FSI_MASTER_TYPE_CMFSI, + cmfsi, + slave_present ); if( l_err ) { //@todo - append the actual slave target to FFDC @@ -466,36 +557,6 @@ errlHndl_t FsiDD::initializeHardware() } } - // initialize all of the remote cMFSI masters - for( std::list<TARGETING::Target*>::iterator itr - = remote_masters.begin(); - itr != remote_masters.end(); - ++itr ) - { - l_err = initMasterControl( *itr, TARGETING::FSI_MASTER_TYPE_CMFSI ); - if( l_err ) - { - // commit the log here so that we can move on to next port - errlCommit(l_err); - } - } - - // initialize all of the remote cMFSI ports - for( std::list<remote_info_t>::iterator itr = remote_cmfsi.begin(); - itr != remote_cmfsi.end(); - ++itr ) - { - l_err = initPort( itr->master, - TARGETING::FSI_MASTER_TYPE_CMFSI, - itr->slave_port ); - if( l_err ) - { - //@todo - append the actual slave target to FFDC - // commit the log here so that we can move on to next port - errlCommit(l_err); - } - } - } while(0); return l_err; @@ -667,7 +728,7 @@ errlHndl_t FsiDD::write(uint64_t i_address, /** * @brief Analyze error bits and recover hardware as needed */ -errlHndl_t FsiDD::handleOpbErrors(TARGETING::Target* i_target, +errlHndl_t FsiDD::handleOpbErrors(const TARGETING::Target* i_target, uint64_t i_address, uint32_t i_opbStatReg) { @@ -804,9 +865,25 @@ errlHndl_t FsiDD::pollForComplete(uint64_t i_address, * @brief Generate a complete FSI address based on the target and the * FSI offset within that target */ -uint64_t FsiDD::genFullFsiAddr(TARGETING::Target* i_target, +uint64_t FsiDD::genFullFsiAddr(const TARGETING::Target* i_target, uint64_t i_address) { + /* @todo - See Task 4086 + once xscoms are enabled on the remote processors it will + more efficient to use xscoms to drive the CMFSI engine directly + versus using the master's FSI logic + + Changes to make: + - change this function to return the master to xscom to + if fsi_info.master != iv_master + AND fsi_info.master:useXscom=true + set xscom target to fsi_info.master + do not add on the MFSI offset to the address + else + use the code as it currently is setup + - that master target has to be passed through the other functions + */ + //target matches master so the address is correct as-is if( i_target == iv_master ) { @@ -838,7 +915,12 @@ uint64_t FsiDD::genFullFsiAddr(TARGETING::Target* i_target, //find this port's master and then get its port information FsiChipInfo_t mfsi_info = getFsiInfo(fsi_info.master); assert( mfsi_info.master == iv_master ); //invalid topology - assert( TARGETING::FSI_MASTER_TYPE_MFSI == fsi_info.type ); //invalid topology + if( TARGETING::FSI_MASTER_TYPE_MFSI != mfsi_info.type ) + { + TRACFCOMP( g_trac_fsi, "target=%llX : master=%llX, type=%d, port=%d", target_to_uint64(i_target), target_to_uint64(fsi_info.master), fsi_info.type, fsi_info.port ); + TRACFCOMP( g_trac_fsi, "Master: target=%llX : master=%llX, type=%d, port=%d", target_to_uint64(fsi_info.master), target_to_uint64(mfsi_info.master), mfsi_info.type, mfsi_info.port ); + } + assert( TARGETING::FSI_MASTER_TYPE_MFSI == mfsi_info.type ); //invalid topology //append the MFSI port l_addr += getPortOffset(mfsi_info.type,mfsi_info.port); @@ -854,6 +936,8 @@ uint64_t FsiDD::genFullFsiAddr(TARGETING::Target* i_target, uint64_t FsiDD::genOpbScomAddr(uint64_t i_opbOffset) { //@todo: handle redundant FSI ports, always using zero for now (Story 3853) + // this might be needed to handle multi-chip config in simics because + // proc2 is connected to port B uint64_t opbaddr = FSI2OPB_OFFSET_0 | i_opbOffset; return opbaddr; } @@ -862,12 +946,14 @@ uint64_t FsiDD::genOpbScomAddr(uint64_t i_opbOffset) /** * @brief Initializes the FSI link to allow slave access */ -errlHndl_t FsiDD::initPort(TARGETING::Target* i_master, +errlHndl_t FsiDD::initPort(const TARGETING::Target* i_master, TARGETING::FSI_MASTER_TYPE i_type, - uint64_t i_port) + uint64_t i_port, + bool& o_enabled) { errlHndl_t l_err = NULL; TRACFCOMP( g_trac_fsi, ENTER_MRK"FsiDD::initPort> Initializing %llX:%d, port %llX", target_to_uint64(i_master), i_type, i_port ); + o_enabled = false; do { uint32_t databuf = 0; @@ -894,11 +980,10 @@ errlHndl_t FsiDD::initPort(TARGETING::Target* i_master, slave_offset += master_offset; // nothing was detected on this port so this is just a NOOP - uint64_t slave_index = getSlaveEnableIndex(i_master,i_type); - if( !(iv_slaves[slave_index] & portbit) ) + if( !isSlavePresent(i_master,i_type,i_port) ) { - TRACFCOMP( g_trac_fsi, "FsiDD::initPort> Slave %llX:%d:%d is not present", target_to_uint64(i_master), i_type, i_port ); - TRACFCOMP( g_trac_fsi, " : sensebits=%.2X, portbit=%.2X", iv_slaves[slave_index], portbit ); + TRACDCOMP( g_trac_fsi, "FsiDD::initPort> Slave %llX:%d:%d is not present", target_to_uint64(i_master), i_type, i_port ); + TRACDCOMP( g_trac_fsi, " : sensebits=%.2X, portbit=%.2X", iv_slaves[getSlaveEnableIndex(i_master,i_type)], portbit ); break; } TRACFCOMP( g_trac_fsi, "FsiDD::initPort> Slave %llX:%d:%d is present", target_to_uint64(i_master), i_type, i_port ); @@ -926,14 +1011,18 @@ errlHndl_t FsiDD::initPort(TARGETING::Target* i_master, * @moduleid FSI::MOD_FSIDD_INITPORT * @reasoncode FSI::RC_ERROR_ENABLING_SLAVE * @userdata1 Target Id of Master - * @userdata2 Port | MAEB from master + * @userdata2[0:15] Type + * @userdata2[16:31] Port + * @userdata2[32:63] MAEB from master * @devdesc FsiDD::initPort> Error after sending BREAK */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, FSI::MOD_FSIDD_INITPORT, FSI::RC_ERROR_ENABLING_SLAVE, target_to_uint64(i_master), - TWO_UINT32_TO_UINT64(TO_UINT32(i_port),databuf)); + TWO_UINT16_ONE_UINT32_TO_UINT64(i_type, + i_port, + databuf) ); break; } @@ -943,6 +1032,10 @@ errlHndl_t FsiDD::initPort(TARGETING::Target* i_master, { slave_offset |= CMFSI_SLAVE_3; } + else if( TARGETING::FSI_MASTER_TYPE_MFSI == i_type ) + { + slave_offset |= MFSI_SLAVE_3; + } //Setup the FSI slave to enable HW recovery, lbus ratio // 2= Enable HW error recovery (bit 2) @@ -983,7 +1076,7 @@ errlHndl_t FsiDD::initPort(TARGETING::Target* i_master, #endif // No support for slave cascades so we're done - + o_enabled = true; } while(0); TRACDCOMP( g_trac_fsi, EXIT_MRK"FsiDD::initPort" ); @@ -993,7 +1086,7 @@ errlHndl_t FsiDD::initPort(TARGETING::Target* i_master, /** * @brief Initializes the FSI master control registers */ -errlHndl_t FsiDD::initMasterControl(TARGETING::Target* i_master, +errlHndl_t FsiDD::initMasterControl(const TARGETING::Target* i_master, TARGETING::FSI_MASTER_TYPE i_type) { errlHndl_t l_err = NULL; @@ -1131,7 +1224,7 @@ uint64_t FsiDD::getPortOffset(TARGETING::FSI_MASTER_TYPE i_type, /** * @brief Retrieve the slave enable index */ -uint64_t FsiDD::getSlaveEnableIndex( TARGETING::Target* i_master, +uint64_t FsiDD::getSlaveEnableIndex( const TARGETING::Target* i_master, TARGETING::FSI_MASTER_TYPE i_type ) { //default to local slave ports @@ -1148,7 +1241,7 @@ uint64_t FsiDD::getSlaveEnableIndex( TARGETING::Target* i_master, * @brief Retrieve the connection information needed to access FSI * registers within the given chip target */ -FsiDD::FsiChipInfo_t FsiDD::getFsiInfo( TARGETING::Target* i_target ) +FsiDD::FsiChipInfo_t FsiDD::getFsiInfo( const TARGETING::Target* i_target ) { FsiChipInfo_t info; info.master = NULL; @@ -1225,6 +1318,36 @@ FsiDD::FsiChipInfo_t FsiDD::getFsiInfo( TARGETING::Target* i_target ) return info; } +/** + * @brief Retrieves the status of a given port + */ +bool FsiDD::isSlavePresent( const TARGETING::Target* i_fsiMaster, + TARGETING::FSI_MASTER_TYPE i_type, + uint8_t i_port ) +{ + if( (i_port < MAX_SLAVE_PORTS) + && (TARGETING::FSI_MASTER_TYPE_NO_MASTER != i_type) + && (NULL != i_fsiMaster) ) + { + uint64_t slave_index = getSlaveEnableIndex(i_fsiMaster,i_type); + return ( iv_slaves[slave_index] & (0x80 >> i_port) ); + } + else + { + return false; + } +} + +/** + * @brief Retrieves the FSI status of a given chip + */ +bool FsiDD::isSlavePresent( const TARGETING::Target* i_target ) +{ + // look up the FSI information for this target + FsiChipInfo_t info = getFsiInfo(i_target); + return isSlavePresent( info.master, info.type, info.port ); +} + /*@ * @errortype * @moduleid FSI::MOD_FSIDD_INITPORT diff --git a/src/usr/fsi/fsidd.H b/src/usr/fsi/fsidd.H index 7e3d1541b..89bab65a9 100644 --- a/src/usr/fsi/fsidd.H +++ b/src/usr/fsi/fsidd.H @@ -64,7 +64,7 @@ class FsiDD * * @return errlHndl_t NULL on success */ - errlHndl_t read(TARGETING::Target* i_target, + errlHndl_t read(const TARGETING::Target* i_target, uint64_t i_address, uint32_t* o_buffer); @@ -77,11 +77,33 @@ class FsiDD * * @return errlHndl_t NULL on success */ - errlHndl_t write(TARGETING::Target* i_target, + errlHndl_t write(const TARGETING::Target* i_target, uint64_t i_address, uint32_t* i_buffer); + /** + * @brief Retrieves the status of a given port + * + * @param[in] i_fsiMaster FSI Master chip + * @param[in] i_type FSI Master Type (MFSI or cMFSI) + * @param[in] i_port Slave port number + * + * @return bool true if port sensed as active during FSI initialization + */ + bool isSlavePresent( const TARGETING::Target* i_fsiMaster, + TARGETING::FSI_MASTER_TYPE i_type, + uint8_t i_port ); + + /** + * @brief Retrieves the FSI status of a given chip + * + * @param[in] i_target + * + * @return bool true if port sensed as active during FSI initialization + */ + bool isSlavePresent( const TARGETING::Target* i_target ); + protected: /** * @brief Constructor @@ -124,22 +146,24 @@ class FsiDD * * @return errlHndl_t NULL on success */ - errlHndl_t initMasterControl(TARGETING::Target* i_master, + errlHndl_t initMasterControl(const TARGETING::Target* i_master, TARGETING::FSI_MASTER_TYPE i_type); /** * @brief Initializes the FSI link to allow slave access * - * @param[in] Chip target of FSI-Master - * @param[in] Type of FSI-Master - * @param[in] FSI port (0-7) being initialized (relative to master) + * @param[in] i_master Chip target of FSI-Master + * @param[in] i_type Type of FSI-Master + * @param[in] i_port FSI port (0-7) being initialized (relative to master) + * @param[out] o_enabled true if the port is successfully enabled * * @return errlHndl_t NULL on success */ - errlHndl_t initPort(TARGETING::Target* i_master, + errlHndl_t initPort(const TARGETING::Target* i_master, TARGETING::FSI_MASTER_TYPE i_type, - uint64_t i_port); + uint64_t i_port, + bool& o_enabled); /** * @brief Analyze error bits and recover hardware as needed @@ -150,7 +174,7 @@ class FsiDD * * @return errlHndl_t NULL on success */ - errlHndl_t handleOpbErrors(TARGETING::Target* i_target, + errlHndl_t handleOpbErrors(const TARGETING::Target* i_target, uint64_t i_address, uint32_t i_opbStatReg); @@ -175,7 +199,7 @@ class FsiDD * * @return uint64_t Fully qualified FSI address */ - uint64_t genFullFsiAddr(TARGETING::Target* i_target, + uint64_t genFullFsiAddr(const TARGETING::Target* i_target, uint64_t i_address); /** @@ -328,7 +352,7 @@ class FsiDD { TARGETING::Target* master; ///< FSI Master TARGETING::FSI_MASTER_TYPE type; ///< Master or Cascaded Master - uint8_t port; ///< Which port is this chip hanging off of + uint8_t port; ///< Which port is this chip hanging off of uint8_t cascade; ///< Slave cascade position uint16_t flags; ///< Reserved for any special flags we might need FsiLinkId_t linkid; ///< Id for traces and error logs @@ -356,7 +380,7 @@ class FsiDD * @param[in] i_type Type of FSI interface * @return uint64_t Index into iv_slaves array */ - uint64_t getSlaveEnableIndex( TARGETING::Target* i_master, + uint64_t getSlaveEnableIndex( const TARGETING::Target* i_master, TARGETING::FSI_MASTER_TYPE i_type ); /** @@ -367,7 +391,7 @@ class FsiDD * * @return FsiChipInfo_t FSI Chip Information */ - FsiChipInfo_t getFsiInfo( TARGETING::Target* i_target ); + FsiChipInfo_t getFsiInfo( const TARGETING::Target* i_target ); diff --git a/src/usr/fsi/test/fsiddtest.H b/src/usr/fsi/test/fsiddtest.H index 1a11d346d..3535bd9f4 100644 --- a/src/usr/fsi/test/fsiddtest.H +++ b/src/usr/fsi/test/fsiddtest.H @@ -41,6 +41,7 @@ extern trace_desc_t* g_trac_fsi; +using namespace TARGETING; class FsiDDTest : public CxxTest::TestSuite { @@ -52,7 +53,7 @@ class FsiDDTest : public CxxTest::TestSuite void test_init(void) { TRACFCOMP( g_trac_fsi, "FsiDDTest::test_init> Start" ); - TRACFCOMP( g_trac_fsi, "FsiDDTest::test_init> Skipping due to simics issues" ); return; + return; //istep is calling this now uint64_t fails = 0; uint64_t total = 0; errlHndl_t l_err = NULL; @@ -72,14 +73,46 @@ class FsiDDTest : public CxxTest::TestSuite }; + //testcode for Simics verification + void test_blah(void) + { + return; + errlHndl_t l_err = NULL; + TARGETING::Target* fsi_target = NULL; + + // master processor target + TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL); + epath.addLast(TARGETING::TYPE_SYS,0); + epath.addLast(TARGETING::TYPE_NODE,0); + epath.addLast(TARGETING::TYPE_PROC,0); + fsi_target = TARGETING::targetService().toTarget(epath); + + uint32_t read_data = 0; + size_t op_size = sizeof(read_data); + + while(1) + { + nanosleep( 1, 0 ); + op_size = sizeof(read_data); + l_err = DeviceFW::deviceRead( fsi_target, + &read_data, + op_size, + DEVICE_FSI_ADDRESS(0x3418) ); + if( l_err ) + { + TRACFCOMP(g_trac_fsi, "FsiDDTest::test_blah> Error from device : RC=%X", l_err->reasonCode() ); + delete l_err; + } + } + }; + /** * @brief FSI DD test - Read/Write * Perform basic read/write operations */ void test_readWrite(void) { - TRACFCOMP( g_trac_fsi, "FsiDDTest::test_readWrite> Start" ); - TRACFCOMP( g_trac_fsi, "FsiDDTest::test_init> Skipping due to simics issues" ); return; + TRACFCOMP( g_trac_fsi, "FsiDDTest::test_readWrite> Start" ); uint64_t fails = 0; uint64_t total = 0; errlHndl_t l_err = NULL; @@ -87,9 +120,10 @@ class FsiDDTest : public CxxTest::TestSuite // Setup some targets to use enum { PROC0, - PROC1, + PROCWRAP, + PROC2, CENTAUR0, - NULL_TARGET, + CENTAUR8, SENTINEL, NUM_TARGETS }; @@ -109,11 +143,17 @@ class FsiDDTest : public CxxTest::TestSuite fsi_target = TARGETING::targetService().toTarget(epath); fsi_targets[PROC0] = fsi_target; - // other (wrap) processor target (physical:sys-0/node-0/proc-1) + // other (wrap) processor target (physical:sys-0/node-0/proc-9) epath.removeLast(); - epath.addLast(TARGETING::TYPE_PROC,1); + epath.addLast(TARGETING::TYPE_PROC,9); fsi_target = TARGETING::targetService().toTarget(epath); - fsi_targets[PROC1] = fsi_target; + fsi_targets[PROCWRAP] = fsi_target; + + // other (wrap) processor target (physical:sys-0/node-0/proc-2) + epath.removeLast(); + epath.addLast(TARGETING::TYPE_PROC,2); + fsi_target = TARGETING::targetService().toTarget(epath); + fsi_targets[PROC2] = fsi_target; // centaur target (physical:sys-0/node-0/membuf-0) epath.removeLast(); @@ -121,6 +161,12 @@ class FsiDDTest : public CxxTest::TestSuite fsi_target = TARGETING::targetService().toTarget(epath); fsi_targets[CENTAUR0] = fsi_target; + // centaur target (physical:sys-0/node-0/membuf-8) + epath.removeLast(); + epath.addLast(TARGETING::TYPE_MEMBUF,8); + fsi_target = TARGETING::targetService().toTarget(epath); + fsi_targets[CENTAUR8] = fsi_target; + // scratch data to use @@ -129,39 +175,42 @@ class FsiDDTest : public CxxTest::TestSuite uint64_t addr; uint32_t data; bool writeable; + bool present; } test_data[] = { //** Master Control Space // version number - { PROC0, 0x003074, 0x91010800, false }, //CMFSI MVER - { PROC0, 0x003474, 0x91010800, false }, //MFSI MVER + { PROC0, 0x003074, 0x91010800, false, true }, //CMFSI MVER + { PROC0, 0x003474, 0x91010800, false, true }, //MFSI MVER // clock rate delay for ports 32-63 (unused ports) - { PROC0, 0x00340C, 0x11111111, true }, //MFSI MCRSP32 - { PROC0, 0x00300C, 0x22222222, true }, //CMFSI MCRSP32 - - // port static levels - { PROC0, 0x003418, 0x80000000, false }, //MFSI MLEVP32 (port0 present) - { PROC0, 0x00341C, 0x00000000, false }, //MFSI MLEVP32 - { PROC0, 0x003018, 0x80000000, false }, //CMFSI MLEVP0 - { PROC0, 0x00301C, 0x00000000, false }, //CMFSI MLEVP32 + { PROC0, 0x00340C, 0x11111111, true, true }, //MFSI MCRSP32 + { PROC0, 0x00300C, 0x22222222, true, true }, //CMFSI MCRSP32 //** Slave Regs (cheating) - { PROC0, 0x080000, 0xC0010EA0, false }, //Config Table entry for slave0 off MFSI-0 - { PROC0, 0x081000, 0x12345678, true }, //DATA_0 from FSI2PIB off MFSI-0 - //@fixme-simics { PROC0, 0x041000, 0x88776655, true }, //DATA_0 from FSI2PIB off cMFSI-0 + { PROC0, 0x080000, 0xC0010EA0, false, false }, //Config Table entry for slave0 off MFSI-0 + { PROC0, 0x081000, 0x12345678, true, false }, //DATA_0 from FSI2PIB off MFSI-0 + { PROC0, 0x041028, 0xC6EE9049 /*fixme 0x160E9049*/, false, false }, //CHIPID from SHIFT off cMFSI-0 + { PROC0, 0x103074, 0x91010800, false, false }, //CMFSI MVER from Proc off MFSI-2 + + //** Slave Regs + { PROCWRAP, 0x000000, 0xC0010EA0, false, false }, //Config Table entry for slave0 off MFSI-0 + { PROCWRAP, 0x001000, 0x12345678, false, false }, //DATA_0 from FSI2PIB off MFSI-0 + { PROCWRAP, 0x001004, 0xA5A5A5A5, true, false }, //DATA_1 from FSI2PIB off MFSI-0 + //SW106529 { PROCWRAP, 0x001028, 0x120EA049, false, false }, //CHIPID from FSI2PIB off MFSI-0 + + //** Slave Regs + { PROC2, 0x000000, 0xC0010EA0, false, false }, //Config Table entry for slave0 off MFSI-2 + { PROC2, 0x001000, 0x12345678, true, false }, //FEL from SHIFT off MFSI-2 + { PROC2, 0x001028, 0x120EA049, false, false }, //CHIPID from FSI2PIB off MFSI-2 //** Slave Regs - { PROC1, 0x000000, 0xC0010EA0, false }, //Config Table entry for slave0 off MFSI-0 - { PROC1, 0x001000, 0x12345678, false }, //DATA_0 from FSI2PIB off MFSI-0 - { PROC1, 0x001004, 0xA5A5A5A5, true }, //DATA_1 from FSI2PIB off MFSI-0 - { PROC1, 0x001028, 0x120EA049, false }, //CHIPID from FSI2PIB off MFSI-0 + { CENTAUR0, 0x000000, 0xC31CEE9C, false, false }, //Config Table entry for slave0 off cMFSI-0 + { CENTAUR0, 0x001028, 0xC6EE9049 /*fixme 0x160E9049*/, false, false }, //CHIPID from FSI2PIB off cMFSI-0 + { CENTAUR0, 0x000C08, 0x12344321, true, false }, //FEL from SHIFT off cMFSI-0 //** Slave Regs - { CENTAUR0, 0x000000, 0xC31CEE9C, false }, //Config Table entry for slave0 off cMFSI-0 - //@fixme-simics { CENTAUR0, 0x001000, 0x88776655, false }, //DATA_0 from FSI2PIB off cMFSI-0 - //@fixme-simics { CENTAUR0, 0x001004, 0xB0B0B0B0, true }, //DATA_1 from FSI2PIB off cMFSI-0 - { CENTAUR0, 0x001028, 0xC6EE9049 /*@fixme-simics 0x160E9049*/, true }, //CHIPID from FSI2PIB off cMFSI-0 - { CENTAUR0, 0x000C08, 0x12344321, true }, //FEL from SHIFT off cMFSI-0 + { CENTAUR8, 0x001000, 0x33333333, true, false }, //FEL from SHIFT off cMFSI-0 of MFSI-7 + { CENTAUR8, 0x001028, /*0xC6EE9049*/ 0x160E9049, false, false }, //CHIPID from FSI2PIB off cMFSI-0 of MFSI-7 }; const uint64_t NUM_ADDRS = sizeof(test_data)/sizeof(test_data[0]); @@ -169,29 +218,55 @@ class FsiDDTest : public CxxTest::TestSuite uint32_t read_data[NUM_ADDRS]; size_t op_size = sizeof(uint32_t); - - // read address X,Y,Z + // figure out which ports are valid to test in the current config + uint64_t patterns_to_run = 0; for( uint64_t x = 0; x < NUM_ADDRS; x++ ) { - op_size = sizeof(uint32_t); - - if( (NULL == fsi_targets[test_data[x].fsitarget]) - || (test_data[x].addr >= 0x040000) ) + // direct writes to slave regs + if( test_data[x].fsitarget == PROC0 ) { - TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL); - syspath.addLast(TARGETING::TYPE_SYS,0); - TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath); - uint8_t vpo_mode = 0; - if( sys - && sys->tryGetAttr<TARGETING::ATTR_VPO_MODE>(vpo_mode) - && (vpo_mode == 1) ) + if( ((0xFF0000 & test_data[x].addr) == 0x080000) + && FSI::isSlavePresent(fsi_targets[PROCWRAP]) ) + { + test_data[x].present = true; + } + else if( ((0xFF0000 & test_data[x].addr) == 0x040000) + && FSI::isSlavePresent(fsi_targets[CENTAUR0]) ) + { + test_data[x].present = true; + } + else if( ((0xFF0000 & test_data[x].addr) == 0x100000) + && FSI::isSlavePresent(fsi_targets[PROC2]) ) { - // skip targets that aren't part of the VPO configs - continue; + test_data[x].present = true; } } + // otherwise only talk to chips that we see + else if( FSI::isSlavePresent(fsi_targets[test_data[x].fsitarget]) ) + { + test_data[x].present = true; + } + else + { + test_data[x].present = false; + } + + if( test_data[x].present ) + { + patterns_to_run |= (0x8000000000000000 >> x); + } + } + + // read address X,Y,Z + for( uint64_t x = 0; x < NUM_ADDRS; x++ ) + { + if( !test_data[x].present ) + { + continue; + } total++; + op_size = sizeof(uint32_t); l_err = DeviceFW::deviceRead( fsi_targets[test_data[x].fsitarget], &(read_data[x]), op_size, @@ -211,11 +286,15 @@ class FsiDDTest : public CxxTest::TestSuite // write X=A, Y=B, Z=C for( uint64_t x = 0; x < NUM_ADDRS; x++ ) { - op_size = sizeof(uint32_t); + if( !test_data[x].present ) + { + continue; + } if( test_data[x].writeable ) { total++; + op_size = sizeof(uint32_t); l_err = DeviceFW::deviceWrite( fsi_targets[test_data[x].fsitarget], &(test_data[x].data), op_size, @@ -234,9 +313,13 @@ class FsiDDTest : public CxxTest::TestSuite // read X,Y,Z for( uint64_t x = 0; x < NUM_ADDRS; x++ ) { - op_size = sizeof(uint32_t); + if( !test_data[x].present ) + { + continue; + } total++; + op_size = sizeof(uint32_t); l_err = DeviceFW::deviceRead( fsi_targets[test_data[x].fsitarget], &(read_data[x]), op_size, @@ -254,6 +337,11 @@ class FsiDDTest : public CxxTest::TestSuite // verify X==A, Y==B, Z==C for( uint64_t x = 0; x < NUM_ADDRS; x++ ) { + if( !test_data[x].present ) + { + continue; + } + total++; if( read_data[x] != test_data[x].data ) { @@ -289,7 +377,7 @@ class FsiDDTest : public CxxTest::TestSuite #endif - TRACFCOMP( g_trac_fsi, "FsiDDTest::test_readWrite> %d/%d fails", fails, total ); + TRACFCOMP( g_trac_fsi, "FsiDDTest::test_readWrite> %d/%d fails (patterns=%.16X)", fails, total, patterns_to_run ); }; /** |