diff options
-rw-r--r-- | src/usr/diag/prdf/common/plat/cen/cen_mba_regs.rule | 13 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.C | 80 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.H | 11 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/cen/prdf_plat_cen.mk | 4 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/p9/p9_mcbist_regs.rule | 15 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/prdfMain_common.C | 27 | ||||
-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 |
11 files changed, 437 insertions, 6 deletions
diff --git a/src/usr/diag/prdf/common/plat/cen/cen_mba_regs.rule b/src/usr/diag/prdf/common/plat/cen/cen_mba_regs.rule index 591c63a5c..f1c9d2712 100644 --- a/src/usr/diag/prdf/common/plat/cen/cen_mba_regs.rule +++ b/src/usr/diag/prdf/common/plat/cen/cen_mba_regs.rule @@ -23,6 +23,19 @@ # # IBM_PROLOG_END_TAG + + ########################################################################### + # P9 MBASPA + ########################################################################### + + register MBASPA_OR + { + name "Memory Buffer MBA SPA OR register"; + scomaddr 0x03010613; + capture group never; + access write_only; + }; + ############################################################################ # Additional regs for CEN MBA target MBASPA ############################################################################ diff --git a/src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.C b/src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.C new file mode 100644 index 000000000..7a41619c5 --- /dev/null +++ b/src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.C @@ -0,0 +1,80 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file prdfCenMbaDomain.C + * @brief chip Plug-in code for mcbist domain + */ + +#include <prdfCenMbaDomain.H> + +// Framework includes +#include <prdfExtensibleChip.H> +#include <prdfPlatServices.H> +#include <prdfTrace.H> +#ifdef __HOSTBOOT_RUNTIME +#include <prdfCenMbaDataBundle.H> +#endif + +using namespace TARGETING; + +namespace PRDF +{ + +using namespace PlatServices; + +#ifdef __HOSTBOOT_RUNTIME +void MbaDomain::handleRrFo() +{ + #define PRDF_FUNC "[MbaDomain::handleRrFo] " + + do + { + uint32_t domainSize = GetSize(); + // Iterate all MBAs in the domain. + for ( uint32_t i = 0; i < domainSize; ++i ) + { + RuleChip * mbaChip = LookUp(i); + + // Start background scrub if required. + MbaDataBundle * mbadb = getMbaDataBundle( mbaChip ); + int32_t l_rc = mbadb->getTdCtlr()->handleRrFo(); + if ( SUCCESS != l_rc ) + { + // Let us not fail here. If problem is contained within a MBA + // we will discover it again during normal TD procedures. + PRDF_ERR( PRDF_FUNC "handleRrFo() failed: MBA=0x%08x", + mbaChip->GetId() ); + continue; // Keep going. + } + } + + } while (0); + + #undef PRDF_FUNC +} +#endif + +} // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.H b/src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.H index 8b79859df..2b9fa6fab 100644 --- a/src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.H +++ b/src/usr/diag/prdf/common/plat/cen/prdfCenMbaDomain.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,15 @@ class MbaDomain : public RuleChipDomain virtual bool Query( ATTENTION_TYPE i_attnType ) { return false; } + #ifdef __HOSTBOOT_RUNTIME + + /** + * @brief Starts memory background scrubbing or VCM procedure for MBA + * during R/R and F/O if required. + */ + void handleRrFo(); + + #endif }; } // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plat/cen/prdf_plat_cen.mk b/src/usr/diag/prdf/common/plat/cen/prdf_plat_cen.mk index 62f2a3b13..956ba6cf2 100644 --- a/src/usr/diag/prdf/common/plat/cen/prdf_plat_cen.mk +++ b/src/usr/diag/prdf/common/plat/cen/prdf_plat_cen.mk @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2016 +# Contributors Listed Below - COPYRIGHT 2016,2017 # [+] International Business Machines Corp. # # @@ -37,4 +37,4 @@ prd_incpath += ${PRD_SRC_PATH}/common/plat/cen # Object files common to both FSP and Hostboot ################################################################################ - +prd_obj += prdfCenMbaDomain.o diff --git a/src/usr/diag/prdf/common/plat/p9/p9_mcbist_regs.rule b/src/usr/diag/prdf/common/plat/p9/p9_mcbist_regs.rule index 4200737bb..e55dbfeda 100644 --- a/src/usr/diag/prdf/common/plat/p9/p9_mcbist_regs.rule +++ b/src/usr/diag/prdf/common/plat/p9/p9_mcbist_regs.rule @@ -38,6 +38,14 @@ access write_only; }; + register MCBISTFIR_OR + { + name "P9 MCBIST target MCBISTFIR OR"; + scomaddr 0x07012302; + capture group never; + access write_only; + }; + register MCBISTFIR_MASK_OR { name "P9 MCBIST target MCBISTFIR MASK OR"; @@ -241,6 +249,13 @@ capture group default; }; + register MCB_CNTLSTAT + { + name "P9 MCBIST Configured Command Sequence Status Register"; + scomaddr 0x070123DC; + capture group default; + }; + ########################################################################### # P9 MCBIST Modal Symbol Counter Registers ########################################################################### diff --git a/src/usr/diag/prdf/common/prdfMain_common.C b/src/usr/diag/prdf/common/prdfMain_common.C index 731466f55..36e1f7072 100755 --- a/src/usr/diag/prdf/common/prdfMain_common.C +++ b/src/usr/diag/prdf/common/prdfMain_common.C @@ -44,6 +44,12 @@ #include <prdfRegisterCache.H> #include <prdfScanFacility.H> #include <prdfMfgThresholdMgr.H> + +#ifdef __HOSTBOOT_RUNTIME +#include <prdfP9McbistDomain.H> +#include <prdfCenMbaDomain.H> +#endif + #if !defined(__HOSTBOOT_MODULE) && !defined(__HOSTBOOT_RUNTIME) #include <prdfSdcFileControl.H> #endif @@ -147,6 +153,27 @@ errlHndl_t noLock_initialize() Prdr::LoadChipCache::flushCache(); } + #ifdef __HOSTBOOT_RUNTIME + + // Handle R/R scenario. + TARGETING::Target* masterProc = nullptr; + TARGETING::targetService().masterProcChipTargetHandle(masterProc); + + if (TARGETING::MODEL_NIMBUS == masterProc->getAttr<TARGETING::ATTR_MODEL>()) + { + McbistDomain * domain = + (McbistDomain *)systemPtr->GetDomain(MCBIST_DOMAIN); + domain->handleRrFo(); + } + else + { + MbaDomain * domain = + (MbaDomain *)systemPtr->GetDomain(MBA_DOMAIN); + domain->handleRrFo(); + } + + #endif + PRDF_EXIT( PRDF_FUNC ); return (g_prd_errlHndl.release()); 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 |