summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2018-04-04 15:38:45 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-04-10 11:09:00 -0400
commit2000b276f2ea60bcfefb212d05015b2968dcb272 (patch)
tree1a02c64403d539844c6b41f73cfa95450d1c4f17
parentda885e721ccc39547b0a29f3350d1b9ae035f6db (diff)
downloadtalos-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.C51
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C65
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.H12
-rw-r--r--src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.C274
-rw-r--r--src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr_ipl.H10
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.C99
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.C310
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
}
OpenPOWER on IntegriCloud