int32_t checkMcsChannelFail( ExtensibleChip * i_mcsChip, STEP_CODE_DATA_STRUCT & io_sc ) { #define PRDF_FUNC "[MemUtils::checkMcsChannelFail] " int32_t o_rc = SUCCESS; do { // Skip if already handling unit checkstop. if ( io_sc.service_data->GetFlag(ServiceDataCollector::UNIT_CS) ) break; // Must be an MCS. if ( TYPE_MCS != getTargetType(i_mcsChip->GetChipHandle()) ) { PRDF_ERR( PRDF_FUNC "i_mcsChip is not TYPE_MCS" ); o_rc = FAIL; break; } // Check MCIFIR[31] for presence of channel fail. SCAN_COMM_REGISTER_CLASS * mcifir = i_mcsChip->getRegister("MCIFIR"); o_rc = mcifir->Read(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "Read() failed on MCIFIR" ); break; } if ( !mcifir->IsBitSet(31) ) break; // No channel fail, so exit. // Set unit checkstop flag and cause attention type. io_sc.service_data->SetFlag(ServiceDataCollector::UNIT_CS); io_sc.service_data->setSecondaryAttnType(UNIT_CS); io_sc.service_data->SetThresholdMaskId(0); // Indicate that cleanup is required. P8McsDataBundle * mcsdb = getMcsDataBundle( i_mcsChip ); ExtensibleChip * membChip = mcsdb->getMembChip(); if ( NULL == membChip ) { PRDF_ERR( PRDF_FUNC "getMembChip() returned NULL" ); o_rc = FAIL; break; } CenMembufDataBundle * mbdb = getMembufDataBundle( membChip ); mbdb->iv_doChnlFailCleanup = true; } while (0); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "Failed: i_mcsChip=0x%08x", i_mcsChip->GetId() ); } return o_rc; #undef PRDF_FUNC }
/** * @brief Handles Max Spares Exceeded attentions on the MCS. * * This function will first check for channel fail conditions on the MCS side of * the bus, handle the attention, then do channel fail cleanup if needed. It * would be preferred that the channel fail handling would be done in a more * generic way, like it is done on the MCS and MEMBUF pre/post analysis * functions. Unfortunately, the IOMCFIRs are not on the MCS chiplet, which * complicates things. Fortunately, the only attentions on the IOMCFIRs that are * hardwired to channel fail are the Max Spares Exceeded attentions. Therefore, * we can deal with the channel fail handling within this attention. * * @param i_procChip A PROC chip. * @param i_sc The step code data struct. * @param i_mcsPos The MCS position. * @return SUCCESS always. */ int32_t maxSparesExceeded_MCS( ExtensibleChip * i_procChip, STEP_CODE_DATA_STRUCT & i_sc, uint32_t i_mcsPos ) { #define PRDF_FUNC "[Proc::maxSparesExceeded_MCS] " int32_t l_rc = SUCCESS; TargetHandle_t procTrgt = i_procChip->GetChipHandle(); TargetHandle_t mcsTrgt = NULL; ExtensibleChip * mcsChip = NULL; ExtensibleChip * membChip = NULL; do { // Get the connected MCS chip mcsTrgt = getConnectedChild( procTrgt, TYPE_MCS, i_mcsPos ); if ( NULL == mcsTrgt ) { PRDF_ERR( PRDF_FUNC"getConnectedChild() returned NULL" ); l_rc = FAIL; break; } mcsChip = (ExtensibleChip *)systemPtr->GetChip( mcsTrgt ); if ( NULL == mcsChip ) { PRDF_ERR( PRDF_FUNC"GetChip() returned NULL" ); l_rc = FAIL; break; } // Check for channel fails on the MCS side of this bus. l_rc = MemUtils::checkMcsChannelFail( mcsChip, i_sc ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"checkMcsChannelFail() failed" ); break; } // Do additional bus analysis. l_rc = handleLaneRepairEvent( i_procChip, TYPE_MCS, i_mcsPos, i_sc, false ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"handleLaneRepairEvent() failed" ); break; } // Get the connected MEMBUF chip. P8McsDataBundle * mcsdb = getMcsDataBundle( mcsChip ); membChip = mcsdb->getMembChip(); if ( NULL == membChip ) { PRDF_ERR( PRDF_FUNC"getMembChip() returned NULL" ); l_rc = FAIL; break; } // Do channel fail cleanup. l_rc = MemUtils::chnlCsCleanup( membChip, i_sc ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"chnlCsCleanup() failed" ); break; } } while (0); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"Failed: i_procChip=0x%08x i_mcsPos=%d", i_procChip->GetId(), i_mcsPos ); CalloutUtil::defaultError( i_sc ); } return SUCCESS; // Always return SUCCESS #undef PRDF_FUNC }