diff options
author | Caleb Palmer <cnpalmer@us.ibm.com> | 2017-10-12 16:13:23 -0500 |
---|---|---|
committer | Zane C. Shelley <zshelle@us.ibm.com> | 2017-11-10 15:22:32 -0500 |
commit | ca3990cbf857f5170183f5276262132c7f8790f5 (patch) | |
tree | f519bdeaa5218b5668b7372d6ab3e7dde956b2f8 /src/usr/diag/prdf/plat | |
parent | 9e703b5d526c1601f053e0df75c2023aedb9a95b (diff) | |
download | talos-hostboot-ca3990cbf857f5170183f5276262132c7f8790f5.tar.gz talos-hostboot-ca3990cbf857f5170183f5276262132c7f8790f5.zip |
PRD: Update handleRrFo
Change-Id: I86bbd32ff782aa30287f493c72142988b4618922
RTC: 171874
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48652
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@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/49483
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')
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H | 18 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C | 224 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.C | 37 | ||||
-rwxr-xr-x | src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.H | 12 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdf_plat_mem_hb_only.mk | 2 |
5 files changed, 290 insertions, 3 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H index 33f3187ea..e9cdfd051 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H +++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H @@ -108,6 +108,24 @@ class MemTdCtlr */ void pushToQueue( TdEntry * i_entry ) { iv_queue.push(i_entry); } + #ifdef __HOSTBOOT_RUNTIME + + /** + * @brief Handles reset-reload or FO scenario. + * @note This function will check if PRD was unable to restart maintenance + * command before R/R or FO. In that scenario, this function will + * start maintenance command. As during R/R or F/O we do not have any + * mechanism to restore the complete state of TD controller, we will + * not start any interrupted or pending TD procedure. We will only + * start BG scrub. If we found any chip marks during TD state + * machine initialize we will start VCM procedure rather than + * BG scrub. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + uint32_t handleRrFo(); + + #endif + private: /** diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C index c6215ba30..d65465964 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C @@ -914,6 +914,230 @@ uint32_t MemTdCtlr<TYPE_MBA>::unmaskEccAttns() //------------------------------------------------------------------------------ +template<> +uint32_t MemTdCtlr<TYPE_MCBIST>::handleRrFo() +{ + #define PRDF_FUNC "[MemTdCtlr<TYPE_MCBIST>::handleRrFo] " + + uint32_t o_rc = SUCCESS; + + do + { + // Check if maintenance command complete attention is set. + SCAN_COMM_REGISTER_CLASS * mcbistfir = + iv_chip->getRegister("MCBISTFIR"); + o_rc = mcbistfir->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on MCBISTFIR"); + break; + } + + // If there is a command complete attention, nothing to do, break out. + if ( mcbistfir->IsBitSet(10) || mcbistfir->IsBitSet(12) ) + break; + + + // Check if a command is not running. + // If bit 0 of MCB_CNTLSTAT is on, a mcbist run is in progress. + SCAN_COMM_REGISTER_CLASS * mcb_cntlstat = + iv_chip->getRegister("MCB_CNTLSTAT"); + o_rc = mcb_cntlstat->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on MCB_CNTLSTAT" ); + break; + } + + // If a command is not running, set command complete attn, break. + if ( !mcb_cntlstat->IsBitSet(0) ) + { + SCAN_COMM_REGISTER_CLASS * mcbistfir_or = + iv_chip->getRegister("MCBISTFIR_OR"); + mcbistfir_or->SetBit( 10 ); + + mcbistfir_or->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on MCBISTFIR_OR" ); + } + break; + } + + // Check if there are unverified chip marks. + std::vector<TdRankListEntry> vectorList = iv_rankList.getList(); + + for ( auto & entry : vectorList ) + { + ExtensibleChip * mcaChip = entry.getChip(); + MemRank rank = entry.getRank(); + + // Get the chip mark + MemMark chipMark; + o_rc = MarkStore::readChipMark<TYPE_MCA>( mcaChip, rank, chipMark ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "readChipMark<TYPE_MCA>(0x%08x,%d) " + "failed", mcaChip->getHuid(), rank.getMaster() ); + break; + } + + if ( !chipMark.isValid() ) continue; // no chip mark present + + // Get the DQ Bitmap data. + TargetHandle_t mcaTrgt = mcaChip->GetChipHandle(); + MemDqBitmap<DIMMS_PER_RANK::MCA> dqBitmap; + + o_rc = getBadDqBitmap<DIMMS_PER_RANK::MCA>(mcaTrgt, rank, dqBitmap); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getBadDqBitmap<DIMMS_PER_RANK::MCA>" + "(0x%08x, %d)", getHuid(mcaTrgt), rank.getMaster() ); + break; + } + + // Check if the chip mark is verified or not. + bool cmVerified = false; + o_rc = dqBitmap.isChipMark( chipMark.getSymbol(), cmVerified ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "dqBitmap.isChipMark failed." ); + break; + } + + // If there are any unverified chip marks, stop the command, break. + if ( !cmVerified ) + { + o_rc = stopBgScrub<TYPE_MCBIST>( iv_chip ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "stopBgScrub<TYPE_MCBIST>(0x%08x) " + "failed", iv_chip->getHuid() ); + } + break; + } + } + + } while (0); + + return o_rc; + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +template<> +uint32_t MemTdCtlr<TYPE_MBA>::handleRrFo() +{ + #define PRDF_FUNC "[MemTdCtlr<TYPE_MBA>::handleRrFo] " + + uint32_t o_rc = SUCCESS; + + do + { + // Check if maintenance command complete attention is set. + SCAN_COMM_REGISTER_CLASS * mbaspa = + iv_chip->getRegister("MBASPA"); + o_rc = mbaspa->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on MBASPA"); + break; + } + + // If there is a command complete attention, nothing to do, break out. + if ( mbaspa->IsBitSet(0) || mbaspa->IsBitSet(8) ) + break; + + // Check if a maintenance command is running currently. + SCAN_COMM_REGISTER_CLASS * mbmsr = + iv_chip->getRegister("MBMSR"); + + o_rc = mbmsr->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on MBMSR"); + break; + } + + // If a command is not running, set command complete attn, break. + if ( !mbmsr->IsBitSet(0) ) + { + SCAN_COMM_REGISTER_CLASS * mbaspa_or = + iv_chip->getRegister("MBASPA_OR"); + mbaspa_or->SetBit( 0 ); + + mbaspa_or->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Write() failed on MBASPA_OR" ); + } + break; + } + + // Check if there are unverified chip marks. + std::vector<TdRankListEntry> vectorList = iv_rankList.getList(); + + for ( auto & entry : vectorList ) + { + ExtensibleChip * mbaChip = entry.getChip(); + MemRank rank = entry.getRank(); + + // Get the chip mark + MemMark chipMark; + o_rc = MarkStore::readChipMark<TYPE_MBA>( mbaChip, rank, chipMark ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "readChipMark<TYPE_MBA>(0x%08x,%d) " + "failed", mbaChip->getHuid(), rank.getMaster() ); + break; + } + + if ( !chipMark.isValid() ) continue; // no chip mark present + + // Get the DQ Bitmap data. + TargetHandle_t mbaTrgt = mbaChip->GetChipHandle(); + MemDqBitmap<DIMMS_PER_RANK::MBA> dqBitmap; + + o_rc = getBadDqBitmap<DIMMS_PER_RANK::MBA>(mbaTrgt, rank, dqBitmap); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getBadDqBitmap<DIMMS_PER_RANK::MBA>" + "(0x%08x, %d)", getHuid(mbaTrgt), rank.getMaster() ); + break; + } + + // Check if the chip mark is verified or not. + bool cmVerified = false; + o_rc = dqBitmap.isChipMark( chipMark.getSymbol(), cmVerified ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "dqBitmap.isChipMark failed." ); + break; + } + + // If there are any unverified chip marks, stop the command, break. + if ( !cmVerified ) + { + o_rc = stopBgScrub<TYPE_MBA>( iv_chip ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "stopBgScrub<TYPE_MBA>(0x%08x) failed", + iv_chip->getHuid() ); + } + break; + } + } + + } while (0); + + return o_rc; + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + + // Avoid linker errors with the template. template class MemTdCtlr<TYPE_MCBIST>; template class MemTdCtlr<TYPE_MBA>; diff --git a/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.C b/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.C index 241d835f2..88c72fdf3 100644 --- a/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.C +++ b/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -35,6 +35,7 @@ #include <prdfPlatServices.H> #include <prdfTrace.H> #include <prdfMemBgScrub.H> +#include <prdfP9McbistDataBundle.H> using namespace TARGETING; @@ -43,6 +44,7 @@ namespace PRDF using namespace PlatServices; +#ifndef __HOSTBOOT_RUNTIME int32_t McbistDomain::startScrub() { #define PRDF_FUNC "[McbistDomain::startScrub] " @@ -72,5 +74,38 @@ int32_t McbistDomain::startScrub() #undef PRDF_FUNC } +#endif + +#ifdef __HOSTBOOT_RUNTIME +void McbistDomain::handleRrFo() +{ + #define PRDF_FUNC "[McbistDomain::handleRrFo] " + + do + { + uint32_t domainSize = GetSize(); + // Iterate all MCBISTs in the domain. + for ( uint32_t i = 0; i < domainSize; ++i ) + { + RuleChip * mcbChip = LookUp(i); + + // Start background scrub if required. + McbistDataBundle * mcbdb = getMcbistDataBundle( mcbChip ); + int32_t l_rc = mcbdb->getTdCtlr()->handleRrFo(); + if ( SUCCESS != l_rc ) + { + // Let us not fail here. If problem is contained within a MCBIST + // we will discover it again during normal TD procedures. + PRDF_ERR( PRDF_FUNC "handleRrFo() failed: MCBIST=0x%08x", + mcbChip->GetId() ); + continue; // Keep going. + } + } + + } while (0); + + #undef PRDF_FUNC +} +#endif } // end namespace PRDF diff --git a/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.H b/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.H index 702c97af9..1e9b15d7e 100755 --- a/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.H +++ b/src/usr/diag/prdf/plat/mem/prdfP9McbistDomain.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -54,6 +54,16 @@ class McbistDomain : public RuleChipDomain virtual bool Query( ATTENTION_TYPE i_attnType ) { return false; } + #ifdef __HOSTBOOT_RUNTIME + + /** + * @brief Starts memory background scrubbing or VCM procedure for MCBIST + * during R/R and F/O if required. + */ + void handleRrFo(); + + #endif + #ifndef __HOSTBOOT_RUNTIME /** diff --git a/src/usr/diag/prdf/plat/mem/prdf_plat_mem_hb_only.mk b/src/usr/diag/prdf/plat/mem/prdf_plat_mem_hb_only.mk index a89ec90f6..1c7770ee4 100644 --- a/src/usr/diag/prdf/plat/mem/prdf_plat_mem_hb_only.mk +++ b/src/usr/diag/prdf/plat/mem/prdf_plat_mem_hb_only.mk @@ -40,6 +40,7 @@ prd_incpath += ${PRD_SRC_PATH}/plat/mem # plat/mem/ (non-rule plugin related) prd_obj += prdfMemScrubUtils.o prd_obj += prdfMemTdCtlr.o +prd_obj += prdfP9McbistDomain.o # plat/mem/ (rule plugin related) prd_rule_plugin += prdfCenMba.o @@ -56,7 +57,6 @@ ifneq (${HOSTBOOT_RUNTIME},1) prd_obj += prdfMemTdCtlr_ipl.o prd_obj += prdfMemTps_ipl.o prd_obj += prdfMemVcm_ipl.o -prd_obj += prdfP9McbistDomain.o prd_obj += prdfMemIplCeStats.o prd_obj += prdfRestoreDramRepairs.o |