summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/plat/mem
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2018-04-09 21:37:56 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-04-19 16:45:24 -0400
commit87201e7f578f9ef54513009acb539af2b1eab43b (patch)
treed500f1ee1f9e66c6a7ebe6341634e1904f466003 /src/usr/diag/prdf/plat/mem
parent360d83a83ec25acbdb6b40e3c773e017c75b6cb4 (diff)
downloadtalos-hostboot-87201e7f578f9ef54513009acb539af2b1eab43b.tar.gz
talos-hostboot-87201e7f578f9ef54513009acb539af2b1eab43b.zip
PRD: add full maint cmd support for all VCM procedures
Change-Id: Id7467120889831e07fa59cd64977b866a8c79ee7 RTC: 190428 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57151 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: Caleb N. Palmer <cnpalmer@us.ibm.com> Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57132 CI-Ready: Zane C. Shelley <zshelle@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/usr/diag/prdf/plat/mem')
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm.H56
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C76
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C67
3 files changed, 174 insertions, 25 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm.H b/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
index c42598935..28f347030 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -73,12 +73,13 @@ class VcmEvent : public TdEntry
switch ( iv_phase )
{
case TD_PHASE_0:
- o_rc = startPhase1( io_sc );
+ o_rc = startNextPhase( io_sc );
break;
case TD_PHASE_1:
o_rc = analyzePhase1( io_sc, o_done );
- if ( SUCCESS == o_rc && !o_done ) o_rc = startPhase2( io_sc );
+ if ( SUCCESS == o_rc && !o_done )
+ o_rc = startNextPhase( io_sc );
break;
case TD_PHASE_2:
@@ -110,37 +111,44 @@ class VcmEvent : public TdEntry
private: // functions
/**
- * @brief Starts phase 1 of the procedure.
- * @param io_sc The step code data struct.
+ * @brief Starts the appropriate maintenance command for each phase of the
+ * VCM procedure.
+ * @pre iv_phase must be set appropriately before calling this function.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
- uint32_t startPhase1( STEP_CODE_DATA_STRUCT & io_sc )
- {
- PRDF_TRAC( "[VcmEvent] Starting VCM Phase 1: 0x%08x,0x%02x",
- iv_chip->getHuid(), getKey() );
-
- iv_phase = TD_PHASE_1;
- io_sc.service_data->AddSignatureList( iv_chip->getTrgt(),
- PRDFSIG_StartVcmPhase1 );
-
- return PlatServices::startVcmPhase1<T>( iv_chip, iv_rank );
- }
+ uint32_t startCmd();
/**
- * @brief Starts phase 2 of the procedure.
+ * @brief Starts the next phase of the procedure.
* @param io_sc The step code data struct.
+ * @post iv_phase will be updated appropriately per design.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
- uint32_t startPhase2( STEP_CODE_DATA_STRUCT & io_sc )
+ uint32_t startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
{
- PRDF_TRAC( "[VcmEvent] Starting VCM Phase 2: 0x%08x,0x%02x",
- iv_chip->getHuid(), getKey() );
+ uint32_t signature = 0;
+
+ 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() );
- iv_phase = TD_PHASE_2;
- io_sc.service_data->AddSignatureList( iv_chip->getTrgt(),
- PRDFSIG_StartVcmPhase2 );
+ io_sc.service_data->AddSignatureList( iv_chip->getTrgt(), signature );
- return PlatServices::startVcmPhase2<T>( iv_chip, iv_rank );
+ return startCmd();
}
/**
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
index bd8a3fde2..2d9458815 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
@@ -195,6 +195,82 @@ uint32_t VcmEvent<T>::checkEcc( const uint32_t & i_eccAttns,
#undef PRDF_FUNC
}
+//##############################################################################
+//
+// Specializations for MCA
+//
+//##############################################################################
+
+template<>
+uint32_t VcmEvent<TYPE_MCA>::startCmd()
+{
+ #define PRDF_FUNC "[VcmEvent::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ // No stop conditions.
+ mss::mcbist::stop_conditions stopCond;
+
+ // Start the time based scrub procedure on this master rank.
+ o_rc = startTdScrub<TYPE_MCA>( 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;
+
+ #undef PRDF_FUNC
+}
+
+//##############################################################################
+//
+// Specializations for MBA
+//
+//##############################################################################
+
+template<>
+uint32_t VcmEvent<TYPE_MBA>::startCmd()
+{
+ #define PRDF_FUNC "[VcmEvent::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ uint32_t stopCond = mss_MaintCmd::NO_STOP_CONDITIONS;
+
+ switch ( iv_phase )
+ {
+ case TD_PHASE_1:
+ // Start the steer cleanup procedure on this master rank.
+ o_rc = startTdSteerCleanup<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK,
+ stopCond );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdSteerCleanup(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+ break;
+
+ case TD_PHASE_2:
+ // Start the superfast read procedure on this master rank.
+ o_rc = startTdSfRead<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK,
+ stopCond );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdSfRead(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+ break;
+
+ default: PRDF_ASSERT( false ); // invalid phase
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
// Avoid linker errors with the template.
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
index caf57d763..a6db8d9b3 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -190,6 +190,31 @@ template class VcmEvent<TYPE_MBA>;
//##############################################################################
template<>
+uint32_t VcmEvent<TYPE_MCA>::startCmd()
+{
+ #define PRDF_FUNC "[VcmEvent::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ // No stop conditions.
+ mss::mcbist::stop_conditions stopCond;
+
+ // Start the time based scrub procedure on this master rank.
+ o_rc = startTdScrub<TYPE_MCA>( 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;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
@@ -272,6 +297,46 @@ uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
//##############################################################################
template<>
+uint32_t VcmEvent<TYPE_MBA>::startCmd()
+{
+ #define PRDF_FUNC "[VcmEvent::startCmd] "
+
+ uint32_t o_rc = SUCCESS;
+
+ uint32_t stopCond = mss_MaintCmd::NO_STOP_CONDITIONS;
+
+ // Due to a hardware bug in the Centaur, we must execute runtime maintenance
+ // commands at a very slow rate. Because of this, we decided that we should
+ // stop the command immediately on error if there is a UE so that we can
+ // respond quicker and send a DMD message to the hypervisor as soon as
+ // possible.
+
+ stopCond |= mss_MaintCmd::STOP_ON_UE;
+ stopCond |= mss_MaintCmd::STOP_IMMEDIATE;
+
+ // Again, due to the hardware bug in the Centaur, we want to stop
+ // immediately if there is an MCE found during phase 2 because that
+ // indicates an error was detected on the bad DRAM and fixed by the chip
+ // mark.
+
+ 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 )
+ {
+ PRDF_ERR( PRDF_FUNC "startTdScrub(0x%08x,0x%2x) failed",
+ iv_chip->getHuid(), getKey() );
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
OpenPOWER on IntegriCloud