summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-06-15 10:18:27 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-06-22 14:19:21 -0400
commitbc2f2095a281a21ab45b829e67c9f1788d5f9984 (patch)
treef3899cd71f2ec77f0c1bf4d546ae7b0dfc7b8473
parentdb5ae2e4c6643b00ee92fc66cd367a678864413f (diff)
downloadtalos-hostboot-bc2f2095a281a21ab45b829e67c9f1788d5f9984.tar.gz
talos-hostboot-bc2f2095a281a21ab45b829e67c9f1788d5f9984.zip
Change memdiags/mcbist stop conditions to incorporate end, thresholds
Change-Id: I74659dc9efd3a348abaa12c65e9aed6eae0fba15 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/25993 Tested-by: Hostboot CI Tested-by: Jenkins Server Reviewed-by: Brian R. Silver <bsilver@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/25998 Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H135
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C112
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H50
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H467
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/tests/mss_memdiags_ut.C166
8 files changed, 626 insertions, 313 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
index 067b1362b..0e678fb79 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
@@ -616,11 +616,12 @@ class program
iv_addr_gen.insertFromRight<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(0b0000);
// By default if there's an error, we stop after the errored address
- iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(
- stop_conditions::STOP_AFTER_ADDRESS);
+ iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE,
+ TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(end_boundary::STOP_AFTER_ADDRESS);
// All mcbist attentions are host attentions, special attention bit is already clear
iv_config.setBit<TT::CFG_ENABLE_HOST_ATTN>();
+
}
///
@@ -636,16 +637,67 @@ class program
///
/// @brief Change the mcbist thresholds
- /// @param[in] i_thresholds the new thresholds
+ /// @param[in] i_thresholds the new thresholds/stop conditions
/// @return void
///
- inline void change_thresholds( const thresholds& i_thresholds )
+ inline void change_thresholds( const stop_conditions& i_thresholds )
{
iv_thresholds = i_thresholds;
return;
}
///
+ /// @brief Change the forced pause state
+ /// @param[in] i_end the end_boundary to pause at
+ /// @return void
+ ///
+ inline void change_forced_pause( const end_boundary& i_end )
+ {
+ if (i_end == end_boundary::DONT_CHANGE)
+ {
+ return;
+ }
+
+ // Clear all the forced pause bits so we don't stack pauses
+ iv_config.clearBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>();
+ iv_config.clearBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
+ iv_config.clearBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>();
+ iv_addr_gen.clearBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
+
+ switch (i_end)
+ {
+ case end_boundary::STOP_AFTER_ADDRESS:
+ iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>();
+ break;
+
+ case end_boundary::STOP_AFTER_SLAVE_RANK:
+ iv_config.setBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
+ iv_addr_gen.setBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
+ break;
+
+ case end_boundary::STOP_AFTER_MASTER_RANK:
+ iv_config.setBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
+ iv_addr_gen.clearBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
+ break;
+
+ case end_boundary::STOP_AFTER_SUBTEST:
+ iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>();
+ break;
+
+ // None is all set, we cleared the bits above
+ case end_boundary::NONE:
+ break;
+
+ // Default is a no forced pause (as we cleared all the bits)
+ default:
+ FAPI_INF("no forced pause state - end state %d unknown", i_end);
+ break;
+ };
+
+ return;
+ }
+
+ ///
/// @brief Change MCBIST Speed
/// @param[in] i_target the target behind which the memory sits
/// @param[in] i_speed the speed eunmeration
@@ -706,70 +758,33 @@ class program
}
///
- /// @brief Change MCBIST Stop conditions
- /// @param[in] i_stops the stop conditions
- /// @param[in] i_only_if_error forces the stop conditions to only be in effect if there is an error
- /// if there is not an error the subtest continues. Defaults to mss::NO, meaning these are forced conditions
- /// @return FAPI2_RC_SUCCSS iff ok
+ /// @brief Change MCBIST Stop-on-error conditions (end boundaries)
+ /// @param[in] i_end the end boundary
/// @note By default the MCBIST is programmed to always stop after an errored address. This API
/// allows the caller to force a stop at a boundary or to force no stopping on errors
///
- inline void change_stops( const stop_conditions i_stops, const bool i_only_if_error = mss::NO )
+ inline void change_end_boundary( const end_boundary i_end )
{
- // If there's no change, just get outta here
- if (i_stops == DONT_CHANGE)
- {
- goto fapi_try_exit;
- }
+ // Which bit in the end boundary which siginifies this is a slave rank detect situation
+ constexpr uint64_t SLAVE_RANK_INDICATED_BIT = 61;
- // If these conditions only take effect when there's an error, set that up in the ERROR_MODE field
- // NO_STOP_ON_ERROR is specific to the ERROR MODE field, so set that up here too
- if ((i_only_if_error == mss::YES) || (i_stops == NO_STOP_ON_ERROR))
+ // If there's no change, just get outta here
+ if (i_end == DONT_CHANGE)
{
- iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(i_stops);
- goto fapi_try_exit;
+ return;
}
- // Otherwise, these are forced conditions and they need to be put in their specific fields
- switch(i_stops)
- {
- case STOP_AFTER_ADDRESS:
- iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>();
- break;
-
- case STOP_AFTER_RANK:
- iv_config.setBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>();
- break;
-
- case STOP_AFTER_SUBTEST:
- iv_config.setBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>();
- break;
+ // The values of the enum were crafted so that we can simply insertFromRight into the register.
+ // We take note of whether to set the slave or master rank indicator and set that as well.
+ // The hardware has to have a 1 or a 0 - so there is no choice for the rank detection. So it
+ // doesn't matter that we're processing other end boundaries here - they'll just look like we
+ // asked for a master rank detect.
+ iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(i_end);
- // Same as don't-change
- default:
- break;
- };
-
- fapi_try_exit:
- FAPI_INF("load MCBIST stops: 0x%016lx (0x%016lx)", i_stops, iv_config);
-
- return;
- }
-
- ///
- /// @brief Change MCBIST End boundaries
- /// @param[in] i_end the end boundary
- /// @return FAPI2_RC_SUCCSS iff ok
- /// @note this really is just deciding if the stop conditions are master or slave rank boundaries
- ///
- inline void change_end_boundary( const end_boundary i_end )
- {
- // This is a little funny ... the hardware has one bit representing 'master' and 'slave'
- // So, NONE really represents a stop condition. We probably should combine the two, but the
- // API doc from PRD asks for them separate.
- uint64_t l_detect_slave = i_end == end_boundary::SLAVE_RANK ? 1 : 0;
+ FAPI_INF("i_end 0x%016lx", i_end);
+ uint64_t l_detect_slave = fapi2::buffer<uint64_t>(i_end).getBit<SLAVE_RANK_INDICATED_BIT>();
+ iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>( l_detect_slave );
FAPI_INF("load MCBIST end boundaries: detect slave? %s", (l_detect_slave == 1 ? "yes" : "no") );
- iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>(l_detect_slave);
}
///
@@ -1139,8 +1154,8 @@ class program
// The pattern for the pattern generator
uint64_t iv_pattern;
- // The error thresholds for the program
- thresholds iv_thresholds;
+ // The error stop conditions, thresholds for the program
+ stop_conditions iv_thresholds;
};
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C
index 004f36720..c9e8c77b3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C
@@ -117,14 +117,11 @@ fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::base_init()
// Load pattern
FAPI_TRY( iv_program.change_pattern(iv_const.iv_pattern) );
- // Load stop conditions
- iv_program.change_stops(iv_const.iv_stop);
-
// Load end boundaries
iv_program.change_end_boundary(iv_const.iv_end_boundary);
// Load thresholds
- iv_program.change_thresholds(iv_const.iv_thresholds);
+ iv_program.change_thresholds(iv_const.iv_stop);
// Setup the requested speed
FAPI_TRY( iv_program.change_speed(iv_target, iv_const.iv_speed) );
@@ -428,19 +425,19 @@ fapi_try_exit:
/// @note Uses broadcast mode if possible
/// @param[in] i_target the target behind which all memory should be read
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
+/// @param[in] i_end whether to end, and where - defaults to immediate (stop after failed address)
/// @return FAPI2_RC_SUCCESS iff everything ok
/// @note The function is asynchronous, and the caller should be looking for a done attention
///
template<>
fapi2::ReturnCode sf_read( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds )
+ const stop_conditions& i_stop,
+ const end_boundary i_end )
{
FAPI_INF("superfast read start");
fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, i_thresholds);
+ constraints l_const(i_stop, speed::LUDICROUS, i_end, mss::mcbist::address());
sf_read_operation<TARGET_TYPE_MCBIST> l_read_op(i_target, l_const, l_rc);
FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
@@ -457,21 +454,21 @@ fapi_try_exit:
/// @brief Super Fast Read to End of Port - used to run superfast read on all memory behind the target
/// @param[in] i_target the target behind which all memory should be read
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
/// @param[in] i_address mcbist::address representing the port, dimm, rank
+/// @param[in] i_end whether to end, and where - defaults to immediate (stop after failed address)
/// @return FAPI2_RC_SUCCESS iff everything ok
/// @note The function is asynchronous, and the caller should be looking for a done attention
///
template<>
fapi2::ReturnCode sf_read( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds,
- const mss::mcbist::address& i_address )
+ const stop_conditions& i_stop,
+ const mss::mcbist::address& i_address,
+ const end_boundary i_end )
{
FAPI_INF("superfast read - end of port");
fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, i_thresholds, i_address);
+ constraints l_const(i_stop, speed::LUDICROUS, i_end, i_address);
sf_read_eop_operation<TARGET_TYPE_MCBIST> l_read_op(i_target, l_const, l_rc);
FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
@@ -488,7 +485,6 @@ fapi_try_exit:
/// @brief Scrub - continuous scrub all memory behind the target
/// @param[in] i_target the target behind which all memory should be scrubbed
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
/// @param[in] i_speed the speed to scrub
/// @param[in] i_address mcbist::address representing the port, dimm, rank
/// @return FAPI2_RC_SUCCESS iff everything ok
@@ -496,15 +492,14 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode background_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds,
+ const stop_conditions& i_stop,
const speed i_speed,
const mss::mcbist::address& i_address )
{
FAPI_INF("continuous (background) scrub");
fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, i_thresholds, i_speed, end_boundary::NONE, i_address);
+ constraints l_const(i_stop, i_speed, end_boundary::NONE, i_address);
continuous_scrub_operation<TARGET_TYPE_MCBIST> l_op(i_target, l_const, l_rc);
FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
@@ -521,7 +516,6 @@ fapi_try_exit:
/// @brief Scrub - targeted scrub all memory behind the target
/// @param[in] i_target the target behind which all memory should be scrubbed
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
/// @param[in] i_speed the speed to scrub
/// @param[in] i_address mcbist::address representing the port, dimm, rank
/// @param[in] i_end whether to end, and where
@@ -530,22 +524,21 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode targeted_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds,
+ const stop_conditions& i_stop,
const speed i_speed,
const mss::mcbist::address& i_address,
const end_boundary i_end )
{
FAPI_INF("targeted scrub");
- if (i_stop == memdiags::stop_conditions::DONT_STOP)
+ if (i_end == end_boundary::NONE)
{
- FAPI_ERR("targeted scrub must have stop conditions");
+ FAPI_ERR("targeted scrub must have end boundaries");
return FAPI2_RC_INVALID_PARAMETER;
}
fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, i_thresholds, i_speed, i_end, i_address);
+ constraints l_const(i_stop, i_speed, i_end, i_address);
targeted_scrub_operation<TARGET_TYPE_MCBIST> l_op(i_target, l_const, l_rc);
FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
@@ -559,11 +552,10 @@ fapi_try_exit:
}
///
-/// @brief Continue current command on next address - change thresholds
+/// @brief Continue current command on next address
/// The current commaand has paused on an error, so we can record the address of the error
/// and finish the current master or slave rank.
/// @param[in] i_target the target
-/// @param[in] i_thresholds new thresholds
/// @param[in] i_end whether to end, and where (default = don't stop at end of rank)
/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
/// @param[in] i_speed the speed to scrub (default - NO_CHANGE meaning leave speed untouched)
@@ -572,9 +564,8 @@ fapi_try_exit:
///
template<>
fapi2::ReturnCode continue_cmd( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const thresholds& i_thresholds,
const end_boundary i_end,
- const stop_conditions i_stop,
+ const stop_conditions& i_stop,
const speed i_speed )
{
// Too long, make shorter
@@ -589,37 +580,44 @@ fapi2::ReturnCode continue_cmd( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targe
// TODO RTC:155518 Check for stop or in progress before allowing continue. Not critical
// as the caller should know and can check the in-progress bit in the event they don't
- // This is OK as because the i_end is optional, for the caller to specify a
- // stop condition other than DONT_CHANGE, they'd have to specify the end too
- // It doean't make any sense to have a 'don't stop' in the end boundaries as
- // you need to tell the stop conditions that.
- if (i_stop != stop_conditions::DONT_CHANGE)
+ if (i_end != end_boundary::DONT_CHANGE)
{
// Before we go too far, check to see if we're already stopped at the boundary we are asking to stop at
bool l_stopped_at_boundary = false;
uint64_t l_error_mode = 0;
+ bool l_detect_slave = false;
- FAPI_TRY( mss::getScom(i_target, MCBIST_MCBCFGQ, l_program.iv_config) );
+ FAPI_TRY( mss::getScom(i_target, TT::CFGQ_REG, l_program.iv_config) );
+ FAPI_TRY( mss::getScom(i_target, TT::MCBAGRAQ_REG, l_program.iv_addr_gen) );
l_program.iv_config.extractToRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(l_error_mode);
+ l_detect_slave = l_program.iv_addr_gen.getBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>();
- switch (i_stop)
+ switch (i_end)
{
- case stop_conditions::STOP_AFTER_ADDRESS:
+ case end_boundary::STOP_AFTER_ADDRESS:
l_stopped_at_boundary =
l_program.iv_config.getBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR>() ||
- l_error_mode == stop_conditions::STOP_AFTER_ADDRESS;
+ l_error_mode == end_boundary::STOP_AFTER_ADDRESS;
+ break;
+
+ case end_boundary::STOP_AFTER_SLAVE_RANK:
+ // Note: we really want STOP_AFTER_MASTER_RANK here even though we're in the slave
+ // case because MASTER_RANK has the a 0 so that l_error_mode will check correctly
+ l_stopped_at_boundary =
+ l_program.iv_config.getBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>() ||
+ ((l_error_mode == end_boundary::STOP_AFTER_MASTER_RANK) && (l_detect_slave == false));
break;
- case stop_conditions::STOP_AFTER_RANK:
+ case end_boundary::STOP_AFTER_MASTER_RANK:
l_stopped_at_boundary =
l_program.iv_config.getBit<TT::MCBIST_CFG_PAUSE_AFTER_RANK>() ||
- l_error_mode == stop_conditions::STOP_AFTER_RANK;
+ ((l_error_mode == end_boundary::STOP_AFTER_MASTER_RANK) && (l_detect_slave == true));
break;
- case stop_conditions::STOP_AFTER_SUBTEST:
+ case end_boundary::STOP_AFTER_SUBTEST:
l_stopped_at_boundary =
l_program.iv_config.getBit<TT::MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST>() ||
- l_error_mode == stop_conditions::STOP_AFTER_SUBTEST;
+ l_error_mode == end_boundary::STOP_AFTER_SUBTEST;
break;
// By default we're not stopped at a boundary we're going to continue from
@@ -635,8 +633,6 @@ fapi2::ReturnCode continue_cmd( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targe
// Read-modify-write the fields in the program.
FAPI_TRY( mss::getScom(i_target, TT::MCBAGRAQ_REG, l_program.iv_addr_gen) );
- l_program.change_stops(i_stop);
-
l_program.change_end_boundary(i_end);
FAPI_TRY( mss::mcbist::load_addr_gen(i_target, l_program) );
@@ -645,7 +641,7 @@ fapi2::ReturnCode continue_cmd( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targe
}
// Thresholds
- FAPI_TRY( mss::mcbist::load_thresholds(i_target, i_thresholds) );
+ FAPI_TRY( mss::mcbist::load_thresholds(i_target, i_stop) );
// Setup speed
FAPI_TRY( l_program.change_speed(i_target, i_speed) );
@@ -661,34 +657,4 @@ fapi_try_exit:
return fapi2::current_err;
}
-///
-/// @brief Continue current command on next address
-/// The current commaand has paused on an error, so we can record the address of the error
-/// and finish the current master or slave rank.
-/// @param[in] i_target the target
-/// @param[in] i_end where to end, if stop conditions change (defaults to Master Rank)
-/// @param[in] i_stop stop conditions (default - DONT_CHANGE meaning 'don't change conditions')
-/// @param[in] i_speed the speed to scrub (default - SAM_SPEED meaning leave speed untouched)
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template<>
-fapi2::ReturnCode continue_cmd( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const end_boundary i_end,
- const stop_conditions i_stop,
- const speed i_speed )
-{
- FAPI_INF("continue_cmd - no change thresholds");
-
- // Read current thresholds and pass them as if they're changed.
- fapi2::buffer<uint64_t> i_thresholds;
- FAPI_TRY( mss::getScom(i_target, mss::mcbist::mcbistTraits<TARGET_TYPE_MCBIST>::THRESHOLD_REG, i_thresholds) );
-
- return continue_cmd( i_target, thresholds(i_thresholds), i_end, i_stop, i_speed );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H
index 961fc5f73..796126171 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H
@@ -43,7 +43,6 @@ namespace memdiags
// Map some of the mcbist namespace here to make it easier for users of memdiags
// This is an intentional using statement in a header which is typically
// disallowed - I am intentionally pulling these into this namespace for all callers.
-using mss::mcbist::thresholds;
using mss::mcbist::constraints;
using mss::mcbist::speed;
using mss::mcbist::end_boundary;
@@ -291,6 +290,9 @@ struct targeted_scrub_operation : public operation<T>
// We're a single-port operation
o_rc = this->single_port_init();
+
+ // Targeted scrub needs to force a pause and the end boundary. So we make sure that happens here.
+ this->iv_program.change_forced_pause( i_const.iv_end_boundary );
}
targeted_scrub_operation() = delete;
@@ -314,37 +316,36 @@ fapi2::ReturnCode sf_init( const fapi2::Target<T>& i_target,
/// @note Uses broadcast mode if possible
/// @param[in] i_target the target behind which all memory should be read
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
+/// @param[in] i_end whether to end, and where - defaults to immediate (stop after failed address)
/// @return FAPI2_RC_SUCCESS iff everything ok
/// @note The function is asynchronous, and the caller should be looking for a done attention
///
template< fapi2::TargetType T >
fapi2::ReturnCode sf_read( const fapi2::Target<T>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds );
+ const stop_conditions& i_stop,
+ const end_boundary i_end = end_boundary::STOP_AFTER_ADDRESS );
///
/// @brief Super Fast Read to End of Port - used to run superfast read on all memory behind the target
/// @tparam T the fapi2::TargetType of the target
/// @param[in] i_target the target behind which all memory should be read
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
/// @param[in] i_address mcbist::address representing the address from which to start.
+/// @param[in] i_end whether to end, and where - defaults to immediate (stop after failed address)
/// @return FAPI2_RC_SUCCESS iff everything ok
/// @note The function is asynchronous, and the caller should be looking for a done attention
/// @note The address is often the port, dimm, rank but this is not enforced in the API.
///
template< fapi2::TargetType T >
fapi2::ReturnCode sf_read( const fapi2::Target<T>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds,
- const mss::mcbist::address& i_address );
+ const stop_conditions& i_stop,
+ const mss::mcbist::address& i_address,
+ const end_boundary i_end = end_boundary::STOP_AFTER_ADDRESS );
///
/// @brief Scrub - continuous scrub all memory behind the target
/// @param[in] i_target the target behind which all memory should be scrubbed
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
/// @param[in] i_speed the speed to scrub
/// @param[in] i_address mcbist::address representing the address from which to start.
/// @return FAPI2_RC_SUCCESS iff everything ok
@@ -353,8 +354,7 @@ fapi2::ReturnCode sf_read( const fapi2::Target<T>& i_target,
///
template< fapi2::TargetType T >
fapi2::ReturnCode background_scrub( const fapi2::Target<T>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds,
+ const stop_conditions& i_stop,
const speed i_speed,
const mss::mcbist::address& i_address );
@@ -362,7 +362,6 @@ fapi2::ReturnCode background_scrub( const fapi2::Target<T>& i_target,
/// @brief Scrub - targeted scrub all memory described by the input address (rank, slave, etc.)
/// @param[in] i_target the target behind which all memory should be scrubbed
/// @param[in] i_stop stop conditions
-/// @param[in] i_thresholds thresholds
/// @param[in] i_speed the speed to scrub
/// @param[in] i_address mcbist::address representing the address from which to start.
/// @param[in] i_end whether to end, and where
@@ -372,8 +371,7 @@ fapi2::ReturnCode background_scrub( const fapi2::Target<T>& i_target,
///
template< fapi2::TargetType T >
fapi2::ReturnCode targeted_scrub( const fapi2::Target<T>& i_target,
- const stop_conditions i_stop,
- const thresholds& i_thresholds,
+ const stop_conditions& i_stop,
const speed i_speed,
const mss::mcbist::address& i_address,
const end_boundary i_end );
@@ -384,37 +382,17 @@ fapi2::ReturnCode targeted_scrub( const fapi2::Target<T>& i_target,
/// and finish the current master or slave rank.
/// @tparam T the fapi2::TargetType of the target
/// @param[in] i_target the target
-/// @param[in] i_end whether to end, and where (default = don't stop at end of rank)
-/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
-/// @param[in] i_speed the speed to scrub (default - NO_CHANGE meaning leave speed untouched)
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode continue_cmd( const fapi2::Target<T>& i_target,
- const end_boundary i_end = end_boundary::NONE,
- const stop_conditions i_stop = stop_conditions::DONT_CHANGE,
- const speed i_speed = speed::SAME_SPEED );
-
-///
-/// @brief Continue current command on next address - change thresholds
-/// The current commaand has paused on an error, so we can record the address of the error
-/// and finish the current master or slave rank.
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target
-/// @param[in] i_thresholds new thresholds
-/// @param[in] i_end whether to end, and where (default = don't stop at end of rank)
+/// @param[in] i_end whether to end, and where (default - don't stop at end of rank)
/// @param[in] i_stop stop conditions (default - 0 meaning 'don't change conditions')
/// @param[in] i_speed the speed to scrub (default - NO_CHANGE meaning leave speed untouched)
/// @return FAPI2_RC_SUCCESS iff ok
///
template< fapi2::TargetType T >
fapi2::ReturnCode continue_cmd( const fapi2::Target<T>& i_target,
- const thresholds& i_thresholds,
const end_boundary i_end = end_boundary::NONE,
- const stop_conditions i_stop = stop_conditions::DONT_CHANGE,
+ const stop_conditions& i_stop = stop_conditions(),
const speed i_speed = speed::SAME_SPEED );
-
} // namespace
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H
index 4ab89090c..5f76ca774 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H
@@ -36,6 +36,7 @@
#include <p9_mc_scom_addresses_fld.H>
#include <lib/mcbist/address.H>
+#include <lib/utils/bit_count.H>
namespace mss
{
@@ -43,29 +44,20 @@ namespace mss
namespace mcbist
{
-/// Stop conditions for MCBIST programs
-enum stop_conditions
+/// End boundaries for MCBIST programs - where to stop when stopping or pausing
+enum end_boundary : uint64_t
{
- NO_STOP_ON_ERROR = 0b00,
- DONT_STOP = NO_STOP_ON_ERROR,
- STOP_AFTER_ADDRESS = 0b01,
- STOP_AFTER_RANK = 0b10,
- STOP_AFTER_SUBTEST = 0b11,
-
- /// Don't change the stop conditions when continuing
- DONT_CHANGE = 0xFF,
-};
-
-/// Boundary conditions for operations - when to stopmc
-enum end_boundary
-{
- NONE = 0,
- CONTINUOUS = NONE,
- NEVER = NONE,
- MASTER_RANK = 1,
- MRANK = MASTER_RANK,
- SLAVE_RANK = 2,
- SRANK = SLAVE_RANK,
+ // We're gonna get a little hacky here. The pause on error mode field
+ // is two bits, with another bit representing slave/master. So we craft
+ // the enum so that we can insertFromRight and get the proper vaules, and
+ // leave on bit out of that two-bit range to represent master or slave
+ NONE = 0b000,
+ STOP_AFTER_ADDRESS = 0b001,
+ STOP_AFTER_MASTER_RANK = 0b010,
+ STOP_AFTER_SLAVE_RANK = 0b110,
+ STOP_AFTER_SUBTEST = 0b011,
+
+ DONT_CHANGE = 0xFF,
};
/// Speeds for performing MCBIST operations
@@ -82,35 +74,108 @@ enum speed
};
///
-/// @class Memory diagnostic subsystem error thresholds
+/// @class Memory diagnostic subsystem stop-on-error settings and thresholds
/// @note Matches Nimbus MBSTRQ, but might be changed later for Centaur, or mapped.
///
-class thresholds
+class stop_conditions
{
public:
+
// Many of the config fields share a disable bit pattern, so we define it here
- static constexpr uint64_t DISABLE = 0b1111;
+ static constexpr uint64_t DISABLE = 0b1111;
+ static constexpr uint64_t MAX_THRESHOLD = 0b1110;
+
+ private:
///
- /// @brief Thresholds class ctor
+ /// @brief Little helper to convert threshold inputs to exponents
+ /// @param[in] i_value, the value of the threshold (presumably)
+ /// @return a value n such that 2^n <= i_value && n < 15
///
- thresholds():
- iv_value(0)
- { }
+ uint64_t make_threshold_setting( const uint64_t i_value )
+ {
+ // If the user passes in DISABLE, let it past. This prevents callers from having to
+ // do the conditional. Zero is none which is disable
+ if ((i_value == DISABLE) || (i_value == 0))
+ {
+ return DISABLE;
+ }
+
+ // Find the first bit set. This represents the largest power of 2 this input can represent
+ // The subtraction from 63 switches from a left-count to a right-count (e.g., 0 (left most
+ // bit) is really bit 63 if you start on the right.)
+ uint64_t l_largest = 63 - first_bit_set(i_value);
+
+ // If the first bit set is off in space and greater than 2^14, we just return 0b1110
+ // Otherwise, l_largest is the droid we're looking for
+ return l_largest >= MAX_THRESHOLD ? MAX_THRESHOLD : l_largest;
+ }
+
+ ///
+ /// @brief Generic pause on threshold
+ /// @tparam F, the bit field to manipulate
+ /// @tparam L, the length of F
+ /// @param[in] the state of the error - mss::ON or mss::OFF
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ template< uint64_t F, uint64_t L >
+ inline stop_conditions& set_pause_on_threshold( const states i_on_or_off )
+ {
+ if (i_on_or_off == mss::OFF)
+ {
+ iv_value.insertFromRight<F, L>(DISABLE);
+ return *this;
+ }
+
+ uint64_t l_thresh = 0;
+ iv_value.extractToRight<F, L>(l_thresh);
+
+ if (l_thresh != DISABLE)
+ {
+ // Note the threshold field is an exponent, so this is 2^0, or 1 count
+ iv_value.insertFromRight<F, L>(0);
+ }
+ return *this;
+ }
+
+ public:
+ ///
+ /// @brief Stop/Thresholds class ctor
+ ///
+ stop_conditions():
+ iv_value(0)
+ {
+ // By default we want to start everything in 'don't stop' mode. This means disabling
+ // the errors which contain thresholds
+ set_thresh_nce_int(DISABLE)
+ .set_thresh_nce_soft(DISABLE)
+ .set_thresh_nce_hard(DISABLE)
+ .set_thresh_rce(DISABLE)
+ .set_thresh_ice(DISABLE)
+ .set_thresh_mce_int(DISABLE)
+ .set_thresh_mce_soft(DISABLE)
+ .set_thresh_mce_hard(DISABLE);
+ }
///
- /// @brief Thresholds class ctor
+ /// @brief Stop/Thresholds class ctor
/// @param[in] uint64_t representing the threshold register contents
///
- thresholds(const uint64_t i_value):
+ stop_conditions(const uint64_t i_value):
iv_value(i_value)
- { }
+ {
+ }
///
- /// @brief Thresholds class dtor
+ /// @brief Stop/Thresholds class dtor
///
- ~thresholds() = default;
+ ~stop_conditions() = default;
///
/// @brief uint64_t conversion
@@ -120,181 +185,378 @@ class thresholds
return uint64_t(iv_value);
}
- /// @brief set_thresh_mag_nce_int
+ ///
+ /// @brief set_thresh_nce_int
/// @param[in] i_value the value of the field
/// NCE intermittent error threshold magnitude to trigger for triggering pause. If
/// 1111, then pause will never be triggered (disabled). Else, then MCBIST will
/// pause if it takes sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_nce_int( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_nce_int( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT, MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(make_threshold_setting(i_value));
return *this;
}
- /// @brief set_thresh_mag_nce_soft
+ ///
+ /// @brief set_pause_on_nce_int - enable NCE intermittent error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_nce_int( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_nce_soft
/// @param[in] i_value the value of the field
/// NCE soft error threshold magnitude to trigger for triggering pause. If 1111,
/// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
/// takes sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_nce_soft( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_nce_soft( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT, MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(make_threshold_setting(i_value));
return *this;
}
- /// @brief set_thresh_mag_nce_hard
+ ///
+ /// @brief set_pause_on_nce_int - enable NCE soft error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_nce_soft( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_nce_hard
/// @param[in] i_value the value of the field
/// NCE hard error threshold magnitude to trigger for triggering pause. If 1111,
/// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
/// takes sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_nce_hard( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_nce_hard( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD, MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(make_threshold_setting(i_value));
return *this;
}
- /// @brief set_thresh_mag_rce
+ ///
+ /// @brief set_pause_on_nce_hard - enable NCE hard error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_nce_hard( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_rce
/// @param[in] i_value the value of the field
/// RCE error threshold magnitude to trigger for triggering pause. If 1111, then
/// pause will never be triggered (disabled). Else, then MCBIST will pause if it takes
/// sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_rce( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_rce( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE, MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(make_threshold_setting(i_value));
return *this;
}
- /// @brief set_thresh_mag_ice
+ ///
+ /// @brief set_pause_on_rce - enable RCE error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_rce( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_ice
/// @param[in] i_value the value of the field
/// ICE (IMPE) error threshold magnitude to trigger for triggering pause. If 1111,
/// then pause will never be triggered (disabled). Else, then MCBIST will pause if
/// it takes sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_ice( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_ice( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE, MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(make_threshold_setting(i_value));
return *this;
}
- /// @brief set_thresh_mag_mce_int
+ ///
+ /// @brief set_pause_on_ice - enable ICE (IMPE) error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_ice( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_mce_int
/// @param[in] i_value the value of the field
/// MCE intermittent error threshold magnitude to trigger for triggering pause. If
/// 1111, then pause will never be triggered (disabled). Else, then MCBIST will
/// pause if it takes sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_mce_int( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_mce_int( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT, MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(make_threshold_setting(i_value));
return *this;
}
- /// @brief set_thresh_mag_mce_soft
+ ///
+ /// @brief set_pause_on_mce_int - enable MCE intermittent error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_mce_int( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_mce_soft
/// @param[in] i_value the value of the field
/// MCE soft error threshold magnitude to trigger for triggering pause. If 1111,
/// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
/// takes sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_mce_soft( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_mce_soft( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT, MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(make_threshold_setting(i_value));
return *this;
}
- /// @brief set_thresh_mag_mce_hard
+ ///
+ /// @brief set_pause_on_mce_soft - enable MCE soft error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_mce_soft( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(i_on_or_off);
+ }
+
+ ///
+ /// @brief set_thresh_mce_hard
/// @param[in] i_value the value of the field
/// MCE hard error threshold magnitude to trigger for triggering pause. If 1111,
/// then pause will never be triggered (disabled). Else, then MCBIST will pause if it
/// takes sees 2^[this value] number of errors of this type.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_thresh_mag_mce_hard( const uint64_t i_value )
+ /// @note The register field is actually an exponent. The hardware will count 2^n for the
+ /// threshold. However, the input represents a count - how many. Thus we need to convert
+ /// the input to a power of 2 to get a proper exponent. Your input will be rounded down
+ /// to the nearest power of 2 which is less than 2^15 before being set in the register.
+ ///
+ inline stop_conditions& set_thresh_mce_hard( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD, MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(make_threshold_setting(i_value));
return *this;
}
+ ///
+ /// @brief set_pause_on_mce_hard - enable MCE hard error
+ /// @param[in] i_on_or_off - the desired state.
+ /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
+ /// @note If the input is mss::ON, this method enables the error, it's corresponding
+ /// threshold defines the threshold at which the engine will stop. If no threshold is
+ /// defined (the error is disabled) this method will set the threshold to 1. A previously
+ /// defined threshold (i.e., not disabled) will be left intact. If the input
+ /// is mss::OFF, this method will disable the error by setting the threshold to disabled.
+ ///
+ inline stop_conditions& set_pause_on_mce_hard( const states i_on_or_off )
+ {
+ return set_pause_on_threshold<MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
+ MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(i_on_or_off);
+ }
+
+ ///
/// @brief set_pause_on_sce
/// @param[in] i_value the value of the field
/// Enable pause on SCE error. When enabled, MCBIST will pause at the boundary
/// configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_on_sce( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_on_sce( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE>(i_value);
return *this;
}
+ ///
/// @brief set_pause_on_mce
/// @param[in] i_value the value of the field
/// Enable pause on MCE error. When enabled, MCBIST will pause at the boundary
/// configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_on_mce( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_on_mce( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_MCE>(i_value);
return *this;
}
+ ///
/// @brief set_pause_on_mpe
/// @param[in] i_value the value of the field
/// Enable pause on MPE error. When enabled, MCBIST will pause at the boundary
/// configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_on_mpe( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_on_mpe( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE>(i_value);
return *this;
}
+ ///
/// @brief set_pause_on_ue
/// @param[in] i_value the value of the field
/// Enable pause on UE error. When enabled, MCBIST will pause at the boundary
/// configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_on_ue( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_on_ue( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_UE>(i_value);
return *this;
}
+ ///
/// @brief set_pause_on_sue
/// @param[in] i_value the value of the field
/// Enable pause on SUE error. When enabled, MCBIST will pause at the boundary
/// configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_on_sue( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_on_sue( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE>(i_value);
return *this;
}
+ ///
/// @brief set_pause_on_aue
/// @param[in] i_value the value of the field
/// Enable pause on AUE error. When enabled, MCBIST will pause at the boundary
/// configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_on_aue( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_on_aue( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE>(i_value);
return *this;
}
+ ///
/// @brief set_pause_on_rcd
/// @param[in] i_value the value of the field
/// Enable pause on RCD error. When enabled, MCBIST will pause at the boundary
/// configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_on_rcd( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_on_rcd( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD>(i_value);
return *this;
}
- // Reserved. 39:52
-
+ ///
/// @brief set_symbol_counter_mode
/// @param[in] i_value the value of the field
/// Selects which mode to use symbol counter latches: Mode 0) MAINT 8-bit error
@@ -302,111 +564,132 @@ class thresholds
/// ranks (port agnostic) Mode 2) MCBIST 4-bit error counters for 18 nibbles x 4
/// ports (rank agnostic) and 1-bit error rank map for 18 nibbles x 4 ports
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_symbol_counter_mode( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_symbol_counter_mode( const uint64_t i_value )
{
- iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE, MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN>(i_value);
+ iv_value.insertFromRight<MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE,
+ MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN>(i_value);
return *this;
}
+ ///
/// @brief set_nce_soft_symbol_count_enable
/// @param[in] i_value the value of the field
/// Enables soft NCEs to trigger per symbol NCE error counting Only applies to
/// scrub where we have different types of NCE. Non scrub counts all NCE.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_nce_soft_symbol_count_enable( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_nce_soft_symbol_count_enable( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE>(i_value);
return *this;
}
+ ///
/// @brief set_nce_inter_symbol_count_enable
/// @param[in] i_value the value of the field
/// Enables intermittent NCEs to trigger per symbol NCE error counting Only applies
/// to scrub where we have different types of NCE. Non scrub counts all NCE.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_nce_inter_symbol_count_enable( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_nce_inter_symbol_count_enable( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE>(i_value);
return *this;
}
+ ///
/// @brief set_nce_hard_symbol_count_enable
/// @param[in] i_value the value of the field
/// Enables hard NCEs to trigger per symbol NCE error counting Only applies to
/// scrub where we have different types of NCE. Non scrub counts all NCE.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_nce_hard_symbol_count_enable( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_nce_hard_symbol_count_enable( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE>(i_value);
return *this;
}
+ ///
/// @brief set_pause_mcb_error
/// @param[in] i_value the value of the field
/// Enable pause when MCBIST error is logged. When enabled, MCBIST will pause at
/// the boundary configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_mcb_error( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_mcb_error( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR>(i_value);
return *this;
}
+ ///
/// @brief set_pause_mcb_log_full
/// @param[in] i_value the value of the field
/// Enable pause when MCBIST log is full. When enabled, MCBIST will pause at the
/// boundary configured if this error is seen.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_pause_mcb_log_full( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_pause_mcb_log_full( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL>(i_value);
return *this;
}
+ ///
/// @brief set_maint_rce_with_ce
/// @param[in] i_value the value of the field
/// cfg_maint_rce_with_ce - not implemented. Need to investigate if needed for nimbus.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_maint_rce_with_ce( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_maint_rce_with_ce( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE>(i_value);
return *this;
}
+ ///
/// @brief set_mce_soft_symbol_count_enable
/// @param[in] i_value the value of the field
/// Enables soft MCEs to trigger per symbol MCE error counting Only applies to
/// scrub where we have different types of MCE. Non scrub counts all MCE.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_mce_soft_symbol_count_enable( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_mce_soft_symbol_count_enable( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE>(i_value);
return *this;
}
+ ///
/// @brief set_mce_inter_symbol_count_enable
/// @param[in] i_value the value of the field
/// Enables intermittent MCEs to trigger per symbol MCE error counting Only applies
/// to scrub where we have different types of MCE. Non scrub counts all MCE.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_mce_inter_symbol_count_enable( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_mce_inter_symbol_count_enable( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE>(i_value);
return *this;
}
+ ///
/// @brief set_mce_hard_symbol_count_enable
/// @param[in] i_value the value of the field
/// Enables hard MCEs to trigger per symbol MCE error counting Only applies to
/// scrub where we have different types of MCE. Non scrub counts all MCE.
/// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining
- inline thresholds& set_mce_hard_symbol_count_enable( const uint64_t i_value )
+ ///
+ inline stop_conditions& set_mce_hard_symbol_count_enable( const uint64_t i_value )
{
iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE>(iv_value);
return *this;
}
private:
+
fapi2::buffer<uint64_t> iv_value;
};
@@ -419,8 +702,7 @@ struct constraints
/// @brief constraints constructor
///
constraints():
- iv_stop(NO_STOP_ON_ERROR),
- iv_thresholds(),
+ iv_stop(),
iv_pattern(NO_PATTERN),
iv_end_boundary(NONE),
iv_speed(LUDICROUS),
@@ -433,7 +715,7 @@ struct constraints
/// @brief constraints constructor
/// @param[in] i_pattern a pattern to set
///
- constraints( const uint64_t i_pattern):
+ constraints( const uint64_t i_pattern ):
constraints()
{
iv_pattern = i_pattern;
@@ -443,45 +725,37 @@ struct constraints
///
/// @brief constraints constructor
/// @param[in] i_stop stop conditions
- /// @param[in] i_thresholds thresholds
///
- constraints( const stop_conditions i_stop,
- const thresholds& i_thresholds ):
+ constraints( const stop_conditions& i_stop ):
constraints()
{
iv_stop = i_stop;
- iv_thresholds = i_thresholds;
- FAPI_INF("setting up constraints with stop %d and thresholds 0x%x", i_stop, uint64_t(i_thresholds));
+ FAPI_INF("setting up constraints with stop 0x%016lx", uint64_t(i_stop));
}
///
/// @brief constraints constructor
/// @param[in] i_stop stop conditions
- /// @param[in] i_thresholds thresholds
/// @param[in] i_start_address address to start from
///
- constraints( const stop_conditions i_stop,
- const thresholds& i_thresholds,
+ constraints( const stop_conditions& i_stop,
const address& i_start_address ):
- constraints(i_stop, i_thresholds)
+ constraints(i_stop)
{
iv_start_address = i_start_address;
- FAPI_INF("setting up constraints with stop %d and thresholds 0x%x start address",
- i_stop, uint64_t(i_thresholds), uint64_t(i_start_address));
+ FAPI_INF("setting up constraints with start address 0x%016lx", uint64_t(i_start_address));
}
///
/// @brief constraints constructor
/// @param[in] i_stop stop conditions
- /// @param[in] i_thresholds thresholds
/// @param[in] i_start_address address to start from
///
- constraints( const stop_conditions i_stop,
- const thresholds& i_thresholds,
+ constraints( const stop_conditions& i_stop,
const speed i_speed,
const end_boundary i_end_boundary,
const address& i_start_address ):
- constraints(i_stop, i_thresholds, i_start_address)
+ constraints(i_stop, i_start_address)
{
iv_end_boundary = i_end_boundary;
iv_speed = i_speed;
@@ -489,7 +763,6 @@ struct constraints
}
stop_conditions iv_stop;
- thresholds iv_thresholds;
uint64_t iv_pattern;
end_boundary iv_end_boundary;
speed iv_speed;
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C
index 55b48cfaa..0b35ed2bf 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C
@@ -24,7 +24,7 @@
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
@@ -69,7 +69,8 @@ extern "C"
mss::poll_parameters l_poll_parameters;
bool l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ [&l_status](const size_t poll_remaining,
+ const fapi2::buffer<uint64_t>& stat_reg) -> bool
{
FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
l_status = stat_reg;
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.H
index 6ffef09ba..546972e03 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.H
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.H
@@ -23,7 +23,7 @@
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
#ifndef __P9_MSS_MEMDIAG__
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
index 20fed5c89..5b131da65 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C
@@ -65,7 +65,7 @@ fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targe
}
// TK do we want these to be arguments to the wrapper?
- return memdiags::background_scrub(i_target, mss::mcbist::stop_conditions::NO_STOP_ON_ERROR, mss::mcbist::thresholds(),
+ return memdiags::background_scrub(i_target, mss::mcbist::stop_conditions(),
mss::mcbist::speed::LUDICROUS, mss::mcbist::address());
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/memory/tests/mss_memdiags_ut.C b/src/import/chips/p9/procedures/hwp/memory/tests/mss_memdiags_ut.C
index 1e20269fb..afd81a6bd 100644
--- a/src/import/chips/p9/procedures/hwp/memory/tests/mss_memdiags_ut.C
+++ b/src/import/chips/p9/procedures/hwp/memory/tests/mss_memdiags_ut.C
@@ -71,45 +71,122 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
REQUIRE_FALSE( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), is_sim) );
- SECTION("Test thresholds structure")
+ SECTION("Test stop_condition structure")
{
- mss::mcbist::thresholds l_t;
- REQUIRE( 0 == l_t );
+ // Stops default to all conditions off and all thresholded conditions disabled
+ mss::mcbist::stop_conditions l_t;
+ REQUIRE( 0xffffffff00000000 == l_t );
{
- l_t.set_thresh_mag_nce_int( mss::mcbist::thresholds::DISABLE );
- REQUIRE( 0xf000000000000000 == l_t );
+ l_t.set_thresh_nce_int( 0 );
+ REQUIRE( 0xffffffff00000000 == l_t );
+
+ l_t.set_thresh_nce_int( 1 );
+ REQUIRE( 0x0fffffff00000000 == l_t );
+
+ l_t.set_thresh_nce_int( 2 );
+ REQUIRE( 0x1fffffff00000000 == l_t );
+
+ // Because 2^3 is 8 which is the exponent of the nearest rounded down power of 2 (12 - 4 == 8)
+ l_t.set_thresh_nce_int( 12 );
+ REQUIRE( 0x3fffffff00000000 == l_t );
+
+ l_t.set_thresh_nce_int( mss::mcbist::stop_conditions::DISABLE );
+ REQUIRE( 0xffffffff00000000 == l_t );
}
{
- l_t.set_thresh_mag_nce_soft( mss::mcbist::thresholds::DISABLE );
- REQUIRE( 0xff00000000000000 == l_t );
+ l_t.set_thresh_nce_soft( 0 );
+ REQUIRE( 0xffffffff00000000 == l_t );
+
+ l_t.set_thresh_nce_soft( 1 );
+ REQUIRE( 0xf0ffffff00000000 == l_t );
+
+ l_t.set_thresh_nce_soft( 2 );
+ REQUIRE( 0xf1ffffff00000000 == l_t );
+
+ // Because 2^3 is 8 which is the exponent of the nearest rounded down power of 2 (12 - 4 == 8)
+ l_t.set_thresh_nce_soft( 12 );
+ REQUIRE( 0xf3ffffff00000000 == l_t );
+
+ l_t.set_thresh_nce_soft( mss::mcbist::stop_conditions::DISABLE );
+ REQUIRE( 0xffffffff00000000 == l_t );
}
{
- l_t.set_thresh_mag_nce_hard( mss::mcbist::thresholds::DISABLE );
- REQUIRE( 0xfff0000000000000 == l_t );
+ l_t.set_thresh_nce_hard( 0 );
+ REQUIRE( 0xffffffff00000000 == l_t );
+
+ l_t.set_thresh_nce_hard( 1 );
+ REQUIRE( 0xff0fffff00000000 == l_t );
+
+ l_t.set_thresh_nce_hard( 2 );
+ REQUIRE( 0xff1fffff00000000 == l_t );
+
+ l_t.set_thresh_nce_hard( 10 );
+ REQUIRE( 0xff3fffff00000000 == l_t );
+
+ l_t.set_thresh_nce_hard( mss::mcbist::stop_conditions::DISABLE );
+ REQUIRE( 0xffffffff00000000 == l_t );
}
{
- l_t.set_thresh_mag_rce( mss::mcbist::thresholds::DISABLE );
- REQUIRE( 0xffff000000000000 == l_t );
+ l_t.set_thresh_rce( 0 );
+ REQUIRE( 0xffffffff00000000 == l_t );
+
+ l_t.set_thresh_rce( 1 );
+ REQUIRE( 0xfff0ffff00000000 == l_t );
+
+ l_t.set_thresh_rce( 2 );
+ REQUIRE( 0xfff1ffff00000000 == l_t );
+
+ l_t.set_thresh_rce( 5 );
+ REQUIRE( 0xfff2ffff00000000 == l_t );
+
+ l_t.set_thresh_rce( mss::mcbist::stop_conditions::DISABLE );
+ REQUIRE( 0xffffffff00000000 == l_t );
}
// Little method chaining check
{
- l_t.set_thresh_mag_ice( mss::mcbist::thresholds::DISABLE )
- .set_thresh_mag_mce_int( mss::mcbist::thresholds::DISABLE );
- REQUIRE( 0xffffff0000000000 == l_t );
+ memdiags::stop_conditions l_t(0);
+ l_t.set_thresh_ice( mss::mcbist::stop_conditions::DISABLE )
+ .set_thresh_mce_int( mss::mcbist::stop_conditions::DISABLE );
+ REQUIRE( 0x0000ff0000000000 == l_t );
}
{
- l_t.set_thresh_mag_mce_soft( mss::mcbist::thresholds::DISABLE );
- REQUIRE( 0xfffffff000000000 == l_t );
+ l_t.set_thresh_mce_soft( 0 );
+ REQUIRE( 0xffffffff00000000 == l_t );
+
+ l_t.set_thresh_mce_soft( 1 );
+ REQUIRE( 0xffffff0f00000000 == l_t );
+
+ l_t.set_thresh_mce_soft( 2 );
+ REQUIRE( 0xffffff1f00000000 == l_t );
+
+ l_t.set_thresh_mce_soft( 10 );
+ REQUIRE( 0xffffff3f00000000 == l_t );
+
+ l_t.set_thresh_mce_soft( mss::mcbist::stop_conditions::DISABLE );
+ REQUIRE( 0xffffffff00000000 == l_t );
+
}
{
- l_t.set_thresh_mag_mce_hard( mss::mcbist::thresholds::DISABLE );
+ l_t.set_thresh_mce_hard( 0 );
+ REQUIRE( 0xffffffff00000000 == l_t );
+
+ l_t.set_thresh_mce_hard( 1 );
+ REQUIRE( 0xfffffff000000000 == l_t );
+
+ l_t.set_thresh_mce_hard( 2 );
+ REQUIRE( 0xfffffff100000000 == l_t );
+
+ l_t.set_thresh_mce_hard( 7 );
+ REQUIRE( 0xfffffff200000000 == l_t );
+
+ l_t.set_thresh_mce_hard( mss::mcbist::stop_conditions::DISABLE );
REQUIRE( 0xffffffff00000000 == l_t );
}
@@ -149,7 +226,7 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
}
{
- l_t.set_symbol_counter_mode( mss::mcbist::thresholds::DISABLE );
+ l_t.set_symbol_counter_mode( mss::mcbist::stop_conditions::DISABLE );
REQUIRE( 0xfffffffffe000600 == l_t );
}
@@ -222,11 +299,11 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
REQUIRE( 0x0000000000000081 == l_read );
}
- // Load thresholds - default state (expecting 0's)
+ // Load thresholds - default state (expecting default threshold register state)
{
fapi2::buffer<uint64_t> l_read;
REQUIRE_FALSE( mss::getScom(i_target, MCBIST_MBSTRQ, l_read) );
- REQUIRE( 0x0 == l_read );
+ REQUIRE( 0xffffffff00000000 == l_read );
}
// Enable maint addressing mode - enabled by default in the mcbist::program ctor
@@ -290,13 +367,15 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
{
// Loading of patterns is tested in the mcbist unit test.
- mss::mcbist::constraints l_const(memdiags::stop_conditions::NO_STOP_ON_ERROR, memdiags::thresholds());
+ memdiags::stop_conditions l_stops;
+ mss::mcbist::constraints l_const(l_stops);
// The addresses here are calculated so that we get a few iterations
// of polling on an AWAN, but not so much that we run the risk of timing out
mss::mcbist::address().get_range<mss::mcbist::address::COL>(l_const.iv_end_address);
l_const.iv_end_address.set_column(0b111111);
- memdiags::operation<TARGET_TYPE_MCBIST> l_bob(i_target, mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>(), l_const);
+ memdiags::operation<TARGET_TYPE_MCBIST> l_bob(i_target, mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>(),
+ l_const);
REQUIRE_FALSE( l_bob.multi_port_init() );
REQUIRE_FALSE( l_bob.execute() );
@@ -315,11 +394,11 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
REQUIRE( 0x0000000000000081 == l_read );
}
- // Load thresholds - default state (expecting 0's)
+ // Load thresholds - default state (expecting default threshold register state)
{
fapi2::buffer<uint64_t> l_read;
REQUIRE_FALSE( mss::getScom(i_target, MCBIST_MBSTRQ, l_read) );
- REQUIRE( 0x0 == l_read );
+ REQUIRE( 0xffffffff00000000 == l_read );
}
// Enable maint addressing mode - enabled by default in the mcbist::program ctor
@@ -390,8 +469,7 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
l_start.set_bank_group(0);
l_start.set_column(0);
- REQUIRE_FALSE( memdiags::sf_read(i_target, mss::mcbist::stop_conditions::STOP_AFTER_ADDRESS,
- mss::mcbist::thresholds(), l_start) );
+ REQUIRE_FALSE( memdiags::sf_read(i_target, mss::mcbist::stop_conditions(), l_start) );
// Check the things we default to so that we have a canary in case the defaults change
// Zero out cmd timebase - mcbist::program constructor does that for us.
@@ -405,14 +483,14 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
{
fapi2::buffer<uint64_t> l_read;
REQUIRE_FALSE( mss::getScom(i_target, MCBIST_MCBCFGQ, l_read) );
- REQUIRE( 0x00000000000000a9 == l_read );
+ REQUIRE( 0x00000000000000a1 == l_read );
}
- // Load thresholds - default state (expecting 0's)
+ // Load thresholds - default state (expecting default threshold register state)
{
fapi2::buffer<uint64_t> l_read;
REQUIRE_FALSE( mss::getScom(i_target, MCBIST_MBSTRQ, l_read) );
- REQUIRE( 0x0 == l_read );
+ REQUIRE( 0xffffffff00000000 == l_read );
}
// Enable maint addressing mode - enabled by default in the mcbist::program ctor
@@ -447,7 +525,8 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
poll_parameters l_poll_parameters;
bool l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ [&l_status](const size_t poll_remaining,
+ const fapi2::buffer<uint64_t>& stat_reg) -> bool
{
FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
l_status = stat_reg;
@@ -488,7 +567,7 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
l_start.set_bank_group(0);
l_start.set_column(0);
- REQUIRE_FALSE( memdiags::background_scrub(i_target, memdiags::stop_conditions::NO_STOP_ON_ERROR, memdiags::thresholds(),
+ REQUIRE_FALSE( memdiags::background_scrub(i_target, memdiags::stop_conditions(),
memdiags::speed::BG_SCRUB, l_start) );
// check the state of the mcbist engine
@@ -581,13 +660,13 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
SECTION("Test targeted scrub")
{
// Test that passing in no-stop is a bug
- REQUIRE( memdiags::targeted_scrub(i_target, memdiags::stop_conditions::DONT_STOP, memdiags::thresholds(),
+ REQUIRE( memdiags::targeted_scrub(i_target, memdiags::stop_conditions(),
memdiags::speed::LUDICROUS, mss::mcbist::address(),
- memdiags::end_boundary::MASTER_RANK) );
+ memdiags::end_boundary::NONE) );
- REQUIRE_FALSE( memdiags::targeted_scrub(i_target, memdiags::stop_conditions::STOP_AFTER_RANK, memdiags::thresholds(),
+ REQUIRE_FALSE( memdiags::targeted_scrub(i_target, memdiags::stop_conditions(),
memdiags::speed::LUDICROUS, mss::mcbist::address(),
- memdiags::end_boundary::MASTER_RANK) );
+ memdiags::end_boundary::STOP_AFTER_MASTER_RANK) );
// Make sure targeted scrub sets the FIR bit. More for verifying our actions than
// anything else
@@ -623,7 +702,7 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
{
fapi2::buffer<uint64_t> l_read;
REQUIRE_FALSE( mss::getScom(i_target, MCBIST_MCBCFGQ, l_read) );
- REQUIRE( 0x0000000020000021 == l_read );
+ REQUIRE( 0x0000000020000041 == l_read );
}
}
@@ -639,8 +718,8 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
l_start_address.get_range<mss::mcbist::address::MRANK>(l_end_address);
l_start_address = l_end_address - 10;
- memdiags::constraints l_const(memdiags::stop_conditions::STOP_AFTER_RANK, memdiags::thresholds(),
- memdiags::speed::LUDICROUS, memdiags::end_boundary::MASTER_RANK,
+ memdiags::constraints l_const(memdiags::stop_conditions(), memdiags::speed::LUDICROUS,
+ memdiags::end_boundary::STOP_AFTER_MASTER_RANK,
l_start_address);
l_const.iv_end_address = l_end_address;
@@ -666,7 +745,8 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
fapi2::buffer<uint64_t> l_last_address;
bool l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ [&l_status](const size_t poll_remaining,
+ const fapi2::buffer<uint64_t>& stat_reg) -> bool
{
FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
l_status = stat_reg;
@@ -692,14 +772,14 @@ TEST_CASE_METHOD(mss::test::mcbist_target_test_fixture, "memdiags", "[memdiags]"
}
// We asked to stop at the end of a rank, so we should not be able to continue to the end of the rank
- REQUIRE( memdiags::continue_cmd(i_target, memdiags::end_boundary::MRANK, memdiags::stop_conditions::STOP_AFTER_RANK) );
+ REQUIRE( memdiags::continue_cmd(i_target, memdiags::end_boundary::STOP_AFTER_MASTER_RANK) );
// Continue but ask to stop at the end of the subtest
- REQUIRE_FALSE( memdiags::continue_cmd(i_target, memdiags::end_boundary::NONE,
- memdiags::stop_conditions::STOP_AFTER_SUBTEST) );
+ REQUIRE_FALSE( memdiags::continue_cmd(i_target, memdiags::end_boundary::STOP_AFTER_SUBTEST) );
l_poll_results = mss::poll(i_target, MCBIST_MCBISTFIRQ, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ [&l_status](const size_t poll_remaining,
+ const fapi2::buffer<uint64_t>& stat_reg) -> bool
{
FAPI_DBG("mcbist firq 0x%llx, remaining: %d", stat_reg, poll_remaining);
l_status = stat_reg;
OpenPOWER on IntegriCloud