int32_t CenMbaTdCtlrCommon::setRtEteThresholds() { #define PRDF_FUNC "[CenMbaTdCtlrCommon::setRtEteThresholds] " int32_t o_rc = SUCCESS; do { const char * reg_str = (0 == iv_mbaPos) ? "MBA0_MBSTR" : "MBA1_MBSTR"; SCAN_COMM_REGISTER_CLASS * mbstr = iv_membChip->getRegister( reg_str ); // MBSTR's content could be modified from cleanupCmd() // so we need to refresh o_rc = mbstr->ForceRead(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "ForceRead() failed on %s", reg_str ); break; } uint16_t softIntCe = 0; o_rc = getScrubCeThreshold( iv_mbaChip, iv_rank, softIntCe ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "getScrubCeThreshold() failed." ); break; } // Only care about retry CEs if there are a lot of them. So the // threshold will be high in the field. However, in MNFG the retry CEs // will be handled differently by putting every occurrence in the RCE // table and doing targeted diagnostics when needed. uint16_t retryCe = mfgMode() ? 1 : 2047; uint16_t hardCe = 1; // Always stop on first occurrence. mbstr->SetBitFieldJustified( 4, 12, softIntCe ); mbstr->SetBitFieldJustified( 16, 12, softIntCe ); mbstr->SetBitFieldJustified( 28, 12, hardCe ); mbstr->SetBitFieldJustified( 40, 12, retryCe ); // Set the per symbol counters to count hard CEs only. This is so that // when the scrub stops on the first hard CE, we can use the per symbol // counters to tell us which symbol reported the hard CE. mbstr->SetBitFieldJustified( 55, 3, 0x1 ); o_rc = mbstr->Write(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str ); break; } } while(0); return o_rc; #undef PRDF_FUNC }
int32_t chnlCsCleanup( ExtensibleChip *i_mbChip, STEP_CODE_DATA_STRUCT & i_sc ) { #define PRDF_FUNC "[MemUtils::chnlCsCleanup] " int32_t o_rc = SUCCESS; do { if( ( NULL == i_mbChip ) || ( TYPE_MEMBUF != getTargetType( i_mbChip->GetChipHandle() ))) { PRDF_ERR( PRDF_FUNC "Invalid parameters" ); o_rc = FAIL; break; } if (( ! i_sc.service_data->IsUnitCS() ) || (CHECK_STOP == i_sc.service_data->getPrimaryAttnType()) ) break; CenMembufDataBundle * mbdb = getMembufDataBundle( i_mbChip ); if ( !mbdb->iv_doChnlFailCleanup ) break; // Cleanup has already been done. // Set it as SUE generation point. i_sc.service_data->SetFlag( ServiceDataCollector::UERE ); ExtensibleChip * mcsChip = mbdb->getMcsChip(); if ( NULL == mcsChip ) { PRDF_ERR( PRDF_FUNC "MCS chip is NULL for Membuf:0x%08X", i_mbChip->GetId() ); o_rc = FAIL; break; } TargetHandle_t mcs = mcsChip->GetChipHandle(); ExtensibleChip * procChip = NULL; uint8_t pos = getTargetPosition( mcs ); TargetHandle_t proc = getParentChip ( mcs ); if ( NULL == proc ) { PRDF_ERR( PRDF_FUNC "Proc is NULL for Mcs:0x%08X", getHuid( mcs ) ); o_rc = FAIL; break; } procChip = (ExtensibleChip *)systemPtr->GetChip( proc ); if( NULL == procChip ) { PRDF_ERR( PRDF_FUNC "Can not find Proc chip for HUID:0x%08X", getHuid( proc) ); o_rc = FAIL; break; } // This is a cleanup function. If we get any error from scom // operations, we will still continue with cleanup. SCAN_COMM_REGISTER_CLASS * l_tpMask = procChip->getRegister("TP_CHIPLET_FIR_MASK"); o_rc |= l_tpMask->Read(); if ( SUCCESS == o_rc ) { // Bits 5-12 maps to attentions from MCS0-MCS7. l_tpMask->SetBit( 5 + pos ); o_rc |= l_tpMask->Write(); } // Mask attentions from the Centaur const char *iomcFirMask = ( pos < 4 )? "IOMCFIR_0_MASK_OR":"IOMCFIR_1_MASK_OR"; SCAN_COMM_REGISTER_CLASS * iomcMask = procChip->getRegister( iomcFirMask); if ( pos >= 4 ) pos -= 4; // 8 bits are reserved for each Centaur in IOMCFIR. // There are total 4 ( for P system ) centaur supported // in MCS. Bits for first centaur starts from bit 8. iomcMask->SetBitFieldJustified( 8+ ( pos*8 ), 8, 0xff); o_rc |= iomcMask->Write(); SCAN_COMM_REGISTER_CLASS * l_tpfirmask = NULL; SCAN_COMM_REGISTER_CLASS * l_nestfirmask = NULL; SCAN_COMM_REGISTER_CLASS * l_memfirmask = NULL; SCAN_COMM_REGISTER_CLASS * l_memspamask = NULL; l_tpfirmask = i_mbChip->getRegister("TP_CHIPLET_FIR_MASK"); l_nestfirmask = i_mbChip->getRegister("NEST_CHIPLET_FIR_MASK"); l_memfirmask = i_mbChip->getRegister("MEM_CHIPLET_FIR_MASK"); l_memspamask = i_mbChip->getRegister("MEM_CHIPLET_SPA_MASK"); l_tpfirmask->setAllBits(); o_rc |= l_tpfirmask->Write(); l_nestfirmask->setAllBits(); o_rc |= l_nestfirmask->Write(); l_memfirmask->setAllBits(); o_rc |= l_memfirmask->Write(); l_memspamask->setAllBits(); o_rc |= l_memspamask->Write(); for ( uint32_t i = 0; i < MAX_MBA_PER_MEMBUF; i++ ) { ExtensibleChip * mbaChip = mbdb->getMbaChip( i ); if( NULL != mbaChip ) { TargetHandle_t mba = mbaChip->GetChipHandle(); if ( NULL != mba ) { #if defined(__HOSTBOOT_MODULE) && \ !defined(__HOSTBOOT_RUNTIME) // This is very small platform specific code. So not // creating a separate file for this. int32_t l_rc = mdiaSendEventMsg( mba, MDIA::SKIP_MBA ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC "mdiaSendEventMsg(0x%08x, SKIP_MBA) " "failed", getHuid( mba ) ); o_rc |= l_rc; } #else int32_t l_rc = DEALLOC::mbaGard( mbaChip ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC "mbaGard failed. HUID: 0x%08x", getHuid( mba ) ); o_rc |= l_rc; } #endif // __HOSTBOOT_MODULE } } } // Clean up complete an is no longer required. mbdb->iv_doChnlFailCleanup = false; } while(0); return o_rc; #undef PRDF_FUNC }
int32_t CenMbaTdCtlrCommon::prepareNextCmd( bool i_clearStats ) { #define PRDF_FUNC "[CenMbaTdCtlrCommon::prepareNextCmd] " int32_t o_rc = SUCCESS; do { //---------------------------------------------------------------------- // Clean up previous command //---------------------------------------------------------------------- o_rc = cleanupPrevCmd(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "cleanupPrevCmd() failed" ); break; } //---------------------------------------------------------------------- // Clear ECC counters //---------------------------------------------------------------------- const char * reg_str = NULL; if ( i_clearStats ) { reg_str = (0 == iv_mbaPos) ? "MBA0_MBSTR" : "MBA1_MBSTR"; SCAN_COMM_REGISTER_CLASS * mbstr = iv_membChip->getRegister( reg_str ); // MBSTR's content could be modified from cleanupCmd() // so we need to refresh o_rc = mbstr->ForceRead(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "ForceRead() failed on %s", reg_str ); break; } mbstr->SetBit(53); // Setting this bit clears all counters. o_rc = mbstr->Write(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str ); break; } // Hardware automatically clears bit 53, so flush this register out // of the register cache to avoid clearing the counters again with // a write from the out-of-date cached copy. RegDataCache & cache = RegDataCache::getCachedRegisters(); cache.flush( iv_membChip, mbstr ); } //---------------------------------------------------------------------- // Clear ECC FIRs //---------------------------------------------------------------------- reg_str = (0 == iv_mbaPos) ? "MBA0_MBSECCFIR_AND" : "MBA1_MBSECCFIR_AND"; SCAN_COMM_REGISTER_CLASS * firand = iv_membChip->getRegister( reg_str ); firand->setAllBits(); // Clear all scrub MPE bits. // This will need to be done when starting a TD procedure or background // scrubbing. iv_rank may not be set when starting background scrubbing // and technically there should only be one of these MPE bits on at a // time so we should not have to worry about losing an attention by // clearing them all. firand->SetBitFieldJustified( 20, 8, 0 ); // Clear scrub NCE, SCE, MCE, RCE, SUE, UE bits (36-41) firand->SetBitFieldJustified( 36, 6, 0 ); o_rc = firand->Write(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str ); break; } SCAN_COMM_REGISTER_CLASS * spaAnd = iv_mbaChip->getRegister("MBASPA_AND"); spaAnd->setAllBits(); // Clear threshold exceeded attentions spaAnd->SetBitFieldJustified( 1, 4, 0 ); o_rc = spaAnd->Write(); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "Write() failed on MBASPA_AND" ); break; } } while (0); return o_rc; #undef PRDF_FUNC }