diff options
-rw-r--r-- | src/include/usr/fsi/fsiif.H | 2 | ||||
-rw-r--r-- | src/usr/fsi/fsidd.C | 65 |
2 files changed, 64 insertions, 3 deletions
diff --git a/src/include/usr/fsi/fsiif.H b/src/include/usr/fsi/fsiif.H index c19bb7ccb..756dbb7b0 100644 --- a/src/include/usr/fsi/fsiif.H +++ b/src/include/usr/fsi/fsiif.H @@ -146,6 +146,8 @@ enum SlaveRegistersP8 FSI2PIB_ENGINE = 0x001000, /**< FSI2PIB Engine (SCOM) */ FSI2PIB_RESET = FSI2PIB_ENGINE|0x18, /**< see 1006 */ FSI2PIB_STATUS = FSI2PIB_ENGINE|0x1C, /**< see 1007 */ + FSI2PIB_COMPMASK = FSI2PIB_ENGINE|0x30, /**< see 100C */ + FSI2PIB_TRUEMASK = FSI2PIB_ENGINE|0x34, /**< see 100D */ FSI_SCRATCHPAD = 0x001400, /**< FSI Scratchpad */ diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C index a8c648827..98f06fa78 100644 --- a/src/usr/fsi/fsidd.C +++ b/src/usr/fsi/fsidd.C @@ -1986,8 +1986,17 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo, sys->getAttr<TARGETING::ATTR_SP_FUNCTIONS>(); if( spfuncs.fsiSlaveInit ) { - TRACFCOMP( g_trac_fsi, "FsiDD::initPort> Skipping Slave Init because SP did it" ); + TRACFCOMP( g_trac_fsi, "FsiDD::initPort> Skipping Slave Init because SP did it, only doing FSI2PIB reset" ); o_enabled = true; + + //Reset the port to clear up any previous error state + // (using idec reg as arbitrary address for lookups) + FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 ); + l_err = genFullFsiAddr( addr_info ); + if( l_err ) { break; } + l_err = errorCleanup( addr_info, FSI::RC_ERROR_IN_MAEB ); + if(l_err) { delete l_err; l_err = NULL; } + break; } @@ -1997,8 +2006,17 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo, && sys->tryGetAttr<TARGETING::ATTR_IS_MPIPL_HB>(is_mpipl) && is_mpipl ) { - TRACFCOMP( g_trac_fsi, "FsiDD::initPort> Skipping Slave Init in MPIPL" ); + TRACFCOMP( g_trac_fsi, "FsiDD::initPort> Skipping Slave Init in MPIPL, only doing reset" ); o_enabled = true; + + //Reset the port to clear up any previous error state + // (using idec reg as arbitrary address for lookups) + FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 ); + l_err = genFullFsiAddr( addr_info ); + if( l_err ) { break; } + l_err = errorCleanup( addr_info, FSI::RC_ERROR_IN_MAEB ); + if(l_err) { delete l_err; l_err = NULL; } + break; } @@ -2076,6 +2094,17 @@ errlHndl_t FsiDD::initPort(FsiChipInfo_t i_fsiInfo, // No support for slave cascades so we're done o_enabled = true; + + //Reset the port to clear up any previous error state + // (using idec reg as arbitrary address for lookups) + //Note, initial cfam reset should have cleaned up everything + // but this makes sure we're in a consistent state + FsiAddrInfo_t addr_info( i_fsiInfo.slave, 0x1028 ); + l_err = genFullFsiAddr( addr_info ); + if( l_err ) { break; } + l_err = errorCleanup( addr_info, FSI::RC_ERROR_IN_MAEB ); + if(l_err) { delete l_err; l_err = NULL; } + } while(0); TRACDCOMP( g_trac_fsi, EXIT_MRK"FsiDD::initPort" ); @@ -2614,7 +2643,20 @@ errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo, //(putcfam 1007) register of the previously failed FSI2PIB //engine on Centaur. data = 0xFFFFFFFF; - l_err = write( i_addrInfo.fsiTarg,FSI:: FSI2PIB_STATUS, &data ); + l_err = write( i_addrInfo.fsiTarg, FSI::FSI2PIB_STATUS, &data ); + if(l_err) break; + + //Need to save/restore the true/comp masks or the FSP will + // get annoyed + uint32_t compmask = 0; + l_err = read( i_addrInfo.fsiTarg, + FSI::FSI2PIB_COMPMASK, + &compmask ); + if(l_err) break; + uint32_t truemask = 0; + l_err = read( i_addrInfo.fsiTarg, + FSI::FSI2PIB_TRUEMASK, + &truemask ); if(l_err) break; //then, write arbitrary data to 1018 (putcfam 1006) to @@ -2634,6 +2676,23 @@ errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo, if(l_err) break; } + //Restore the true/comp masks + l_err = write( i_addrInfo.fsiTarg, + FSI::FSI2PIB_COMPMASK, + &compmask ); + if(l_err) break; + l_err = write( i_addrInfo.fsiTarg, + FSI::FSI2PIB_TRUEMASK, + &truemask ); + if(l_err) break; + + if( iv_ffdcTask == 0 ) + { + //skip the extra FFDC if we aren't in the middle of + // handling an error + break; + } + //Trace some values for FFDC in case this cleanup // didn't really work uint32_t grabregs[] = { |