diff options
| author | Zane Shelley <zshelle@us.ibm.com> | 2017-05-15 16:35:40 -0500 |
|---|---|---|
| committer | Zane C. Shelley <zshelle@us.ibm.com> | 2017-06-08 16:44:28 -0400 |
| commit | e1929d0094d34bd207cfc6533f1e77b4d122060e (patch) | |
| tree | c7a03b9b0cba6a8aea6b4ab1207be3a385ff283d | |
| parent | bf3f4096b25c185704d5dec4c15711e8139eb966 (diff) | |
| download | blackbird-hostboot-e1929d0094d34bd207cfc6533f1e77b4d122060e.tar.gz blackbird-hostboot-e1929d0094d34bd207cfc6533f1e77b4d122060e.zip | |
PRD: runtime VCM support
Change-Id: Ibeb45ceb1a2d0db1e3941b5b8ac5f9e2f5122770
RTC: 171913
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40942
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@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>
Squashed: I85a0240782b2985797a2ace1aa3eb9a9a18cb621
Squashed: I1663ee55509348cdaddf216d0b3c9ac527c21113
Squashed: Ib9a3bef7a4df3b1b2a5914cf4155dca569c11026
Squashed: I3739b49f17a5413a0ad9c3adfd555f74b91895cc
Squashed: Ifc2e4501775a09ad06381970ba47be5b953312d8
Squashed: Id7f5648ed810f9505acecea99cb27af2d832a669
Squashed: I0ec33104ac7920282482e79c2376d115a1274b46
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41040
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
| -rwxr-xr-x | src/usr/diag/prdf/common/plat/mem/prdfMemRank.H | 8 | ||||
| -rw-r--r-- | src/usr/diag/prdf/common/plat/mem/prdfP9McaExtraSig.H | 1 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTdFalseAlarm.H | 95 | ||||
| -rwxr-xr-x | src/usr/diag/prdf/plat/mem/prdfMemTdQueue.H | 34 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTps.H | 9 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemVcm.H | 263 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemVcm_ipl.C | 288 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemVcm_rt.C | 201 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices.C | 22 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices.H | 8 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices_ipl.C | 48 | ||||
| -rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices_rt.C | 55 |
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 |

