summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/mem/prdfMemRank.H8
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfP9McaExtraSig.H1
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H95
-rwxr-xr-xsrc/usr/diag/prdf/plat/mem/prdfMemTdQueue.H34
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTps.H9
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm.H263
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C288
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C201
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.C22
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.H8
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.C48
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_rt.C55
12 files changed, 792 insertions, 240 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemRank.H b/src/usr/diag/prdf/common/plat/mem/prdfMemRank.H
index 80519d435..a373d1bd4 100755
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemRank.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemRank.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -87,6 +87,12 @@ class MemRank
/** @return The master rank select. */
uint8_t getRankSlct() const { return iv_mrnk & 0x3; }
+ /** @return This value will mostly be used for traces. The first nibble will
+ * contain the master rank, including DIMM select. The second
+ * nibble will contain the slave rank. For example, 0x41 will be
+ * master rank 4, slave rank 1. */
+ uint8_t getKey() const { return getMaster() << 4 | getSlave(); }
+
/** @brief '==' operator */
bool operator==( const MemRank & i_rank ) const
{
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfP9McaExtraSig.H b/src/usr/diag/prdf/common/plat/mem/prdfP9McaExtraSig.H
index a7dbf102f..bc1bdaeb8 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfP9McaExtraSig.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfP9McaExtraSig.H
@@ -42,6 +42,7 @@ PRDR_ERROR_SIGNATURE(MaintMPE, 0xffff0012, "", "Maintenance MPE");
PRDR_ERROR_SIGNATURE(MaintHARD_CTE, 0xffff0013, "", "Maintenance HARD CTE");
PRDR_ERROR_SIGNATURE(MaintSOFT_CTE, 0xffff0014, "", "Maintenance SOFT CTE");
PRDR_ERROR_SIGNATURE(MaintINTER_CTE, 0xffff0015, "", "Maintenance INTER CTE");
+PRDR_ERROR_SIGNATURE(MaintRETRY_CTE, 0xffff0016, "", "Maintenance RETRY CTE");
PRDR_ERROR_SIGNATURE(VcmVerified, 0xffff0020, "", "VCM: verified");
PRDR_ERROR_SIGNATURE(VcmFalseAlarm, 0xffff0021, "", "VCM: false alarm");
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H b/src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H
new file mode 100644
index 000000000..fd38ff832
--- /dev/null
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H
@@ -0,0 +1,95 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 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 */
+
+#ifndef __prdfMemTdFalseAlarm_H
+#define __prdfMemTdFalseAlarm_H
+
+#ifdef __HOSTBOOT_RUNTIME // All of this code is runtime only
+
+// Framework includes
+#include <iipServiceDataCollector.h>
+#include <prdfThresholdUtils.H>
+
+// Other includes
+#include <map>
+
+namespace PRDF
+{
+
+/**
+ * @brief At runtime, we have to keep a false alarm threshold for Targeted
+ * Diagnostics to avoid flooding of intermittent errors.
+ *
+ * This class is intented to be a static class variable for each TD event class
+ * that requires this type of thresholding. It will contain a map for each chip
+ * and unique key within each chip to the threshold container. Note that the key
+ * could be different per TD event class. For example, VCM events will use only
+ * the master rank, where TPS events will use both the master and slave rank.
+ */
+class TdFalseAlarm
+{
+ public:
+
+ /**
+ * @brief Constructor.
+ * @param i_th Threshold value for all entries in the map.
+ * @param i_int Threshold interval for all entries in the map.
+ */
+ TdFalseAlarm( uint8_t i_th, uint32_t i_int ) :
+ iv_thVal(i_th), iv_thInt(i_int)
+ {}
+
+ /**
+ * @brief Increments the false alarm count.
+ * @param i_chip Target chip.
+ * @param i_key Key relative to the chip.
+ * @param io_sc The step code data struct.
+ * @return True if false alarm count has reached threshold, false otherwise.
+ */
+ bool inc( ExtensibleChip * i_chip, uint32_t i_key,
+ STEP_CODE_DATA_STRUCT & io_sc )
+ {
+ // Create a new entry if an entry does not exist.
+ if ( iv_map[i_chip].end() == iv_map[i_chip].find(i_key) )
+ iv_map[i_chip][i_key] = TimeBasedThreshold( iv_thVal, iv_thInt );
+
+ return iv_map[i_chip][i_key].inc( io_sc );
+ }
+
+ private:
+
+ const uint8_t iv_thVal; ///< Threshold value for all entries in the map.
+ const uint32_t iv_thInt; ///< Threshold interval for all entries in the map.
+
+ /** A nested map containing the thresholds for each chip and key. */
+ std::map< ExtensibleChip *, std::map<uint32_t,TimeBasedThreshold> > iv_map;
+};
+
+} // end namespace PRDF
+
+#endif // __HOSTBOOT_RUNTIME
+
+#endif // __prdfMemTdFalseAlarm_H
+
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H b/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H
index 7603328dc..9d20f5b1d 100755
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H
@@ -84,19 +84,25 @@ class TdEntry
* @brief Each entry will have a set of steps that need to be performed.
* This function tells the procedure to move onto the next step.
* @param io_sc The step code data struct.
- * @param o_done Returns true if this procedure is complete, false
+ * @param o_done True if the procedure is complete or has aborted, false
* otherwise.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
virtual uint32_t nextStep( STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done ) = 0;
+ /** @return Each event type will have a unique key identifier used for each
+ * procedure. The value is arbitrary. The only requirement is that
+ * it is unique to the hardware it is targeting. For example, VCM
+ * events will use only the master rank, where TPS events will use
+ * both the master and slave rank. */
+ virtual uint32_t getKey() const = 0;
+
/** @brief '==' operator */
bool operator==( const TdEntry & i_e ) const
{
- return ( this->iv_chip == i_e.iv_chip &&
- this->iv_tdType == i_e.iv_tdType &&
- this->iv_rank == i_e.iv_rank );
+ return ( this->iv_tdType == i_e.iv_tdType &&
+ this->getKey() == i_e.getKey() );
}
/**
@@ -126,21 +132,19 @@ class TdEntry
* @param i_rank Target rank
*/
TdEntry( TdType i_tdType, ExtensibleChip * i_chip, MemRank i_rank ) :
- iv_chip(i_chip), iv_tdType(i_tdType), iv_rank(i_rank)
- {
- PRDF_ASSERT( (TARGETING::TYPE_MCA == iv_chip->getType()) ||
- (TARGETING::TYPE_MBA == iv_chip->getType()) );
- }
+ iv_tdType(i_tdType), iv_chip(i_chip), iv_rank(i_rank)
+ {}
protected: // instance variables
- /** The chip associated with this entry. This isn't used for any
- * comparisons, but is needed for every TD procedure. */
- ExtensibleChip * const iv_chip;
-
- const TdType iv_tdType; ///< The event type (see enum TdType).
- const MemRank iv_rank; ///< The rank in which this event occurred.
+ const TdType iv_tdType; ///< The event type (see enum TdType).
Phase iv_phase = TD_PHASE_0; ///< The event phase (see enum Phase).
+
+ // These are not used for comparisons, but used by all procedures and also
+ // used for displaying FFDC in the TD controller.
+ ExtensibleChip * const iv_chip; ///< The chip in which this event occurred.
+ const MemRank iv_rank; ///< The rank in which this event occurred.
+
};
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTps.H b/src/usr/diag/prdf/plat/mem/prdfMemTps.H
index ef2fd6368..6b05550cb 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTps.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTps.H
@@ -48,10 +48,17 @@ class TpsEvent : public TdEntry
*/
TpsEvent<T>( ExtensibleChip * i_chip, MemRank i_rank, bool i_ban = false ) :
TdEntry(TPS_EVENT, i_chip, i_rank)
- {}
+ {
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( T == i_chip->getType() );
+ }
+
+ public: // overloaded functions from parent class
uint32_t nextStep( STEP_CODE_DATA_STRUCT & io_sc, bool & o_done );
+ uint32_t getKey() const { return iv_rank.getKey(); } // Master and slave
+
};
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm.H b/src/usr/diag/prdf/plat/mem/prdfMemVcm.H
index ab8414132..17dfaa517 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 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -29,31 +29,282 @@
#define __prdfMemVcm_H
// Platform includes
-#include <prdfMemTdQueue.H>
+#include <prdfMemEccAnalysis.H>
#include <prdfMemMark.H>
+#include <prdfMemScrubUtils.H>
+#include <prdfMemTdFalseAlarm.H>
+#include <prdfMemTdQueue.H>
+#include <prdfP9McaExtraSig.H>
+#include <prdfPlatServices.H>
namespace PRDF
{
/** @brief Verify chip mark procedure. */
-template <TARGETING::TYPE T>
+template<TARGETING::TYPE T>
class VcmEvent : public TdEntry
{
public: // functions
- /** @brief Constructor */
+ /**
+ * @brief Constructor
+ * @param i_chip MCA or MBA.
+ * @param i_rank Rank reporting chip mark.
+ * @param i_mark Chip mark placed by hardware.
+ */
VcmEvent<T>( ExtensibleChip * i_chip, const MemRank & i_rank,
const MemMark & i_mark ) :
TdEntry(VCM_EVENT, i_chip, i_rank), iv_mark(i_mark)
{
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( T == i_chip->getType() );
PRDF_ASSERT( i_mark.isValid() );
}
- uint32_t nextStep( STEP_CODE_DATA_STRUCT & io_sc, bool & o_done );
+ public: // overloaded functions from parent class
+
+ uint32_t nextStep( STEP_CODE_DATA_STRUCT & io_sc, bool & o_done )
+ {
+ uint32_t o_rc = SUCCESS;
+
+ o_done = false;
+
+ // Add the chip mark to the callout list.
+ MemoryMru mm { iv_chip->getTrgt(), iv_rank, iv_mark.getSymbol() };
+ io_sc.service_data->SetCallout( mm );
+
+ // Take action based on the current phase.
+ switch ( iv_phase )
+ {
+ case TD_PHASE_0:
+ o_rc = startPhase1( 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 );
+ break;
+
+ case TD_PHASE_2:
+ o_rc = analyzePhase2( io_sc, o_done );
+ break;
+
+ default: PRDF_ASSERT( false ); // invalid phase
+ }
+
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( "[VcmEvent::nextStep] failed: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+ }
+
+ return o_rc;
+ }
+
+ uint32_t getKey() const
+ { return MemRank(iv_rank.getMaster()).getKey(); } // Master rank only
+
+ private: // functions
+
+ /**
+ * @brief Starts phase 1 of the procedure.
+ * @param io_sc The step code data struct.
+ * @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 );
+ }
+
+ /**
+ * @brief Starts phase 2 of the procedure.
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ uint32_t startPhase2( STEP_CODE_DATA_STRUCT & io_sc )
+ {
+ PRDF_TRAC( "[VcmEvent] Starting VCM Phase 2: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ iv_phase = TD_PHASE_2;
+ io_sc.service_data->AddSignatureList( iv_chip->getTrgt(),
+ PRDFSIG_StartVcmPhase2 );
+
+ return PlatServices::startVcmPhase2<T>( iv_chip, iv_rank );
+ }
+
+ /**
+ * @brief Analyzes the state of the hardware after phase 1 completes.
+ * @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 analyzePhase1( STEP_CODE_DATA_STRUCT & io_sc, bool & o_done )
+ {
+ #define PRDF_FUNC "[VcmEvent::analyzePhase1] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ uint32_t eccAttns;
+ o_rc = checkEccFirs<T>( iv_chip, eccAttns );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "checkEccFirs(0x%08x) failed",
+ iv_chip->getHuid() );
+ break;
+ }
+
+ o_rc = checkEcc( eccAttns, io_sc, o_done );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "checkEcc() failed" );
+ break;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+ }
+
+ /**
+ * @brief Analyzes the state of the hardware after phase 1 completes.
+ * @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 analyzePhase2( STEP_CODE_DATA_STRUCT & io_sc, bool & o_done )
+ {
+ #define PRDF_FUNC "[VcmEvent::analyzePhase2] "
+
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ uint32_t eccAttns;
+ o_rc = checkEccFirs<T>( iv_chip, eccAttns );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "checkEccFirs(0x%08x) failed",
+ iv_chip->getHuid() );
+ break;
+ }
+
+ o_rc = checkEcc( eccAttns, io_sc, o_done );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "checkEcc() failed" );
+ break;
+ }
+
+ if ( o_done ) break; // nothing more to do
+
+ // 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;
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+ }
+
+ /**
+ * @brief Does isolation for ECC attentions during each phase. Note that
+ * isolation is the same for both phases.
+ * @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 checkEcc( 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.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ uint32_t verified( STEP_CODE_DATA_STRUCT & io_sc )
+ {
+ #define PRDF_FUNC "[VcmEvent::verified] "
+
+ uint32_t o_rc = SUCCESS;
+
+ PRDF_TRAC( PRDF_FUNC "Chip mark verified: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_VcmVerified );
+
+ do
+ {
+ // If DRAM repairs are disabled, make the error log predictive.
+ if ( PlatServices::areDramRepairsDisabled() )
+ {
+ io_sc.service_data->setServiceCall();
+ break; // Nothing more to do.
+ }
+
+ // If there is a symbol mark on the same DRAM as the newly verified
+ // chip mark, remove the symbol mark.
+ o_rc = MarkStore::balance<T>( iv_chip, iv_rank, io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "MarkStore::balance(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), getKey() );
+ break;
+ }
+
+ // Set the entire chip in DRAM Repairs VPD.
+ // TODO: RTC 169939
+
+ // Add a DRAM sparing procedure to the queue, if supported.
+ // TODO: RTC 157888
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+ }
+
+ /**
+ * @brief Verification failed. Do additional processing such as removing
+ * the chip mark and false alarm threshold handling.
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ uint32_t falseAlarm( STEP_CODE_DATA_STRUCT & io_sc );
private: // instance variables
- const MemMark iv_mark;
+ const MemMark iv_mark; ///< The chip mark from hardware.
+
+ #ifdef __HOSTBOOT_RUNTIME
+ /** False alarm counter for all instances of this class. */
+ static TdFalseAlarm cv_falseAlarm;
+ #endif
};
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
index 4eb08798f..730a2f687 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C
@@ -26,11 +26,7 @@
/** @file prdfMemVcm_ipl.C */
// Platform includes
-#include <prdfMemEccAnalysis.H>
#include <prdfMemVcm.H>
-#include <prdfMemScrubUtils.H>
-#include <prdfPlatServices.H>
-#include <prdfP9McaExtraSig.H>
using namespace TARGETING;
@@ -39,221 +35,149 @@ namespace PRDF
using namespace PlatServices;
-//------------------------------------------------------------------------------
+//##############################################################################
+//
+// Generic template functions
+//
+//##############################################################################
-template<>
-uint32_t VcmEvent<TYPE_MCA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc,
- bool & o_done )
+template<TARGETING::TYPE T>
+uint32_t VcmEvent<T>::falseAlarm( STEP_CODE_DATA_STRUCT & io_sc )
{
- #define PRDF_FUNC "[VcmEvent<TYPE_MCA>::nextStep] "
+ #define PRDF_FUNC "[VcmEvent::falseAlarm] "
uint32_t o_rc = SUCCESS;
- o_done = false;
- // add iv_mark to the callout list
- MemoryMru memmru( iv_chip->getTrgt(), iv_rank, iv_mark.getSymbol() );
- io_sc.service_data->SetCallout( memmru );
+ PRDF_TRAC( PRDF_FUNC "Chip mark false alarm: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_VcmFalseAlarm );
do
{
- //phase 0
- if ( TD_PHASE_0 == iv_phase )
+ // If DRAM repairs are disabled, make the error log predictive.
+ if ( areDramRepairsDisabled() )
{
- // Start VCM phase 1
- io_sc.service_data->AddSignatureList( iv_chip->getTrgt(),
- PRDFSIG_StartVcmPhase1 );
+ io_sc.service_data->setServiceCall();
+ break; // Nothing more to do.
+ }
- PRDF_TRAC( PRDF_FUNC "Starting VCM Phase 1" );
+ // Remove the chip mark.
+ o_rc = MarkStore::clearChipMark<T>( iv_chip, iv_rank );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "clearChipMark(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), getKey() );
+ break;
+ }
- o_rc = startVcmPhase1<TYPE_MCA>( iv_chip, iv_rank );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "startVcmPhase1(0x%08x, %d) failed",
- iv_chip->getHuid(), iv_rank.getMaster() );
- break;
- }
+ } while (0);
- iv_phase = TD_PHASE_1;
- }
- //phase 1
- else if ( TD_PHASE_1 == iv_phase )
- {
- //get the ecc attentions
- uint32_t eccAttns;
- o_rc = checkEccFirs<TYPE_MCA>( iv_chip, eccAttns );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "checkEccFirs(0x%08x) failed",
- iv_chip->getHuid() );
- break;
- }
+ return o_rc;
- //if there was a UE or IUE
- if ( (eccAttns & MAINT_UE) || (eccAttns & MAINT_IUE) )
- {
- PRDF_TRAC( PRDF_FUNC "UE Detected. Aborting this procedure." );
- //UE
- if ( eccAttns & MAINT_UE )
- {
- io_sc.service_data->setSignature( iv_chip->getHuid(),
- PRDFSIG_MaintUE );
- }
- //IUE
- else
- {
- io_sc.service_data->setSignature( iv_chip->getHuid(),
- PRDFSIG_MaintIUE );
- }
-
- // Do memory UE handling.
- o_rc = MemEcc::handleMemUe<TYPE_MCA>(iv_chip,
- MemAddr::fromRank(iv_rank),
- UE_TABLE::SCRUB_UE, io_sc);
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "handleMemUe<T>(0x%08x) failed",
- iv_chip->getHuid() );
- break;
- }
-
- //Leave the mark in place
- //Abort this procedure
- o_done = true;
- }
- else
- {
- // Start VCM phase 2
- io_sc.service_data->AddSignatureList( iv_chip->getTrgt(),
- PRDFSIG_StartVcmPhase2 );
+ #undef PRDF_FUNC
+}
- PRDF_TRAC( PRDF_FUNC "Starting VCM Phase 2" );
+//------------------------------------------------------------------------------
- o_rc = startVcmPhase2<TYPE_MCA>( iv_chip, iv_rank );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "startVcmPhase2(0x%08x, %d) failed",
- iv_chip->getHuid(), iv_rank.getMaster() );
- break;
- }
+// Avoid linker errors with the template.
+template class VcmEvent<TYPE_MCA>;
+template class VcmEvent<TYPE_MBA>;
- iv_phase = TD_PHASE_2;
- }
- }
- //phase 2
- else if ( TD_PHASE_2 == iv_phase )
- {
- //get the ecc attentions
- uint32_t eccAttns;
- o_rc = checkEccFirs<TYPE_MCA>( iv_chip, eccAttns );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "Call to 'checkEccFirs' failed on chip: "
- "0x%08x", iv_chip->getHuid() );
- break;
- }
+//##############################################################################
+//
+// Specializations for MCA
+//
+//##############################################################################
- //If DRAM repairs is disabled (via MNFG policy)
- if ( areDramRepairsDisabled() )
- {
- //Make the error log predictive
- io_sc.service_data->setServiceCall();
- }
+template<>
+uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool & o_done )
+{
+ #define PRDF_FUNC "[VcmEvent<TYPE_MCA>::checkEcc] "
- //if there was a UE or IUE
- if ( (eccAttns & MAINT_UE) || (eccAttns & MAINT_IUE) )
- {
- //UE
- if ( eccAttns & MAINT_UE )
- {
- io_sc.service_data->setSignature( iv_chip->getHuid(),
- PRDFSIG_MaintUE );
- }
- //IUE
- else
- {
- io_sc.service_data->setSignature( iv_chip->getHuid(),
- PRDFSIG_MaintIUE );
- }
-
- // Do memory UE handling.
- o_rc = MemEcc::handleMemUe<TYPE_MCA>(iv_chip,
- MemAddr::fromRank(iv_rank),
- UE_TABLE::SCRUB_UE, io_sc);
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "handleMemUe<T>(0x%08x) failed",
- iv_chip->getHuid() );
- break;
- }
-
- //Leave the mark in place
- }
- //else if there was a MCE
- else if ( eccAttns & MAINT_MCE )
- {
- PRDF_TRAC( PRDF_FUNC "Chip mark verified" );
-
- //The chip mark is verified
- io_sc.service_data->setSignature( iv_chip->getHuid(),
- PRDFSIG_VcmVerified );
-
- // If there is a symbol mark on the same DRAM as the newly
- // verified chip mark, remove the symbol mark.
- o_rc = MarkStore::balance<TYPE_MCA>( iv_chip, iv_rank, io_sc );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "MarkStore::balance(0x%08x, %d) failed",
- iv_chip->getHuid(), iv_rank.getMaster() );
- }
-
- // Set entire chip in DRAM Repairs VPD.
- // TODO: RTC 169939
- }
- //else - verification failed
- else
- {
- PRDF_TRAC( PRDF_FUNC "Chip mark false alarm" );
+ uint32_t o_rc = SUCCESS;
- io_sc.service_data->setSignature( iv_chip->getHuid(),
- PRDFSIG_VcmFalseAlarm );
+ do
+ {
+ // IUEs are reported as UEs during read operations. Therefore, we will
+ // treat IUEs like UEs for these scrub operations simply to maintain
+ // consistency during all of Memory Diagnostics.
+ if ( (i_eccAttns & MAINT_UE) || (i_eccAttns & MAINT_IUE) )
+ {
+ PRDF_TRAC( PRDF_FUNC "UE Detected: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
- //Remove the chip mark
- o_rc = MarkStore::clearChipMark<TYPE_MCA>( iv_chip, iv_rank );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "Failure to clear chip mark on chip: "
- "0x%08x", iv_chip->getHuid() );
- }
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ (i_eccAttns & MAINT_UE)
+ ? PRDFSIG_MaintUE
+ : PRDFSIG_MaintIUE );
+ o_rc = MemEcc::handleMemUe<TYPE_MCA>( iv_chip,
+ MemAddr::fromRank(iv_rank),
+ UE_TABLE::SCRUB_UE, io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "handleMemUe(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), getKey() );
+ break;
}
- //Abort the procedure
- o_done = true;
- }
- else
- {
- PRDF_ASSERT( false ); //invalid value in iv_phase
+
+ // Leave the mark in place and abort this procedure.
+ o_done = true; break;
}
- }while(0);
+
+ } while (0);
return o_rc;
#undef PRDF_FUNC
}
-//------------------------------------------------------------------------------
+//##############################################################################
+//
+// Specializations for MBA
+//
+//##############################################################################
-// TODO: RTC 157888 Actual implementation of this procedure will be done later.
template<>
-uint32_t VcmEvent<TYPE_MBA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc,
+uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
{
- #define PRDF_FUNC "[VcmEvent<TYPE_MBA>::nextStep] "
+ #define PRDF_FUNC "[VcmEvent<TYPE_MBA>::checkEcc] "
uint32_t o_rc = SUCCESS;
- o_done = true;
+ do
+ {
+ // IUEs (reported via RCE ETE) are reported as UEs during read
+ // operations. Therefore, we will treat IUEs like UEs for these scrub
+ // operations simply to maintain consistency during all of Memory
+ // Diagnostics.
+ if ( (i_eccAttns & MAINT_UE) || (i_eccAttns & MAINT_RCE_ETE) )
+ {
+ PRDF_TRAC( PRDF_FUNC "UE Detected: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ (i_eccAttns & MAINT_UE)
+ ? PRDFSIG_MaintUE
+ : PRDFSIG_MaintRETRY_CTE );
+ // TODO: RTC 157888
+ // - Call mssIplUeIsolation() and add all DIMMs with bad bits to the
+ // callout list.
+ // - Make the error log predictive.
+ // - Might be able to tuck this into MemEcc::handleMemUe().
+ PRDF_ERR( PRDF_FUNC "function not implemented yet" );
+
+ // Leave the mark in place and abort this procedure.
+ o_done = true;
+ }
- PRDF_ERR( PRDF_FUNC "function not implemented yet" );
+ } while (0);
return o_rc;
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
index 6952f40f5..02b577216 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C
@@ -27,46 +27,227 @@
// Platform includes
#include <prdfMemVcm.H>
+#include <prdfP9McaDataBundle.H>
using namespace TARGETING;
namespace PRDF
{
+using namespace PlatServices;
+
+//##############################################################################
+//
+// Generic template functions
+//
+//##############################################################################
+
+template<TARGETING::TYPE T>
+uint32_t VcmEvent<T>::falseAlarm( STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[VcmEvent::falseAlarm] "
+
+ uint32_t o_rc = SUCCESS;
+
+ PRDF_TRAC( PRDF_FUNC "Chip mark false alarm: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_VcmFalseAlarm );
+
+ do
+ {
+ // If DRAM repairs are disabled, make the error log predictive.
+ if ( areDramRepairsDisabled() )
+ {
+ io_sc.service_data->setServiceCall();
+ break; // Nothing more to do.
+ }
+
+ // Increment the false alarm counter and check threshold.
+ if ( cv_falseAlarm.inc(iv_chip, getKey(), io_sc) )
+ {
+ // False alarm threshold has been reached. Leave the mark in place
+ // and treat the chip mark as verified.
+
+ io_sc.service_data->AddSignatureList( iv_chip->getTrgt(),
+ PRDFSIG_VcmFalseAlarm );
+
+ PRDF_TRAC( PRDF_FUNC "False alarm threshold: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ o_rc = verified( io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "verified() failed" );
+ break;
+ }
+ }
+ else
+ {
+ // Remove the chip mark.
+ o_rc = MarkStore::clearChipMark<T>( iv_chip, iv_rank );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "clearChipMark(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), getKey() );
+ break;
+ }
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
//------------------------------------------------------------------------------
-// TODO: RTC 171913 Actual implementation of this procedure will be done later.
+// Avoid linker errors with the template.
+template class VcmEvent<TYPE_MCA>;
+template class VcmEvent<TYPE_MBA>;
+
+//##############################################################################
+//
+// Specializations for MCA
+//
+//##############################################################################
+
template<>
-uint32_t VcmEvent<TYPE_MCA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc,
+TdFalseAlarm VcmEvent<TYPE_MCA>::cv_falseAlarm
+ = TdFalseAlarm { 4, ThresholdResolution::ONE_DAY };
+
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t VcmEvent<TYPE_MCA>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
{
- #define PRDF_FUNC "[VcmEvent<TYPE_MCA>::nextStep] "
+ #define PRDF_FUNC "[VcmEvent<TYPE_MCA>::checkEcc] "
uint32_t o_rc = SUCCESS;
- o_done = true;
+ do
+ {
+ if ( i_eccAttns & MAINT_UE )
+ {
+ PRDF_TRAC( PRDF_FUNC "UE Detected: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_MaintUE );
+
+ o_rc = MemEcc::handleMemUe<TYPE_MCA>( iv_chip,
+ MemAddr::fromRank(iv_rank),
+ UE_TABLE::SCRUB_UE, io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "handleMemUe(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), getKey() );
+ break;
+ }
+
+ // Leave the mark in place and abort this procedure.
+ o_done = true; break;
+ }
+
+ if ( mfgMode() && (i_eccAttns & MAINT_IUE) )
+ {
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_MaintIUE );
+
+ o_rc = MemEcc::handleMemIue<TYPE_MCA, McaDataBundle *>( iv_chip,
+ iv_rank,
+ io_sc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "handleMemIue(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), getKey() );
+ break;
+ }
+
+ // If service call is set, then IUE threshold was reached.
+ if ( io_sc.service_data->queryServiceCall() )
+ {
+ PRDF_TRAC( PRDF_FUNC "IUE threshold detected: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
- PRDF_ERR( PRDF_FUNC "function not implemented yet" );
+ // Leave the mark in place and abort this procedure.
+ o_done = true; break;
+ }
+ }
+
+ } while (0);
return o_rc;
#undef PRDF_FUNC
}
+//##############################################################################
+//
+// Specializations for MBA
+//
+//##############################################################################
+
+template<>
+TdFalseAlarm VcmEvent<TYPE_MBA>::cv_falseAlarm
+ = TdFalseAlarm { 4, 7 * ThresholdResolution::ONE_DAY };
+
//------------------------------------------------------------------------------
-// TODO: RTC 157888 Actual implementation of this procedure will be done later.
template<>
-uint32_t VcmEvent<TYPE_MBA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc,
+uint32_t VcmEvent<TYPE_MBA>::checkEcc( const uint32_t & i_eccAttns,
+ STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
{
- #define PRDF_FUNC "[VcmEvent<TYPE_MBA>::nextStep] "
+ #define PRDF_FUNC "[VcmEvent<TYPE_MBA>::checkEcc] "
uint32_t o_rc = SUCCESS;
- o_done = true;
+ do
+ {
+ if ( i_eccAttns & MAINT_UE )
+ {
+ PRDF_TRAC( PRDF_FUNC "UE Detected: 0x%08x,0x%02x",
+ iv_chip->getHuid(), getKey() );
+
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_MaintUE );
+
+ /* TODO: RTC 157888
+ o_rc = MemEcc::handleMemUe<TYPE_MBA>( iv_chip,
+ MemAddr::fromRank(iv_rank),
+ UE_TABLE::SCRUB_UE, io_sc );
+ */
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "handleMemUe(0x%08x,0x%02x) failed",
+ iv_chip->getHuid(), getKey() );
+ break;
+ }
+
+ // Leave the mark in place and abort this procedure.
+ o_done = true; break;
+ }
+
+ if ( i_eccAttns & MAINT_RCE_ETE )
+ {
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_MaintRETRY_CTE );
+
+ // Add the rank to the callout list.
+ MemoryMru mm { iv_chip->getTrgt(), iv_rank,
+ MemoryMruData::CALLOUT_RANK };
+ io_sc.service_data->SetCallout( mm );
+
+ // Make the error log predictive.
+ io_sc.service_data->setServiceCall();
+ }
- PRDF_ERR( PRDF_FUNC "function not implemented yet" );
+ } while (0);
return o_rc;
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C
index b0d8f8328..06102c3d1 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.C
@@ -432,7 +432,7 @@ uint32_t __startTdScrub_mca( ExtensibleChip * i_mcaChip,
// startBgScrub() for the reasons why.
i_stopCond.set_pause_on_aue(mss::ON);
- // Start the super fast read command.
+ // Start targeted scrub command.
errlHndl_t errl;
FAPI_INVOKE_HWP( errl, memdiags::targeted_scrub, fapiTrgt, i_stopCond,
i_saddr, i_eaddr, mss::mcbist::NONE );
@@ -573,26 +573,6 @@ uint32_t startBgScrub<TYPE_MBA>( ExtensibleChip * i_mbaChip,
//------------------------------------------------------------------------------
template<>
-uint32_t startVcmPhase1<TYPE_MBA>( ExtensibleChip * i_mbaChip,
- const MemRank & i_rank )
-{
- PRDF_ERR( "function not implemented yet" ); // TODO RTC 157888
- return SUCCESS;
-}
-
-//------------------------------------------------------------------------------
-
-template<>
-uint32_t startVcmPhase2<TYPE_MBA>( ExtensibleChip * i_mbaChip,
- const MemRank & i_rank )
-{
- PRDF_ERR( "function not implemented yet" ); // TODO RTC 157888
- return SUCCESS;
-}
-
-//------------------------------------------------------------------------------
-
-template<>
uint32_t startTpsPhase1<TYPE_MBA>( ExtensibleChip * i_mbaChip,
const MemRank & i_rank )
{
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.H b/src/usr/diag/prdf/plat/prdfPlatServices.H
index bea0a3c6c..00eef6888 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.H
@@ -120,7 +120,7 @@ uint32_t startBgScrub( ExtensibleChip * i_chip, const MemRank & i_rank );
/**
* @brief Starts a targeted scrub command on the target rank for VCM phase 1.
* @param i_chip MCA or MBA chip.
- * @param i_rank The rank to target.
+ * @param i_rank The rank to target.
* @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
*/
template<TARGETING::TYPE T>
@@ -129,7 +129,7 @@ uint32_t startVcmPhase1( ExtensibleChip * i_chip, const MemRank & i_rank );
/**
* @brief Starts a targeted scrub command on the target rank for VCM phase 2.
* @param i_chip MCA or MBA chip.
- * @param i_rank The rank to target.
+ * @param i_rank The rank to target.
* @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
*/
template<TARGETING::TYPE T>
@@ -138,7 +138,7 @@ uint32_t startVcmPhase2( ExtensibleChip * i_chip, const MemRank & i_rank );
/**
* @brief Starts a targeted scrub command on the target rank for TPS phase 1.
* @param i_chip MCA or MBA chip.
- * @param i_rank The rank to target.
+ * @param i_rank The rank to target.
* @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
*/
template<TARGETING::TYPE T>
@@ -147,7 +147,7 @@ uint32_t startTpsPhase1( ExtensibleChip * i_chip, const MemRank & i_rank );
/**
* @brief Starts a targeted scrub command on the target rank for TPS phase 2.
* @param i_chip MCA or MBA chip.
- * @param i_rank The rank to target.
+ * @param i_rank The rank to target.
* @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
*/
template<TARGETING::TYPE T>
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
index 8f5fdb34e..3a6d53f63 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
@@ -317,6 +317,54 @@ uint32_t startSfRead<TYPE_MBA>( ExtensibleChip * i_mbaChip,
//------------------------------------------------------------------------------
+template<>
+uint32_t startVcmPhase1<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank )
+{
+ #define PRDF_FUNC "[PlatServices::startVcmPhase1<TYPE_MBA>] "
+
+ 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.
+
+ PRDF_ERR( PRDF_FUNC "function not implemented yet" );
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t startVcmPhase2<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank )
+{
+ #define PRDF_FUNC "[PlatServices::startVcmPhase2<TYPE_MBA>] "
+
+ 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.
+
+ PRDF_ERR( PRDF_FUNC "function not implemented yet" );
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
} // end namespace PlatServices
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_rt.C b/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
index 687fc0b86..012ab02ac 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_rt.C
@@ -260,6 +260,61 @@ uint32_t resumeBgScrub<TYPE_MBA>( ExtensibleChip * i_chip )
//------------------------------------------------------------------------------
+template<>
+uint32_t startVcmPhase1<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank )
+{
+ #define PRDF_FUNC "[PlatServices::startVcmPhase1<TYPE_MBA>] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
+
+ // TODO RTC 157888
+ // - Start a time based scrub.
+ // - If fast scrub is enabled use FAST_MAX_BW_IMPACT speed, otherwise use
+ // FAST_MIN_BW_IMPACT speed.
+ // - Stop on UE.
+ // - Stop on RCE ETE (threshold 2047 field, 1 mnfg).
+ // - The command should stop immediately on error, or at the end of the
+ // master rank if no errors are found.
+
+ PRDF_ERR( "function not implemented yet" );
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t startVcmPhase2<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank )
+{
+ #define PRDF_FUNC "[PlatServices::startVcmPhase2<TYPE_MBA>] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
+
+ // TODO RTC 157888
+ // - Start a time based scrub.
+ // - If fast scrub is enabled use FAST_MAX_BW_IMPACT speed, otherwise use
+ // FAST_MIN_BW_IMPACT speed.
+ // - Stop on UE.
+ // - Stop on MCE.
+ // - Stop on RCE ETE (threshold 2047 field, 1 mnfg).
+ // - The command should stop immediately on error, or at the end of the
+ // master rank if no errors are found.
+
+ PRDF_ERR( "function not implemented yet" );
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
} // end namespace PlatServices
} // end namespace PRDF
OpenPOWER on IntegriCloud