summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2018-08-08 11:13:25 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-08-15 22:04:51 -0500
commit396c1d36653634a037f2cdc32332a92aad75d2c0 (patch)
tree43786137cd74f5ede49ea6cfb35b534325534f19
parent4f0f9f1534a110cbd369e7ee3f57ce7cfd6719b8 (diff)
downloadtalos-hostboot-396c1d36653634a037f2cdc32332a92aad75d2c0.tar.gz
talos-hostboot-396c1d36653634a037f2cdc32332a92aad75d2c0.zip
PRD: resume command support in VcmEvent for Row Repair
Change-Id: I2d1faf7303b6c334b4107891994b8b89c53ade36 RTC: 196073 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64144 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64557 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>
-rwxr-xr-xsrc/usr/diag/prdf/plat/mem/prdfMemTdQueue.H2
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm.C191
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm.H32
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C24
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C138
-rw-r--r--src/usr/diag/prdf/plat/mem/prdf_plat_mem_hb_only.mk1
6 files changed, 226 insertions, 162 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H b/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H
index 56254abe3..5ecdb1cf4 100755
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H
@@ -150,11 +150,9 @@ class TdEntry
// used for displaying FFDC in the TD controller.
const MemRank iv_rank; ///< The rank in which this event occurred.
- #ifdef __HOSTBOOT_RUNTIME
/** True if the current TD command can be resumed, false otherwise. Resume
* only supported for MBA at this time. */
bool iv_canResumeScrub = false;
- #endif
};
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm.C
new file mode 100644
index 000000000..9991c3f81
--- /dev/null
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm.C
@@ -0,0 +1,191 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/plat/mem/prdfMemVcm.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018 */
+/* [+] 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 prdfMemVcm.C */
+
+#include <prdfMemVcm.H>
+
+// Platform includes
+#include <prdfCenMbaExtraSig.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+//##############################################################################
+//
+// Specializations for MCA
+//
+//##############################################################################
+
+template<>
+uint32_t VcmEvent<TYPE_MCA>::handlePhaseComplete( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
+{
+ #define PRDF_FUNC "[VcmEvent<TYPE_MCA>::handlePhaseComplete] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ if ( TD_PHASE_2 == iv_phase )
+ {
+ // Determine if the chip mark has been verified.
+ o_rc = (i_eccAttns & MAINT_MCE) ? verified(io_sc)
+ : falseAlarm(io_sc);
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "verified()/falseAlarm() failed" );
+ break;
+ }
+
+ o_done = true; // Procedure is complete.
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//##############################################################################
+//
+// Specializations for MBA
+//
+//##############################################################################
+
+template<>
+uint32_t VcmEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
+{
+ uint32_t signature = 0;
+
+ if ( iv_canResumeScrub )
+ {
+ signature = PRDFSIG_VcmResume;
+
+ PRDF_TRAC( "[VcmEvent] Resuming VCM Phase %d: 0x%08x,0x%02x",
+ iv_phase, iv_chip->getHuid(), getKey() );
+ }
+ else
+ {
+ 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() );
+ }
+
+ io_sc.service_data->AddSignatureList( iv_chip->getTrgt(), signature );
+
+ return startCmd();
+}
+
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t VcmEvent<TYPE_MBA>::handlePhaseComplete( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
+{
+ #define PRDF_FUNC "[VcmEvent<TYPE_MBA>::handlePhaseComplete] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // Determine if the command stopped on the last address.
+ bool lastAddr = false;
+ o_rc = didCmdStopOnLastAddr<TYPE_MBA>( iv_chip, MASTER_RANK, lastAddr );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "didCmdStopOnLastAddr(0x%08x) failed",
+ iv_chip->getHuid() );
+ break;
+ }
+
+ // It is important to initialize iv_canResumeScrub here, so that we will
+ // know to resume the current phase in startNextPhase() instead of
+ // starting phase.
+ iv_canResumeScrub = !lastAddr;
+
+ if ( TD_PHASE_2 == iv_phase )
+ {
+ if ( i_eccAttns & MAINT_MCE )
+ {
+ // The chip mark has been verified.
+ o_rc = verified( io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "verified() failed on 0x%08x",
+ iv_chip->getHuid() );
+ break;
+ }
+
+ o_done = true; // Procedure is complete.
+ }
+ else if ( !iv_canResumeScrub )
+ {
+ // The chip mark is not verified and the command has reached the
+ // end of the rank. So this is a false alarm.
+ o_rc = falseAlarm( io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "falseAlarm() failed on 0x%08x",
+ iv_chip->getHuid() );
+ break;
+ }
+
+ o_done = true; // Procedure is complete.
+ }
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm.H b/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
index 6b33fa9f5..7aff78c14 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
@@ -192,19 +192,13 @@ class VcmEvent : public TdEntry
if ( o_done ) break; // abort the procedure.
- if ( TD_PHASE_2 == iv_phase )
+ // Complete the phase.
+ o_rc = handlePhaseComplete( eccAttns, io_sc, o_done );
+ if ( SUCCESS != o_rc )
{
- // Determine if the chip mark has been verified.
- o_rc = (eccAttns & MAINT_MCE) ? verified(io_sc)
- : falseAlarm(io_sc);
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "verified()/falseAlarm() failed" );
- break;
- }
-
- // Procedure is complete.
- o_done = true;
+ PRDF_ERR( PRDF_FUNC "checkEcc() failed on 0x%08x",
+ iv_chip->getHuid() );
+ break;
}
} while (0);
@@ -235,6 +229,20 @@ class VcmEvent : public TdEntry
STEP_CODE_DATA_STRUCT & io_sc, bool & o_done );
/**
+ * @brief Does appropriate actions at the end of a phase if it was not
+ * aborted due to an error. Note that the actions will differ per
+ * target type, runtime/IPL, or if there is an MCE on phase 2.
+ * @param i_eccAttns Mask of all currently active maintenance attentions.
+ * See enum MaintEccAttns for values.
+ * @param io_sc The step code data struct.
+ * @param o_done True if the procedure is complete or has aborted.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ uint32_t handlePhaseComplete( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done );
+
+ /**
* @brief The chip mark is verified. Do additional processing such as
* updating the VPD and initiating DRAM sparing, if supported.
* @param io_sc The step code data struct.
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
index d3de6d20d..78e881b5a 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
@@ -202,24 +202,28 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd()
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 );
+ o_rc = ( iv_canResumeScrub )
+ ? resumeTdSteerCleanup<TYPE_MBA>( iv_chip, MASTER_RANK,
+ stopCond )
+ : 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() );
+ PRDF_ERR( PRDF_FUNC "steer cleanup command failed on 0x%08x",
+ iv_chip->getHuid() );
}
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 );
+ o_rc = ( iv_canResumeScrub )
+ ? resumeTdSfRead<TYPE_MBA>( iv_chip, MASTER_RANK,
+ stopCond )
+ : 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() );
+ PRDF_ERR( PRDF_FUNC "sf read command failed on 0x%08x",
+ iv_chip->getHuid() );
}
break;
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
index ce46f822b..ec4223fad 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
@@ -266,48 +266,6 @@ uint32_t VcmEvent<TYPE_MBA>::startCmd()
//------------------------------------------------------------------------------
template<>
-uint32_t VcmEvent<TYPE_MBA>::startNextPhase( STEP_CODE_DATA_STRUCT & io_sc )
-{
- uint32_t signature = 0;
-
- if ( iv_canResumeScrub )
- {
- signature = PRDFSIG_VcmResume;
-
- PRDF_TRAC( "[VcmEvent] Resuming VCM Phase %d: 0x%08x,0x%02x",
- iv_phase, iv_chip->getHuid(), getKey() );
- }
- else
- {
- 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() );
- }
-
- io_sc.service_data->AddSignatureList( iv_chip->getTrgt(), signature );
-
- return startCmd();
-
- #undef PRDF_FUNC
-}
-
-//------------------------------------------------------------------------------
-
-template<>
uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
@@ -375,102 +333,6 @@ uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
#undef PRDF_FUNC
}
-//------------------------------------------------------------------------------
-
-template<>
-uint32_t VcmEvent<TYPE_MBA>::analyzePhase( STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
-{
- #define PRDF_FUNC "[VcmEvent::analyzePhase] "
-
- uint32_t o_rc = SUCCESS;
-
- do
- {
- if ( TD_PHASE_0 == iv_phase ) break; // Nothing to analyze yet.
-
- // Look for any ECC errors that occurred during the command.
- uint32_t eccAttns;
- o_rc = checkEccFirs<TYPE_MBA>( iv_chip, eccAttns );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "checkEccFirs(0x%08x) failed",
- iv_chip->getHuid() );
- break;
- }
-
- // Analyze the ECC errors, if needed.
- o_rc = checkEcc( eccAttns, io_sc, o_done );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "checkEcc() failed on 0x%08x",
- iv_chip->getHuid() );
- break;
- }
-
- if ( o_done ) break; // abort the procedure.
-
- // Determine if the command stopped on the last address.
- bool lastAddr = false;
- o_rc = didCmdStopOnLastAddr<TYPE_MBA>( iv_chip, MASTER_RANK, lastAddr );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "didCmdStopOnLastAddr(0x%08x) failed",
- iv_chip->getHuid() );
- break;
- }
-
- // It is important to initialize iv_canResumeScrub here, so that we will
- // know to resume the current phase in startNextPhase() instead of
- // starting phase.
- iv_canResumeScrub = !lastAddr;
-
- if ( TD_PHASE_2 == iv_phase )
- {
- if ( eccAttns & MAINT_MCE )
- {
- // The chip mark has been verified.
- o_rc = verified( io_sc );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "verified() failed on 0x%08x",
- iv_chip->getHuid() );
- break;
- }
-
- // Procedure is complete.
- o_done = true;
- }
- else if ( !iv_canResumeScrub )
- {
- // The chip mark is not verified and the command has reached the
- // end of the rank. So this is a false alarm.
- o_rc = falseAlarm( io_sc );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "falseAlarm() failed on 0x%08x",
- iv_chip->getHuid() );
- break;
- }
-
- // Procedure is complete.
- o_done = true;
- }
- }
-
- } while (0);
-
- if ( (SUCCESS == o_rc) && o_done )
- {
- // Clear the ECC FFDC for this master rank.
- MemDbUtils::resetEccFfdc<TYPE_MBA>( iv_chip, iv_rank, MASTER_RANK );
- }
-
- return o_rc;
-
- #undef PRDF_FUNC
-}
-
//##############################################################################
//
// Generic template functions
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 2ff127bc1..18bad3a60 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 += prdfMemVcm.o
prd_obj += prdfP9McbistDomain.o
# plat/mem/ (rule plugin related)
OpenPOWER on IntegriCloud