diff options
-rw-r--r-- | src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C | 54 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H | 19 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H | 17 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C | 16 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTps.H | 3 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C | 139 |
6 files changed, 199 insertions, 49 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C index 23e97f0d2..b394b8408 100644 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C @@ -28,15 +28,8 @@ // Platform includes #include <prdfMemAddress.H> #include <prdfMemCaptureData.H> -#include <prdfMemMark.H> #include <prdfP9McaDataBundle.H> -#ifdef __HOSTBOOT_RUNTIME - #include <prdfMemTps.H> - #include <prdfMemVcm.H> - #include <prdfP9McbistDataBundle.H> -#endif - using namespace TARGETING; namespace PRDF @@ -94,17 +87,13 @@ void calloutMemUe<TYPE_MBA>( ExtensibleChip * i_chip, const MemRank & i_rank, //------------------------------------------------------------------------------ -#ifdef __HOSTBOOT_RUNTIME - -template<TARGETING::TYPE T> -uint32_t __addVcmEvent( ExtensibleChip * i_chip, const MemRank & i_rank, - const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc ); +#ifdef __HOSTBOOT_MODULE template<> -uint32_t __addVcmEvent<TYPE_MCA>( ExtensibleChip * i_chip, - const MemRank & i_rank, - const MemMark & i_mark, - STEP_CODE_DATA_STRUCT & io_sc ) +uint32_t addVcmEvent<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + const MemMark & i_mark, + STEP_CODE_DATA_STRUCT & io_sc ) { PRDF_ASSERT( TYPE_MCA == i_chip->getType() ); @@ -119,10 +108,10 @@ uint32_t __addVcmEvent<TYPE_MCA>( ExtensibleChip * i_chip, /* TODO: RTC 144083 template<> -uint32_t __addVcmEvent<TYPE_MBA>( ExtensibleChip * i_chip, - const MemRank & i_rank, - const MemMark & i_mark, - STEP_CODE_DATA_STRUCT & io_sc ) +uint32_t addVcmEvent<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + const MemMark & i_mark, + STEP_CODE_DATA_STRUCT & io_sc ) { PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); @@ -138,16 +127,13 @@ uint32_t __addVcmEvent<TYPE_MBA>( ExtensibleChip * i_chip, //------------------------------------------------------------------------------ -#ifdef __HOSTBOOT_RUNTIME +#ifdef __HOSTBOOT_MODULE -template<TARGETING::TYPE T> -uint32_t __addTpsEvent( ExtensibleChip * i_chip, const MemRank & i_rank, - STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps = false ); template<> -uint32_t __addTpsEvent<TYPE_MCA>( ExtensibleChip * i_chip, - const MemRank & i_rank, - STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps ) +uint32_t addTpsEvent<TYPE_MCA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps ) { PRDF_ASSERT( TYPE_MCA == i_chip->getType() ); @@ -163,9 +149,9 @@ uint32_t __addTpsEvent<TYPE_MCA>( ExtensibleChip * i_chip, /* TODO: RTC 144083 template<> -uint32_t __addTpsEvent<TYPE_MBA>( ExtensibleChip * i_chip, - const MemRank & i_rank, - STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps ) +uint32_t addTpsEvent<TYPE_MBA>( ExtensibleChip * i_chip, + const MemRank & i_rank, + STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps ) { PRDF_ASSERT( TYPE_MBA == i_chip->getType() ); @@ -243,10 +229,10 @@ uint32_t analyzeFetchMpe( ExtensibleChip * i_chip, const MemRank & i_rank, io_sc.service_data->SetCallout( mm ); // Add a VCM request to the TD queue. - o_rc = __addVcmEvent<T>( i_chip, i_rank, chipMark, io_sc ); + o_rc = addVcmEvent<T>( i_chip, i_rank, chipMark, io_sc ); if ( SUCCESS != o_rc ) { - PRDF_ERR( PRDF_FUNC "__addVcmEvent() failed: i_chip=0x%08x " + PRDF_ERR( PRDF_FUNC "addVcmEvent() failed: i_chip=0x%08x " "i_rank=%d,%d", i_chip->getHuid(), i_rank.getMaster(), i_rank.getSlave() ); break; @@ -311,10 +297,10 @@ uint32_t analyzeFetchUe( ExtensibleChip * i_chip, // Add a TPS request to the TD queue and ban any further TPS requests // for this rank. - o_rc = __addTpsEvent<T>( i_chip, rank, io_sc, true ); + o_rc = addTpsEvent<T>( i_chip, rank, io_sc, true ); if ( SUCCESS != o_rc ) { - PRDF_ERR( PRDF_FUNC "__addTpsEvent() failed: i_chip=0x%08x " + PRDF_ERR( PRDF_FUNC "addTpsEvent() failed: i_chip=0x%08x " "rank=%d,%d", i_chip->getHuid(), rank.getMaster(), rank.getSlave() ); // NOTE: We are not adding a break here because we still want to do diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H index 00dbd33e5..52240465d 100644 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H @@ -33,6 +33,13 @@ // Platform includes #include <prdfMemRank.H> #include <prdfPlatServices.H> +#include <prdfMemMark.H> + +#ifdef __HOSTBOOT_MODULE + #include <prdfMemTps.H> + #include <prdfMemVcm.H> + #include <prdfP9McbistDataBundle.H> +#endif namespace PRDF { @@ -72,6 +79,18 @@ template<TARGETING::TYPE T, typename D> uint32_t analyzeFetchUe( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc ); +#ifdef __HOSTBOOT_MODULE + +template<TARGETING::TYPE T> +uint32_t addVcmEvent( ExtensibleChip * i_chip, const MemRank & i_rank, + const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc ); + +template<TARGETING::TYPE T> +uint32_t addTpsEvent( ExtensibleChip * i_chip, const MemRank & i_rank, + STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps = false ); + +#endif + } // end namespace MemEcc } // end namespace PRDF diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H index 59cf8c5d8..e493e0c51 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H +++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H @@ -75,23 +75,25 @@ class MemTdCtlr */ uint32_t handleCmdComplete( STEP_CODE_DATA_STRUCT & io_sc ); - #ifdef __HOSTBOOT_RUNTIME /** * @brief Adds a new TD procedure to the queue. * - * This is only supported during runtime. It is used to process TD requests - * during analysis of attentions other than the command complete attention - * (i.e. memory CEs and UEs). If there isn't a current TD procedure in - * progress, this function will stop background scrubbing and start this new - * procedure. Otherwise, this new procedure is simply added to the queue. + * During runtime, this is used to process TD requests during analysis of + * attentions other than the command complete attention (i.e. memory CEs + * and UEs). If there isn't a current TD procedure in progress, this + * function will stop background scrubbing and start this new procedure. + * Otherwise, this new procedure is simply added to the queue. * - * It is possible that some of the other attentions my occur during the IPL + * It is possible that some of the other attentions may occur during the IPL * after Hostboot has been flushed from the cache to system memory. At that * point we don't have time to complete a TD procedure. Therefore, the * requests will be ignored. Any chip marks placed during this time will be * redetected when the runtime TD controller is initialized. * + * During IPL, this will simply add a new procedure to the queue, since we + * know TD will already be in progress when this is called. + * * @note Initializes the TD controller, if needed. * @param io_sc The step code data struct. * @param i_entry The new TD queue entry. @@ -100,7 +102,6 @@ class MemTdCtlr uint32_t handleTdEvent( STEP_CODE_DATA_STRUCT & io_sc, TdEntry * i_entry ); - #endif private: diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C index e10a0595e..06993bdb7 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C @@ -48,6 +48,22 @@ using namespace PlatServices; //------------------------------------------------------------------------------ template <TARGETING::TYPE T> +uint32_t MemTdCtlr<T>::handleTdEvent( STEP_CODE_DATA_STRUCT & io_sc, + TdEntry * i_entry ) +{ + #define PRDF_FUNC "[MemTdCtlr::handleTdEvent] " + + // Add this entry to the queue. + iv_queue.push( i_entry ); + + return SUCCESS; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template <TARGETING::TYPE T> uint32_t MemTdCtlr<T>::defaultStep( STEP_CODE_DATA_STRUCT & io_sc ) { #define PRDF_FUNC "[MemTdCtlr::defaultStep] " diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTps.H b/src/usr/diag/prdf/plat/mem/prdfMemTps.H index 924f55c94..ef2fd6368 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemTps.H +++ b/src/usr/diag/prdf/plat/mem/prdfMemTps.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -34,7 +34,6 @@ namespace PRDF { -// TODO: RTC 157889 Actual implementation of this procedure will be done later. /** @brief Two-Phase Scrub procedure. */ template <TARGETING::TYPE T> class TpsEvent : public TdEntry diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C index e18269c97..3a4f0a714 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -26,16 +26,23 @@ /** @file prdfMemTps_ipl.C */ // Platform includes +#include <prdfMemEccAnalysis.H> +#include <prdfMemIplCeStats.H> +#include <prdfMemMark.H> +#include <prdfMemScrubUtils.H> #include <prdfMemTps.H> +#include <prdfP9McaExtraSig.H> +#include <prdfPlatServices.H> using namespace TARGETING; namespace PRDF { +using namespace PlatServices; + //------------------------------------------------------------------------------ -// TODO: RTC 157608 Actual implementation of this procedure will be done later. template<> uint32_t TpsEvent<TYPE_MCA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc, bool & o_done ) @@ -43,10 +50,132 @@ uint32_t TpsEvent<TYPE_MCA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc, #define PRDF_FUNC "[TpsEvent<TYPE_MCA>::nextStep] " uint32_t o_rc = SUCCESS; - o_done = true; - - PRDF_ERR( PRDF_FUNC "function not implemented yet" ); + MemIplCeStats<TYPE_MCA> ceStats( iv_chip ); + + do + { + //only done in MNFG IPL CE Handling mode + PRDF_ASSERT( isMfgCeCheckingEnabled() ); + + //phase 0 + if ( TD_PHASE_0 == iv_phase ) + { + //start TPS phase 1 + o_rc = startTpsPhase1<TYPE_MCA>( iv_chip, iv_rank ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Call to 'startTpsPhase1 failed on chip: " + "0x%08x", iv_chip->getHuid() ); + break; + } + iv_phase = TD_PHASE_1; + + } + //phase 1/2 + else + { + //collect the CE statistics for later analysis use + o_rc = ceStats.collectStats( iv_rank ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Call to 'ceStats.collectStats' failed " + "on chip: 0x%08x", iv_chip->getHuid() ); + break; + } + + //get the ecc attentions + uint32_t eccAttns; + o_rc = checkEccFirs<TYPE_MCA>( iv_chip, eccAttns ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Call to 'checkEccFirs' failed on chip: " + "0x%08x", iv_chip->getHuid() ); + break; + } + + //if there was a UE or IUE + if ( (eccAttns & MAINT_UE) || (eccAttns & MAINT_IUE) ) + { + //UE + if ( eccAttns & MAINT_UE ) + { + io_sc.service_data->setSignature( iv_chip->getHuid(), + PRDFSIG_MaintUE ); + } + //IUE + else + { + io_sc.service_data->setSignature( iv_chip->getHuid(), + PRDFSIG_MaintIUE ); + } + + //Add the rank to the callout list + MemoryMru memmru(iv_chip->getTrgt(), iv_rank, + MemoryMruData::CALLOUT_RANK); + io_sc.service_data->SetCallout( memmru ); + + //Make the error log predictive + io_sc.service_data->setServiceCall(); + + //Abort this procedure + o_done = true; + } + //else if there was an MPE + else if ( eccAttns & MAINT_MPE ) + { + //Add the mark to the callout list + MemMark chipMark; + o_rc = MarkStore::readChipMark<TYPE_MCA>( iv_chip, iv_rank, + chipMark ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "readChipMark<T>(0x%08x,%d) failed", + iv_chip->getHuid(), iv_rank.getMaster() ); + break; + } + + MemoryMru memmru( iv_chip->getTrgt(), iv_rank, + chipMark.getSymbol() ); + io_sc.service_data->SetCallout( memmru ); + + //Add a VCM procedure to the queue + MemEcc::addVcmEvent<TYPE_MCA>( iv_chip, iv_rank, chipMark, + io_sc ); + + //Abort this procedure + o_done = true; + } + else + { + //Add the rank to the callout list + MemoryMru memmru(iv_chip->getTrgt(), iv_rank, + MemoryMruData::CALLOUT_RANK); + io_sc.service_data->SetCallout( memmru ); + + //phase 1 + if ( TD_PHASE_1 == iv_phase ) + { + //Start TPS phase 2 + o_rc = startTpsPhase2<TYPE_MCA>( iv_chip, iv_rank ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Call to 'startTpsPhase2 failed on " + "chip: 0x%08x", iv_chip->getHuid() ); + break; + } + iv_phase = TD_PHASE_2; + } + //phase 2 + else + { + //Abort this procedure + o_done = true; + } + } + } + + }while(0); return o_rc; |