diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2018-04-04 15:38:45 -0500 |
---|---|---|
committer | Zane C. Shelley <zshelle@us.ibm.com> | 2018-04-10 11:09:00 -0400 |
commit | 2000b276f2ea60bcfefb212d05015b2968dcb272 (patch) | |
tree | 1a02c64403d539844c6b41f73cfa95450d1c4f17 | |
parent | da885e721ccc39547b0a29f3350d1b9ae035f6db (diff) | |
download | talos-hostboot-2000b276f2ea60bcfefb212d05015b2968dcb272.tar.gz talos-hostboot-2000b276f2ea60bcfefb212d05015b2968dcb272.zip |
PRD: VCM/TPS/BG scrub commands support for MBA
Change-Id: If68765fc01cfe4d56a24ca41b39e875205a485b0
RTC: 190428
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56772
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com>
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56893
CI-Ready: Zane C. Shelley <zshelle@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: Zane C. Shelley <zshelle@us.ibm.com>
-rw-r--r-- | src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C | 51 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C | 65 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.H | 12 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.C | 274 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.H | 10 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices.C | 99 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices_ipl.C | 310 |
7 files changed, 460 insertions, 361 deletions
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C index cc5d59966..02e6c0fd9 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2017 */ +/* Contributors Listed Below - COPYRIGHT 2013,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -625,56 +625,13 @@ int32_t CenMbaTdCtlrCommon::handleMCE_DSD2( STEP_CODE_DATA_STRUCT & io_sc ) 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; - } - - uint32_t softIntCe = getScrubCeThreshold( iv_mbaChip, iv_rank ); - - // 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); + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Moved to setBgScrubThresholds() in prdfMemScrubUtils.C + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! return o_rc; - - #undef PRDF_FUNC } //------------------------------------------------------------------------------ diff --git a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C index 5e1efccc8..3b6700922 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,6 +38,9 @@ #include <prdfRegisterCache.H> #include <lib/mcbist/memdiags.H> +// Platform includes +#include <prdfMemThresholds.H> + using namespace TARGETING; namespace PRDF @@ -473,5 +476,65 @@ uint32_t isBgScrubConfig<TYPE_MBA>( ExtensibleChip * i_chip, //------------------------------------------------------------------------------ +template<> +uint32_t setBgScrubThresholds<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank ) +{ + #define PRDF_FUNC "[setBgScrubThresholds] " + + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); + + uint32_t o_rc = SUCCESS; + + do + { + ExtensibleChip * membChip = getConnectedParent( i_chip, TYPE_MEMBUF ); + const char * reg_str = (0 == i_chip->getPos()) ? "MBA0_MBSTR" + : "MBA1_MBSTR"; + SCAN_COMM_REGISTER_CLASS * mbstr = membChip->getRegister( reg_str ); + o_rc = mbstr->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on %s", reg_str ); + break; + } + + uint32_t softIntCe = getScrubCeThreshold<TYPE_MBA>( i_chip, i_rank ); + + // 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 +} + +//------------------------------------------------------------------------------ + } // end namespace PRDF diff --git a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.H b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.H index c81c6b4a7..3fbc4a895 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.H +++ b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -152,6 +152,16 @@ uint32_t checkEccFirs( ExtensibleChip * i_chip, uint32_t & o_eccAttns ); template<TARGETING::TYPE T> uint32_t isBgScrubConfig( ExtensibleChip * i_chip, bool & o_isBgScrub ); +/** + * @brief Sets the ETE thresholds needed for background scrubbing. + * @param i_chip An MBA. + * @param i_rank A rank on the target DIMM. + * @return Non-SUCCESS on SCOM failures, SUCCESS otherwise. + */ +template<TARGETING::TYPE T> +uint32_t setBgScrubThresholds( ExtensibleChip * i_chip, + const MemRank & i_rank ); + } //end namespace PRDF #endif // __prdfMemScrubUtils_H diff --git a/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.C b/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.C index ba33de77c..bbaadfd1a 100644 --- a/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.C +++ b/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* Contributors Listed Below - COPYRIGHT 2014,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -243,75 +243,9 @@ int32_t CenMbaTdCtlr::startInitialBgScrub() break; } - // Cleanup hardware before starting the maintenance command. This will - // clear the ECC counters, which must be done before setting the ETE - // thresholds. - o_rc = prepareNextCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "prepareNextCmd() failed" ); - break; - } - - // Set the default thresholds for all ETE attentions. - o_rc = setRtEteThresholds(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "setRtEteThresholds() failed" ); - break; - } - - // Need the first rank in memory. - CenAddr startAddr, junk; - o_rc = getMemAddrRange( iv_mbaTrgt, startAddr, junk ); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "getMemAddrRange() failed" ); - break; - } - - mss_MaintCmd::TimeBaseSpeed cmdSpeed = enableFastBgScrub() - ? mss_MaintCmd::FAST_MED_BW_IMPACT - : mss_MaintCmd::FAST_MIN_BW_IMPACT; - - uint32_t stopCond = COND_FAST_SCRUB; - - // TODO: RTC 123338: There are some OpenPOWER companies that do not want - // to run with HBRT PRD enabled. Currently the only option right - // now is to use the compile flag. Eventually, we may want to add - // this as MRW/BIOS option. - #ifndef CONFIG_HBRT_PRD - - // HBRT PRD is not enabled. Check if this system has an FSP. - if ( !isSpConfigFsp() ) - { - // No runtime PRD will be present. Do not start the initial fast - // scrub. Instead, simply start continuous background scrubbing with - // no stop-on-error conditions. - cmdSpeed = enableFastBgScrub() ? mss_MaintCmd::FAST_MED_BW_IMPACT - : mss_MaintCmd::BG_SCRUB; - stopCond = 0; - } - - #endif // ifdef CONFIG_HBRT_PRD - - // Start the initial fast scrub. - iv_mssCmd = createMssCmd( mss_MaintCmdWrapper::TIMEBASE_SCRUB, - iv_mbaTrgt, startAddr.getRank(), - stopCond, cmdSpeed, - mss_MaintCmdWrapper::END_OF_MEMORY ); - if ( NULL == iv_mssCmd ) - { - PRDF_ERR( PRDF_FUNC "createMssCmd() failed" ); - o_rc = FAIL; break; - } - - o_rc = iv_mssCmd->setupAndExecuteCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() failed" ); - break; - } + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Moved to startBgScrub() in prdfPlatServices.C + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } while (0); @@ -322,10 +256,6 @@ int32_t CenMbaTdCtlr::startInitialBgScrub() PRDF_ERR( PRDF_FUNC "iv_mbaChip:0x%08x iv_initialized:%c", iv_mbaChip->GetId(), iv_initialized ? 'T' : 'F' ); - - int32_t l_rc = cleanupPrevCmd(); // Just in case. - if ( SUCCESS != l_rc ) - PRDF_ERR( PRDF_FUNC "cleanupPrevCmd() failed" ); } return o_rc; @@ -880,32 +810,9 @@ int32_t CenMbaTdCtlr::startVcmPhase1( STEP_CODE_DATA_STRUCT & io_sc ) io_sc.service_data->AddSignatureList( iv_mbaTrgt, PRDFSIG_StartVcmPhase1 ); iv_tdState = VCM_PHASE_1; - do - { - o_rc = prepareNextCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "prepareNextCmd() failed" ); - break; - } - - // Start phase 1. - iv_mssCmd = createMssCmd( mss_MaintCmdWrapper::TIMEBASE_STEER_CLEANUP, - iv_mbaTrgt, iv_rank, COND_TARGETED_CMD ); - if ( NULL == iv_mssCmd ) - { - PRDF_ERR( PRDF_FUNC "createMssCmd() failed"); - o_rc = FAIL; break; - } - - o_rc = iv_mssCmd->setupAndExecuteCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() failed" ); - break; - } - - } while(0); + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Moved to startVcmPhase1() in prdfPlatServices_ipl.C + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! return o_rc; @@ -923,32 +830,9 @@ int32_t CenMbaTdCtlr::startVcmPhase2( STEP_CODE_DATA_STRUCT & io_sc ) io_sc.service_data->AddSignatureList( iv_mbaTrgt, PRDFSIG_StartVcmPhase2 ); iv_tdState = VCM_PHASE_2; - do - { - o_rc = prepareNextCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "prepareNextCmd() failed" ); - break; - } - - // Start phase 2. - iv_mssCmd = createMssCmd( mss_MaintCmdWrapper::SUPERFAST_READ, - iv_mbaTrgt, iv_rank, COND_TARGETED_CMD ); - if ( NULL == iv_mssCmd ) - { - PRDF_ERR( PRDF_FUNC "createMssCmd() failed"); - o_rc = FAIL; break; - } - - o_rc = iv_mssCmd->setupAndExecuteCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() failed" ); - break; - } - - } while(0); + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Moved to startVcmPhase2() in prdfPlatServices_ipl.C + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! return o_rc; @@ -1061,43 +945,9 @@ int32_t CenMbaTdCtlr::startTpsPhase1( STEP_CODE_DATA_STRUCT & io_sc ) io_sc.service_data->AddSignatureList( iv_mbaTrgt, PRDFSIG_StartTpsPhase1 ); iv_tdState = TPS_PHASE_1; - do - { - o_rc = prepareNextCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "prepareNextCmd() failed" ); - break; - } - - // We are using current state as input parameter in mnfgCeSetup. - // So it is mandatory to set iv_tdState before calling this function. - o_rc = mnfgCeSetup(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "mnfgCeSetup() failed" ); - break; - } - - // Start phase 1. - iv_mssCmd = createMssCmd( mss_MaintCmdWrapper::TIMEBASE_SCRUB, - iv_mbaTrgt, iv_rank, COND_TARGETED_CMD, - mss_MaintCmd::FAST_MAX_BW_IMPACT, - mss_MaintCmdWrapper::SLAVE_RANK_ONLY ); - if ( NULL == iv_mssCmd ) - { - PRDF_ERR( PRDF_FUNC "createMssCmd() failed"); - o_rc = FAIL; break; - } - - o_rc = iv_mssCmd->setupAndExecuteCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() failed" ); - break; - } - - } while(0); + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Moved to startTpsPhase1() in prdfPlatServices_ipl.C + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! return o_rc; @@ -1115,43 +965,9 @@ int32_t CenMbaTdCtlr::startTpsPhase2( STEP_CODE_DATA_STRUCT & io_sc ) io_sc.service_data->AddSignatureList( iv_mbaTrgt, PRDFSIG_StartTpsPhase2 ); iv_tdState = TPS_PHASE_2; - do - { - o_rc = prepareNextCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "prepareNextCmd() failed" ); - break; - } - - // We are using current state as input parameter in mnfgCeSetup. - // So it is mandatory to set iv_tdState before calling this function. - o_rc = mnfgCeSetup(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "mnfgCeSetup() failed" ); - break; - } - - // Start phase 2. - iv_mssCmd = createMssCmd( mss_MaintCmdWrapper::TIMEBASE_SCRUB, - iv_mbaTrgt, iv_rank, COND_TARGETED_CMD, - mss_MaintCmd::FAST_MAX_BW_IMPACT, - mss_MaintCmdWrapper::SLAVE_RANK_ONLY ); - if ( NULL == iv_mssCmd ) - { - PRDF_ERR( PRDF_FUNC "createMssCmd() failed"); - o_rc = FAIL; break; - } - - o_rc = iv_mssCmd->setupAndExecuteCmd(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() failed" ); - break; - } - - } while(0); + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Moved to startTpsPhase2() in prdfPlatServices_ipl.C + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! return o_rc; @@ -1405,63 +1221,5 @@ int32_t CenMbaTdCtlr::signalMdiaCmdComplete() #undef PRDF_FUNC } -//------------------------------------------------------------------------------ - -// Do the setup for mnfg IPL CE -int32_t CenMbaTdCtlr::mnfgCeSetup() -{ - #define PRDF_FUNC "[CenMbaTdCtlr::mnfgCeSetup] " - - 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 "Read() failed on %s", reg_str ); - break; - } - - if ( TPS_PHASE_1 == iv_tdState ) - { - // Enable per-symbol error counters to count soft CEs - mbstr->SetBit(55); - mbstr->SetBit(56); - // Disable per-symbol error counters to count hard CEs - mbstr->ClearBit(57); - } - else if ( TPS_PHASE_2 == iv_tdState ) - { - // Disable per-symbol error counters to count soft CEs - mbstr->ClearBit(55); - mbstr->ClearBit(56); - // Enable per-symbol error counters to count hard CEs - mbstr->SetBit(57); - } - else - { - PRDF_ERR( PRDF_FUNC "Inavlid State:%u", iv_tdState ); - o_rc = FAIL; break; - } - - 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 -} - } // end namespace PRDF diff --git a/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.H b/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.H index 790c80e32..4e49b2024 100644 --- a/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.H +++ b/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -147,14 +147,6 @@ class CenMbaTdCtlr : public CenMbaTdCtlrCommon */ int32_t signalMdiaCmdComplete(); - /** - * @brief Does mnfg setup for CE threshold. - * @note Before calling this function, set current state to new - * value (TPS_PHASE_1/ TPS_PHASE_2). - * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. - */ - int32_t mnfgCeSetup(); - private: // instance variables /** Array of functions pointers for TD controller states. This is used to diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C index ed81bd376..6e9c45c0c 100644 --- a/src/usr/diag/prdf/plat/prdfPlatServices.C +++ b/src/usr/diag/prdf/plat/prdfPlatServices.C @@ -574,13 +574,13 @@ uint32_t startBgScrub<TYPE_MCA>( ExtensibleChip * i_mcaChip, // Start the background scrub command. errlHndl_t errl = nullptr; - FAPI_INVOKE_HWP( errl, mss::memdiags::background_scrub, fapiTrgt, stopCond, - scrubSpeed, saddr ); + FAPI_INVOKE_HWP( errl, mss::memdiags::background_scrub, fapiTrgt, + stopCond, scrubSpeed, saddr ); if ( nullptr != errl ) { - PRDF_ERR( PRDF_FUNC "mss::memdiags::background_scrub(0x%08x,%d) failed", - mcbChip->getHuid(), i_rank.getMaster() ); + PRDF_ERR( PRDF_FUNC "mss::memdiags::background_scrub(0x%08x,%d) " + "failed", mcbChip->getHuid(), i_rank.getMaster() ); PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); o_rc = FAIL; break; } @@ -755,29 +755,84 @@ uint32_t startTpsRuntime<TYPE_MCA>( ExtensibleChip * i_mcaChip, //############################################################################## template<> -uint32_t startBgScrub<TYPE_MBA>( ExtensibleChip * i_mbaChip, +uint32_t startBgScrub<TYPE_MBA>( ExtensibleChip * i_chip, const MemRank & i_rank ) { #define PRDF_FUNC "[PlatServices::startBgScrub<TYPE_MBA>] " - PRDF_ASSERT( nullptr != i_mbaChip ); - PRDF_ASSERT( TYPE_MBA == i_mbaChip->getType() ); + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); uint32_t o_rc = SUCCESS; + // Get the MBA fapi target + fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() ); + + // Get the stop conditions. + // NOTE: If HBRT_PRD is not configured, we want to use the defaults so that + // background scrubbing never stops. + uint32_t stopCond = mss_MaintCmd::NO_STOP_CONDITIONS; + + #ifdef CONFIG_HBRT_PRD + + stopCond = mss_MaintCmd::STOP_ON_HARD_NCE_ETE | + mss_MaintCmd::STOP_ON_INT_NCE_ETE | + mss_MaintCmd::STOP_ON_SOFT_NCE_ETE | + mss_MaintCmd::STOP_ON_RETRY_CE_ETE | + mss_MaintCmd::STOP_ON_MPE | + mss_MaintCmd::STOP_ON_UE | + mss_MaintCmd::STOP_IMMEDIATE | + mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION; + + #endif + + // Get the command speed. + mss_MaintCmd::TimeBaseSpeed cmdSpeed = enableFastBgScrub() + ? mss_MaintCmd::FAST_MED_BW_IMPACT + : mss_MaintCmd::BG_SCRUB; do { + // Get the first address of the given rank. + fapi2::buffer<uint64_t> saddr, eaddr; + o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr, + SLAVE_RANK ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed", + i_chip->getHuid(), i_rank.getKey() ); + break; + } + + // Set the required thresholds for background scrubbing. + o_rc = setBgScrubThresholds<TYPE_MBA>( i_chip, i_rank ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "setBgScrubThresholds(0x%08x) failed", + i_chip->getHuid() ); + break; + } + // Clear all of the counters and maintenance ECC attentions. - o_rc = prepareNextCmd<TYPE_MBA>( i_mbaChip ); + o_rc = prepareNextCmd<TYPE_MBA>( i_chip ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed", - i_mbaChip->getHuid() ); + i_chip->getHuid() ); break; } // Start the background scrub command. - PRDF_ERR( PRDF_FUNC "function not implemented yet" ); // TODO RTC 157888 + mss_TimeBaseScrub cmd { fapiTrgt, saddr, eaddr, cmdSpeed, + stopCond, false }; + errlHndl_t errl = nullptr; + FAPI_INVOKE_HWP( errl, cmd.setupAndExecuteCmd ); + if ( nullptr != errl ) + { + PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed", + i_chip->getHuid(), i_rank.getKey() ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; break; + } } while (0); @@ -789,26 +844,6 @@ uint32_t startBgScrub<TYPE_MBA>( ExtensibleChip * i_mbaChip, //------------------------------------------------------------------------------ template<> -uint32_t startTpsPhase1<TYPE_MBA>( ExtensibleChip * i_mbaChip, - const MemRank & i_rank ) -{ - PRDF_ERR( "function not implemented yet" ); // TODO RTC 157888 - return SUCCESS; -} - -//------------------------------------------------------------------------------ - -template<> -uint32_t startTpsPhase2<TYPE_MBA>( ExtensibleChip * i_mbaChip, - const MemRank & i_rank ) -{ - PRDF_ERR( "function not implemented yet" ); // TODO RTC 157888 - return SUCCESS; -} - -//------------------------------------------------------------------------------ - -template<> uint32_t startTpsRuntime<TYPE_MBA>( ExtensibleChip * i_mbaChip, const MemRank & i_rank, bool i_countAllCes ) @@ -817,7 +852,9 @@ uint32_t startTpsRuntime<TYPE_MBA>( ExtensibleChip * i_mbaChip, return SUCCESS; } -//------------------------------------------------------------------------------ +//############################################################################## +//## Core/cache trace array functions +//############################################################################## int32_t restartTraceArray(TargetHandle_t i_tgt) { diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C index f556520ea..58c6e63ce 100644 --- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C +++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C @@ -492,17 +492,64 @@ uint32_t startVcmPhase1<TYPE_MBA>( ExtensibleChip * i_chip, { #define PRDF_FUNC "[PlatServices::startVcmPhase1<TYPE_MBA>] " + PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running. + PRDF_ASSERT( nullptr != i_chip ); PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); - // TODO RTC 157888 - // - Start a targeted steer cleanup. - // - Stop on RCE ETE (threshold 1). - // - The command should always stop at the end of the master rank. + uint32_t o_rc = SUCCESS; - PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + // Get the MBA fapi target + fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() ); + + // Get the stop conditions. + uint32_t stopCond = mss_MaintCmd::STOP_ON_RETRY_CE_ETE | + mss_MaintCmd::STOP_ON_END_ADDRESS | + mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION; + + // Note that we set the stop on RCE ETE flag. This requires us to set a + // threshold in the MBSTR. Fortunately, MDIA sets the threshold for us when + // it starts the first command on this MBA. + + do + { + // Get the address range of the master rank. + fapi2::buffer<uint64_t> saddr, eaddr; + o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr, + MASTER_RANK ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed", + i_chip->getHuid(), i_rank.getKey() ); + break; + } - return SUCCESS; + // Clear all of the counters and maintenance ECC attentions. + o_rc = prepareNextCmd<TYPE_MBA>( i_chip ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed", + i_chip->getHuid() ); + break; + } + + // Start a steer cleanup command. + mss_TimeBaseSteerCleanup cmd { fapiTrgt, saddr, eaddr, + mss_MaintCmd::FAST_MAX_BW_IMPACT, + stopCond, false }; + errlHndl_t errl; + FAPI_INVOKE_HWP( errl, cmd.setupAndExecuteCmd ); + if ( nullptr != errl ) + { + PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed", + i_chip->getHuid(), i_rank.getKey() ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; break; + } + + } while (0); + + return o_rc; #undef PRDF_FUNC } @@ -515,19 +562,254 @@ uint32_t startVcmPhase2<TYPE_MBA>( ExtensibleChip * i_chip, { #define PRDF_FUNC "[PlatServices::startVcmPhase2<TYPE_MBA>] " + PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running. + PRDF_ASSERT( nullptr != i_chip ); PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); - // TODO RTC 157888 - // - Start a targeted super fast read. - // - No stop-on-error conditions. Note that RCEs will report as UEs during - // read operations. You can still set stop-on-RCE-ETE to be consistent - // with phase 1, but it will not have any effect and is not required. - // - The command should always stop at the end of the master rank. + uint32_t o_rc = SUCCESS; + + // Get the MBA fapi target + fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() ); + + // Get the stop conditions. + uint32_t stopCond = mss_MaintCmd::STOP_ON_END_ADDRESS | + mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION; + + do + { + // Get the address range of the master rank. + fapi2::buffer<uint64_t> saddr, eaddr; + o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr, + MASTER_RANK ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed", + i_chip->getHuid(), i_rank.getKey() ); + break; + } + + // Clear all of the counters and maintenance ECC attentions. + o_rc = prepareNextCmd<TYPE_MBA>( i_chip ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed", + i_chip->getHuid() ); + break; + } + + // Create the new command. Store a pointer to the command in the MBA + // data bundle so that we can call the cleanup function after the + // command has completed. + MbaDataBundle * db = getMbaDataBundle( i_chip ); + PRDF_ASSERT( nullptr == db->iv_sfCmd ); // Code bug. + db->iv_sfCmd = new mss_SuperFastRead { fapiTrgt, saddr, eaddr, + stopCond, false }; + + // Start the super fast read command. + errlHndl_t errl; + FAPI_INVOKE_HWP( errl, db->iv_sfCmd->setupAndExecuteCmd ); + if ( nullptr != errl ) + { + PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed", + i_chip->getHuid(), i_rank.getKey() ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; break; + } + + } while (0); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t startTpsPhase1<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank ) +{ + #define PRDF_FUNC "[PlatServices::startTpsPhase1<TYPE_MBA>] " + + PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running. + + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); + + uint32_t o_rc = SUCCESS; + + // Get the MBA fapi target + fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() ); + + // Get the stop conditions. + uint32_t stopCond = mss_MaintCmd::STOP_ON_RETRY_CE_ETE | + mss_MaintCmd::STOP_ON_END_ADDRESS | + mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION; - PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + // Note that we set the stop on RCE ETE flag. This requires us to set a + // threshold in the MBSTR. Fortunately, MDIA sets the threshold for us when + // it starts the first command on this MBA. - return SUCCESS; + do + { + // Set up the per-symbol counters to capture soft CEs. + ExtensibleChip * membChip = getConnectedParent( i_chip, TYPE_MEMBUF ); + const char * reg_str = (0 == i_chip->getPos()) ? "MBA0_MBSTR" + : "MBA1_MBSTR"; + SCAN_COMM_REGISTER_CLASS * mbstr = membChip->getRegister( reg_str ); + o_rc = mbstr->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on %s", reg_str ); + break; + } + + // Enable per-symbol error counters to count soft CEs + mbstr->SetBit(55); + mbstr->SetBit(56); + // Disable per-symbol error counters to count hard CEs + mbstr->ClearBit(57); + + o_rc = mbstr->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str ); + break; + } + + // Get the address range of the master rank. + fapi2::buffer<uint64_t> saddr, eaddr; + o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr, + SLAVE_RANK ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed", + i_chip->getHuid(), i_rank.getKey() ); + break; + } + + // Clear all of the counters and maintenance ECC attentions. + o_rc = prepareNextCmd<TYPE_MBA>( i_chip ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed", + i_chip->getHuid() ); + break; + } + + // Start a steer cleanup command. + mss_TimeBaseScrub cmd { fapiTrgt, saddr, eaddr, + mss_MaintCmd::FAST_MAX_BW_IMPACT, + stopCond, false }; + errlHndl_t errl; + FAPI_INVOKE_HWP( errl, cmd.setupAndExecuteCmd ); + if ( nullptr != errl ) + { + PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed", + i_chip->getHuid(), i_rank.getKey() ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; break; + } + + } while (0); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t startTpsPhase2<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank ) +{ + #define PRDF_FUNC "[PlatServices::startTpsPhase2<TYPE_MBA>] " + + PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running. + + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); + + uint32_t o_rc = SUCCESS; + + // Get the MBA fapi target + fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() ); + + // Get the stop conditions. + uint32_t stopCond = mss_MaintCmd::STOP_ON_RETRY_CE_ETE | + mss_MaintCmd::STOP_ON_END_ADDRESS | + mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION; + + // Note that we set the stop on RCE ETE flag. This requires us to set a + // threshold in the MBSTR. Fortunately, MDIA sets the threshold for us when + // it starts the first command on this MBA. + + do + { + // Set up the per-symbol counters to capture soft CEs. + ExtensibleChip * membChip = getConnectedParent( i_chip, TYPE_MEMBUF ); + const char * reg_str = (0 == i_chip->getPos()) ? "MBA0_MBSTR" + : "MBA1_MBSTR"; + SCAN_COMM_REGISTER_CLASS * mbstr = membChip->getRegister( reg_str ); + o_rc = mbstr->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on %s", reg_str ); + break; + } + + // Disable per-symbol error counters to count soft CEs + mbstr->ClearBit(55); + mbstr->ClearBit(56); + // Enable per-symbol error counters to count hard CEs + mbstr->SetBit(57); + + o_rc = mbstr->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str ); + break; + } + + // Get the address range of the master rank. + fapi2::buffer<uint64_t> saddr, eaddr; + o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr, + SLAVE_RANK ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed", + i_chip->getHuid(), i_rank.getKey() ); + break; + } + + // Clear all of the counters and maintenance ECC attentions. + o_rc = prepareNextCmd<TYPE_MBA>( i_chip ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed", + i_chip->getHuid() ); + break; + } + + // Start a steer cleanup command. + mss_TimeBaseScrub cmd { fapiTrgt, saddr, eaddr, + mss_MaintCmd::FAST_MAX_BW_IMPACT, + stopCond, false }; + errlHndl_t errl; + FAPI_INVOKE_HWP( errl, cmd.setupAndExecuteCmd ); + if ( nullptr != errl ) + { + PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed", + i_chip->getHuid(), i_rank.getKey() ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; break; + } + + } while (0); + + return o_rc; #undef PRDF_FUNC } |