diff options
author | Caleb Palmer <cnpalmer@us.ibm.com> | 2018-04-27 14:20:47 -0500 |
---|---|---|
committer | Zane C. Shelley <zshelle@us.ibm.com> | 2018-05-23 15:11:48 -0400 |
commit | 67499d6a3e8747725083398348f655dedc86b552 (patch) | |
tree | b3b291720e4d7bc65e6f03f7bdd5aa128d29a44e /src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C | |
parent | 7ff47d2af40b0321d5391956d99d402e8993f5b6 (diff) | |
download | talos-hostboot-67499d6a3e8747725083398348f655dedc86b552.tar.gz talos-hostboot-67499d6a3e8747725083398348f655dedc86b552.zip |
PRD: Runtime VCM support for Centaur
Change-Id: I0dc0361b4d258961e23ff43098261a47feb52834
RTC: 191847
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/58458
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59235
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: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C')
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C | 170 |
1 files changed, 160 insertions, 10 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C index b7cb13653..122c54367 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C @@ -29,6 +29,8 @@ #include <prdfMemDqBitmap.H> #include <prdfMemVcm.H> #include <prdfP9McaDataBundle.H> +#include <prdfCenMbaDataBundle.H> +#include <prdfCenMbaExtraSig.H> using namespace TARGETING; @@ -55,9 +57,7 @@ VcmFalseAlarm * __getFalseAlarmCounter<TYPE_MCA>( ExtensibleChip * i_chip ) template<> VcmFalseAlarm * __getFalseAlarmCounter<TYPE_MBA>( ExtensibleChip * i_chip ) { - // TODO: RTC 157888 - //return getMbaDataBundle(i_chip)->getVcmFalseAlarmCounter(); - return nullptr; + return getMbaDataBundle(i_chip)->getVcmFalseAlarmCounter(); } //############################################################################## @@ -232,12 +232,26 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd() if ( TD_PHASE_2 == iv_phase ) stopCond |= mss_MaintCmd::STOP_ON_MCE; - // Start the time based scrub procedure on this master rank. - o_rc = startTdScrub<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK, stopCond ); - if ( SUCCESS != o_rc ) + if ( iv_canResumeScrub ) { - PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed", - iv_chip->getHuid(), getKey() ); + // Resume the command from the next address to the end of this master + // rank. + o_rc = resumeTdScrub<TYPE_MBA>( iv_chip, MASTER_RANK, stopCond ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "resumeTdScrub(0x%08x) failed", + iv_chip->getHuid() ); + } + } + else + { + // Start the time based scrub procedure on this master rank. + o_rc = startTdScrub<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK, stopCond); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed", + iv_chip->getHuid(), getKey() ); + } } return o_rc; @@ -248,6 +262,48 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd() //------------------------------------------------------------------------------ template<> +uint32_t VcmEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc ) +{ + uint32_t signature = 0; + + if ( iv_canResumeScrub ) + { + signature = PRDFSIG_VcmResume; + + PRDF_TRAC( "[VcmEvent] Resuming VCM Phase %d: 0x%08x,0x%02x", + iv_phase, iv_chip->getHuid(), getKey() ); + } + else + { + switch ( iv_phase ) + { + case TD_PHASE_0: + iv_phase = TD_PHASE_1; + signature = PRDFSIG_StartVcmPhase1; + break; + + case TD_PHASE_1: + iv_phase = TD_PHASE_2; + signature = PRDFSIG_StartVcmPhase2; + break; + + default: PRDF_ASSERT( false ); // invalid phase + } + + PRDF_TRAC( "[VcmEvent] Starting VCM Phase %d: 0x%08x,0x%02x", + iv_phase, iv_chip->getHuid(), getKey() ); + } + + io_sc.service_data->AddSignatureList( iv_chip->getTrgt(), signature ); + + return startCmd(); + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns, STEP_CODE_DATA_STRUCT & io_sc, bool & o_done ) @@ -277,10 +333,8 @@ uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns, break; } - /* TODO: RTC 157888 o_rc = MemEcc::handleMemUe<TYPE_MBA>( iv_chip, addr, UE_TABLE::SCRUB_UE, io_sc ); - */ if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "handleMemUe(0x%08x,0x%02x) failed", @@ -313,6 +367,102 @@ uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns, #undef PRDF_FUNC } +//------------------------------------------------------------------------------ + +template<> +uint32_t VcmEvent<TYPE_MBA>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc, + bool & o_done ) +{ + #define PRDF_FUNC "[VcmEvent::analyzePhase] " + + uint32_t o_rc = SUCCESS; + + do + { + if ( TD_PHASE_0 == iv_phase ) break; // Nothing to analyze yet. + + // Look for any ECC errors that occurred during the command. + uint32_t eccAttns; + o_rc = checkEccFirs<TYPE_MBA>( iv_chip, eccAttns ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "checkEccFirs(0x%08x) failed", + iv_chip->getHuid() ); + break; + } + + // Analyze the ECC errors, if needed. + o_rc = checkEcc( eccAttns, io_sc, o_done ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "checkEcc() failed on 0x%08x", + iv_chip->getHuid() ); + break; + } + + if ( o_done ) break; // abort the procedure. + + // Determine if the command stopped on the last address. + bool lastAddr = false; + o_rc = didCmdStopOnLastAddr<TYPE_MBA>( iv_chip, MASTER_RANK, lastAddr ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "didCmdStopOnLastAddr(0x%08x) failed", + iv_chip->getHuid() ); + break; + } + + // It is important to initialize iv_canResumeScrub here, so that we will + // know to resume the current phase in startNextPhase() instead of + // starting phase. + iv_canResumeScrub = !lastAddr; + + if ( TD_PHASE_2 == iv_phase ) + { + if ( eccAttns & MAINT_MCE ) + { + // The chip mark has been verified. + o_rc = verified( io_sc ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "verified() failed on 0x%08x", + iv_chip->getHuid() ); + break; + } + + // Procedure is complete. + o_done = true; + } + else if ( !iv_canResumeScrub ) + { + // The chip mark is not verified and the command has reached the + // end of the rank. So this is a false alarm. + o_rc = falseAlarm( io_sc ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "falseAlarm() failed on 0x%08x", + iv_chip->getHuid() ); + break; + } + + // Procedure is complete. + o_done = true; + } + } + + } while (0); + + if ( (SUCCESS == o_rc) && o_done ) + { + // Clear the ECC FFDC for this master rank. + MemDbUtils::resetEccFfdc<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK ); + } + + return o_rc; + + #undef PRDF_FUNC +} + //############################################################################## // // Generic template functions |