summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H140
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H488
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C597
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H3334
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H469
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C597
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.H396
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C146
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H104
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/settings.H760
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C175
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H64
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H175
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H54
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H55
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/mss.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_memdiag.C3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_scrub.C5
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml10
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml11
29 files changed, 648 insertions, 6982 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C b/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C
index 58b382a97..c50a874e3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lab/sdk/example/C/mss_lab_sfwrite.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -35,6 +35,7 @@
#include <mss_lab_tools.H>
+#include <lib/shared/nimbus_defaults.H>
#include <generic/memory/lib/utils/poll.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/memdiags.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
index 869e18f25..ffc5300e4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
@@ -37,6 +37,7 @@
#include <fapi2.H>
#include <vector>
+#include <lib/shared/mss_const.H>
#include <lib/dimm/ddr4/nvdimm_utils.H>
#include <lib/mc/mc.H>
#include <lib/ccs/ccs.H>
@@ -82,7 +83,7 @@ fapi2::ReturnCode get_maint_addr_mode_en( const fapi2::Target<fapi2::TARGET_TYPE
mss::states& o_state )
{
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
+ typedef mcbistTraits<> TT;
fapi2::buffer<uint64_t> l_data;
FAPI_TRY( mss::getScom(l_mcbist, TT::MCBAGRAQ_REG, l_data),
@@ -105,7 +106,7 @@ fapi2::ReturnCode change_maint_addr_mode_en( const fapi2::Target<fapi2::TARGET_T
const mss::states i_state )
{
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
+ typedef mcbistTraits<> TT;
fapi2::buffer<uint64_t> l_data;
FAPI_TRY( mss::getScom(l_mcbist, TT::MCBAGRAQ_REG, l_data),
@@ -213,7 +214,7 @@ fapi2::ReturnCode self_refresh_exit_helper( const fapi2::Target<fapi2::TARGET_TY
mss::mcbist::address l_start = 0, l_end = 0;
mss::mcbist::end_boundary l_end_boundary = mss::mcbist::end_boundary::STOP_AFTER_SLAVE_RANK;
l_start.set_port(l_port);
- mss::mcbist::stop_conditions l_stop_conditions;
+ mss::mcbist::stop_conditions<> l_stop_conditions;
// Read with targeted scrub
FAPI_TRY ( mss::memdiags::targeted_scrub(l_mcbist,
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
index 901ed1a8c..86270182e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H
@@ -41,7 +41,7 @@
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
#include <generic/memory/lib/utils/scom.H>
-#include <lib/utils/num.H>
+#include <generic/memory/lib/utils/num.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
#include <lib/phy/phy_cntrl.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H
index c27603b6b..3a2275c3a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ecc/fw_mark_store.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -558,7 +558,7 @@ template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<
inline void set_address( fapi2::buffer<uint64_t>& io_data, const mcbist::address& i_address)
{
// construct fwms::address from mcbist::address
- const auto l_addr = address<T>(i_address);
+ const auto l_addr = address<>(i_address);
io_data.insert<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_addr);
FAPI_INF("set_address: 0x%016lx", uint64_t(l_addr));
}
@@ -574,7 +574,7 @@ template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = eccTraits<
inline void get_address( const fapi2::buffer<uint64_t>& i_data, mcbist::address& o_address )
{
// construct fwms::address from i_data
- const auto l_addr = address<T>(uint64_t(i_data));
+ const auto l_addr = address<>(uint64_t(i_data));
// construct mcbist::address from fwms::address
o_address = mcbist::address(l_addr);
FAPI_INF("get_address: 0x%016lx", uint64_t(l_addr));
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C
index c56b1ff90..b2037c0df 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C
@@ -34,7 +34,7 @@
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
-#include <lib/utils/dump_regs.H>
+#include <generic/memory/lib/utils/dump_regs.H>
#include <lib/mc/mc.H>
#include <generic/memory/lib/utils/find.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
index 33131ad4f..98cf5f7b2 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
@@ -75,6 +75,10 @@ template<>
class portTraits<mss::mc_type::NIMBUS>
{
public:
+
+ // PORT_TYPE
+ static constexpr enum fapi2::TargetType PORT_TYPE = fapi2::TARGET_TYPE_MCA;
+
static constexpr uint64_t FARB0Q_REG = MCA_MBA_FARB0Q;
static constexpr uint64_t FARB1Q_REG = MCA_MBA_FARB1Q;
static constexpr uint64_t FARB5Q_REG = MCA_MBA_FARB5Q;
@@ -957,127 +961,6 @@ fapi_try_exit:
}
///
-/// @brief Configures the write reorder queue for MCBIST operations
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_wrq(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const mss::states i_state)
-{
- typedef portTraits<mss::mc_type::NIMBUS> TT;
-
- fapi2::buffer<uint64_t> l_data;
-
- // Gets the reg
- FAPI_TRY(mss::getScom(i_target, TT::WRQ_REG, l_data), "%s failed to getScom from MCA_MBA_WRQ0Q", mss::c_str(i_target));
-
- // Sets the bit
- l_data.writeBit<TT::WRQ_FIFO_MODE>(i_state == mss::states::ON);
-
- // Sets the regs
- FAPI_TRY(mss::putScom(i_target, TT::WRQ_REG, l_data), "%s failed to putScom to MCA_MBA_WRQ0Q", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Configures the write reorder queue bit
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_wrq(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- const mss::states i_state)
-{
- // Loops through all MCA targets, hitting all the registers
- for( const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target) )
- {
- FAPI_TRY(configure_wrq(l_mca, i_state));
- }
-
- // In case we don't have any MCA's
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Configures the read reorder queue for MCBIST operations
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_rrq(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const mss::states i_state)
-{
- typedef portTraits<mss::mc_type::NIMBUS> TT;
-
- fapi2::buffer<uint64_t> l_data;
-
- // Gets the reg
- FAPI_TRY(mss::getScom(i_target, TT::RRQ_REG, l_data), "%s failed to getScom from MCA_MBA_RRQ0Q", mss::c_str(i_target));
-
- // Sets the bit
- l_data.writeBit<TT::RRQ_FIFO_MODE>(i_state == mss::states::ON);
-
- // Sets the regs
- FAPI_TRY(mss::putScom(i_target, TT::RRQ_REG, l_data), "%s failed to putScom to MCA_MBA_RRQ0Q", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Configures the read reorder queue bit
-/// @param[in] i_target the target to effect
-/// @param[in] i_state to set the bit too
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-inline fapi2::ReturnCode configure_rrq(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- const mss::states i_state)
-{
- // Loops through all MCA targets, hitting all the registers
- for( const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target) )
- {
- FAPI_TRY(configure_rrq(l_mca, i_state));
- }
-
- // In case we don't have any MCA's
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Resets the write/read reorder queue values - needs to be called after MCBIST execution
-/// @tparam T, the fapi2 target type of the target
-/// @param[in] i_target the target to effect
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T>
-fapi2::ReturnCode reset_reorder_queue_settings(const fapi2::Target<T>& i_target)
-{
- uint8_t l_reorder_queue = 0;
- FAPI_TRY(reorder_queue_setting(i_target, l_reorder_queue));
-
- // Changes the reorder queue settings
- {
- // Two settings are FIFO and REORDER. FIFO is a 1 in the registers, while reorder is a 0 state
- const mss::states l_state = ((l_reorder_queue == fapi2::ENUM_ATTR_MSS_REORDER_QUEUE_SETTING_FIFO) ?
- mss::states::ON : mss::states::OFF);
- FAPI_TRY(configure_rrq(i_target, l_state), "%s failed to reset read reorder queue settings", mss::c_str(i_target));
- FAPI_TRY(configure_wrq(i_target, l_state), "%s failed to reset read reorder queue settings", mss::c_str(i_target));
- }
-
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Convert a bitmap from the BAD_DQ_BITMAP attribute to a vector of bad DQ indexes
/// @param[in] i_bad_bits an 8-bit bitmap of bad bits
/// @param[in] i_nibble which nibble of the bitmap to convert
@@ -1508,6 +1391,21 @@ fapi2::ReturnCode restore_repairs( const fapi2::Target<T>& i_target,
fapi2::buffer<uint8_t>& o_repairs_applied,
fapi2::buffer<uint8_t>& o_repairs_exceeded);
+/// @brief Get the attributes for the reorder queue setting
+/// @param[in] const ref to the mc target
+/// @param[out] uint8_t& reference to store the value
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Contains the settings for write/read reorder
+/// queue
+///
+template< >
+inline fapi2::ReturnCode reorder_queue_setting<mss::mc_type::NIMBUS>(const
+ fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ uint8_t& o_value)
+{
+ return mss::reorder_queue_setting(i_target, o_value);
+}
+
}// mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H
index 3a7a4ee2c..844c94caa 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/address.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,489 +38,11 @@
#include <fapi2.H>
#include <utility>
+#include <lib/shared/mss_const.H>
#include <lib/ecc/ecc_traits.H>
+#include <lib/mcbist/mcbist_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_address.H>
-namespace mss
-{
-
-namespace ecc
-{
-
-namespace fwms
-{
-
-///
-/// @class address
-/// @brief Converts Firmware Mark Store ADDRESS field into mcbist::address
-/// @tparam T fapi2 Target Type defaults to fapi2::TARGET_TYPE_MCA
-/// @tparam TT traits type defaults to eccTraits<T>
-/// @note template argument defaults are in forward declaration in lib/mcbist/address.H
-/// @note 12 = dimm
-/// @note 13:14 = mrank
-/// @note 15:17 = srank
-/// @note 18:19 = bank group
-/// @note 20:22 = bank
-///
-// See declaration below
-template< fapi2::TargetType T, typename TT = eccTraits<T> >
-class address;
-
-} // close namespace fwms
-} // close namespace ecc
-
-namespace mcbist
-{
-
-///
-/// @class address
-/// @brief Represents a physical address in memory
-/// @note
-/// 0:1 port select
-/// 2 dimm select
-/// 3:4 mrank(0 to 1)
-/// 5:7 srank(0 to 2)
-/// 8:25 row(0 to 17)
-/// 26:32 col(3 to 9)
-/// 33:35 bank(0 to 2)
-/// 36:37 bank_group(0 to 1)
-///
-class address
-{
- private:
- // How far over we shift to align the address in either the register or a buffer
- enum { MAGIC_PAD = 26 };
-
- public:
-
- // first is the start bit of the field, second is the length
- typedef std::pair<uint64_t, uint64_t> field;
-
- constexpr static field PORT = {0, 2};
- constexpr static field DIMM = {2, 1};
- constexpr static field MRANK = {3, 2};
- constexpr static field SRANK = {5, 3};
- constexpr static field ROW = {8, 18};
- constexpr static field COL = {26, 7};
- constexpr static field BANK = {33, 3};
- constexpr static field BANK_GROUP = {36, 2};
- constexpr static field LAST_VALID = BANK_GROUP;
-
- address() = default;
-
- static constexpr uint64_t LARGEST_ADDRESS = ~0 >> MAGIC_PAD;
-
- // Used when accessing an integral value containing a port and DIMM combination
- static constexpr uint64_t DIMM_BIT = 63;
- static constexpr uint64_t PORT_START = 61;
- static constexpr uint64_t PORT_LEN = 2;
-
- ///
- /// @brief Construct an address from a uint64_t (scom'ed value)
- /// @param[in] i_value representing an address; say from a trap register
- ///
- /// @note This assumes input has the same bit layout as this address
- /// structure, and this is presently not the case for the trap registers (3/16).
- /// These are presently unused, however. There is an open defect against the
- /// design team to correct this.
- /// @warn Assumes right-aligned value; bit 63 is shifted to represent the Bank Group
- address( const uint64_t i_value ):
- iv_address(i_value << MAGIC_PAD)
- {
- }
-
- ///
- /// @brief Construct an address from an ecc::fwms::address
- /// @tparam T fapi2 Target Type
- /// @param[in] i_address representing an address field from a firmware mark store register
- ///
- template< fapi2::TargetType T >
- address( const ecc::fwms::address<T>& i_address )
- {
- fapi2::buffer<uint64_t> l_value = uint64_t(i_address);
- uint64_t l_temp = 0;
- l_value.extractToRight<ecc::fwms::address<T>::DIMM.first, ecc::fwms::address<T>::DIMM.second>(l_temp);
- this->set_field<DIMM>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::MRANK.first, ecc::fwms::address<T>::MRANK.second>(l_temp);
- this->set_field<MRANK>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::SRANK.first, ecc::fwms::address<T>::SRANK.second>(l_temp);
- this->set_field<SRANK>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::BANK_GROUP.first, ecc::fwms::address<T>::BANK_GROUP.second>(l_temp);
- this->set_field<BANK_GROUP>(l_temp);
- l_value.extractToRight<ecc::fwms::address<T>::BANK.first, ecc::fwms::address<T>::BANK.second>(l_temp);
- this->set_field<BANK>(l_temp);
- }
-
- ///
- /// @brief Conversion operator to uint64_t
- /// @warn Right-aligns the address
- ///
- inline operator uint64_t() const
- {
- return iv_address >> MAGIC_PAD;
- }
-
- ///
- /// @brief Set a field for an address
- /// @tparam F the field to set
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- template< const field& F >
- inline address& set_field( const uint64_t i_value )
- {
- iv_address.insertFromRight<F.first, F.second>(i_value);
- return *this;
- }
-
- ///
- /// @brief Get a field from an address
- /// @tparam F the field to get
- /// @return right-aligned uint64_t representing the value
- ///
- template< const field& F >
- inline uint64_t get_field() const
- {
- uint64_t l_value = 0;
- iv_address.extractToRight<F.first, F.second>(l_value);
- return l_value;
- }
-
- ///
- /// @brief Get a range of addresses.
- /// @tparam[in] F the left-most valid field. So, if the address was for master rank,
- /// the left-most valid field would be MRANK
- /// @param[out] o_end representing an address to end at
- /// @note this pointer is the start address
- ///
- template< const field& F >
- inline void get_range( address& o_end ) const
- {
- constexpr uint64_t START = F.first + F.second;
- constexpr uint64_t LEN = (LAST_VALID.first + LAST_VALID.second) - START;
-
- // All we need to do is fill in the bits to the right of the last valid field
- o_end.iv_address = iv_address;
- o_end.iv_address.setBit<START, LEN>();
- }
-
-
- ///
- /// @brief Get an end address for sim mode
- /// @param[out] o_end representing an address to end at
- /// @note this pointer is the start address
- ///
- inline void get_sim_end_address( address& o_end ) const
- {
- // This magic number represents a range of addresses which cover all
- // cache lines the training algorithms touch. By effecting 0 - this end
- // address you'll effect everything which has bad ECC in the sim.
- constexpr uint64_t l_magic_sim_number = 0b1000000;
-
- get_range<COL>(o_end);
- o_end.set_column(l_magic_sim_number);
- return;
- }
-
- ///
- /// @brief Get a range of addresses given a master rank
- /// @param[in] i_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_mrank_range( const address& i_start, address& o_end )
- {
- i_start.get_range<MRANK>(o_end);
- }
-
- ///
- /// @brief Get a range of addresses given a master rank
- /// @param[in] i_port representing the port for the starting address
- /// @param[in] i_dimm representing the dimm for the starting address
- /// @param[in] i_mrank representing the master rank for the starting address
- /// @param[out] o_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_mrank_range( const uint64_t i_port, const uint64_t i_dimm, const uint64_t i_mrank,
- address& o_start, address& o_end )
- {
- o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank);
- get_mrank_range(o_start, o_end);
- }
-
- ///
- /// @brief Get a range of addresses given a slave rank
- /// @param[in] i_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_srank_range( const address& i_start, address& o_end )
- {
- i_start.get_range<SRANK>(o_end);
- }
-
- ///
- /// @brief Get a range of addresses given a slave rank
- /// @param[in] i_port representing the port for the starting address
- /// @param[in] i_dimm representing the dimm for the starting address
- /// @param[in] i_mrank representing the master rank for the starting address
- /// @param[in] i_srank representing the slave rank for the starting address
- /// @param[out] o_start representing an address to start from
- /// @param[out] o_end representing an address to end at
- ///
- inline static void get_srank_range( const uint64_t i_port, const uint64_t i_dimm,
- const uint64_t i_mrank, const uint64_t i_srank,
- address& o_start, address& o_end )
- {
- o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank).set_slave_rank(i_srank);
- get_srank_range(o_start, o_end);
- }
-
- ///
- /// @brief Set the port value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_port( const uint64_t i_value )
- {
- return set_field<PORT>(i_value);
- }
-
- ///
- /// @brief Get the port value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_port() const
- {
- return get_field<PORT>();
- }
-
- ///
- /// @brief Set the DIMM value for an address
- /// @param[in] i_value the value to set
- /// @note 0 is the DIMM[0] != 0 is DIMM[1]
- /// @return address& for method chaining
- ///
- inline address& set_dimm( const uint64_t i_value )
- {
- return set_field<DIMM>(i_value);
- }
-
- ///
- /// @brief Get the DIMM value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_dimm() const
- {
- return get_field<DIMM>();
- }
-
- ///
- /// @brief Set the port and DIMM value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- /// @note Useful for indexing all ports/DIMM on a controller
- ///
- inline address& set_port_dimm( const fapi2::buffer<uint64_t> i_value )
- {
- uint64_t l_read_port = 0;
-
- i_value.extractToRight<PORT_START, PORT_LEN>(l_read_port);
- return set_dimm(i_value.getBit<DIMM_BIT>()).set_port(l_read_port);
- }
-
- ///
- /// @brief Get the port and DIMM value for an address
- /// @return right-aligned uint64_t representing the value
- /// @note Useful for indexing all ports/DIMM on a controller
- ///
- inline uint64_t get_port_dimm() const
- {
- fapi2::buffer<uint64_t> l_value;
-
- l_value.insertFromRight<PORT_START, PORT_LEN>(get_port());
- l_value.writeBit<DIMM_BIT>(get_dimm());
-
- return l_value;
- }
-
- ///
- /// @brief Set the master rank value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_master_rank( const uint64_t i_value )
- {
- return set_field<MRANK>(i_value);
- }
-
- ///
- /// @brief Get the master rank value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_master_rank() const
- {
- return get_field<MRANK>();
- }
-
-
- ///
- /// @brief Set the slave rank value for an address
- /// @param[in] i_value the value to set
- ///
- inline void set_slave_rank( const uint64_t i_value )
- {
- set_field<SRANK>(i_value);
- }
-
- ///
- /// @brief Get the slave rank value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_slave_rank() const
- {
- return get_field<SRANK>();
- }
-
-
- ///
- /// @brief Set the row value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_row( const uint64_t i_value )
- {
- return set_field<ROW>(i_value);
- }
-
- ///
- /// @brief Get the row value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_row() const
- {
- return get_field<ROW>();
- }
-
-
- ///
- /// @brief Set the column value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_column( const uint64_t i_value )
- {
- return set_field<COL>(i_value);
- }
-
- ///
- /// @brief Get the column value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_column() const
- {
- return get_field<COL>();
- }
-
-
- ///
- /// @brief Set the bank value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_bank( const uint64_t i_value )
- {
- return set_field<BANK>(i_value);
- }
-
- ///
- /// @brief Get the bank value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_bank() const
- {
- return get_field<BANK>();
- }
-
- ///
- /// @brief Set the bank group value for an address
- /// @param[in] i_value the value to set
- /// @return address& for method chaining
- ///
- inline address& set_bank_group( const uint64_t i_value )
- {
- return set_field<BANK_GROUP>(i_value);
- }
-
- ///
- /// @brief Get the bank group value for an address
- /// @return right-aligned uint64_t representing the value
- ///
- inline uint64_t get_bank_group() const
- {
- return get_field<BANK_GROUP>();
- }
-
- private:
- // We use a fapi2 buffer as it has static compile-time support
- fapi2::buffer<uint64_t> iv_address;
-};
-
-} // close namespace mcbist
-
-// Documented above in its declaration.
-template< fapi2::TargetType T, typename TT >
-class ecc::fwms::address
-{
- public:
- // first is the start bit of the field, second is the length
- typedef std::pair<uint64_t, uint64_t> field;
-
- constexpr static field DIMM = {TT::FIRMWARE_MS_ADDRESS, 1};
- constexpr static field MRANK = {TT::FIRMWARE_MS_ADDRESS + 1, 2};
- constexpr static field SRANK = {TT::FIRMWARE_MS_ADDRESS + 3, 3};
- constexpr static field BANK_GROUP = {TT::FIRMWARE_MS_ADDRESS + 6, 2};
- constexpr static field BANK = {TT::FIRMWARE_MS_ADDRESS + 8, 3};
- constexpr static field LAST_VALID = BANK;
-
- address() = default;
-
- ///
- /// @brief Construct an address from a uint64_t (scom'ed value)
- /// @param[in] i_value representing raw value from FWMS register
- ///
- address( const uint64_t& i_value ):
- iv_value(i_value)
- {
- }
-
- ///
- /// @brief Construct an address from an mcbist::address
- /// @param[in] i_mcbist_address mcbist formatted address
- /// @note Construction of mcbist::address from ecc::fwms::address
- /// @note located in mcbist::address class
- ///
- address( const mcbist::address& i_mcbist_address )
- {
- iv_value.insertFromRight<DIMM.first, DIMM.second>(i_mcbist_address.get_field<mcbist::address::DIMM>());
- iv_value.insertFromRight<MRANK.first, MRANK.second>(i_mcbist_address.get_field<mcbist::address::MRANK>());
- iv_value.insertFromRight<SRANK.first, SRANK.second>(i_mcbist_address.get_field<mcbist::address::SRANK>());
- iv_value.insertFromRight<BANK_GROUP.first, BANK_GROUP.second>
- (i_mcbist_address.get_field<mcbist::address::BANK_GROUP>());
- iv_value.insertFromRight<BANK.first, BANK.second>(i_mcbist_address.get_field<mcbist::address::BANK>());
- }
-
- ///
- /// @brief Conversion operator to uint64_t
- ///
- inline operator uint64_t() const
- {
- uint64_t l_temp = 0;
- iv_value.extract<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_temp);
- return l_temp;
- }
-
- private:
- fapi2::buffer<uint64_t> iv_value;
-};
-
-} // close namespace mss
+// This file is still necessary to put traits and generic code together
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
index f5ef0e24c..c5b43fce7 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
@@ -35,8 +35,8 @@
#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
+#include <lib/mss_attribute_accessors.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/utils/dump_regs.H>
#include <lib/workarounds/mcbist_workarounds.H>
#include <generic/memory/lib/utils/pos.H>
@@ -47,7 +47,22 @@ using fapi2::TARGET_TYPE_MCS;
namespace mss
{
-const std::pair<uint64_t, uint64_t> mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::address_pairs[] =
+///
+/// @brief Gets the attribute for freq
+/// @param[in] const ref to the target
+/// @param[out] uint64_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Frequency of this memory channel in MT/s (Mega Transfers per second)
+///
+template<>
+fapi2::ReturnCode freq<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
+ i_target, uint64_t& o_value)
+{
+ return mss::freq(i_target, o_value);
+}
+
+const std::pair<uint64_t, uint64_t> mcbistTraits<>::address_pairs[] =
{
{ START_ADDRESS_0, END_ADDRESS_0 },
{ START_ADDRESS_1, END_ADDRESS_1 },
@@ -55,7 +70,7 @@ const std::pair<uint64_t, uint64_t> mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::add
{ START_ADDRESS_3, END_ADDRESS_3 },
};
-const std::vector< mss::mcbist::op_type > mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::FIFO_MODE_REQUIRED_OP_TYPES =
+const std::vector< mss::mcbist::op_type > mcbistTraits<>::FIFO_MODE_REQUIRED_OP_TYPES =
{
mss::mcbist::op_type::WRITE ,
mss::mcbist::op_type::READ ,
@@ -71,459 +86,16 @@ namespace mcbist
{
///
-/// @brief Load MCBIST maint pattern given a pattern
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_pattern an mcbist::patterns
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< >
-fapi2::ReturnCode load_maint_pattern( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const pattern& i_pattern,
- const bool i_invert )
-{
- // Init the fapi2 return code
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // Array access control
- fapi2::buffer<uint64_t> l_aacr;
- // Array access data
- fapi2::buffer<uint64_t> l_aadr;
-
- // first we must setup the access control register
- // Setup the array address
- // enable the auto increment bit
- // set ecc mode bit on
- l_aacr
- .writeBit<MCA_WREITE_AACR_BUFFER>(mss::states::OFF)
- .insertFromRight<MCA_WREITE_AACR_ADDRESS, MCA_WREITE_AACR_ADDRESS_LEN>(mss::mcbist::rmw_address::DW0)
- .writeBit<MCA_WREITE_AACR_AUTOINC>(mss::states::ON)
- .writeBit<MCA_WREITE_AACR_ECCGEN>(mss::states::ON);
-
- // This loop will be run twice to write the pattern twice. Once per 64B write.
- // When MCBIST maint mode is in 64B mode it will only use the first 64B when in 128B mode
- // MCBIST maint will use all 128B (it will perform two consecutive writes)
- const auto l_ports = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target);
- // Init the port map
-
- for (const auto& p : l_ports)
- {
- l_aacr.insertFromRight<MCA_WREITE_AACR_ADDRESS, MCA_WREITE_AACR_ADDRESS_LEN>(mss::mcbist::rmw_address::DW0);
-
- for (auto l_num_reads = 0; l_num_reads < 2; ++l_num_reads)
- {
- FAPI_INF("Setting the array access control register.");
- FAPI_TRY( mss::putScom(p, MCA_WREITE_AACR, l_aacr) );
-
- for (const auto& l_cache_line : i_pattern)
- {
- fapi2::buffer<uint64_t> l_value_first = i_invert ? ~l_cache_line.first : l_cache_line.first;
- fapi2::buffer<uint64_t> l_value_second = i_invert ? ~l_cache_line.second : l_cache_line.second;
- FAPI_INF("Loading cache line pattern 0x%016lx 0x%016lx", l_value_first, l_value_second);
- FAPI_TRY( mss::putScom(p, MCA_AADR, l_value_first) );
-
- // In order for the data to actually be written into the RMW buffer, we must issue a putscom to the MCA_AAER register
- // This register is used for the ECC, we will just write all zero to this register. The ECC will be auto generated
- // when the aacr MCA_WREITE_AACR_ECCGEN bit is set
- FAPI_TRY( mss::putScom(p, MCA_AAER, 0) );
-
- // No need to increment the address because the logic does it automatically when MCA_WREITE_AACR_AUTOINC is set
- FAPI_TRY( mss::putScom(p, MCA_AADR, l_value_second) );
-
- // In order for the data to actually be written into the RMW buffer, we must issue a putscom to the MCA_AAER register
- // This register is used for the ECC, we will just write all zero to this register. The ECC will be auto generated
- // when the aacr MCA_WREITE_AACR_ECCGEN bit is set
- FAPI_TRY( mss::putScom(p, MCA_AAER, 0) );
- }
-
- l_aacr.insertFromRight<MCA_WREITE_AACR_ADDRESS, MCA_WREITE_AACR_ADDRESS_LEN>(mss::mcbist::rmw_address::DW8);
- }
- }
-
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST data compare mask registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< >
-fapi2::ReturnCode load_data_compare_mask( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const mcbist::program<TARGET_TYPE_MCBIST>& i_program )
-{
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
-
- // Init the fapi2 return code
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // Load the MCBCM Data compare masks
-
- const auto l_ports = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target);
- FAPI_INF("Loading the MCBIST data compare mask registers!");
-
- for (const auto& p : l_ports)
- {
- FAPI_TRY( mss::putScom(p, TT::COMPARE_MASK, i_program.iv_compare_mask) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Load MCBIST 24b random data seeds given a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_random24_data_seed mcbist::random24_data_seed
-/// @param[in] i_random24_map mcbist::random24_seed_map
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< >
-fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const random24_data_seed& i_random24_data_seed,
- const random24_seed_map& i_random24_map,
- const bool i_invert )
-{
- // Init the fapi2 return code
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- const uint64_t l_random_addr0 = MCBIST_MCBRDS0Q;
- const uint64_t l_random_addr1 = MCBIST_MCBRDS1Q;
- uint64_t l_index = 0;
- uint64_t l_map_index = 0;
- uint64_t l_map_offset = 0;
-
- fapi2::buffer<uint64_t> l_mcbrsd0q;
- fapi2::buffer<uint64_t> l_mcbrsd1q;
-
-
- // We are going to loop through the random seeds and load them into the random seed registers
- // Because the 24b random data seeds share the same registers as the 24b random data byte LFSR maps
- // we will load those as well
-
- for (const auto& l_seed : i_random24_data_seed)
- {
- FAPI_INF("Loading 24b random seed index %ld ", l_index);
- fapi2::buffer<uint64_t> l_value = i_invert ? ~l_seed : l_seed;
-
- // Print an informational message to indicate if a random seed is 0
- // TK Do we want an error here? 0 may be used on purpose to hold a byte at all 0 on purpose
- if ( l_value == 0 )
- {
- FAPI_INF("Warning: Random 24b data seed is set to 0 for seed index %d", l_index);
- }
-
- // If we are processing the first 24b random data seed we will add it to the fapi buffer
- // we won't load it yet because the second 24b seed will be loaded into the same register
- if ( l_index == 0 )
- {
- l_mcbrsd0q.insertFromRight<MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0, MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN>(l_value);
- }
- // The second 24b random data seed is loaded into the same register as the first seed
- // therefore we will add the second seed tothe fapi buffer and then issue the putscom
- else if (l_index == 1 )
- {
- l_mcbrsd0q.insertFromRight<MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1, MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN>(l_value);
- FAPI_INF("Loading 24b random seeds 0 and 1 0x%016lx ", l_mcbrsd0q);
- FAPI_TRY( mss::putScom(i_target, l_random_addr0, l_mcbrsd0q) );
- }
- // The third 24b random data seed occupies the same register as the random data byte maps. Therefore we first
- // add the third random 24b data seed to the register and then loop through all of the byte mappings a total of
- // 9. ach of the byte mappings associates a byte of the random data to a byte in the 24b random data LFSRs
- // Each byte map is offset by 4 bits in the register.
- else
- {
- l_mcbrsd1q.insertFromRight<MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2, MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN>(l_value);
-
- for (const auto& l_map : i_random24_map)
- {
- l_map_offset = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING + (l_map_index * RANDOM24_SEED_MAP_FIELD_LEN);
- l_mcbrsd1q.insertFromRight(l_map, l_map_offset, RANDOM24_SEED_MAP_FIELD_LEN);
- FAPI_INF("Loading 24b random seed map index %ld ", l_map_index);
- FAPI_ASSERT( l_map_index < mss::mcbist::MAX_NUM_RANDOM24_MAPS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(l_map_index),
- "Attempting to load a 24b random data seed map which does not exist %d", l_map_index );
- ++l_map_index;
- }
-
- FAPI_TRY( mss::putScom(i_target, l_random_addr1, l_mcbrsd1q) );
- }
-
- FAPI_ASSERT( l_index < MAX_NUM_RANDOM24_SEEDS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(l_index),
- "Attempting to load a 24b random data seed which does not exist %d", l_index );
- ++l_index;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load a set of MCBIST subtests in to the MCBIST registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] the target to effect
-/// @param[in] the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note assumes the MCBIST engine has been configured.
-///
-template<>
-fapi2::ReturnCode load_mcbmr( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const mcbist::program<TARGET_TYPE_MCBIST>& i_program )
-{
-
- // Leave if there are no subtests.
- if (0 == i_program.iv_subtests.size())
- {
- FAPI_INF("no subtests, nothing to do");
- return fapi2::current_err;
- }
-
- // List of the 8 MCBIST registers - each holds 4 subtests.
- static const std::vector< uint64_t > l_memory_registers =
- {
- MCBIST_MCBMR0Q, MCBIST_MCBMR1Q, MCBIST_MCBMR2Q, MCBIST_MCBMR3Q,
- MCBIST_MCBMR4Q, MCBIST_MCBMR5Q, MCBIST_MCBMR6Q, MCBIST_MCBMR7Q,
- };
-
- std::vector< uint64_t > l_memory_register_buffers =
- {
- 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- static const size_t SUBTEST_PER_REG = 4;
- static const size_t SUBTEST_PER_PROGRAM = 32;
-
- static const auto BITS_IN_SUBTEST = sizeof(mcbist::subtest_t<TARGET_TYPE_MCBIST>().iv_mcbmr) * 8;
- static const auto LEFT_SHIFT = (sizeof(uint64_t) * 8) - BITS_IN_SUBTEST;
-
- ssize_t l_bin = -1;
- size_t l_register_shift = 0;
-
- // We'll shift this in to position to indicate which subtest is the last
- static const uint64_t l_done_bit( 0x8000000000000000 >> MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE );
-
- // TK: For now limit MCBIST programs to 32 subtests.
- const auto l_program_size = i_program.iv_subtests.size();
- FAPI_ASSERT( l_program_size <= SUBTEST_PER_PROGRAM,
- fapi2::MSS_MCBIST_PROGRAM_TOO_BIG().set_PROGRAM_LENGTH(l_program_size),
- "mcbist program of length %d exceeds arbitrary maximum of %d", l_program_size, SUBTEST_PER_PROGRAM );
-
- // Distribute the program over the 8 MCBIST subtest registers
- // We need the index, so increment thru i_program.iv_subtests.size()
- for (size_t l_index = 0; l_index < l_program_size; ++l_index)
- {
- l_bin = (l_index % SUBTEST_PER_REG) == 0 ? l_bin + 1 : l_bin;
- l_register_shift = (l_index % SUBTEST_PER_REG) * BITS_IN_SUBTEST;
-
- l_memory_register_buffers[l_bin] |=
- (uint64_t(i_program.iv_subtests[l_index].iv_mcbmr) << LEFT_SHIFT) >> l_register_shift;
-
- FAPI_DBG("putting subtest %d (0x%x) in MCBMR%dQ shifted %d 0x%016llx",
- l_index, i_program.iv_subtests[l_index].iv_mcbmr, l_bin,
- l_register_shift, l_memory_register_buffers[l_bin]);
- }
-
- // l_bin and l_register_shift are the values for the last subtest we'll tell the MCBIST about.
- // We need to set that subtest's done-bit so the MCBIST knows it's the end of the line
- l_memory_register_buffers[l_bin] |= l_done_bit >> l_register_shift;
- FAPI_DBG("setting MCBMR%dQ subtest %llu as the last subtest 0x%016llx",
- l_bin, l_register_shift, l_memory_register_buffers[l_bin]);
-
- // ... and slam the values in to the registers.
- // Could just decrement l_bin, but that scoms the subtests in backwards and is confusing
- for (auto l_index = 0; l_index <= l_bin; ++l_index)
- {
- FAPI_TRY( mss::putScom(i_target, l_memory_registers[l_index], l_memory_register_buffers[l_index]) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Poll the mcbist engine and check for errors
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program, the mcbist program which is executing
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode poll( const fapi2::Target<T>& i_target, const program<T>& i_program )
-{
- fapi2::buffer<uint64_t> l_status;
-
- static const uint64_t l_done = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_DONE>();
- static const uint64_t l_fail = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_FAIL>();
- static const uint64_t l_in_progress = fapi2::buffer<uint64_t>().setBit<TT::MCBIST_IN_PROGRESS>();
-
- // A small vector of addresses to poll during the polling loop
- const std::vector<mss::poll_probe<fapi2::TARGET_TYPE_MCBIST>> l_probes =
- {
- {i_target, "mcbist current address", MCBIST_MCBMCATQ},
- };
-
- mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_DBG("mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- l_status = stat_reg;
- return l_status.getBit<TT::MCBIST_IN_PROGRESS>() != 1;
- },
- l_probes);
-
- // Check to see if we're still in progress - meaning we timed out.
- FAPI_ASSERT((l_status & l_in_progress) != l_in_progress,
- fapi2::MSS_MCBIST_TIMEOUT().set_MCBIST_TARGET(i_target),
- "MCBIST timed out %s", mss::c_str(i_target));
-
- // The control register has a bit for done-and-happy and a bit for done-and-unhappy
- if ( ((l_status & l_done) == l_done) || ((l_status & l_fail) == l_fail) )
- {
- FAPI_INF("MCBIST completed, processing errors");
-
- // We're done. It doesn't mean that there were no errors.
- FAPI_TRY( i_program.process_errors(i_target) );
-
- // If we're here there were no errors, but lets report if the fail bit was set anyway.
- FAPI_ASSERT( (l_status & l_fail) != l_fail,
- fapi2::MSS_MCBIST_UNKNOWN_FAILURE()
- .set_MCBIST_TARGET(i_target)
- .set_STATUS_REGISTER(l_status),
- "%s MCBIST reported a fail, but process_errors didn't find it 0x%016llx",
- mss::c_str(i_target), l_status );
-
- // And if we're here all is good with the world.
- return fapi2::current_err;
- }
-
- FAPI_ASSERT(false,
- fapi2::MSS_MCBIST_DATA_FAIL()
- .set_MCBIST_TARGET(i_target)
- .set_STATUS_REGISTER(l_status),
- "%s MCBIST executed but we got corrupted data in the control register 0x%016llx",
- mss::c_str(i_target), l_status );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Execute the mcbist program
-/// @param[in] i_target the target to effect
-/// @param[in] i_program, the mcbist program to execute
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template<>
-fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const program<TARGET_TYPE_MCBIST>& i_program )
-{
- typedef mcbistTraits<TARGET_TYPE_MCBIST> TT;
-
- fapi2::buffer<uint64_t> l_status;
- bool l_poll_result = false;
- poll_parameters l_poll_parameters;
-
- // Before we go off into the bushes, lets see if there are any instructions in the
- // program. If not, we can save everyone the hassle
- FAPI_ASSERT(0 != i_program.iv_subtests.size(),
- fapi2::MSS_MEMDIAGS_NO_MCBIST_SUBTESTS().set_MCBIST_TARGET(i_target),
- "Attempt to run an MCBIST program with no subtests on %s", mss::c_str(i_target));
-
- // Implement any mcbist work-arounds.
- // I'm going to do the unthinkable here - and cast away the const of the mcbist program input.
- // The work arounds need to change this, and so it needs to not be const. However, I don't want
- // to risk general const-correctness by changing the input parameter to non-const. So, I use
- // const_cast<> (ducks out of the way of the flying adjectives.) These are work-arounds ...
- FAPI_TRY( workarounds::mcbist::end_of_rank(i_target, const_cast<program<TARGET_TYPE_MCBIST>&>(i_program)) );
-
- FAPI_TRY( clear_errors(i_target) );
-
- // Configures the write/read FIFO bit
- FAPI_TRY( load_fifo_mode( i_target, i_program) );
-
- // Slam the address generator config
- FAPI_TRY( load_addr_gen(i_target, i_program) );
-
- // Slam the parameters in to the mcbist parameter register
- FAPI_TRY( load_mcbparm(i_target, i_program) );
-
- // Slam the configured address maps down
- FAPI_TRY( load_mcbamr( i_target, i_program) );
-
- // Slam the config register down
- FAPI_TRY( load_config( i_target, i_program) );
-
- // Slam the control register down
- FAPI_TRY( load_control( i_target, i_program) );
-
- // Load the patterns and any associated bits for random, etc
- FAPI_TRY( load_data_config( i_target, i_program) );
-
- // Load the thresholds
- FAPI_TRY( load_thresholds( i_target, i_program) );
-
- // Slam the subtests in to the mcbist registers
- // Always do this last so the action file triggers see the other bits set
- FAPI_TRY( load_mcbmr(i_target, i_program) );
-
- // Start the engine, and then poll for completion
- FAPI_TRY(start_stop(i_target, mss::START));
-
- // Verify that the in-progress bit has been set, so we know we started
- // Don't use the program's poll as it could be a very long time. Use the default poll.
- l_poll_result = mss::poll(i_target, TT::STATQ_REG, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_DBG("looking for mcbist start, mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- l_status = stat_reg;
- // We're done polling when either we see we're in progress or we see we're done.
- return (l_status.getBit<TT::MCBIST_IN_PROGRESS>() == true) || (l_status.getBit<TT::MCBIST_DONE>() == true);
- });
-
- // So we've either run/are running or we timed out waiting for the start.
- FAPI_ASSERT( l_poll_result == true,
- fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_START().set_MCBIST_TARGET(i_target),
- "The MCBIST engine failed to start its program" );
-
- // If the user asked for async mode, we can leave. Otherwise, poll and check for errors
- if (!i_program.iv_async)
- {
- return mcbist::poll(i_target, i_program);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Get a list of ports involved in the program
-/// Specialization for program<fapi2::TARGET_TYPE_MCBIST>
+/// Specialization for program<>
/// @param[in] i_target the target for this program
/// @return vector of port targets
///
template<>
-template<>
std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>
- program<fapi2::TARGET_TYPE_MCBIST>::get_port_list<fapi2::TARGET_TYPE_MCA>( const
- fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target ) const
+ program<>::get_port_list( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target ) const
{
- typedef mss::mcbistTraits<TARGET_TYPE_MCBIST> TT;
+ using TT = mss::mcbistTraits<>;
std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>> l_list;
@@ -542,81 +114,6 @@ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>
return l_list;
}
-///
-/// @brief Read entries from MCBIST Read Modify Write (RMW) array
-/// Specialization for fapi2::TARGET_TYPE_MCA
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[in] i_roll_over_for_compare_mode set to true if only using first
-/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
-/// @param[out] o_data vector of output data
-/// @param[out] o_ecc_data vector of ecc data
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
-/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
-/// that since reads work in a circular buffer fashion
-///
-template<>
-fapi2::ReturnCode read_rmw_array(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- const bool i_roll_over_for_compare_mode,
- std::vector< fapi2::buffer<uint64_t> >& o_data,
- std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
-{
- typedef mcbistTraits<fapi2::TARGET_TYPE_MCA> TT;
-
- fapi2::buffer<uint64_t> l_control_value;
- fapi2::buffer<uint64_t> l_data;
- uint64_t l_array_addr = i_start_addr;
-
- // Clear out any stale values from output vectors
- o_data.clear();
- o_ecc_data.clear();
-
- // Set the control register for the RMW array
- l_control_value.writeBit<TT::RMW_WRT_BUFFER_SEL>(TT::SELECT_RMW_BUFFER)
- // set start address
- .insertFromRight<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>(l_array_addr)
- // enable the auto increment bit
- .setBit<TT::RMW_WRT_AUTOINC>()
- // set ecc mode bit off
- .clearBit<TT::RMW_WRT_ECCGEN>();
-
- FAPI_INF("Setting the RMW array access control register.");
- FAPI_TRY( mss::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );
-
- for (uint8_t l_index = 0; l_index < i_num_entries; ++l_index)
- {
- // Read info out of RMW array and put into output vector
- // Note that since we enabled AUTOINC above, reading ECC_REG will increment
- // the array pointer so the next DATA_REG read will read the next array entry
- FAPI_TRY( mss::getScom(i_target, TT::RMW_WRT_BUF_DATA_REG, l_data) );
-
- FAPI_INF("RMW data index %d is: %016lx", l_array_addr, l_data);
- o_data.push_back(l_data);
-
- // Need to read ecc register to increment array index
- FAPI_TRY( mss::getScom(i_target, TT::RMW_WRT_BUF_ECC_REG, l_data) );
- o_ecc_data.push_back(l_data);
- ++l_array_addr;
-
- // Need to manually roll over address if we go beyond NUM_COMPARE_INFO_ENTRIES
- // Since actual array is bigger than what is used for compare mode
- if (i_roll_over_for_compare_mode &&
- (l_array_addr >= TT::NUM_COMPARE_INFO_ENTRIES))
- {
- FAPI_INF("Rolling over the RMW array access control register address from %d to %d.", (i_start_addr + l_index), 0);
- l_control_value.clearBit<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>();
- FAPI_TRY( mss::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );
- l_array_addr = 0;
- }
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
///
/// @brief Read entries from MCBIST Read Buffer (RB) array
@@ -635,7 +132,7 @@ fapi2::ReturnCode read_rb_array(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_t
std::vector< fapi2::buffer<uint64_t> >& o_data,
std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
{
- typedef mcbistTraits<fapi2::TARGET_TYPE_MCS> TT;
+ using TT = mcbistTraits<DEFAULT_MC_TYPE, fapi2::TARGET_TYPE_MCS>;
fapi2::buffer<uint64_t> l_control_value;
fapi2::buffer<uint64_t> l_data;
@@ -687,7 +184,7 @@ fapi_try_exit:
/// @param[in] i_targets the vector of targets to analyze - specialization for MCA target type
/// @return l_capable - yes iff these vector of targets are broadcast capable
///
-template< >
+template<>
const mss::states is_broadcast_capable(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>& i_targets)
{
// If we don't have MCA's exit out
@@ -911,7 +408,7 @@ fapi_try_exit:
///
template< >
fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mcbist::program<fapi2::TARGET_TYPE_MCBIST>& io_program)
+ mcbist::program<>& io_program)
{
// constexpr's for beautification
constexpr bool ENABLE = true;
@@ -934,6 +431,52 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Configures broadcast mode, if it is needed
+/// @param[in] i_target the target to effect
+/// @param[in,out] io_program the mcbist::program
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template<>
+fapi2::ReturnCode configure_broadcast_mode(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ mcbist::program<>& io_program)
+{
+ // If we're not capable to do broadcast mode on this target, exit out
+ const auto l_broadcast_capable = is_broadcast_capable(i_target);
+
+ if(l_broadcast_capable == mss::states::NO)
+ {
+ FAPI_INF("%s is not broadcast capable, skipping enablement of broadcast mode", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Enable broadcast mode
+ FAPI_INF("%s is broadcast capable, enabling broadcast mode", mss::c_str(i_target));
+ return enable_broadcast_mode(i_target, io_program);
+}
+
+///
+/// @brief Clear the errors helper. Chip can specialise this
+/// function to put any necessary workaround in it.
+/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
+///
+template< >
+fapi2::ReturnCode clear_error_helper( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const program<>& i_program )
+{
+ // Implement any mcbist work-arounds.
+ // I'm going to do the unthinkable here - and cast away the const of the mcbist program input.
+ // The work arounds need to change this, and so it needs to not be const. However, I don't want
+ // to risk general const-correctness by changing the input parameter to non-const. So, I use
+ // const_cast<> (ducks out of the way of the flying adjectives.) These are work-arounds ...
+ FAPI_TRY( workarounds::mcbist::end_of_rank(i_target, const_cast<program<>&>(i_program)) );
+
+ FAPI_TRY( clear_errors(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // namespace MCBIST
// Note: outside of the mcbist namespace
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 bba494154..33318c3e5 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
@@ -42,3156 +42,27 @@
#include <p9_mc_scom_addresses_fld.H>
#include <lib/shared/mss_const.H>
-#include <generic/memory/lib/utils/find.H>
-#include <generic/memory/lib/utils/poll.H>
-#include <generic/memory/lib/utils/memory_size.H>
+#include <lib/ecc/ecc_traits.H>
+#include <lib/mc/port.H>
#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/utils/bit_count.H>
-#include <lib/utils/num.H>
-#include <lib/mcbist/patterns.H>
-#include <lib/mcbist/settings.H>
-#include <lib/mc/port.H>
#include <lib/dimm/kind.H>
+#include <lib/mcbist/mcbist_traits.H>
+#include <generic/memory/lib/utils/num.H>
+#include <generic/memory/lib/utils/poll.H>
+#include <generic/memory/lib/utils/memory_size.H>
+#include <generic/memory/lib/utils/mcbist/gen_patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_settings.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H>
+#include <generic/memory/lib/utils/dump_regs.H>
+#include <lib/workarounds/mcbist_workarounds.H>
namespace mss
{
-
-// I have a dream that the MCBIST engine code can be shared among controllers. So, I drive the
-// engine from a set of traits. This might be folly. Allow me to dream. BRS
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the MCBIST engine or hardware
-///
-template< fapi2::TargetType T >
-class mcbistTraits;
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Centaur MCBIST engine or hardware
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MEMBUF_CHIP>
-{
-};
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Nimbus MCBIST engine or hardware
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MCBIST>
-{
- public:
- /// MCBIST "memory registers" - config for subtests.
- static constexpr uint64_t MCBMR0_REG = MCBIST_MCBMR0Q;
- static constexpr uint64_t CFGQ_REG = MCBIST_MCBCFGQ;
- static constexpr uint64_t CNTLQ_REG = MCBIST_MCB_CNTLQ;
- static constexpr uint64_t STATQ_REG = MCBIST_MCB_CNTLSTATQ;
- static constexpr uint64_t MCBSTATQ_REG = MCBIST_MCBSTATQ;
- static constexpr uint64_t MCBPARMQ_REG = MCBIST_MCBPARMQ;
- static constexpr uint64_t MCBAGRAQ_REG = MCBIST_MCBAGRAQ;
- static constexpr uint64_t SRERR0_REG = MCBIST_MBSEC0Q;
- static constexpr uint64_t SRERR1_REG = MCBIST_MBSEC1Q;
- static constexpr uint64_t THRESHOLD_REG = MCBIST_MBSTRQ;
- static constexpr uint64_t FIRQ_REG = MCBIST_MCBISTFIRQ;
- static constexpr uint64_t LAST_ADDR_REG = MCBIST_MCBMCATQ;
-
- static constexpr uint64_t MCBAMR0A0Q_REG = MCBIST_MCBAMR0A0Q;
- static constexpr uint64_t MCBAMR1A0Q_REG = MCBIST_MCBAMR1A0Q;
- static constexpr uint64_t MCBAMR2A0Q_REG = MCBIST_MCBAMR2A0Q;
- static constexpr uint64_t MCBAMR3A0Q_REG = MCBIST_MCBAMR3A0Q;
-
- // MCBIST FIR registers
- static constexpr uint64_t MCBFIRMASK_REG = MCBIST_MCBISTFIRMASK;
- static constexpr uint64_t MCBFIRQ_REG = MCBIST_MCBISTFIRQ;
-
- // All of the pattern registers are calculated off of this base
- static constexpr uint64_t PATTERN0_REG = MCBIST_MCBFD0Q;
-
- static constexpr uint64_t DATA_ROTATE_CNFG_REG = MCBIST_MCBDRCRQ;
- static constexpr uint64_t DATA_ROTATE_SEED_REG = MCBIST_MCBDRSRQ;
-
- static constexpr uint64_t START_ADDRESS_0 = MCBIST_MCBSA0Q;
- static constexpr uint64_t START_ADDRESS_1 = MCBIST_MCBSA1Q;
- static constexpr uint64_t START_ADDRESS_2 = MCBIST_MCBSA2Q;
- static constexpr uint64_t START_ADDRESS_3 = MCBIST_MCBSA3Q;
-
- static constexpr uint64_t END_ADDRESS_0 = MCBIST_MCBEA0Q;
- static constexpr uint64_t END_ADDRESS_1 = MCBIST_MCBEA1Q;
- static constexpr uint64_t END_ADDRESS_2 = MCBIST_MCBEA2Q;
- static constexpr uint64_t END_ADDRESS_3 = MCBIST_MCBEA3Q;
-
- static constexpr uint64_t RANDOM_DATA_SEED0 = MCBIST_MCBRDS0Q;
- static constexpr uint64_t RANDOM_DATA_SEED1 = MCBIST_MCBRDS1Q;
-
-
- // MCBIST Compare Masks, used to setup the ECC traps
- // TK there is one reg per port, does writing to this one write to all?
- static constexpr uint64_t COMPARE_MASK = MCA_MCBCM;
-
- static constexpr uint64_t PATTERN_COUNT = 4;
-
- // Sometimes we want to access the start/end address registers based off
- // of an index, like master rank. This allows us to do that.
- static const std::pair<uint64_t, uint64_t> address_pairs[];
-
- // Subtest types that need to be run in FIFO mode
- static const std::vector< mss::mcbist::op_type > FIFO_MODE_REQUIRED_OP_TYPES;
-
- enum
- {
- // Subtest control bits. These are the same in all '16 bit subtest' field
- COMPL_1ST_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
- COMPL_2ND_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_2ND_CMD,
- COMPL_3RD_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_3RD_CMD,
- ADDR_REV_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_REV_MODE,
- ADDR_RAND_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_RAND_MODE,
-
- // Goto subtests use the compl_1st - rand_mode to define the subtest to jump to
- GOTO_SUBTEST = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
- GOTO_SUBTEST_LEN = 5,
-
- ECC_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ECC_MODE,
- DATA_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE,
- DATA_MODE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE_LEN,
- ADDR_SEL = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL,
- ADDR_SEL_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL_LEN,
- OP_TYPE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE,
- OP_TYPE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE_LEN,
- DONE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE,
-
- SYNC_EN = MCBIST_MCBCFGQ_BROADCAST_SYNC_EN,
- SYNC_WAIT = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT,
- SYNC_WAIT_LEN = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT_LEN,
-
- PORT_SEL = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL,
- PORT_SEL_LEN = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL_LEN,
-
- MCBIST_START = MCBIST_MCB_CNTLQ_START,
- MCBIST_STOP = MCBIST_MCB_CNTLQ_STOP,
- MCBIST_RESUME = MCBIST_MCB_CNTLQ_RESUME_FROM_PAUSE,
- MCBIST_RESET_ERRORS = MCBIST_MCB_CNTLQ_RESET_ERROR_LOGS,
-
- MCBIST_IN_PROGRESS = MCBIST_MCB_CNTLSTATQ_IP,
- MCBIST_DONE = MCBIST_MCB_CNTLSTATQ_DONE,
- MCBIST_FAIL = MCBIST_MCB_CNTLSTATQ_FAIL,
-
- MIN_CMD_GAP = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP,
- MIN_CMD_GAP_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_LEN,
- MIN_GAP_TIMEBASE = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE,
- MIN_CMD_GAP_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER,
- MIN_CMD_GAP_BLIND_STEER_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER_LEN,
- MIN_GAP_TIMEBASE_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE_BLIND_STEER,
- RANDCMD_WGT = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT,
- RANDCMD_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT_LEN,
- CLOCK_MONITOR_EN = MCBIST_MCBPARMQ_CFG_CLOCK_MONITOR_EN,
- EN_RANDCMD_GAP = MCBIST_MCBPARMQ_CFG_EN_RANDCMD_GAP,
- RANDGAP_WGT = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT,
- RANDGAP_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT_LEN,
- BC4_EN = MCBIST_MCBPARMQ_CFG_BC4_EN,
-
- FIXED_WIDTH = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH,
- FIXED_WIDTH_LEN = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH_LEN,
- ADDR_COUNTER_MODE = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE,
- ADDR_COUNTER_MODE_LEN = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE_LEN,
- MAINT_ADDR_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN,
- MAINT_BROADCAST_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_BROADCAST_MODE_EN,
- MAINT_DETECT_SRANK_BOUNDARIES = MCBIST_MCBAGRAQ_CFG_MAINT_DETECT_SRANK_BOUNDARIES,
-
- CFG_CMD_TIMEOUT_MODE = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE,
- CFG_CMD_TIMEOUT_MODE_LEN = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE_LEN,
- RESET_KEEPER = MCBIST_MCBCFGQ_RESET_KEEPER,
- CFG_CURRENT_ADDR_TRAP_UPDATE_DIS = MCBIST_MCBCFGQ_CFG_CURRENT_ADDR_TRAP_UPDATE_DIS,
- CFG_CCS_RETRY_DIS = MCBIST_MCBCFGQ_CFG_CCS_RETRY_DIS,
- CFG_RESET_CNTS_START_OF_RANK = MCBIST_MCBCFGQ_CFG_RESET_CNTS_START_OF_RANK,
- CFG_LOG_COUNTS_IN_TRACE = MCBIST_MCBCFGQ_CFG_LOG_COUNTS_IN_TRACE,
- SKIP_INVALID_ADDR_DIMM_DIS = MCBIST_MCBCFGQ_SKIP_INVALID_ADDR_DIMM_DIS,
- REFRESH_ONLY_SUBTEST_EN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_EN,
- REFRESH_ONLY_SUBTEST_TIMEBASE_SEL = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL,
- REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN,
- RAND_ADDR_ALL_ADDR_MODE_EN = MCBIST_MCBCFGQ_RAND_ADDR_ALL_ADDR_MODE_EN,
- MCBIST_CFG_REF_WAIT_TIME = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME,
- MCBIST_CFG_REF_WAIT_TIME_LEN = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME_LEN,
- CFG_MCB_LEN64 = MCBIST_MCBCFGQ_CFG_MCB_LEN64,
- CFG_PAUSE_ON_ERROR_MODE = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE,
- CFG_PAUSE_ON_ERROR_MODE_LEN = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE_LEN,
- MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST,
- MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR,
- MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST,
- CFG_ENABLE_SPEC_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_SPEC_ATTN,
- CFG_ENABLE_HOST_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_HOST_ATTN,
- MCBIST_CFG_PAUSE_AFTER_RANK = MCBIST_MCBCFGQ_CFG_MCBIST_CFG_FORCE_PAUSE_AFTER_RANK,
-
- LOGGED_ERROR_ON_PORT_INDICATOR = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR,
- LOGGED_ERROR_ON_PORT_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR_LEN,
- SUBTEST_NUM_INDICATOR = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR,
- SUBTEST_NUM_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR_LEN,
-
- UE_COUNT = MCBIST_MBSEC1Q_UE_COUNT,
- UE_COUNT_LEN = MCBIST_MBSEC1Q_UE_COUNT_LEN,
-
- CFG_AMAP_DIMM_SELECT = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT,
- CFG_AMAP_DIMM_SELECT_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT_LEN,
- CFG_AMAP_MRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0,
- CFG_AMAP_MRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0_LEN,
- CFG_AMAP_MRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1,
- CFG_AMAP_MRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1_LEN,
- CFG_AMAP_SRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0,
- CFG_AMAP_SRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0_LEN,
- CFG_AMAP_SRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1,
- CFG_AMAP_SRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1_LEN,
- CFG_AMAP_SRANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2,
- CFG_AMAP_SRANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2_LEN,
- CFG_AMAP_BANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2,
- CFG_AMAP_BANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2_LEN ,
- CFG_AMAP_BANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1,
- CFG_AMAP_BANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1_LEN ,
- CFG_AMAP_BANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0,
- CFG_AMAP_BANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0_LEN ,
-
- CFG_AMAP_BANK_GROUP1 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1,
- CFG_AMAP_BANK_GROUP1_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1_LEN ,
- CFG_AMAP_BANK_GROUP0 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0,
- CFG_AMAP_BANK_GROUP0_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0_LEN ,
- CFG_AMAP_ROW17 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17,
- CFG_AMAP_ROW17_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17_LEN,
- CFG_AMAP_ROW16 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16,
- CFG_AMAP_ROW16_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16_LEN,
- CFG_AMAP_ROW15 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15,
- CFG_AMAP_ROW15_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15_LEN,
- CFG_AMAP_ROW14 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14,
- CFG_AMAP_ROW14_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14_LEN,
- CFG_AMAP_ROW13 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13,
- CFG_AMAP_ROW13_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13_LEN,
- CFG_AMAP_ROW12 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12,
- CFG_AMAP_ROW12_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12_LEN,
- CFG_AMAP_ROW11 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11,
- CFG_AMAP_ROW11_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11_LEN,
- CFG_AMAP_ROW10 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10,
- CFG_AMAP_ROW10_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10_LEN,
-
- CFG_AMAP_ROW9 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9,
- CFG_AMAP_ROW9_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9_LEN,
- CFG_AMAP_ROW8 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8,
- CFG_AMAP_ROW8_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8_LEN,
- CFG_AMAP_ROW7 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7,
- CFG_AMAP_ROW7_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7_LEN,
- CFG_AMAP_ROW6 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6,
- CFG_AMAP_ROW6_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6_LEN,
- CFG_AMAP_ROW5 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5,
- CFG_AMAP_ROW5_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5_LEN,
- CFG_AMAP_ROW4 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4,
- CFG_AMAP_ROW4_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4_LEN,
- CFG_AMAP_ROW3 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3,
- CFG_AMAP_ROW3_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3_LEN,
- CFG_AMAP_ROW2 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2,
- CFG_AMAP_ROW2_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2_LEN,
- CFG_AMAP_ROW1 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1,
- CFG_AMAP_ROW1_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1_LEN,
- CFG_AMAP_ROW0 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0,
- CFG_AMAP_ROW0_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0_LEN,
-
- CFG_AMAP_COL9 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9,
- CFG_AMAP_COL9_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9_LEN,
- CFG_AMAP_COL8 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8,
- CFG_AMAP_COL8_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8_LEN,
- CFG_AMAP_COL7 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7,
- CFG_AMAP_COL7_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7_LEN,
- CFG_AMAP_COL6 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6,
- CFG_AMAP_COL6_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6_LEN,
- CFG_AMAP_COL5 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5,
- CFG_AMAP_COL5_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5_LEN,
- CFG_AMAP_COL4 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4,
- CFG_AMAP_COL4_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4_LEN,
- CFG_AMAP_COL3 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3,
- CFG_AMAP_COL3_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3_LEN,
- CFG_AMAP_COL2 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2,
- CFG_AMAP_COL2_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2_LEN,
-
- CFG_DATA_ROT_SEED1 = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED,
- CFG_DATA_ROT_SEED1_LEN = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED_LEN,
- CFG_DATA_ROT = MCBIST_MCBDRCRQ_CFG_DATA_ROT,
- CFG_DATA_ROT_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_LEN,
- CFG_DATA_ROT_SEED2 = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED,
- CFG_DATA_ROT_SEED2_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED_LEN,
- CFG_DATA_SEED_MODE = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE,
- CFG_DATA_SEED_MODE_LEN = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE_LEN,
-
- CFG_TRAP_CE_ENABLE = MCA_MCBCM_MCBIST_TRAP_CE_ENABLE,
- CFG_TRAP_UE_ENABLE = MCA_MCBCM_MCBIST_TRAP_UE_ENABLE,
- CFG_TRAP_MPE_ENABLE = MCA_MCBCM_MCBIST_TRAP_MPE_ENABLE,
-
- CFG_DGEN_RNDD_SEED0 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0,
- CFG_DGEN_RNDD_SEED0_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN,
- CFG_DGEN_RNDD_SEED1 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1,
- CFG_DGEN_RNDD_SEED1_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN,
- CFG_DGEN_RNDD_SEED2 = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2,
- CFG_DGEN_RNDD_SEED2_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN,
- CFG_DGEN_RNDD_DATA_MAPPING = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING,
- CFG_DGEN_RNDD_DATA_MAPPING_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN,
-
- // Bit mapping for MCBIST error log control data (address+ in Nimbus doc)
- ERROR_LOG_SUBTEST = 0,
- ERROR_LOG_SUBTEST_LEN = 5,
- ERROR_LOG_SUBCMD = 5,
- ERROR_LOG_SUBCMD_LEN = 2,
- ERROR_LOG_ADDR_DIMM = 7,
- ERROR_LOG_ADDR_MRANK = 8,
- ERROR_LOG_ADDR_MRANK_LEN = 2,
- ERROR_LOG_ADDR_SRANK = 10,
- ERROR_LOG_ADDR_SRANK_LEN = 3,
- ERROR_LOG_ADDR_BANK_GROUP = 13,
- ERROR_LOG_ADDR_BANK_GROUP_LEN = 2,
- ERROR_LOG_ADDR_BANK = 15,
- ERROR_LOG_ADDR_BANK_LEN = 3,
- ERROR_LOG_ADDR_ROW = 18,
- ERROR_LOG_ADDR_ROW_LEN = 18,
- ERROR_LOG_ADDR_COLUMN = 36,
- ERROR_LOG_ADDR_COLUMN_LEN = 8,
- ERROR_LOG_BEAT = 44,
- ERROR_LOG_BEAT_LEN = 2,
- ERROR_LOG_TYPE = 46,
- ERROR_LOG_TYPE_LEN = 2,
-
- //MCBIST FIR mask
- MCB_PROGRAM_COMPLETE = MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE,
- MCB_WAT_DEBUG_ATTN = MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN,
- MCB_PROGRAM_COMPLETE_MASK = MCB_PROGRAM_COMPLETE,
- MCB_WAT_DEBUG_ATTN_MASK = MCB_WAT_DEBUG_ATTN,
- };
-
-};
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Nimbus MCA
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MCA>
-{
- public:
- // MCBIST error log related registers
- static constexpr uint64_t ERROR_LOG_PTR_REG = MCA_ELPR;
- static constexpr uint64_t RMW_WRT_BUF_CTL_REG = MCA_WREITE_AACR;
- static constexpr uint64_t RMW_WRT_BUF_DATA_REG = MCA_AADR;
- static constexpr uint64_t RMW_WRT_BUF_ECC_REG = MCA_AAER;
-
- enum
- {
- // Register field constants
- ERROR_LOG_PTR = MCA_ELPR_LOG_POINTER,
- ERROR_LOG_PTR_LEN = MCA_ELPR_LOG_POINTER_LEN,
- ERROR_LOG_FULL = MCA_ELPR_LOG_FULL,
- RMW_WRT_BUFFER_SEL = MCA_WREITE_AACR_BUFFER,
- RMW_WRT_ADDRESS = MCA_WREITE_AACR_ADDRESS,
- RMW_WRT_ADDRESS_LEN = MCA_WREITE_AACR_ADDRESS_LEN,
- RMW_WRT_AUTOINC = MCA_WREITE_AACR_AUTOINC,
- RMW_WRT_ECCGEN = MCA_WREITE_AACR_ECCGEN,
-
- // Constants used for field settings
- SELECT_RMW_BUFFER = 0,
- SELECT_WRT_BUFFER = 1,
-
- // Other constants
- NUM_COMPARE_LOG_ENTRIES = 64,
- // In compare mode, there is one "info" entry per 4 data (log) entries
- // so compare mode only uses 16 info entries total in the rmw array
- NUM_COMPARE_DATA_PER_INFO_LOG = 4,
- NUM_COMPARE_INFO_ENTRIES = 16,
- };
-
-};
-
-///
-/// @class mcbistTraits
-/// @brief a collection of traits associated with the Nimbus MCS
-///
-template<>
-class mcbistTraits<fapi2::TARGET_TYPE_MCS>
-{
- public:
- // MCBIST error log related registers
- static constexpr uint64_t RD_BUF_CTL_REG = MCS_PORT02_AACR;
- static constexpr uint64_t RD_BUF_DATA_REG = MCS_PORT02_AADR;
- static constexpr uint64_t RD_BUF_ECC_REG = MCS_PORT02_AAER;
-
- enum
- {
- // Register field constants
- RB_BUFFER_SEL = MCS_PORT02_AACR_BUFFER,
- RB_ADDRESS = MCS_PORT02_AACR_ADDRESS,
- RB_ADDRESS_LEN = MCS_PORT02_AACR_ADDRESS_LEN,
- RB_AUTOINC = MCS_PORT02_AACR_AUTOINC,
-
- // Other constants
- NUM_COMPARE_LOG_ENTRIES = 64,
- };
-
-};
-
-///
-/// @brief Return the estimated time an MCBIST subtest will take to complete
-/// Useful for initial polling delays, probably isn't accurate for much else
-/// as it doesn't take refresh in to account (which will necessarily slow down
-/// the program.)
-/// @param[in] i_target the target from which to gather memory frequency
-/// @param[in] i_bytes number of *bytes* in the address range
-/// @param[in] i_64B_per mss::YES if the command is 64B, mss::NO if it's 128B. Defaults to mss::YES
-/// @return the initial polling delay for this program in ns
-///
-template< fapi2::TargetType T >
-inline uint64_t calculate_initial_delay(const fapi2::Target<T>& i_target,
- const uint64_t i_bytes,
- const bool i_64B_per = mss::YES)
-{
- // TODO RTC: 164104 Update MCBIST delay calculator. As we learn more about what
- // the lab really needs, we can probably make this function better.
- const uint64_t l_bytes_per_cmd = (i_64B_per == mss::YES) ? 64 : 128;
-
- // Best case is a command takes 4 cycles. Given the number of commands and address space size
- // we can get some idea of how long to wait before we start polling.
- return cycles_to_ns(i_target, (i_bytes / l_bytes_per_cmd) * mss::CYCLES_PER_CMD);
-}
-
namespace mcbist
{
-///
-/// @class subtest_t
-/// @brief encapsulation of an MCBIST subtest.
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-class subtest_t
-{
- public:
- subtest_t( const uint16_t i_data = 0 ):
- iv_mcbmr(i_data)
- {}
-
- ///
- /// @brief Checks if the op type requires FIFO mode to be on
- /// @return bool fifo_mode_requried - true if FIFO mode is required to be forced on
- ///
- inline bool fifo_mode_required() const
- {
- // Gets the op type for this subtest
- uint64_t l_value_to_find = 0;
- iv_mcbmr.extractToRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_value_to_find);
-
- // Finds if this op type is in the vector that stores the OP types that require FIFO mode to be run
- const auto l_op_type_it = std::find(TT::FIFO_MODE_REQUIRED_OP_TYPES.begin(), TT::FIFO_MODE_REQUIRED_OP_TYPES.end(),
- l_value_to_find);
-
- // If the op type is required (aka was found), it will be less than end
- // std::find returns the ending iterator if it was not found, so this will return false in that case
- return l_op_type_it != TT::FIFO_MODE_REQUIRED_OP_TYPES.end();
- }
-
- ///
- /// @brief Convert to a 16 bit int
- /// @return the subtest as a 16 bit integer, useful for testing
- ///
- inline operator uint16_t()
- {
- return uint16_t(iv_mcbmr);
- }
-
- ///
- /// @brief Complement the data for the first subcommand
- /// @param[in] i_state the desired state (mss::ON or mss::OFF)
- ///
- inline void change_compliment_1st_cmd( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::COMPL_1ST_CMD>(i_state);
- return;
- }
-
- ///
- /// @brief Complement the data for the second subcommand
- /// @param[in] i_state the desired state (mss::ON or mss::OFF)
- /// @return void
- ///
- inline void change_compliment_2nd_cmd( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::COMPL_2ND_CMD>(i_state);
- return;
- }
-
- ///
- /// @brief Complement the data for the third subcommand
- /// @param[in] i_state the desired state (mss::ON or mss::OFF)
- /// @return void
- ///
- inline void change_compliment_3rd_cmd( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::COMPL_3RD_CMD>(i_state);
- return;
- }
-
- ///
- /// @brief Enable a specific port for this test - maint address mode
- /// @param[in] i_port the port desired to be enabled - int 0, 1, 2, 3
- /// @note The port number is relative to the MCBIST
- /// @return void
- ///
- inline void enable_port( const uint64_t i_port )
- {
- constexpr uint64_t l_len = (TT::COMPL_2ND_CMD - TT::COMPL_1ST_CMD) + 1;
- iv_mcbmr.template insertFromRight<TT::COMPL_1ST_CMD, l_len>(i_port);
- return;
- }
-
- ///
- /// @brief Enable a specific dimm for this test - maint address mode
- /// @param[in] i_dimm the dimm desired to be enabled - int 0, 1
- /// @return void
- ///
- inline void enable_dimm( const uint64_t i_dimm )
- {
- iv_mcbmr.template writeBit<TT::COMPL_3RD_CMD>(i_dimm);
- return;
- }
-
- ///
- /// @brief Get the port from this subtest
- /// @note The port number is relative to the MCBIST
- /// @return the port of the subtest
- ///
- inline uint64_t get_port() const
- {
- uint64_t l_port = 0;
- constexpr uint64_t l_len = (TT::COMPL_2ND_CMD - TT::COMPL_1ST_CMD) + 1;
- iv_mcbmr.template extractToRight<TT::COMPL_1ST_CMD, l_len>(l_port);
- return l_port;
- }
-
- ///
- /// @brief Get the DIMM from this subtest
- /// @return the DIMM this subtest has been configured for
- ///
- inline uint64_t get_dimm() const
- {
- return iv_mcbmr.template getBit<TT::COMPL_3RD_CMD>() ? 1 : 0;
- }
-
- ///
- /// @brief Add the subtest to go to
- /// @param[in] the subtest to jump to
- /// @return void
- ///
- inline void change_goto_subtest( const uint64_t i_jmp_to )
- {
- iv_mcbmr.template insertFromRight<TT::GOTO_SUBTEST, TT::GOTO_SUBTEST_LEN>(i_jmp_to);
- FAPI_INF("changing subtest to jump to %d (0x%02x)", i_jmp_to, iv_mcbmr);
- return;
- }
-
- ///
- /// @brief Generate addresses in reverse order
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_addr_rev_mode( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::ADDR_REV_MODE>(i_state);
- return;
- }
-
- ///
- /// @brief Generate addresses in random order
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_addr_rand_mode( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::ADDR_RAND_MODE>(i_state);
- return;
- }
-
- ///
- /// @brief Generate and check data with ECC
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_ecc_mode( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::ECC_MODE>(i_state);
- return;
- }
-
- ///
- /// @brief Set the 'done after this test' bit
- /// @param[in] i_state the desired state of the function; mss:ON, mss::OFF
- /// @return void
- ///
- inline void change_done( const mss::states i_state )
- {
- iv_mcbmr.template writeBit<TT::DONE>(i_state);
- return;
- }
-
- ///
- /// @brief Set the data mode for this subtest
- /// @param[in] i_mode the desired mcbist::data_mode
- /// @return void
- ///
- inline void change_data_mode( const data_mode i_mode )
- {
- iv_mcbmr.template insertFromRight<TT::DATA_MODE, TT::DATA_MODE_LEN>(i_mode);
- return;
- }
-
- ///
- /// @brief Set the operation type for this subtest
- /// @param[in] i_mode the desired mcbist::op_type
- /// @return void
- ///
- inline void change_op_type( const op_type i_type )
- {
- iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(i_type);
- return;
- }
-
- ///
- /// @brief Configure which address registers to use for this subtest
- /// @param[in] i_index 0 = MCBSA0Q, 1 = MCBSA1Q, ...
- /// @note wraps to 0-3 no matter what value you pass in.
- /// @return void
- ///
- inline void change_addr_sel( const uint16_t i_index )
- {
- // Roll the index around - tidy support for an index which is out of range.
- constexpr uint16_t MAX_ADDRESS_START_END_REGISTERS = 3 + 1;
- iv_mcbmr.template insertFromRight<TT::ADDR_SEL, TT::ADDR_SEL_LEN>(i_index % MAX_ADDRESS_START_END_REGISTERS);
- FAPI_INF("changed address select to index %d (0x%x)", i_index, iv_mcbmr);
- return;
- }
-
- //
- // @brief operator== for mcbist subtests
- // @param[in] i_rhs the right hand side of the compare
- // @return bool, true iff i_rhs == this
- inline bool operator==(const subtest_t<T>& i_rhs) const
- {
- return i_rhs.iv_mcbmr == iv_mcbmr;
- }
-
- /// The mcbist 'memory register' for this subtest.
- // Note that it is only 16 bits.
- // Each 64b memory register contains multiple 16 bit subtest definitions.
- // As we create a vector of subtests, we'll drop them in to their appropriate
- // MCBMR register before executing.
- fapi2::buffer<uint16_t> iv_mcbmr;
-};
-
-///
-/// @brief Return a write subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> write_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0000 - we want subtest type to be a Write (W)
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::WRITE);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 12 = 1 - ecc
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- // 14:15 = 0 address select config registers 0
-
- return l_subtest;
-}
-
-
-///
-/// @brief Return an alter subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> alter_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1011 - we want subtest type to be a Alter
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::ALTER);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return an display subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> display_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1100 - we want subtest type to be a Display
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::DISPLAY);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return an scrub subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> scrub_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1001 - we want subtest type to be a Scrub
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::SCRUB_RRWR);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a steer subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> steer_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 1010 - we want subtest type to be a Steer
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::STEER_RW);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a read subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> read_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0001 - we want subtest type to be a Read (R)
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a read write subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> read_write_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0010 - we want subtest type to be a Read Write (RW)
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_WRITE);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a read write read subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> read_write_read_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0100 - we want subtest type to be a Read Write Read (RWR) 7
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::READ_WRITE_READ);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a random subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> random_subtest()
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0110 - we want subtest type to be a Random Seq, a randomly chosen read or write
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::RAND_SEQ);
-
- // - Not a special subtest, so no other configs associated
- // 4 = 0 - we don't want to complement data for our Writes
- // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix
- // 7 = 0 - forward address generation
- // 8 = 0 - non random address generation
- // - Don't need to set up anything for LFSRs
- // 9:11 = 000 - Fixed data mode
-
- // 14:15 = 0 address select config registers 0
-
- // By default we want to turn on ECC. Caller can turn it off.
- l_subtest.change_ecc_mode(mss::ON);
-
- return l_subtest;
-}
-
-///
-/// @brief Return a goto subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] the subtest we should go to
-/// @return mss::mcbist::subtest_t
-/// @note Turns on ECC mode for the returned subtest - caller can turn it off
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> goto_subtest( const uint64_t i_jump_to )
-{
- // Starts life full of 0's
- subtest_t<T> l_subtest;
-
- // 0:3 = 0111 - we want subtest type to be a Goto
- l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::GOTO_SUBTEST_N);
-
- // Plug in the subtest the user passed in
- l_subtest.change_goto_subtest(i_jump_to);
- return l_subtest;
-}
-
-///
-/// @brief Return an init subtest - configured simply
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @return mss::mcbist::subtest_t
-/// @note Configures for start/end address select bit as address config register 0
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline subtest_t<T> init_subtest()
-{
- return write_subtest<T>();
-}
-
-///
-/// @brief A class representing a series of MCBIST subtests, and the
-/// MCBIST engine parameters associated with running the subtests
-/// @tparam T fapi2::TargetType representing the fapi2 target which
-/// contains the MCBIST engine (e.g., fapi2::TARGET_TYPE_MCBIST)
-/// @tparam TT, the mssTraits associtated with T
-/// @note MCBIST Memory Parameter Register defaults to
-/// - issue commands as fast as possible
-/// - even weighting of read/write if random addressing
-/// - disable clock monitoring
-/// - random command gap is disabled
-/// - BC4 disabled
-/// - no selected ports
-/// @note Address Generation Config Register defaults to
-/// - 0 fixed slots
-/// - All address counter modes on (so addr configs are start + len)
-/// - maint address mode enabled
-/// - maint broadcast mode disabled
-/// - maint slave rank boundary detect disabled
-/// @note Config register defaults to
-/// - BROADCAST_SYNC_EN disabled
-/// - BROADCAST_SYNC_WAIT 0
-/// - TIMEOUT_MODE - wait 524288 cycles until timeout is called
-/// - RESET_KEEPER - 0
-/// - CURRENT_ADDR_TRAP_UPDATE_DIS - 0
-/// - CCS_RETRY_DIS - 0
-/// - RESET_CNTS_START_OF_RANK - 0
-/// - LOG_COUNTS_IN_TRACE - 0
-/// - SKIP_INVALID_ADDR_DIMM_DIS - 0
-/// - REFRESH_ONLY_SUBTEST_EN - 0
-/// - REFRESH_ONLY_SUBTEST_TIMEBASE_SEL(0:1) - 0
-/// - RAND_ADDR_ALL_ADDR_MODE_EN - 0
-/// - REF_WAIT_TIME(0:13) - 0
-/// - MCB_LEN64 - 1
-/// - PAUSE_ON_ERROR_MODE(0:1) - don't pause on error
-/// - PAUSE_AFTER_CCS_SUBTEST - don't puase after CCS subtest
-/// - FORCE_PAUSE_AFTER_ADDR - don't pause after current address
-/// - FORCE_PAUSE_AFTER_SUBTEST - no pause after subtest
-/// - ENABLE_SPEC_ATTN - disabled
-/// - ENABLE_HOST_ATTN - enabled
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-class program
-{
- public:
- // Setup our poll parameters so the MCBIST executer can see
- // whether to use the delays in the instruction stream or not
- program():
- iv_parameters(0),
- iv_addr_gen(0),
- iv_test_type(CENSHMOO), // Used as default in Centaur
- iv_addr_map0(0),
- iv_addr_map1(0),
- iv_addr_map2(0),
- iv_addr_map3(0),
- iv_data_rotate_cnfg(0),
- iv_data_rotate_seed(0),
- iv_config(0),
- iv_control(0),
- iv_async(false),
- iv_pattern(PATTERN_0),
- iv_random24_data_seed(RANDOM24_SEEDS_0),
- iv_random24_seed_map(RANDOM24_SEED_MAP_0),
- iv_compare_mask(0)
- {
- // Enable the maintenance mode addressing
- change_maint_address_mode(mss::ON);
-
- // Enable 64B lengths by default. Commands which need 128B (scrub, steer, alter, display)
- // can change this to 128B (mss::OFF).
- change_len64(mss::ON);
-
- // Turn off counting mode for all address configs
- 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>(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>();
-
- }
-
- ///
- /// @brief Change the DIMM select in the address mapping
- /// @param[in] i_bitmap DIMM select bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_dimm_select_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_DIMM_SELECT, TT::CFG_AMAP_DIMM_SELECT_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK0 address mapping when not in 5D mode
- /// @param[in] i_bitmap MRANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_MRANK0, TT::CFG_AMAP_MRANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK0 address mapping when in 5D mode
- /// @param[in] i_bitmap MRANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank0_bit_5d( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK0, TT::CFG_AMAP_SRANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK1 address mapping when not in 5D mode
- /// @param[in] i_bitmap MRANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_MRANK1, TT::CFG_AMAP_MRANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK1 address mapping when in 5D mode
- /// @param[in] i_bitmap MRANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank1_bit_5d( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK1, TT::CFG_AMAP_SRANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the MRANK2 address mapping when in 5D mode
- /// @param[in] i_bitmap MRANK2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_mrank2_bit_5d( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK2, TT::CFG_AMAP_SRANK2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the SRANK0 address mapping when in 5D mode
- /// @param[in] i_bitmap SRANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_srank0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK0, TT::CFG_AMAP_SRANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the SRANK1 address mapping
- /// @param[in] i_bitmap SRANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_srank1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK1, TT::CFG_AMAP_SRANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the SRANK2 address mapping
- /// @param[in] i_bitmap SRANK2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_srank2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_SRANK2, TT::CFG_AMAP_SRANK2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK2 address mapping
- /// @param[in] i_bitmap BANK2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK2, TT::CFG_AMAP_BANK2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK1 address mapping
- /// @param[in] i_bitmap BANK1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK1, TT::CFG_AMAP_BANK1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK0 address mapping
- /// @param[in] i_bitmap BANK0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map0.insertFromRight<TT::CFG_AMAP_BANK0, TT::CFG_AMAP_BANK0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK_GROUP1 address mapping
- /// @param[in] i_bitmap BANK_GROUP1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank_group1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_BANK_GROUP1, TT::CFG_AMAP_BANK_GROUP1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the BANK_GROUP0 address mapping
- /// @param[in] i_bitmap BANK_GROUP0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_bank_group0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_BANK_GROUP0, TT::CFG_AMAP_BANK_GROUP0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW17 address mapping
- /// @param[in] i_bitmap ROW17 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row17_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW17, TT::CFG_AMAP_ROW17_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW16 address mapping
- /// @param[in] i_bitmap ROW16 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row16_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW16, TT::CFG_AMAP_ROW16_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW15 address mapping
- /// @param[in] i_bitmap ROW15 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row15_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW15, TT::CFG_AMAP_ROW15_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW14 address mapping
- /// @param[in] i_bitmap ROW14 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row14_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW14, TT::CFG_AMAP_ROW14_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW13 address mapping
- /// @param[in] i_bitmap ROW13 bit map in the address counter
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_row13_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW13, TT::CFG_AMAP_ROW13_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW12 address mapping
- /// @param[in] i_bitmap ROW12 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row12_bit( const uint64_t i_bitmap )
- {
- // CFG_AMAP_ROW12 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12 ,
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW12, TT::CFG_AMAP_ROW12_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW11 address mapping
- /// @param[in] i_bitmap ROW11 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row11_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW11, TT::CFG_AMAP_ROW11_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW10 address mapping
- /// @param[in] i_bitmap ROW10 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row10_bit( const uint64_t i_bitmap )
- {
- iv_addr_map1.insertFromRight<TT::CFG_AMAP_ROW10, TT::CFG_AMAP_ROW10_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW9 address mapping
- /// @param[in] i_bitmap ROW9 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row9_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW9, TT::CFG_AMAP_ROW9_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW8 address mapping
- /// @param[in] i_bitmap ROW8 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row8_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW8, TT::CFG_AMAP_ROW8_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW7 address mapping
- /// @param[in] i_bitmap ROW7 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row7_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW7, TT::CFG_AMAP_ROW7_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW6 address mapping
- /// @param[in] i_bitmap ROW6 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row6_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW6, TT::CFG_AMAP_ROW6_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW5 address mapping
- /// @param[in] i_bitmap ROW5 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row5_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW5, TT::CFG_AMAP_ROW5_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW4 address mapping
- /// @param[in] i_bitmap ROW4 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row4_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW4, TT::CFG_AMAP_ROW4_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW3 address mapping
- /// @param[in] i_bitmap ROW3 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row3_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW3, TT::CFG_AMAP_ROW3_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW2 address mapping
- /// @param[in] i_bitmap ROW2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW2, TT::CFG_AMAP_ROW2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW1 address mapping
- /// @param[in] i_bitmap ROW1 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row1_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW1, TT::CFG_AMAP_ROW1_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the ROW0 address mapping
- /// @param[in] i_bitmap ROW0 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_row0_bit( const uint64_t i_bitmap )
- {
- iv_addr_map2.insertFromRight<TT::CFG_AMAP_ROW0, TT::CFG_AMAP_ROW0_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL9 address mapping
- /// @param[in] i_bitmap COL9 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col9_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL9, TT::CFG_AMAP_COL9_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL8 address mapping
- /// @param[in] i_bitmap COL8 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col8_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL8, TT::CFG_AMAP_COL8_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL7 address mapping
- /// @param[in] i_bitmap COL7 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col7_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL7, TT::CFG_AMAP_COL7_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the COL6 address mapping
- /// @param[in] i_bitmap COL6 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col6_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL6, TT::CFG_AMAP_COL6_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL5 address mapping
- /// @param[in] i_bitmap COL5 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col5_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL5, TT::CFG_AMAP_COL5_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL4 address mapping
- /// @param[in] i_bitmap COL4 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col4_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL4, TT::CFG_AMAP_COL4_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL3 address mapping
- /// @param[in] i_bitmap COL3 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col3_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL3, TT::CFG_AMAP_COL3_LEN>(i_bitmap);
- return;
- }
-
- /// @brief Change the COL2 address mapping
- /// @param[in] i_bitmap COL2 bit map in the address counter
- /// @note Assumes data is right-aligned
- ///
- inline void change_col2_bit( const uint64_t i_bitmap )
- {
- iv_addr_map3.insertFromRight<TT::CFG_AMAP_COL2, TT::CFG_AMAP_COL2_LEN>(i_bitmap);
- return;
- }
-
- ///
- /// @brief Change the mcbist 64/128 byte control
- /// @param[in] i_state mss::ON if you want 64B, mss::OFF if you want 128B
- /// @return void
- ///
- inline void change_len64( const mss::states i_state )
- {
- iv_config.writeBit<TT::CFG_MCB_LEN64>(i_state);
- return;
- }
-
- ///
- /// @brief Change the random address all address mode
- /// @param[in] i_state mss::ON if you random addressing all addresses, mss::OFF if you don't
- /// @return void
- ///
- inline void random_address_all( const mss::states i_state )
- {
- iv_config.writeBit<TT::RAND_ADDR_ALL_ADDR_MODE_EN>(i_state);
- return;
- }
-
- ///
- /// @brief Change the broadcast sync enable bit
- /// @param[in] i_state mss::ON to enable the sync pulse, mss::OFF to disable
- /// @return void
- ///
- inline void broadcast_sync_enable( const mss::states i_state )
- {
- iv_config.writeBit<TT::SYNC_EN>(i_state);
- return;
- }
-
- ///
- /// @brief Change the broadcast mode sync timbase count
- /// @param[in] i_broadcast_timebase
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_broadcast_timebase( mss::mcbist::broadcast_timebase i_broadcast_timebase )
- {
- iv_config.insertFromRight<TT::SYNC_WAIT, TT::SYNC_WAIT_LEN>(i_broadcast_timebase);
- return;
- }
-
- ///
- /// @brief Change the mcbist thresholds
- /// @param[in] i_thresholds the new thresholds/stop conditions
- /// @return void
- ///
- inline void change_thresholds( const stop_conditions& i_thresholds )
- {
- iv_thresholds = i_thresholds;
- return;
- }
-
- ///
- /// @brief Change the data rotate value
- /// @param[in] i_data_rotate
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_rotate( mss::mcbist::data_rotate_mode i_data_rotate )
- {
- iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_ROT, TT::CFG_DATA_ROT_LEN>(i_data_rotate);
- return;
- }
-
- ///
- /// @brief Get the data rotate value
- /// @note Assumes data is right aligned
- /// @return the data rotate value config
- ///
- inline uint64_t get_data_rotate()
- {
- uint64_t l_data_rotate = 0;
- iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_ROT, TT::CFG_DATA_ROT_LEN>(l_data_rotate);
- return l_data_rotate;
- }
-
- ///
- /// @brief Change the data seed mode value
- /// @param[in] i_data_seed_mode
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_seed_mode( const mss::mcbist::data_seed_mode i_data_seed_mode )
- {
- iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_SEED_MODE, TT::CFG_DATA_SEED_MODE_LEN>(i_data_seed_mode);
- return;
- }
-
- ///
- /// @brief Get the data seed mode value
- /// @note Assumes data is right aligned
- /// @return the data seed mode value
- ///
- inline uint64_t get_data_seed_mode()
- {
- uint64_t l_data_seed_mode = 0;
- iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_SEED_MODE, TT::CFG_DATA_SEED_MODE_LEN>(l_data_seed_mode);
- return l_data_seed_mode;
- }
-
- ///
- /// @brief Change the data rotate seed for data bits 0:63
- /// @param[in] i_width
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_rotate_seed1( const uint64_t i_data_rotate_seed1 )
- {
- iv_data_rotate_seed.insertFromRight<TT::CFG_DATA_ROT_SEED1, TT::CFG_DATA_ROT_SEED1_LEN>(i_data_rotate_seed1);
- return;
- }
-
- ///
- /// @brief Get the data rotate seed for data bits 0:63
- /// @note Assumes data is right aligned
- /// @return the data rotate seed for data bits 0:63
- ///
- inline uint64_t get_data_rotate_seed1()
- {
- uint64_t l_data_rotate_seed1 = 0;
- iv_data_rotate_seed.extractToRight<TT::CFG_DATA_ROT_SEED1, TT::CFG_DATA_ROT_SEED1_LEN>(l_data_rotate_seed1);
- return l_data_rotate_seed1;
- }
-
- ///
- /// @brief Change the data rotate seed for data bits 64:79
- /// @param[in] i_width
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_data_rotate_seed2( const uint64_t i_data_rotate_seed2 )
- {
- iv_data_rotate_cnfg.insertFromRight<TT::CFG_DATA_ROT_SEED2, TT::CFG_DATA_ROT_SEED2_LEN>(i_data_rotate_seed2);
- return;
- }
-
- ///
- /// @brief Get the data rotate seed for data bits 64:79
- /// @note Assumes data is right aligned
- /// @return the data rotate seed for data bits 64:79
- ///
- inline uint64_t get_data_rotate_seed2()
- {
- uint64_t l_data_rotate_seed2 = 0;
- iv_data_rotate_cnfg.extractToRight<TT::CFG_DATA_ROT_SEED2, TT::CFG_DATA_ROT_SEED2_LEN>(l_data_rotate_seed2);
- return l_data_rotate_seed2;
- }
-
- ///
- /// @brief Change the compare mask CE trap enable
- /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
- /// @return void
- ///
- inline void change_ce_trap_enable( const mss::states i_state )
- {
- iv_compare_mask.writeBit<TT::CFG_TRAP_CE_ENABLE>(i_state);
- return;
- }
-
- ///
- /// @brief Change the compare mask UE trap enable
- /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
- /// @return void
- ///
- inline void change_ue_trap_enable( const mss::states i_state )
- {
- iv_compare_mask.writeBit<TT::CFG_TRAP_UE_ENABLE>(i_state);
- return;
- }
-
- ///
- /// @brief Change the compare mask MPE trap enable
- /// @param[in] i_state mss::ON to enable the trap, mss::OFF to disable the trap
- /// @return void
- ///
- inline void change_mpe_trap_enable( const mss::states i_state )
- {
- iv_compare_mask.writeBit<TT::CFG_TRAP_MPE_ENABLE>(i_state);
- 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 Calculate minimum command gap for BG_SCRUB
- /// @param[in] i_target the target behind which the memory sits
- /// @param[in] i_freq the DRAM frequency
- /// @param[in] i_size the sum of all DIMM sizes
- /// @param[out] o_min_cmd_gap the setting for MCBPARMQ_CFG_MIN_CMD_GAP
- /// @param[out] o_timebase the setting for MCBPARMQ_CFG_MIN_GAP_TIMEBASE
- ///
- inline void calculate_min_cmd_gap( const fapi2::Target<T>& i_target,
- const uint64_t i_freq,
- const uint64_t i_size,
- uint64_t& o_min_cmd_gap,
- mss::states& o_timebase )
- {
- constexpr uint64_t l_seconds = SEC_IN_HOUR * BG_SCRUB_IN_HOURS;
- constexpr uint64_t MIN_CMD_GAP = 0x001;
-
- // Sanity check our inputs, just assert if bad since they come directly from eff_config
- // this will prevent us from any divide by zero problems
- if ((i_freq == 0) || (i_size == 0))
- {
- FAPI_ERR("received zero memory freq or size in calculate_min_cmd_gap");
- fapi2::Assert(false);
- }
-
- // MIN CMD GAP = TOTAL CYCLES / TOTAL ADDRESSES
- // TOTAL CYCLES = 12 hours x 60 min/hr x 60 sec/min x [DRAM freq] cycles/sec x
- // 1/2 (MEM logic runs half DRAM freq)
- const uint64_t l_mem_cycles_per_sec = (i_freq * T_PER_MT) / 2;
- const uint64_t l_total_cycles = l_seconds * l_mem_cycles_per_sec;
-
- // TOTAL ADDRESSES = sum over all dimms of ( [DIMM CAPACITY]/128B )
- const uint64_t l_total_addresses = i_size * BYTES_PER_GB / 128;
-
- const auto l_min_cmd_gap = l_total_cycles / l_total_addresses;
-
- // If we're greater than the timebase, set the multiplier and divide down to get the gap setting
- if (CMD_TIMEBASE < l_min_cmd_gap)
- {
- o_min_cmd_gap = l_min_cmd_gap / CMD_TIMEBASE;
- o_timebase = mss::ON;
- return;
- }
-
- // If we're greater than the max gap setting, get as close to 12 hours as we can instead of just truncating
- if (l_min_cmd_gap > MAX_CMD_GAP)
- {
- // work backwards to calculate what the total scrub time would be with the highest cmd gap with no multiplier...
- const uint64_t l_scrub_time_fff = (l_total_addresses * MAX_CMD_GAP) / l_mem_cycles_per_sec;
- // and with the lowest cmd gap with the multiplier
- const uint64_t l_scrub_time_001 = (l_total_addresses * CMD_TIMEBASE) / l_mem_cycles_per_sec;
-
- if ((l_seconds - l_scrub_time_fff) > (l_scrub_time_001 - l_seconds))
- {
- FAPI_INF("%s gap is greater than the field will allow. Setting to: %03x", mss::c_str(i_target), MIN_CMD_GAP);
- o_min_cmd_gap = MIN_CMD_GAP;
- o_timebase = mss::ON;
- }
- else
- {
- FAPI_INF("%s gap is greater than the field will allow. Setting to: %03x", mss::c_str(i_target), MAX_CMD_GAP);
- o_min_cmd_gap = MAX_CMD_GAP;
- o_timebase = mss::OFF;
- }
-
- return;
- }
-
- // Else, we're good to just set the calculated gap value directly
- o_min_cmd_gap = l_min_cmd_gap;
- o_timebase = mss::OFF;
- }
-
- ///
- /// @brief Change MCBIST Speed
- /// @param[in] i_target the target behind which the memory sits
- /// @param[in] i_speed the speed eunmeration
- /// @return FAPI2_RC_SUCCSS iff ok
- ///
- inline fapi2::ReturnCode change_speed( const fapi2::Target<T>& i_target, const speed i_speed )
- {
- switch (i_speed)
- {
- case speed::LUDICROUS:
- change_min_cmd_gap(0);
- change_min_gap_timebase(mss::OFF);
- return fapi2::FAPI2_RC_SUCCESS;
- break;
-
- case speed::BG_SCRUB:
- {
- uint64_t l_freq = 0;
- uint64_t l_size = 0;
- uint64_t l_min_cmd_gap = 0;
- mss::states l_timebase = mss::OFF;
-
- constexpr uint64_t l_seconds = SEC_IN_HOUR * BG_SCRUB_IN_HOURS;
-
- FAPI_TRY( mss::freq(i_target, l_freq) );
- FAPI_TRY( mss::eff_memory_size<mss::mc_type::NIMBUS>(i_target, l_size) );
-
- calculate_min_cmd_gap(i_target, l_freq, l_size, l_min_cmd_gap, l_timebase);
-
- FAPI_INF("%s setting bg scrub speed: %dMT/s, memory: %dGB, duration: %ds, gap: %d",
- mss::c_str(i_target), l_freq, l_size, l_seconds, l_min_cmd_gap);
-
- change_min_cmd_gap(l_min_cmd_gap);
- change_min_gap_timebase(l_timebase);
-
- return fapi2::FAPI2_RC_SUCCESS;
- }
- break;
-
- // Otherwise it's SAME_SPEED or something else in which case we do nothing
- default:
- break;
- };
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Get a list of ports involved in the program
- /// @tparam P fapi2 target type of port
- /// @param[in] i_target the target for this program
- /// @return vector of port targets
- ///
- template< fapi2::TargetType P >
- std::vector<fapi2::Target<P>> get_port_list( const fapi2::Target<T>& i_target ) const;
-
- ///
- /// @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_end_boundary( const end_boundary i_end )
- {
- // Which bit in the end boundary which siginifies this is a slave rank detect situation
- constexpr uint64_t SLAVE_RANK_INDICATED_BIT = 61;
-
- // If there's no change, just get outta here
- if (i_end == DONT_CHANGE)
- {
- return;
- }
-
- // 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);
-
- 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 0x%016lx detect slave? %s",
- i_end, (l_detect_slave == 1 ? "yes" : "no") );
- }
-
- ///
- /// @brief Change the mcbist min command gap
- /// @param[in] i_gap minimum number of cycles between commands when cfg_en_randcmd_gap is a 0 (disabled)
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_cmd_gap( const uint64_t i_gap )
- {
- iv_parameters.insertFromRight<TT::MIN_CMD_GAP, TT::MIN_CMD_GAP_LEN>(i_gap);
- return;
- }
-
- ///
- /// @brief Change the mcbist gap timebase
- /// @param[in] i_tb When set to mss::ON and cfg_en_randcmd_gap is a 0, then the number of minimum
- /// cycles between commands will be cfg_min_cmd_gap multiplied by 2^13.
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_gap_timebase( const bool i_tb )
- {
- iv_parameters.writeBit<TT::MIN_GAP_TIMEBASE>(i_tb);
- return;
- }
-
- ///
- /// @brief Change the mcbist min command gap blind steer
- /// @param[in] i_gap min gap between commands when doing steering
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_cmd_gap_blind_steer( const uint64_t i_gap )
- {
- iv_parameters.insertFromRight<TT::MIN_CMD_GAP_BLIND_STEER, TT::MIN_CMD_GAP_BLIND_STEER_LEN>(i_gap);
- return;
- }
-
- ///
- /// @brief Change the mcbist gap timebase for blind steer
- /// @param[in] i_program the program in question
- /// @param[in] i_tb When set to mss::ON and cfg_en_randcmd_gap is a 0, then the number of minimum
- /// cycles between commands will be cfg_min_cmd_gap multiplied by 2^13.
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_min_gap_timebase_blind_steer( const bool i_tb )
- {
- iv_parameters.writeBit<TT::MIN_GAP_TIMEBASE_BLIND_STEER>(i_tb);
- return;
- }
-
- ///
- /// @brief Change the weights for random mcbist reads, writes
- /// @param[in] i_weight
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_randcmd_wgt( const uint64_t i_weight )
- {
- iv_parameters.insertFromRight<TT::RANDCMD_WGT, TT::RANDCMD_WGT_LEN>(i_weight);
- return;
- }
-
- ///
- /// @brief Change the weights for random mcbist command gaps
- /// @param[in] i_program the program in question
- /// @param[in] i_weight
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_randgap_wgt( const uint64_t i_weight )
- {
- iv_parameters.insertFromRight<TT::RANDGAP_WGT, TT::RANDGAP_WGT_LEN>(i_weight);
- return;
- }
-
- ///
- /// @brief Enable or disable mcbist clock monitoring
- /// @param[in] i_monitor mss::ON to monitor
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_clock_monitor_en( const bool i_monitor )
- {
- iv_parameters.writeBit<TT::CLOCK_MONITOR_EN>(i_monitor);
- return;
- }
-
- ///
- /// @brief Enable or disable mcbist random command gaps
- /// @param[in] i_rndgap mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_en_randcmd_gap( const bool i_rndgap )
- {
- iv_parameters.writeBit<TT::EN_RANDCMD_GAP>(i_rndgap);
- return;
- }
-
- ///
- /// @brief Enable or disable mcbist BC4 support
- /// @param[in] i_bc4 mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_bc4_en( const bool i_bc4 )
- {
- iv_parameters.writeBit<TT::BC4_EN>(i_bc4);
- return;
- }
-
- ///
- /// @brief Change fixed width address generator config
- /// @param[in] i_width
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_fixed_width( const uint64_t i_width )
- {
- iv_addr_gen.insertFromRight<TT::FIXED_WIDTH, TT::FIXED_WIDTH_LEN>(i_width);
- return;
- }
-
- ///
- /// @brief Get the fixed width address config
- /// @note Assumes data is right aligned
- /// @return the fixed width address config
- ///
- inline uint64_t get_fixed_width()
- {
- uint64_t l_fixed_width = 0;
- iv_addr_gen.extractToRight<TT::FIXED_WIDTH, TT::FIXED_WIDTH_LEN>(l_fixed_width);
- return l_fixed_width;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 0
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode0( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<0>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 1
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode1( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<1>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 2
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode2( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<2>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
- ///
- /// @brief Enable or disable address counting mode for address config 3
- /// @param[in] i_program, the program in question
- /// @param[in] i_mode mss::ON to enable
- /// @note Assumes data is right-aligned
- /// @return void
- ///
- inline void change_address_counter_mode3( const bool i_mode )
- {
- fapi2::buffer<uint64_t> l_value;
- iv_addr_gen.extract<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- l_value.writeBit<3>(i_mode);
- iv_addr_gen.insert<TT::ADDR_COUNTER_MODE, TT::ADDR_COUNTER_MODE_LEN>(l_value);
- return;
- }
-
-
- ///
- /// @brief Enable or disable maint address mode
- /// @param[in] i_mode mss::ON to enable
- /// @warn Address counter modes must be 0 for this to work.
- /// @note When enabled subtest complement bits become 3-bit port-dimm selector field
- /// (Note: when turning this off, make sure you clear or reprogram complement bits)
- /// @return void
- ///
- inline void change_maint_address_mode( const bool i_mode )
- {
- iv_addr_gen.writeBit<TT::MAINT_ADDR_MODE_EN>(i_mode);
- return;
- }
-
- ///
- /// @brief Enable or disable broadcast mode
- /// @param[in] i_program the program in question
- /// @param[in] i_mode mss::ON to enable
- /// @warn Maint address mode must be enabled for this to work
- /// @return void
- ///
- inline void change_maint_broadcast_mode( const bool i_mode )
- {
- iv_addr_gen.writeBit<TT::MAINT_BROADCAST_MODE_EN>(i_mode);
- return;
- }
-
-
- ///
- /// @brief Enable or disable slave rank boundary detect
- /// @param[in] i_program the program in question
- /// @param[in] i_mode mss::ON to enable
- /// @return void
- ///
- inline void change_srank_boundaries( const bool i_mode )
- {
- iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>(i_mode);
- return;
- }
-
- ///
- /// @brief Enable or disable async mode
- /// @param[in] i_program the program in question
- /// @param[in] i_mode mss::ON to enable, programs will run async
- /// @return void
- ///
- inline void change_async( const bool i_mode )
- {
- iv_async = i_mode;
- return;
- }
-
- ///
- /// @brief Select the port(s) to be used by the MCBIST
- /// @param[in] i_ports uint64_t representing the ports. Multiple bits set imply broadcast
- /// i_ports is a right-aligned uint64_t, of which only the right-most 4 bits are used. The register
- /// field is defined such that the left-most bit in the field represents port 0, the right most
- /// bit in the field represents port 3. So, to run on port 0, i_ports should be 0b1000. 0b0001
- /// (or 0x1) is port 3 - not port 0
- /// @return void
- ///
- inline void select_ports( const uint64_t i_ports )
- {
- iv_control.insertFromRight<TT::PORT_SEL, TT::PORT_SEL_LEN>(i_ports);
- FAPI_INF("mcbist select ports: iv_control 0x%016lx (ports: 0x%x)", iv_control, i_ports);
- return;
- }
-
- ///
- /// @brief Process mcbist errors
- /// @tparam MCBIST target type
- /// @tparam T fapi2::TargetType representing the fapi2 target which
- /// contains the MCBIST engine (e.g., fapi2::TARGET_TYPE_MCBIST)
- /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
- /// This shouldn't be called in firmware? Check with PRD
- ///
- inline fapi2::ReturnCode process_errors( const fapi2::Target<T> i_target ) const
- {
- // Until reading the error array is documented, comparison errors 'just' result in
- // a flag indicating there was a problem on port.
- {
- fapi2::buffer<uint64_t> l_data;
- uint64_t l_port = 0;
- uint64_t l_subtest = 0;
- FAPI_TRY( mss::getScom(i_target, TT::MCBSTATQ_REG, l_data), "%s Failed getScom", mss::c_str(i_target) );
- l_data.extractToRight<TT::LOGGED_ERROR_ON_PORT_INDICATOR, TT::LOGGED_ERROR_ON_PORT_INDICATOR_LEN>(l_port);
- l_data.extractToRight<TT::SUBTEST_NUM_INDICATOR, TT::SUBTEST_NUM_INDICATOR_LEN>(l_subtest);
-
- FAPI_ASSERT( l_port == 0,
- fapi2::MSS_MEMDIAGS_COMPARE_ERROR_IN_LAST_PATTERN()
- .set_MCBIST_TARGET(i_target)
- .set_PORT(mss::first_bit_set(l_port))
- .set_SUBTEST(l_subtest),
- "%s MCBIST error on port %d subtest %d", mss::c_str(i_target), mss::first_bit_set(l_port), l_subtest );
- }
-
- // Check for UE errors
- {
- fapi2::buffer<uint64_t> l_read0;
- fapi2::buffer<uint64_t> l_read1;
-
- FAPI_TRY( mss::getScom(i_target, TT::SRERR0_REG, l_read0), "%s Failed getScom", mss::c_str(i_target) );
- FAPI_TRY( mss::getScom(i_target, TT::SRERR1_REG, l_read1), "%s Failed getScom", mss::c_str(i_target) );
-
- FAPI_ASSERT( ((l_read0 == 0) && (l_read1 == 0)),
- fapi2::MSS_MEMDIAGS_ERROR_IN_LAST_PATTERN()
- .set_MCBIST_TARGET(i_target)
- .set_STATUS0(l_read0)
- .set_STATUS1(l_read1),
- "%s MCBIST scrub/read error reg0: 0x%016lx reg1: 0x%016lx", mss::c_str(i_target), l_read0, l_read1 );
- }
-
- FAPI_INF("%s Execution success - no errors seen from MCBIST program", mss::c_str(i_target));
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Store off the pattern index. We'll use this to write the patterns when we load the program
- /// @param[in] i_index an index such as mss::mcbist::PATTERN_0
- /// @return fapi2::ReturnCode checks for bad pattern index
- /// @warning if you give a pattern index which does not exist your pattern will not change.
- /// @note patterns default to PATTERN_0
- ///
- inline fapi2::ReturnCode change_pattern( const uint64_t i_pattern )
- {
- FAPI_INF("change MCBIST pattern index %d", i_pattern);
-
- // Sanity check the pattern since they're just numbers.
- FAPI_ASSERT( i_pattern <= mcbist::NO_PATTERN,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_pattern),
- "Attempting to change a pattern which does not exist %d", i_pattern );
-
- iv_pattern = i_pattern;
-
- return fapi2::FAPI2_RC_SUCCESS;
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Store off the random 24b data seed index. We'll use this to write the 24b random data seeds when we load the program
- /// @param[in] i_index an index such as mss::mcbist::RANDOM24_SEEDS_0
- /// @return fapi2::ReturnCode checks for bad pattern index
- /// @warning if you give a pattern index which does not exist your pattern will not change.
- /// @note patterns default to PATTERN_0
- ///
- inline fapi2::ReturnCode change_random_24b_seeds( const uint64_t i_random24_seed )
- {
- FAPI_INF("change MCBIST 24b random data seeds index %d", i_random24_seed );
-
- // TK Want a new RC for random 24
- // Sanity check the pattern since they're just numbers.
- FAPI_ASSERT( i_random24_seed <= mcbist::NO_RANDOM24_SEEDS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_random24_seed),
- "Attempting to change to a 24b random data seed which does not exist %d", i_random24_seed );
-
- iv_random24_data_seed = i_random24_seed;
-
- return fapi2::FAPI2_RC_SUCCESS;
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief Store off the random 24b data seed mapping index. We'll use this to write the 24b random data seed mappings when we load the program
- /// @param[in] i_index an index such as mss::mcbist::RANDOM24_SEEDS_0
- /// @return fapi2::ReturnCode checks for bad pattern index
- /// @warning if you give a pattern index which does not exist your pattern will not change.
- /// @note patterns default to PATTERN_0
- ///
- inline fapi2::ReturnCode change_random_24b_maps( const uint64_t i_random24_map )
- {
- FAPI_INF("change MCBIST 24b random data seed mappings index %d", i_random24_map );
-
- // TK Want a new RC for random 24
- // Sanity check the pattern since they're just numbers.
- FAPI_ASSERT( i_random24_map <= mcbist::NO_RANDOM24_SEED_MAP,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_random24_map),
- "Attempting to change to a random seed map which does not exist %d", i_random24_map );
-
- iv_random24_seed_map = i_random24_map;
-
- return fapi2::FAPI2_RC_SUCCESS;
-
- fapi_try_exit:
- return fapi2::current_err;
- }
-
- ///
- /// @brief checks if two programs are equal
- /// @param[in] i_rhs program to compare
- /// @return bool true if equal
- ///
- inline bool operator==( const program<T>& i_rhs ) const
- {
- //checks the vector first, to save time if they're not equal (no sense in checking everything else)
- if(iv_subtests != i_rhs.iv_subtests)
- {
- return false;
- }
-
- //checks everything else
- bool l_equal = iv_parameters == i_rhs.iv_parameters;
- l_equal &= iv_addr_gen == i_rhs.iv_addr_gen;
- l_equal &= iv_test_type == i_rhs.iv_test_type;
- l_equal &= iv_poll == i_rhs.iv_poll;
- l_equal &= iv_addr_map0 == i_rhs.iv_addr_map0;
- l_equal &= iv_addr_map1 == i_rhs.iv_addr_map1;
- l_equal &= iv_addr_map2 == i_rhs.iv_addr_map2;
- l_equal &= iv_addr_map3 == i_rhs.iv_addr_map3;
- l_equal &= iv_config == i_rhs.iv_config;
- l_equal &= iv_control == i_rhs.iv_control;
- l_equal &= iv_async == i_rhs.iv_async;
- l_equal &= iv_pattern == i_rhs.iv_pattern;
- l_equal &= iv_thresholds == i_rhs.iv_thresholds;
- l_equal &= iv_data_rotate_cnfg == i_rhs.iv_data_rotate_cnfg;
- l_equal &= iv_data_rotate_seed == i_rhs.iv_data_rotate_seed;
- l_equal &= iv_random24_data_seed == i_rhs.iv_random24_data_seed;
- l_equal &= iv_random24_seed_map == i_rhs.iv_random24_seed_map;
- l_equal &= iv_data_rotate_cnfg == i_rhs.iv_data_rotate_cnfg;
- l_equal &= iv_data_rotate_seed == i_rhs.iv_data_rotate_seed;
- l_equal &= iv_compare_mask == i_rhs.iv_compare_mask;
-
- //returns result
- return l_equal;
- }
-
- // Vector of subtests. Note the MCBIST subtests are spread across
- // 8 registers - 4 subtests fit in one 64b register
- // (16 bits/test, 4 x 16 == 64, 4x8 = 32 subtests)
- // We keep a vector of 16 bit subtests here, and we program the
- // MCBIST engine (i.e., spread the subtests over the 8 registers)
- // when we're told to execute the program.
- std::vector< subtest_t<T> > iv_subtests;
-
- // Place to hold the value of the MCBIST Memory Parameter Register. We'll scom
- // it when we execute the program.
- fapi2::buffer<uint64_t> iv_parameters;
-
- // Place to hold the value of the MCBIST Address Generation Config. We'll scom
- // it when we execute the program.
- fapi2::buffer<uint64_t> iv_addr_gen;
-
- test_type iv_test_type;
-
- poll_parameters iv_poll;
-
- // Address Map Registers
- // We might want to refactor to a vector ... BRS
- // uint64_t iv_addr_map0;
- // uint64_t iv_addr_map1;
- // uint64_t iv_addr_map2;
- // uint64_t iv_addr_map3;
- //Perhaps this isn't the right approach, we can discuss and change if needed, leaving the above comments for now
- fapi2::buffer<uint64_t> iv_addr_map0;
- fapi2::buffer<uint64_t> iv_addr_map1;
- fapi2::buffer<uint64_t> iv_addr_map2;
- fapi2::buffer<uint64_t> iv_addr_map3;
-
- // Data Rotate Seed and Config Registers
- fapi2::buffer<uint64_t> iv_data_rotate_cnfg;
- fapi2::buffer<uint64_t> iv_data_rotate_seed;
-
- // Config register
- fapi2::buffer<uint64_t> iv_config;
-
- // Control register
- fapi2::buffer<uint64_t> iv_control;
-
- // True iff we want to run in asynchronous mode
- bool iv_async;
-
- // The pattern for the pattern generator
- uint64_t iv_pattern;
-
- // The pattern for the random 24b seeds
- uint64_t iv_random24_data_seed;
-
- // The pattern for the random 24b data seed mapping
- uint64_t iv_random24_seed_map;
-
- // The pattern for the pattern generator
- fapi2::buffer<uint64_t> iv_compare_mask;
-
- // The error stop conditions, thresholds for the program
- stop_conditions iv_thresholds;
-};
-
-///
-/// @brief Load the mcbist config register
-/// @tparam T fapi2::TargetType of the MCBIST engine
-/// @tparam TT the mssTraits associtated with T
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_config( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("loading MCBIST Config 0x%016lx", i_program.iv_config);
-
- // Copy the program's config settings - we want to modify them if we're in sim.
- fapi2::buffer<uint64_t> l_config = i_program.iv_config;
-
- // If we're running in Cronus, there is no interrupt so any attention bits will
- // hang something somewhere. Make sure there's nothing in this config which can
- // turn on attention bits unless we're running in hostboot
-#ifndef __HOSTBOOT_MODULE
- l_config.template clearBit<TT::CFG_ENABLE_HOST_ATTN>();
- l_config.template clearBit<TT::CFG_ENABLE_SPEC_ATTN>();
-#endif
-
- FAPI_TRY( mss::putScom(i_target, TT::CFGQ_REG, l_config) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Load the mcbist control register
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_control( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("loading MCBIST Control 0x%016lx", i_program.iv_control);
- return mss::putScom(i_target, TT::CNTLQ_REG, i_program.iv_control);
-}
-
-
-///
-/// @brief Load the address generator config
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_addr_gen( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("loading MCBIST Address Generation 0x%016lx", i_program.iv_addr_gen);
- return mss::putScom(i_target, TT::MCBAGRAQ_REG, i_program.iv_addr_gen);
-}
-
-///
-/// @brief Configure address range based on index
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @param[in] i_index which start/end pair to effect
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end, const uint64_t i_index )
-{
- FAPI_INF("config MCBIST address range %d start: 0x%016lx (0x%016lx), end/len 0x%016lx (0x%016lx)",
- i_index, i_start, (i_start << 26), i_end, (i_end << 26));
- FAPI_TRY( mss::putScom(i_target, TT::address_pairs[i_index].first, i_start << 26) );
- FAPI_TRY( mss::putScom(i_target, TT::address_pairs[i_index].second, i_end << 26) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Configure address range 0
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range0( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 0);
-}
-
-
-///
-/// @brief Configure address range 1
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range1( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 1);
-}
-
-
-///
-/// @brief Configure address range 2
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-/// @warn if address counting mode is enabled in the MCBIST program, these bits are start, len
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range2( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 2);
-}
-
-
-///
-/// @brief Configure address range 3
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start 64b right-aligned address
-/// @param[in] i_end 64b right-aligned address
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note Only the right-most 37 bits of the start/end are used.
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode config_address_range3( const fapi2::Target<T>& i_target, const uint64_t i_start,
- const uint64_t i_end )
-{
- return config_address_range(i_target, i_start, i_end, 3);
-}
-
-///
-/// @brief Start or stop the MCBIST engine
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_stop bool START for starting, STOP otherwise
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, bool i_start_stop )
-{
- // This is the same as the CCS start_stop ... perhaps we need one template for all
- // 'engine' control functions? BRS
- fapi2::buffer<uint64_t> l_buf;
- FAPI_TRY(mss::getScom(i_target, TT::CNTLQ_REG, l_buf));
-
- FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG,
- i_start_stop ? l_buf.setBit<TT::MCBIST_START>() : l_buf.setBit<TT::MCBIST_STOP>()) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Resume the MCBIST engine
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode resume( const fapi2::Target<T>& i_target )
-{
- fapi2::buffer<uint64_t> l_buf;
-
- FAPI_TRY( mss::getScom(i_target, TT::CNTLQ_REG, l_buf) );
- FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG, l_buf.setBit<TT::MCBIST_RESUME>()) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Reset the MCBIST error logs
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode reset_errors( const fapi2::Target<T>& i_target )
-{
- fapi2::buffer<uint64_t> l_buf;
-
- FAPI_TRY( mss::getScom(i_target, TT::CNTLQ_REG, l_buf) );
- FAPI_TRY( mss::putScom(i_target, TT::CNTLQ_REG, l_buf.setBit<TT::MCBIST_RESET_ERRORS>()) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Return whether or not the MCBIST engine has an operation in progress
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the target to effect
-/// @param[out] i_in_progress - false if no operation is in progress
-/// @return FAPI2_RC_SUCCESS if getScom succeeded
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode in_progress( const fapi2::Target<T>& i_target, bool o_in_progress )
-{
- fapi2::buffer<uint64_t> l_buf;
-
- FAPI_TRY(mss::getScom(i_target, TT::STATQ_REG, l_buf));
- o_in_progress = l_buf.getBit<TT::MCBIST_IN_PROGRESS>();
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Execute the mcbist program
-/// @tparam T the fapi2::TargetType - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist program to execute
-/// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS iff OK
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode execute( const fapi2::Target<T>& i_target, const program<T>& i_program );
-
-///
-/// @brief Load a set of MCBIST subtests in to the MCBIST registers
-/// @tparam T the fapi2::TargetType - derived
-/// @tparam TT the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_mcbmr( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program );
-
-
-///
-/// @brief Load a set of MCBIST address map registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] the target to effect
-/// @param[in] the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_mcbamr( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- // Vector? Can decide when we fully understand the methods to twiddle the maps themselves. BRS
- FAPI_INF("load MCBIST address map register 0: 0x%016lx", i_program.iv_addr_map0);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR0A0Q_REG, i_program.iv_addr_map0) );
-
- FAPI_INF("load MCBIST address map register 1: 0x%016lx", i_program.iv_addr_map1);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR1A0Q_REG, i_program.iv_addr_map1) );
-
- FAPI_INF("load MCBIST address map register 2: 0x%016lx", i_program.iv_addr_map2);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR2A0Q_REG, i_program.iv_addr_map2) );
-
- FAPI_INF("load MCBIST address map register 3: 0x%016lx", i_program.iv_addr_map3);
- FAPI_TRY( mss::putScom(i_target, TT::MCBAMR3A0Q_REG, i_program.iv_addr_map3) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Load MCBIST Memory Parameter Register
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] the target to effect
-/// @param[in] the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_mcbparm( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- FAPI_INF("load MCBIST parameter register: 0x%016lx", i_program.iv_parameters);
- return mss::putScom(i_target, TT::MCBPARMQ_REG, i_program.iv_parameters);
-}
-
-///
-/// @brief Clear mcbist errors
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target fapi2::Target<T> of the MCBIST
-/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode clear_errors( const fapi2::Target<T> i_target )
-{
- // TK: Clear the more detailed errors checked above
- FAPI_INF("Clear MCBIST error state");
- FAPI_TRY( mss::putScom(i_target, TT::MCBSTATQ_REG, 0) );
- FAPI_TRY( mss::putScom(i_target, TT::SRERR0_REG, 0) );
- FAPI_TRY( mss::putScom(i_target, TT::SRERR1_REG, 0) );
- FAPI_TRY( mss::putScom(i_target, TT::FIRQ_REG, 0) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST pattern given a pattern
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_pattern an mcbist::patterns
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, const pattern& i_pattern, const bool i_invert )
-{
- uint64_t l_address = TT::PATTERN0_REG;
-
- // TODO RTC:155561 Add random pattern support.
-
- // TK: algorithm for patterns which include ECC bits in them
- // Loop over the cache lines in the pattern. We write one half of the cache line
- // to the even register and half to the odd.
- for (const auto& l_cache_line : i_pattern)
- {
- fapi2::buffer<uint64_t> l_value_first = i_invert ? ~l_cache_line.first : l_cache_line.first;
- fapi2::buffer<uint64_t> l_value_second = i_invert ? ~l_cache_line.second : l_cache_line.second;
- FAPI_INF("Loading cache line pattern 0x%016lx 0x%016lx", l_value_first, l_value_second);
- FAPI_TRY( mss::putScom(i_target, l_address, l_value_first) );
- FAPI_TRY( mss::putScom(i_target, ++l_address, l_value_second) );
- ++l_address;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_index the pattern index
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, uint64_t i_pattern )
-{
- if (NO_PATTERN != i_pattern)
- {
- bool l_invert = false;
-
- // Sanity check the pattern since they're just numbers.
- // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
- FAPI_ASSERT( i_pattern <= mcbist::LAST_PATTERN,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_pattern),
- "Attempting to load a pattern which does not exist %d", i_pattern );
-
- // The indexes are split in to even and odd where the odd indexes don't really exist.
- // They're just indicating that we want to grab the even index and invert it. So calculate
- // the proper vector index and acknowledge the inversion if necessary.
- if (mss::is_odd(i_pattern))
- {
- l_invert = true;
- i_pattern -= 1;
- }
-
- return load_pattern(i_target, patterns[i_pattern / 2], l_invert);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_pattern( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_pattern(i_target, i_program.iv_pattern);
-}
-
-///
-/// @brief Load MCBIST maint pattern given a pattern
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_pattern an mcbist::patterns
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, const pattern& i_pattern, const bool i_invert );
-
-
-///
-/// @brief Load MCBIST maint pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_index the pattern index
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, uint64_t i_pattern )
-{
- if (NO_PATTERN != i_pattern)
- {
- bool l_invert = false;
-
- // Sanity check the pattern since they're just numbers.
- // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
- FAPI_ASSERT( i_pattern <= mcbist::LAST_PATTERN,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_pattern),
- "Attempting to load a pattern which does not exist %d", i_pattern );
-
- // The indexes are split in to even and odd where the odd indexes don't really exist.
- // They're just indicating that we want to grab the even index and invert it. So calculate
- // the proper vector index and acknowledge the inversion if necessary.
- if ((i_pattern % 2) != 0)
- {
- l_invert = true;
- i_pattern -= 1;
- }
-
- return load_maint_pattern(i_target, patterns[i_pattern / 2], l_invert);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST Maint mode pattern given an index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_maint_pattern( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_maint_pattern(i_target, i_program.iv_pattern);
-}
-
-
-///
-/// @brief Load MCBIST 24b random data seeds given a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_random24_data_seed mcbist::random24_data_seed
-/// @param[in] i_random24_map mcbist::random24_seed_map
-/// @param[in] i_invert whether to invert the pattern or not
-/// @note this overload disappears when we have real patterns.
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target,
- const random24_data_seed& i_random24_data_seed,
- const random24_seed_map& i_random24_map,
- const bool i_invert );
-
-///
-/// @brief Load MCBIST 24b Random data seeds given a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_data_seed the 24b random data seed index
-/// @param[in] i_seed_map the 24b random data map index
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target, uint64_t i_data_seed,
- uint64_t i_seed_map )
-{
- if ((NO_RANDOM24_SEEDS != i_data_seed) && (NO_RANDOM24_SEED_MAP != i_seed_map))
- {
- bool l_invert = false;
-
- // TK Want a new RC for random 24
- // Sanity check the pattern since they're just numbers.
- // Belt-and-suspenders FAPI_ASSERT as the sim-only uses this API directly.
- FAPI_ASSERT( i_data_seed <= mcbist::LAST_RANDOM24_SEEDS,
- fapi2::MSS_MEMDIAGS_INVALID_PATTERN_INDEX().set_INDEX(i_data_seed),
- "Attempting to load a 24b random data seed set which does not exist %d", i_data_seed );
-
- // The indexes are split in to even and odd where the odd indexes don't really exist.
- // They're just indicating that we want to grab the even index and invert it. So calculate
- // the proper vector index and acknowledge the inversion if necessary.
- if ((i_data_seed % 2) != 0)
- {
- l_invert = true;
- i_data_seed -= 1;
- }
-
- return load_random24b_seeds(i_target, random24_data_seeds[i_data_seed / 2], random24_seed_maps[i_seed_map], l_invert);
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST 24b Random data seeds given a program conatining a pattern index
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_random24b_seeds( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_random24b_seeds(i_target, i_program.iv_random24_data_seed, i_program.iv_random24_seed_map);
-}
-
-///
-/// @brief Loads the FIFO value if needed
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_fifo_mode( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
-
- // Checks if FIFO mode is required by checking all subtests
- const auto l_subtest_it = std::find_if(i_program.iv_subtests.begin(),
- i_program.iv_subtests.end(), []( const mss::mcbist::subtest_t<T>& i_rhs) -> bool
- {
- return i_rhs.fifo_mode_required();
- });
-
- // if the FIFO load is not needed (no subtest requiring it was found), just exit out
- if(l_subtest_it == i_program.iv_subtests.end())
- {
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- // Turns on FIFO mode
- constexpr mss::states FIFO_ON = mss::states::ON;
-
- FAPI_TRY(mss::configure_wrq(i_target, FIFO_ON));
- FAPI_TRY(mss::configure_rrq(i_target, FIFO_ON));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Load MCBIST data patterns and configuration
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_data_config( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- uint64_t l_data_rotate_cnfg_addr = TT::DATA_ROTATE_CNFG_REG;
- uint64_t l_data_rotate_seed_addr = TT::DATA_ROTATE_SEED_REG;
-
- // First load the data pattern registers
- FAPI_INF("Loading the data pattern seeds!");
- FAPI_TRY( mss::mcbist::load_pattern(i_target, i_program.iv_pattern) );
-
- // Load the 24b random data pattern seeds registers
- FAPI_INF("Loading the 24b Random data pattern seeds!");
- FAPI_TRY( mss::mcbist::load_random24b_seeds(i_target, i_program.iv_random24_data_seed,
- i_program.iv_random24_seed_map) );
-
- // Load the maint data pattern into the Maint entry in the RMW buffer
- // TK Might want to only load the RMW buffer if maint commands are present in the program
- // The load takes 33 Putscoms to load 16 64B registers, might slow down mcbist programs that
- // don't need the RMW buffer maint entry loaded
- FAPI_INF("Loading the maint data pattern into the RMW buffer!");
- FAPI_TRY( mss::mcbist::load_maint_pattern(i_target, i_program.iv_pattern) );
-
- FAPI_INF("Loading the data rotate config and seeds!");
- FAPI_TRY( mss::putScom(i_target, l_data_rotate_cnfg_addr, i_program.iv_data_rotate_cnfg) );
- FAPI_TRY( mss::putScom(i_target, l_data_rotate_seed_addr, i_program.iv_data_rotate_seed) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Load MCBIST data compare mask registers
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode load_data_compare_mask( const fapi2::Target<T>& i_target,
- const mcbist::program<T>& i_program );
-
-///
-/// @brief Load MCBIST Thresholds
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_thresholds the thresholds
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_thresholds( const fapi2::Target<T>& i_target, const uint64_t i_thresholds )
-{
- FAPI_INF("load MCBIST threshold register: 0x%016lx", i_thresholds );
- return mss::putScom(i_target, TT::THRESHOLD_REG, i_thresholds);
-}
-
-///
-/// @brief Load MCBIST Threshold Register
-/// @tparam T, the fapi2::TargetType - derived
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_program the program containing the thresholds
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode load_thresholds( const fapi2::Target<T>& i_target, const mcbist::program<T>& i_program )
-{
- return load_thresholds(i_target, i_program.iv_thresholds);
-}
-
-///
-/// @brief Read entries from MCBIST Read Modify Write (RMW) array
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[in] i_roll_over_for_compare_mode set to true if only using first
-/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
-/// @param[out] o_data vector of output data
-/// @param[out] o_ecc_data vector of ecc data
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
-/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
-/// that since reads work in a circular buffer fashion
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- const bool i_roll_over_for_compare_mode,
- std::vector< fapi2::buffer<uint64_t> >& o_data,
- std::vector< fapi2::buffer<uint64_t> >& o_ecc_data);
-
-///
-/// @brief Read entries from MCBIST Read Modify Write (RMW) array
-/// Overload for the case where o_ecc_data is not needed
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[in] i_roll_over_for_compare_mode set to true if only using first
-/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
-/// @param[out] o_data vector of output data
-/// @return FAPI2_RC_SUCCSS iff ok
-/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
-/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
-/// that since reads work in a circular buffer fashion
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- const bool i_roll_over_for_compare_mode,
- std::vector< fapi2::buffer<uint64_t> >& o_data)
-{
- std::vector< fapi2::buffer<uint64_t> > l_temp;
- return read_rmw_array(i_target, i_start_addr, i_num_entries, i_roll_over_for_compare_mode, o_data, l_temp);
-}
-
-///
-/// @brief Read entries from MCBIST Read Buffer (RB) array
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[out] o_data vector of output data
-/// @param[out] o_ecc_data vector of ecc data
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- std::vector< fapi2::buffer<uint64_t> >& o_data,
- std::vector< fapi2::buffer<uint64_t> >& o_ecc_data);
-
-///
-/// @brief Read entries from MCBIST Read Buffer (RB) array
-/// Overload for the case where o_ecc_data is not needed
-/// @tparam T, the fapi2::TargetType
-/// @tparam TT, the mcbistTraits associated with T - derived
-/// @param[in] i_target the target to effect
-/// @param[in] i_start_addr the array address to read first
-/// @param[in] i_num_entries the number of array entries to read
-/// @param[out] o_data vector of output data
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
- const uint64_t i_start_addr,
- const uint64_t i_num_entries,
- std::vector< fapi2::buffer<uint64_t> >& o_data)
-{
- std::vector< fapi2::buffer<uint64_t> > l_temp;
- return read_rb_array(i_target, i_start_addr, i_num_entries, o_data, l_temp);
-}
-
-///
+////
/// @brief Checks if broadcast mode is capable of being enabled on this target
/// @param[in] i_target the target to effect
/// @param[in] i_bc_force attribute's value to force off broadcast mode
@@ -3206,20 +77,23 @@ const mss::states is_broadcast_capable_helper(const fapi2::Target<fapi2::TARGET_
///
/// @brief Checks if broadcast mode is capable of being enabled on this target
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_target the target to effect
/// @return o_capable - yes iff these vector of targets are broadcast capable
///
-template< fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
const mss::states is_broadcast_capable(const fapi2::Target<T>& i_target);
+
///
/// @brief Checks if broadcast mode is capable of being enabled on this vector of targets
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_targets the vector of targets to analyze
/// @return o_capable - yes iff these vector of targets are broadcast capable
///
-template< fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
const mss::states is_broadcast_capable(const std::vector<fapi2::Target<T>>& i_targets);
///
@@ -3229,189 +103,31 @@ const mss::states is_broadcast_capable(const std::vector<fapi2::Target<T>>& i_ta
///
const mss::states is_broadcast_capable(const std::vector<mss::dimm::kind>& i_kinds);
+
///
/// @brief Configures all of the ports for broadcast mode
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_target the target to effect
/// @param[out] o_port_select - the configuration of the selected ports
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T >
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
fapi2::ReturnCode setup_broadcast_port_select(const fapi2::Target<T>& i_target, uint64_t& o_port_select);
///
/// @brief Enables broadcast mode
+/// @tparam MC the mc type of the T
/// @tparam T, the fapi2::TargetType
/// @param[in] i_target the target to effect
/// @param[in,out] io_program the mcbist::program
/// @return FAPI2_RC_SUCCSS iff ok
///
-template< fapi2::TargetType T >
-fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target<T>& i_target, mcbist::program<T>& io_program);
-
-///
-/// @brief Configures broadcast mode, if it is needed
-/// @tparam T, the fapi2::TargetType
-/// @param[in] i_target the target to effect
-/// @param[in,out] io_program the mcbist::program
-/// @return FAPI2_RC_SUCCSS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode configure_broadcast_mode(const fapi2::Target<T>& i_target, mcbist::program<T>& io_program)
-{
- // If we're not capable to do broadcast mode on this target, exit out
- const auto l_broadcast_capable = is_broadcast_capable(i_target);
-
- if(l_broadcast_capable == mss::states::NO)
- {
- FAPI_INF("%s is not broadcast capable, skipping enablement of broadcast mode", mss::c_str(i_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- // Enable broadcast mode
- FAPI_INF("%s is broadcast capable, enabling broadcast mode", mss::c_str(i_target));
- return enable_broadcast_mode(i_target, io_program);
-}
-
-} // mcbist namespace
-
-///
-/// @brief Reads the contents of the MCBISTFIRMASK
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[out] o_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode read_mcbfirmask( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- o_data = 0;
-
- FAPI_TRY( mss::getScom(i_target, TT::MCBFIRMASK_REG, o_data ), "%s failed to read MCBISTFIRMASK regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRMASK has data 0x%016lx", mss::c_str(i_target), o_data);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Writes the contents of the MCBISTFIRMASK
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[in] i_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode write_mcbfirmask( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::MCBFIRMASK_REG, i_data ), "%s failed to write MCBISTFIRMASK regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRMASK has data 0x%016lx", mss::c_str(i_target), i_data);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Reads the contents of the MCBISTFIRQ
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[out] o_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode read_mcbfirq( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
-{
- o_data = 0;
-
- FAPI_TRY( mss::getScom(i_target, TT::MCBFIRQ_REG, o_data ), "%s failed to read MCBISTFIRQ regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRQ has data 0x%016lx", mss::c_str(i_target), o_data);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
+template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T >
+fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target<T>& i_target, mcbist::program<>& io_program);
-///
-/// @brief Writes the contents of the MCBISTFIRQ
-/// @tparam T fapi2 Target Type - derived
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in] i_target the target on which to operate
-/// @param[in] i_data the register data
-/// @return fapi2::fapi2_rc_success if ok
-///
-template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
-inline fapi2::ReturnCode write_mcbfirq( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
-{
- FAPI_TRY( mss::putScom(i_target, TT::MCBFIRQ_REG, i_data ), "%s failed to write MCBISTFIRQ regiser",
- mss::c_str(i_target));
- FAPI_DBG("%s MCBISTFIRQ has data 0x%016lx", mss::c_str(i_target), i_data);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Sets the mask for program complete
-/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in,out] io_data the value of the register
-/// @param[in] i_state the state to write into the enable
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void set_mcbist_program_complete_mask( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::MCB_PROGRAM_COMPLETE_MASK>(i_state == mss::states::ON);
- FAPI_DBG("set_mcbist_program_complete_mask to %d 0x%016lx", i_state, io_data);
-}
-
-///
-/// @brief Sets the mask for WAT debug ATTN
-/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in,out] io_data the value of the register
-/// @param[in] i_state the state to write into the enable
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void set_mcbist_wat_debug_attn_mask( fapi2::buffer<uint64_t>& io_data, const mss::states i_state )
-{
- io_data.writeBit<TT::MCB_WAT_DEBUG_ATTN_MASK>(i_state == mss::states::ON);
- FAPI_DBG("set_mcbist_wat_debug_attn_mask to %d 0x%016lx", i_state, io_data);
-}
-
-///
-/// @brief Clears the program complete and WAT debug ATTN
-/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCBIST
-/// @tparam TT traits type defaults to mcbistTraits<T>
-/// @param[in,out] io_data the value of the register
-/// @param[in] i_state the state to write into the enable
-///
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void clear_mcbist_program_complete( fapi2::buffer<uint64_t>& io_data )
-{
- io_data.writeBit<TT::MCB_PROGRAM_COMPLETE>(mss::states::OFF);
- io_data.writeBit<TT::MCB_WAT_DEBUG_ATTN>(mss::states::OFF);
- FAPI_DBG("clear_mcbist_program_complete to %d 0x%016lx", mss::states::OFF, io_data);
-}
-
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void get_mcbist_program_complete_mask( const fapi2::buffer<uint64_t> i_data, mss::states& o_state )
-{
- o_state = i_data.getBit<TT::MCB_PROGRAM_COMPLETE>() ? mss::states::HIGH : mss::states::LOW;
- FAPI_DBG("get_mcbist_program_complete_mask %d", o_state);
-}
-
-template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCBIST, typename TT = mcbistTraits<T> >
-inline void get_mcbist_wat_debug_attn_mask( const fapi2::buffer<uint64_t> i_data, mss::states& o_state )
-{
- o_state = i_data.getBit<TT::MCB_WAT_DEBUG_ATTN>() ? mss::states::HIGH : mss::states::LOW;
- FAPI_DBG("mcbist_wat_debug_attn_mask %d", o_state);
-}
+} // namespace MCBIST
-} // mss namespace
+} // namespace mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
index 6936f7aff..89206597e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist_traits.H
@@ -22,3 +22,472 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mcbist_traits.H
+/// @brief Run and manage the MCBIST engine
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_MCBIST_TRAITS_H_
+#define _MSS_MCBIST_TRAITS_H_
+
+#include <fapi2.H>
+
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mcbist/gen_address.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H>
+#include <p9_mc_scom_addresses.H>
+#include <p9_mc_scom_addresses_fld.H>
+
+namespace mss
+{
+
+///
+/// @class mcbistMCTraits
+/// @brief A MC to MC_TARGET_TYPE mapping
+///
+template<>
+class mcbistMCTraits<mss::mc_type::NIMBUS>
+{
+ public:
+ static constexpr fapi2::TargetType MC_TARGET_TYPE = fapi2::TARGET_TYPE_MCBIST;
+ static constexpr fapi2::TargetType FWMS_ADDR_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
+};
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Nimbus MCBIST engine or hardware
+///
+template<>
+class mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCBIST>
+{
+ public:
+
+ // PORT_TYPE used in continuous_scrub_operation
+ static constexpr enum fapi2::TargetType PORT_TYPE = fapi2::TARGET_TYPE_MCA;
+
+ // ATTN support
+ static constexpr mss::states CFG_ENABLE_ATTN_SUPPORT = mss::states::YES;
+
+ // Multi-ports, dimms
+ static constexpr mss::states MULTI_PORTS = mss::states::YES;
+ static constexpr mss::states MULTI_DIMMS = mss::states::YES;
+
+ // Subtest
+ static constexpr size_t SUBTEST_PER_REG = 4;
+ static constexpr size_t SUBTEST_PER_PROGRAM = 32;
+ static constexpr size_t BITS_IN_SUBTEST = 16; // 2 Bytes
+ static constexpr size_t LEFT_SHIFT = (sizeof(uint64_t) * 8) - BITS_IN_SUBTEST;
+
+ // LARGEST_ADDRESS
+ static constexpr uint64_t LARGEST_ADDRESS = ~0 >> mss::mcbist::address::MAGIC_PAD;
+
+ /// MCBIST "memory registers" - config for subtests.
+ static constexpr uint64_t MCBMR0_REG = MCBIST_MCBMR0Q;
+ static constexpr uint64_t MCBMR1_REG = MCBIST_MCBMR1Q;
+ static constexpr uint64_t MCBMR2_REG = MCBIST_MCBMR2Q;
+ static constexpr uint64_t MCBMR3_REG = MCBIST_MCBMR3Q;
+ static constexpr uint64_t MCBMR4_REG = MCBIST_MCBMR4Q;
+ static constexpr uint64_t MCBMR5_REG = MCBIST_MCBMR5Q;
+ static constexpr uint64_t MCBMR6_REG = MCBIST_MCBMR6Q;
+ static constexpr uint64_t MCBMR7_REG = MCBIST_MCBMR7Q;
+ static constexpr uint64_t CFGQ_REG = MCBIST_MCBCFGQ;
+ static constexpr uint64_t CNTLQ_REG = MCBIST_MCB_CNTLQ;
+ static constexpr uint64_t STATQ_REG = MCBIST_MCB_CNTLSTATQ;
+ static constexpr uint64_t MCBSTATQ_REG = MCBIST_MCBSTATQ;
+ static constexpr uint64_t MCBPARMQ_REG = MCBIST_MCBPARMQ;
+ static constexpr uint64_t MCBAGRAQ_REG = MCBIST_MCBAGRAQ;
+ static constexpr uint64_t SRERR0_REG = MCBIST_MBSEC0Q;
+ static constexpr uint64_t SRERR1_REG = MCBIST_MBSEC1Q;
+ static constexpr uint64_t THRESHOLD_REG = MCBIST_MBSTRQ;
+ static constexpr uint64_t FIRQ_REG = MCBIST_MCBISTFIRQ;
+ static constexpr uint64_t LAST_ADDR_REG = MCBIST_MCBMCATQ;
+
+ static constexpr uint64_t MCBAMR0A0Q_REG = MCBIST_MCBAMR0A0Q;
+ static constexpr uint64_t MCBAMR1A0Q_REG = MCBIST_MCBAMR1A0Q;
+ static constexpr uint64_t MCBAMR2A0Q_REG = MCBIST_MCBAMR2A0Q;
+ static constexpr uint64_t MCBAMR3A0Q_REG = MCBIST_MCBAMR3A0Q;
+
+ // MCBIST FIR registers
+ static constexpr uint64_t MCBFIRMASK_REG = MCBIST_MCBISTFIRMASK;
+ static constexpr uint64_t MCBFIRQ_REG = MCBIST_MCBISTFIRQ;
+
+ // All of the pattern registers are calculated off of this base
+ static constexpr uint64_t PATTERN0_REG = MCBIST_MCBFD0Q;
+
+ static constexpr uint64_t DATA_ROTATE_CNFG_REG = MCBIST_MCBDRCRQ;
+ static constexpr uint64_t DATA_ROTATE_SEED_REG = MCBIST_MCBDRSRQ;
+
+ static constexpr uint16_t MAX_ADDRESS_START_END_REGISTERS = 4;
+ static constexpr uint64_t START_ADDRESS_0 = MCBIST_MCBSA0Q;
+ static constexpr uint64_t START_ADDRESS_1 = MCBIST_MCBSA1Q;
+ static constexpr uint64_t START_ADDRESS_2 = MCBIST_MCBSA2Q;
+ static constexpr uint64_t START_ADDRESS_3 = MCBIST_MCBSA3Q;
+
+ static constexpr uint64_t END_ADDRESS_0 = MCBIST_MCBEA0Q;
+ static constexpr uint64_t END_ADDRESS_1 = MCBIST_MCBEA1Q;
+ static constexpr uint64_t END_ADDRESS_2 = MCBIST_MCBEA2Q;
+ static constexpr uint64_t END_ADDRESS_3 = MCBIST_MCBEA3Q;
+
+ static constexpr uint64_t RANDOM_DATA_SEED0 = MCBIST_MCBRDS0Q;
+ static constexpr uint64_t RANDOM_DATA_SEED1 = MCBIST_MCBRDS1Q;
+
+
+ static constexpr uint64_t MBSTRQ_CFG_PAUSE_ON_MPE = MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE;
+
+
+ // MCBIST Compare Masks, used to setup the ECC traps
+ // TK there is one reg per port, does writing to this one write to all?
+ static constexpr uint64_t COMPARE_MASK = MCA_MCBCM;
+
+ static constexpr uint64_t PATTERN_COUNT = 4;
+
+ // Sometimes we want to access the start/end address registers based off
+ // of an index, like master rank. This allows us to do that.
+ static const std::pair<uint64_t, uint64_t> address_pairs[];
+ static constexpr uint64_t ADDRESS_PAIRS = 4;
+
+ // Subtest types that need to be run in FIFO mode
+ static const std::vector< mss::mcbist::op_type > FIFO_MODE_REQUIRED_OP_TYPES;
+
+ // Which bit in the end boundary which siginifies this is a slave rank detect situation
+ static constexpr uint64_t SLAVE_RANK_INDICATED_BIT = 61;
+
+ enum
+ {
+ // Subtest control bits. These are the same in all '16 bit subtest' field
+ COMPL_1ST_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
+ COMPL_2ND_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_2ND_CMD,
+ COMPL_3RD_CMD = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_3RD_CMD,
+ ADDR_REV_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_REV_MODE,
+ ADDR_RAND_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_RAND_MODE,
+
+ // Goto subtests use the compl_1st - rand_mode to define the subtest to jump to
+ GOTO_SUBTEST = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_COMPL_1ST_CMD,
+ GOTO_SUBTEST_LEN = 5,
+
+ ECC_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ECC_MODE,
+ DATA_MODE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE,
+ DATA_MODE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DATA_MODE_LEN,
+ ADDR_SEL = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL,
+ ADDR_SEL_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_ADDR_SEL_LEN,
+ OP_TYPE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE,
+ OP_TYPE_LEN = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_OP_TYPE_LEN,
+ DONE = MCBIST_MCBMR0Q_MCBIST_CFG_TEST00_DONE,
+
+ SYNC_EN = MCBIST_MCBCFGQ_BROADCAST_SYNC_EN,
+ SYNC_WAIT = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT,
+ SYNC_WAIT_LEN = MCBIST_MCBCFGQ_BROADCAST_SYNC_WAIT_LEN,
+
+ PORT_SEL = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL,
+ PORT_SEL_LEN = MCBIST_MCB_CNTLQ_MCBCNTL_PORT_SEL_LEN,
+
+ MCBIST_START = MCBIST_MCB_CNTLQ_START,
+ MCBIST_STOP = MCBIST_MCB_CNTLQ_STOP,
+ MCBIST_RESUME = MCBIST_MCB_CNTLQ_RESUME_FROM_PAUSE,
+ MCBIST_RESET_ERRORS = MCBIST_MCB_CNTLQ_RESET_ERROR_LOGS,
+
+ MCBIST_IN_PROGRESS = MCBIST_MCB_CNTLSTATQ_IP,
+ MCBIST_DONE = MCBIST_MCB_CNTLSTATQ_DONE,
+ MCBIST_FAIL = MCBIST_MCB_CNTLSTATQ_FAIL,
+
+ MIN_CMD_GAP = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP,
+ MIN_CMD_GAP_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_LEN,
+ MIN_GAP_TIMEBASE = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE,
+ MIN_CMD_GAP_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER,
+ MIN_CMD_GAP_BLIND_STEER_LEN = MCBIST_MCBPARMQ_CFG_MIN_CMD_GAP_BLIND_STEER_LEN,
+ MIN_GAP_TIMEBASE_BLIND_STEER = MCBIST_MCBPARMQ_CFG_MIN_GAP_TIMEBASE_BLIND_STEER,
+ RANDCMD_WGT = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT,
+ RANDCMD_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDCMD_WGT_LEN,
+ CLOCK_MONITOR_EN = MCBIST_MCBPARMQ_CFG_CLOCK_MONITOR_EN,
+ EN_RANDCMD_GAP = MCBIST_MCBPARMQ_CFG_EN_RANDCMD_GAP,
+ RANDGAP_WGT = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT,
+ RANDGAP_WGT_LEN = MCBIST_MCBPARMQ_CFG_RANDGAP_WGT_LEN,
+ BC4_EN = MCBIST_MCBPARMQ_CFG_BC4_EN,
+
+ FIXED_WIDTH = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH,
+ FIXED_WIDTH_LEN = MCBIST_MCBAGRAQ_CFG_FIXED_WIDTH_LEN,
+ ADDR_COUNTER_MODE = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE,
+ ADDR_COUNTER_MODE_LEN = MCBIST_MCBAGRAQ_CFG_ADDR_COUNTER_MODE_LEN,
+ MAINT_ADDR_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_ADDR_MODE_EN,
+ MAINT_BROADCAST_MODE_EN = MCBIST_MCBAGRAQ_CFG_MAINT_BROADCAST_MODE_EN,
+ MAINT_DETECT_SRANK_BOUNDARIES = MCBIST_MCBAGRAQ_CFG_MAINT_DETECT_SRANK_BOUNDARIES,
+
+ CFG_CMD_TIMEOUT_MODE = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE,
+ CFG_CMD_TIMEOUT_MODE_LEN = MCBIST_MCBCFGQ_CFG_CMD_TIMEOUT_MODE_LEN,
+ RESET_KEEPER = MCBIST_MCBCFGQ_RESET_KEEPER,
+ CFG_CURRENT_ADDR_TRAP_UPDATE_DIS = MCBIST_MCBCFGQ_CFG_CURRENT_ADDR_TRAP_UPDATE_DIS,
+ CFG_CCS_RETRY_DIS = MCBIST_MCBCFGQ_CFG_CCS_RETRY_DIS,
+ CFG_RESET_CNTS_START_OF_RANK = MCBIST_MCBCFGQ_CFG_RESET_CNTS_START_OF_RANK,
+ CFG_LOG_COUNTS_IN_TRACE = MCBIST_MCBCFGQ_CFG_LOG_COUNTS_IN_TRACE,
+ SKIP_INVALID_ADDR_DIMM_DIS = MCBIST_MCBCFGQ_SKIP_INVALID_ADDR_DIMM_DIS,
+ REFRESH_ONLY_SUBTEST_EN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_EN,
+ REFRESH_ONLY_SUBTEST_TIMEBASE_SEL = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL,
+ REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN = MCBIST_MCBCFGQ_REFRESH_ONLY_SUBTEST_TIMEBASE_SEL_LEN,
+ RAND_ADDR_ALL_ADDR_MODE_EN = MCBIST_MCBCFGQ_RAND_ADDR_ALL_ADDR_MODE_EN,
+ MCBIST_CFG_REF_WAIT_TIME = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME,
+ MCBIST_CFG_REF_WAIT_TIME_LEN = MCBIST_MCBCFGQ_MCBIST_CFG_REF_WAIT_TIME_LEN,
+ CFG_MCB_LEN64 = MCBIST_MCBCFGQ_CFG_MCB_LEN64,
+ CFG_PAUSE_ON_ERROR_MODE = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE,
+ CFG_PAUSE_ON_ERROR_MODE_LEN = MCBIST_MCBCFGQ_CFG_PAUSE_ON_ERROR_MODE_LEN,
+ MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_PAUSE_AFTER_CCS_SUBTEST,
+ MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_ADDR,
+ MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST = MCBIST_MCBCFGQ_MCBIST_CFG_FORCE_PAUSE_AFTER_SUBTEST,
+ CFG_ENABLE_SPEC_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_SPEC_ATTN,
+ CFG_ENABLE_HOST_ATTN = MCBIST_MCBCFGQ_CFG_ENABLE_HOST_ATTN,
+ MCBIST_CFG_PAUSE_AFTER_RANK = MCBIST_MCBCFGQ_CFG_MCBIST_CFG_FORCE_PAUSE_AFTER_RANK,
+
+ LOGGED_ERROR_ON_PORT_INDICATOR = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR,
+ LOGGED_ERROR_ON_PORT_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_LOGGED_ERROR_ON_PORT_INDICATOR_LEN,
+ SUBTEST_NUM_INDICATOR = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR,
+ SUBTEST_NUM_INDICATOR_LEN = MCBIST_MCBSTATQ_MCBIST_SUBTEST_NUM_INDICATOR_LEN,
+
+ UE_COUNT = MCBIST_MBSEC1Q_UE_COUNT,
+ UE_COUNT_LEN = MCBIST_MBSEC1Q_UE_COUNT_LEN,
+
+ MBSTRQ_CFG_MAINT_RCE_WITH_CE = MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE,
+
+ CFG_AMAP_DIMM_SELECT = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT,
+ CFG_AMAP_DIMM_SELECT_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_DIMM_SELECT_LEN,
+ CFG_AMAP_MRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0,
+ CFG_AMAP_MRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK0_LEN,
+ CFG_AMAP_MRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1,
+ CFG_AMAP_MRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_MRANK1_LEN,
+ CFG_AMAP_SRANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0,
+ CFG_AMAP_SRANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK0_LEN,
+ CFG_AMAP_SRANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1,
+ CFG_AMAP_SRANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK1_LEN,
+ CFG_AMAP_SRANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2,
+ CFG_AMAP_SRANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_SRANK2_LEN,
+ CFG_AMAP_BANK2 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2,
+ CFG_AMAP_BANK2_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK2_LEN ,
+ CFG_AMAP_BANK1 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1,
+ CFG_AMAP_BANK1_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK1_LEN ,
+ CFG_AMAP_BANK0 = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0,
+ CFG_AMAP_BANK0_LEN = MCBIST_MCBAMR0A0Q_CFG_AMAP_BANK0_LEN ,
+
+ CFG_AMAP_BANK_GROUP1 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1,
+ CFG_AMAP_BANK_GROUP1_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP1_LEN ,
+ CFG_AMAP_BANK_GROUP0 = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0,
+ CFG_AMAP_BANK_GROUP0_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_BANK_GROUP0_LEN ,
+ CFG_AMAP_ROW17 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17,
+ CFG_AMAP_ROW17_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW17_LEN,
+ CFG_AMAP_ROW16 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16,
+ CFG_AMAP_ROW16_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW16_LEN,
+ CFG_AMAP_ROW15 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15,
+ CFG_AMAP_ROW15_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW15_LEN,
+ CFG_AMAP_ROW14 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14,
+ CFG_AMAP_ROW14_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW14_LEN,
+ CFG_AMAP_ROW13 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13,
+ CFG_AMAP_ROW13_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW13_LEN,
+ CFG_AMAP_ROW12 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12,
+ CFG_AMAP_ROW12_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW12_LEN,
+ CFG_AMAP_ROW11 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11,
+ CFG_AMAP_ROW11_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW11_LEN,
+ CFG_AMAP_ROW10 = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10,
+ CFG_AMAP_ROW10_LEN = MCBIST_MCBAMR1A0Q_CFG_AMAP_ROW10_LEN,
+
+ CFG_AMAP_ROW9 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9,
+ CFG_AMAP_ROW9_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW9_LEN,
+ CFG_AMAP_ROW8 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8,
+ CFG_AMAP_ROW8_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW8_LEN,
+ CFG_AMAP_ROW7 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7,
+ CFG_AMAP_ROW7_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW7_LEN,
+ CFG_AMAP_ROW6 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6,
+ CFG_AMAP_ROW6_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW6_LEN,
+ CFG_AMAP_ROW5 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5,
+ CFG_AMAP_ROW5_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW5_LEN,
+ CFG_AMAP_ROW4 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4,
+ CFG_AMAP_ROW4_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW4_LEN,
+ CFG_AMAP_ROW3 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3,
+ CFG_AMAP_ROW3_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW3_LEN,
+ CFG_AMAP_ROW2 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2,
+ CFG_AMAP_ROW2_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW2_LEN,
+ CFG_AMAP_ROW1 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1,
+ CFG_AMAP_ROW1_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW1_LEN,
+ CFG_AMAP_ROW0 = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0,
+ CFG_AMAP_ROW0_LEN = MCBIST_MCBAMR2A0Q_CFG_AMAP_ROW0_LEN,
+
+ CFG_AMAP_COL9 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9,
+ CFG_AMAP_COL9_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL9_LEN,
+ CFG_AMAP_COL8 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8,
+ CFG_AMAP_COL8_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL8_LEN,
+ CFG_AMAP_COL7 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7,
+ CFG_AMAP_COL7_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL7_LEN,
+ CFG_AMAP_COL6 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6,
+ CFG_AMAP_COL6_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL6_LEN,
+ CFG_AMAP_COL5 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5,
+ CFG_AMAP_COL5_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL5_LEN,
+ CFG_AMAP_COL4 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4,
+ CFG_AMAP_COL4_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL4_LEN,
+ CFG_AMAP_COL3 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3,
+ CFG_AMAP_COL3_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL3_LEN,
+ CFG_AMAP_COL2 = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2,
+ CFG_AMAP_COL2_LEN = MCBIST_MCBAMR3A0Q_CFG_AMAP_COL2_LEN,
+
+ CFG_DATA_ROT_SEED1 = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED,
+ CFG_DATA_ROT_SEED1_LEN = MCBIST_MCBDRSRQ_CFG_DATA_ROT_SEED_LEN,
+ CFG_DATA_ROT = MCBIST_MCBDRCRQ_CFG_DATA_ROT,
+ CFG_DATA_ROT_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_LEN,
+ CFG_DATA_ROT_SEED2 = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED,
+ CFG_DATA_ROT_SEED2_LEN = MCBIST_MCBDRCRQ_CFG_DATA_ROT_SEED_LEN,
+ CFG_DATA_SEED_MODE = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE,
+ CFG_DATA_SEED_MODE_LEN = MCBIST_MCBDRCRQ_CFG_DATA_SEED_MODE_LEN,
+
+ CFG_TRAP_CE_ENABLE = MCA_MCBCM_MCBIST_TRAP_CE_ENABLE,
+ CFG_TRAP_UE_ENABLE = MCA_MCBCM_MCBIST_TRAP_UE_ENABLE,
+ CFG_TRAP_MPE_ENABLE = MCA_MCBCM_MCBIST_TRAP_MPE_ENABLE,
+
+ CFG_DGEN_RNDD_SEED0 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0,
+ CFG_DGEN_RNDD_SEED0_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED0_LEN,
+ CFG_DGEN_RNDD_SEED1 = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1,
+ CFG_DGEN_RNDD_SEED1_LEN = MCBIST_MCBRDS0Q_DGEN_RNDD_SEED1_LEN,
+ CFG_DGEN_RNDD_SEED2 = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2,
+ CFG_DGEN_RNDD_SEED2_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN,
+ CFG_DGEN_RNDD_DATA_MAPPING = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING,
+ CFG_DGEN_RNDD_DATA_MAPPING_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN,
+
+ // THRESHOLD control bits
+ MBSTRQ_CFG_THRESH_MAG_NCE_INT = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT,
+ MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_NCE_SOFT = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT,
+ MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_NCE_HARD = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD,
+ MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN,
+ MBSTRQ_CFG_THRESH_MAG_RCE = MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE,
+ MBSTRQ_CFG_THRESH_MAG_RCE_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_RCE_LEN,
+ MBSTRQ_CFG_THRESH_MAG_ICE = MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE,
+ MBSTRQ_CFG_THRESH_MAG_ICE_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_ICE_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_INT = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT,
+ MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_SOFT = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT,
+ MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN,
+ MBSTRQ_CFG_THRESH_MAG_MCE_HARD = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD,
+ MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN = MCBIST_MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN,
+ MBSTRQ_CFG_PAUSE_ON_SCE = MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE,
+ MBSTRQ_CFG_PAUSE_ON_MCE = MCBIST_MBSTRQ_CFG_PAUSE_ON_MCE,
+ MBSTRQ_CFG_PAUSE_ON_UE = MCBIST_MBSTRQ_CFG_PAUSE_ON_UE,
+ MBSTRQ_CFG_PAUSE_ON_SUE = MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE,
+ MBSTRQ_CFG_PAUSE_ON_AUE = MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE,
+ MBSTRQ_CFG_PAUSE_ON_RCD = MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD,
+ MBSTRQ_CFG_SYMBOL_COUNTER_MODE = MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE,
+ MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN = MCBIST_MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN,
+ MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_PAUSE_MCB_ERROR = MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR,
+ MBSTRQ_CFG_PAUSE_MCB_LOG_FULL = MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL,
+ MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE,
+ MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE = MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE,
+
+ // Bit mapping for MCBIST error log control data (address+ in Nimbus doc)
+ ERROR_LOG_SUBTEST = 0,
+ ERROR_LOG_SUBTEST_LEN = 5,
+ ERROR_LOG_SUBCMD = 5,
+ ERROR_LOG_SUBCMD_LEN = 2,
+ ERROR_LOG_ADDR_DIMM = 7,
+ ERROR_LOG_ADDR_MRANK = 8,
+ ERROR_LOG_ADDR_MRANK_LEN = 2,
+ ERROR_LOG_ADDR_SRANK = 10,
+ ERROR_LOG_ADDR_SRANK_LEN = 3,
+ ERROR_LOG_ADDR_BANK_GROUP = 13,
+ ERROR_LOG_ADDR_BANK_GROUP_LEN = 2,
+ ERROR_LOG_ADDR_BANK = 15,
+ ERROR_LOG_ADDR_BANK_LEN = 3,
+ ERROR_LOG_ADDR_ROW = 18,
+ ERROR_LOG_ADDR_ROW_LEN = 18,
+ ERROR_LOG_ADDR_COLUMN = 36,
+ ERROR_LOG_ADDR_COLUMN_LEN = 8,
+ ERROR_LOG_BEAT = 44,
+ ERROR_LOG_BEAT_LEN = 2,
+ ERROR_LOG_TYPE = 46,
+ ERROR_LOG_TYPE_LEN = 2,
+
+ //MCBIST FIR mask
+ MCB_PROGRAM_COMPLETE = MCBIST_MCBISTFIRQ_MCBIST_PROGRAM_COMPLETE,
+ MCB_WAT_DEBUG_ATTN = MCBIST_MCBISTFIRQ_WAT_DEBUG_ATTN,
+ MCB_PROGRAM_COMPLETE_MASK = MCB_PROGRAM_COMPLETE,
+ MCB_WAT_DEBUG_ATTN_MASK = MCB_WAT_DEBUG_ATTN,
+ };
+
+};
+
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Nimbus MCA
+///
+template<>
+class mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCA>
+{
+ public:
+ // MCBIST error log related registers
+ static constexpr uint64_t ERROR_LOG_PTR_REG = MCA_ELPR;
+ static constexpr uint64_t RMW_WRT_BUF_CTL_REG = MCA_WREITE_AACR;
+ static constexpr uint64_t RMW_WRT_BUF_DATA_REG = MCA_AADR;
+ static constexpr uint64_t RMW_WRT_BUF_ECC_REG = MCA_AAER;
+
+ enum
+ {
+ // Register field constants
+ ERROR_LOG_PTR = MCA_ELPR_LOG_POINTER,
+ ERROR_LOG_PTR_LEN = MCA_ELPR_LOG_POINTER_LEN,
+ ERROR_LOG_FULL = MCA_ELPR_LOG_FULL,
+ RMW_WRT_BUFFER_SEL = MCA_WREITE_AACR_BUFFER,
+ RMW_WRT_ADDRESS = MCA_WREITE_AACR_ADDRESS,
+ RMW_WRT_ADDRESS_LEN = MCA_WREITE_AACR_ADDRESS_LEN,
+ RMW_WRT_AUTOINC = MCA_WREITE_AACR_AUTOINC,
+ RMW_WRT_ECCGEN = MCA_WREITE_AACR_ECCGEN,
+
+ // Constants used for field settings
+ SELECT_RMW_BUFFER = 0,
+ SELECT_WRT_BUFFER = 1,
+
+ // Other constants
+ NUM_COMPARE_LOG_ENTRIES = 64,
+ // In compare mode, there is one "info" entry per 4 data (log) entries
+ // so compare mode only uses 16 info entries total in the rmw array
+ NUM_COMPARE_DATA_PER_INFO_LOG = 4,
+ NUM_COMPARE_INFO_ENTRIES = 16,
+ };
+
+};
+
+
+///
+/// @class mcbistTraits
+/// @brief a collection of traits associated with the Nimbus MCS
+///
+template<>
+class mcbistTraits<mss::mc_type::NIMBUS, fapi2::TARGET_TYPE_MCS>
+{
+ public:
+ // MCBIST error log related registers
+ static constexpr uint64_t RD_BUF_CTL_REG = MCS_PORT02_AACR;
+ static constexpr uint64_t RD_BUF_DATA_REG = MCS_PORT02_AADR;
+ static constexpr uint64_t RD_BUF_ECC_REG = MCS_PORT02_AAER;
+
+ enum
+ {
+ // Register field constants
+ RB_BUFFER_SEL = MCS_PORT02_AACR_BUFFER,
+ RB_ADDRESS = MCS_PORT02_AACR_ADDRESS,
+ RB_ADDRESS_LEN = MCS_PORT02_AACR_ADDRESS_LEN,
+ RB_AUTOINC = MCS_PORT02_AACR_AUTOINC,
+
+ // Other constants
+ NUM_COMPARE_LOG_ENTRIES = 64,
+ };
+
+};
+
+
+} // namespace mss
+
+#endif
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 b235637b5..682226cfd 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
@@ -33,26 +33,17 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
-#include <lib/shared/nimbus_defaults.H>
#include <fapi2.H>
+#include <lib/shared/nimbus_defaults.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
#include <generic/memory/lib/utils/find_magic.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/address.H>
-#include <lib/mcbist/settings.H>
-#include <lib/mcbist/sim.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/poll.H>
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_DIMM;
-using fapi2::TARGET_TYPE_SYSTEM;
-using fapi2::FAPI2_RC_SUCCESS;
-using fapi2::FAPI2_RC_INVALID_PARAMETER;
namespace mss
{
@@ -61,164 +52,16 @@ namespace memdiags
{
///
-/// @brief Stop the current command
-/// @param[in] i_target the target
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template<>
-fapi2::ReturnCode stop( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
-{
- // Too long, make shorter
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
-
- // Poll parameters are defined as TK so that we wait a nice time for operations
- // For now use the defaults
- mss::poll_parameters l_poll_parameters;
- fapi2::buffer<uint64_t> l_status;
- fapi2::buffer<uint64_t> l_last_address;
- bool l_poll_result = false;
-
- FAPI_INF("Stopping any mcbist operations which are in progress for %s", mss::c_str(i_target));
-
- // TODO RTC:153951 Add masking of FIR when stopping
- FAPI_TRY( mss::mcbist::start_stop(i_target, mss::STOP) );
-
- // Poll waiting for the engine to stop
- l_poll_result = mss::poll(i_target, TT::STATQ_REG, l_poll_parameters,
- [&l_status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
- {
- FAPI_DBG("looking for mcbist not in-progress, mcbist statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
- l_status = stat_reg;
- // We're done polling when either we see we're in progress or we see we're done.
- return l_status.getBit<TT::MCBIST_IN_PROGRESS>() == false;
- });
-
- // Pass or fail output the current address. This is useful for debugging when we can get it.
- // It's in the register FFDC for memdiags so we don't need it below
- FAPI_TRY( mss::getScom(i_target, TT::LAST_ADDR_REG, l_last_address) );
- FAPI_INF("MCBIST last address (during stop): 0x%016lx for %s",
- l_last_address, mss::c_str(i_target));
-
- // So we've either stopped or we timed out
- FAPI_ASSERT( l_poll_result == true,
- fapi2::MSS_MEMDIAGS_MCBIST_FAILED_TO_STOP()
- .set_MCBIST_TARGET(i_target)
- .set_POLL_COUNT(l_poll_parameters.iv_poll_count),
- "%s The MCBIST engine failed to stop its program",
- mss::c_str(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief memdiags init helper
-/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
-/// in subclassed constructors more easily.
-/// @return FAPI2_RC_SUCCESS iff everything ok
-///
-template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::base_init()
-{
- FAPI_INF("memdiags base init for %s", mss::c_str(iv_target));
-
- // Check the state of the MCBIST engine to make sure its OK that we proceed.
- // Force stop the engine (per spec, as opposed to waiting our turn)
- FAPI_TRY( memdiags::stop(iv_target) );
-
- // Zero out cmd timebase - mcbist::program constructor does that for us.
- // Load pattern
- FAPI_TRY( iv_program.change_pattern(iv_const.iv_pattern) );
-
- // Load end boundaries
- iv_program.change_end_boundary(iv_const.iv_end_boundary);
-
- // Load 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) );
-
- // Enable maint addressing mode - enabled by default in the mcbist::program ctor
-
- // Apparently the MCBIST engine needs the ports selected even though the ports are specified
- // in the subtest. We can just select them all, and it adjusts when it executes the subtest
- iv_program.select_ports(0b1111);
-
- // Kick it off, don't wait for a result
- iv_program.change_async(mss::ON);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Single port initializer
-/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
-/// in subclassed constructors more easily.
-/// @return FAPI2_RC_SUCCESS iff everything ok
-///
-template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::single_port_init()
-{
- FAPI_INF("single port init for %s", mss::c_str(iv_target));
-
- const uint64_t l_relative_port_number = iv_const.iv_start_address.get_port();
- const uint64_t l_dimm_number = iv_const.iv_start_address.get_dimm();
-
- // Make sure the specificed port is functional
- FAPI_ASSERT( mss::is_functional<TARGET_TYPE_MCA>(iv_target, l_relative_port_number),
- fapi2::MSS_MEMDIAGS_PORT_NOT_FUNCTIONAL()
- .set_RELATIVE_PORT_POSITION(l_relative_port_number)
- .set_ADDRESS( uint64_t(iv_const.iv_start_address) )
- .set_MCBIST_TARGET(iv_target),
- "Port with relative postion %d is not functional for %s",
- l_relative_port_number, mss::c_str(iv_target));
-
- // No broadcast mode for this one
- // Push on a read subtest
- {
- mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_subtest = iv_subtest;
-
- l_subtest.enable_port(l_relative_port_number);
- l_subtest.enable_dimm(l_dimm_number);
- iv_program.iv_subtests.push_back(l_subtest);
- FAPI_INF("%s adding subtest 0x%04x for port %d, DIMM %d",
- mss::c_str(iv_target), l_subtest, l_relative_port_number, l_dimm_number);
- }
-
- // The address should have the port and DIMM noted in it. All we need to do is calculate the
- // remainder of the address
- if (iv_sim)
- {
- iv_const.iv_start_address.get_sim_end_address(iv_const.iv_end_address);
- }
- else if (iv_const.iv_end_address == mss::mcbist::address::LARGEST_ADDRESS)
- {
- // Only the DIMM range as we don't want to cross ports.
- iv_const.iv_start_address.get_range<mss::mcbist::address::DIMM>(iv_const.iv_end_address);
- }
-
- // Configure the address range
- FAPI_TRY( mss::mcbist::config_address_range0(iv_target, iv_const.iv_start_address, iv_const.iv_end_address) );
-
- // Initialize the common sections
- FAPI_TRY( base_init() );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Helper to encapsualte the setting of multi-port address configurations
/// @return FAPI2_RC_SUCCESS iff ok
///
template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::multi_port_addr()
+fapi2::ReturnCode operation<DEFAULT_MC_TYPE>::multi_port_addr()
{
+ using TT = mcbistTraits<>;
+
mss::mcbist::address l_end_of_start_port;
- mss::mcbist::address l_end_of_complete_port(mss::mcbist::address::LARGEST_ADDRESS);
+ mss::mcbist::address l_end_of_complete_port(TT::LARGEST_ADDRESS);
mss::mcbist::address l_start_of_end_port;
// The last address in the start port is the start address thru the "DIMM range" (all addresses left on this DIMM)
@@ -255,8 +98,8 @@ fapi_try_exit:
/// @param[in] i_dimms a vector of DIMM targets
///
template<>
-void operation<TARGET_TYPE_MCBIST>::configure_multiport_subtests(const
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms)
+void operation<DEFAULT_MC_TYPE>::configure_multiport_subtests(
+ const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms)
{
// Constexpr's to beautify the code
constexpr uint64_t FIRST_ADDRESS = 0;
@@ -424,37 +267,21 @@ fapi_try_exit:
}
///
-/// @brief memdiags multi-port init helper
+/// @brief memdiags multi-port init
/// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
/// in subclassed constructors more easily.
/// @return FAPI2_RC_SUCCESS iff everything ok
///
template<>
-fapi2::ReturnCode operation<TARGET_TYPE_MCBIST>::multi_port_init()
+fapi2::ReturnCode operation<DEFAULT_MC_TYPE>::multi_port_init_internal()
{
- FAPI_INF("multi-port init for %s", mss::c_str(iv_target));
+ FAPI_INF("multi-port init internal for %s", mss::c_str(iv_target));
- const auto l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(iv_target);
-
- // Make sure we have ports, if we don't then exit out
- if(l_mcas.size() == 0)
- {
- // Cronus can have no ports under an MCBIST, FW deconfigures by association
- FAPI_INF("%s has no attached MCAs skipping setup", mss::c_str(iv_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
// Let's assume we are going to send out all subtest unless we are in broadcast mode,
// where we only send up to 2 subtests under an MCA ( 1 for each DIMM) which is why no const
auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target);
- if( l_dimms.size() == 0)
- {
- // Cronus can have no DIMMS under an MCBIST, FW deconfigures by association
- FAPI_INF("%s has no attached DIMMs skipping setup", mss::c_str(iv_target));
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
// Get the port/DIMM information for the addresses. This is an integral value which allows us to index
// all the DIMM across a controller.
const uint64_t l_portdimm_start_address = iv_const.iv_start_address.get_port_dimm();
@@ -532,407 +359,7 @@ fapi_try_exit:
return fapi2::current_err;
}
-///
-/// @brief memdiags::continuous_scrub_operation constructor
-/// @param[in] i_target the target of the mcbist engine
-/// @param[in] i_const the contraints of the operation
-/// @param[out] o_rc the fapi2::ReturnCode of the intialization process
-///
-template<>
-continuous_scrub_operation<TARGET_TYPE_MCBIST>::continuous_scrub_operation(
- const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc ):
- operation<TARGET_TYPE_MCBIST>(i_target, mss::mcbist::scrub_subtest<TARGET_TYPE_MCBIST>(), i_const)
-{
- mss::mcbist::address l_generic_start_address;
- mss::mcbist::address l_generic_end_address;
-
- FAPI_INF("setting up for continuous scrub for %s", mss::c_str(i_target));
-
- // Scrub operations run 128B
- iv_program.change_len64(mss::OFF);
-
- // We build a little program here which allows us to restart the loop in the event of a pause.
- // So we need to craft some of the address ranges and some of the subtests by hand.
-
- // Setup address config 0 to cover all the addresses for a port/dimm.
- // We leverage the MCBIST's ability to skip invalid addresses, and just setup
- // If we're running in the simulator, we want to only touch the addresses which training touched
- // *INDENT-OFF*
- iv_sim ?
- l_generic_start_address.get_sim_end_address(l_generic_end_address) :
- l_generic_start_address.get_range<mss::mcbist::address::DIMM>(l_generic_end_address);
- // *INDENT-ON*
-
- FAPI_TRY( mss::mcbist::config_address_range0(i_target, l_generic_start_address, l_generic_end_address) );
-
- // We push on a fake subtest 0 and subtest 1. We fix them up after we fill in the
- // rest of the subtests.
- iv_program.iv_subtests.push_back(iv_subtest);
- iv_program.iv_subtests.push_back(iv_subtest);
-
- // a generic 0 - DIMM address range.
- //
- // Subtests 2-9: One subtest per port/dimm each covering the whole range of that
- // port/dimm. scrub_subtests by default are using address config 0, so each of
- // these get their full address complement.
- for (const auto& p : iv_target.template getChildren<TARGET_TYPE_MCA>())
- {
- for (const auto& d : p.template getChildren<TARGET_TYPE_DIMM>())
- {
- // Don't destroy the subtest passed in, copy it
- auto l_subtest = iv_subtest;
-
- l_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_subtest.enable_dimm(mss::index(d));
- iv_program.iv_subtests.push_back(l_subtest);
- FAPI_INF("adding scrub subtest for %s (dimm %d) ( 0x%04x)", mss::c_str(d), mss::index(d), l_subtest);
- }
- }
-
- //
- // Subtest 10: goto subtest 2. This causes us to loop back to the first port/dimm and go thru them all
- // This subtest will be marked the last when the MCBMR registers are filled in.
- //
- iv_program.iv_subtests.push_back(mss::mcbist::goto_subtest<TARGET_TYPE_MCBIST>(2));
- FAPI_INF("last goto subtest (10) is going to subtest 2 ( 0x%04x) for %s", iv_program.iv_subtests[2],
- mss::c_str(iv_target));
-
- // Ok, now we can go back in to fill in the first two subtests.
-
- {
- auto l_subtest = iv_subtest;
- auto l_port = iv_const.iv_start_address.get_port();
- auto l_dimm = iv_const.iv_start_address.get_dimm();
- size_t l_index = 2;
-
- // By default if we don't find our port/dimm in the subtests, we just go back to the beginning.
- uint64_t l_goto_subtest = 2;
-
- //
- // subtest 0
- //
-
- // load the start address given and calculate the end address. Stick this into address config 1
- // We don't need to account for the simulator here as the caller can do that when they setup the
- // start address.
- // *INDENT-OFF*
- iv_sim ?
- iv_const.iv_start_address.get_sim_end_address(iv_const.iv_end_address) :
- iv_const.iv_start_address.get_range<mss::mcbist::address::DIMM>(iv_const.iv_end_address);
- // *INDENT-ON*
-
- FAPI_TRY( mss::mcbist::config_address_range1(i_target, iv_const.iv_start_address, iv_const.iv_end_address) );
-
- // We need to use this address range. We know it's ok to write to element 0 as we pushed it on above
- l_subtest.change_addr_sel(1);
- l_subtest.enable_port(l_port);
- l_subtest.enable_dimm(l_dimm);
-
- iv_program.iv_subtests[0] = l_subtest;
- FAPI_INF("adding scrub subtest 0 for port %d dimm %d (0x%04x) for %s", l_port, l_dimm, l_subtest, mss::c_str(i_target));
-
- //
- // subtest 1
- //
-
- // From the port/dimm specified in the start address, we know what subtest should execute next. The idea
- // being that this 0'th subtest is a mechanism to allow the caller to start a scrub 'in the middle' and
- // jump to the next port/dimm which would have been scrubbed. The hard part is that we don't know where
- // in the subtest vector the 'next' port/dimm are placed. So we look for our port/dimm (skipping subtest 0
- // since we know that's us and skipping subtest 1 since it isn't there yet.)
- for (; l_index < iv_program.iv_subtests.size(); ++l_index)
- {
- auto l_my_dimm = iv_program.iv_subtests[l_index].get_dimm();
- auto l_my_port = iv_program.iv_subtests[l_index].get_port();
-
- if ((l_dimm == l_my_dimm) && (l_port == l_my_port))
- {
- l_goto_subtest = l_index + 1;
- break;
- }
- }
-
- // Since we set l_goto_subtest up with a meaningful default, we can just make a subtest with the
- // l_goto_subtest subtest specified and pop that in to index 1.
- FAPI_INF("adding scrub subtest 1 to goto subtest %d (port %d, dimm %d, test 0x%04x) for %s", l_goto_subtest,
- iv_program.iv_subtests[l_goto_subtest].get_port(),
- iv_program.iv_subtests[l_goto_subtest].get_dimm(),
- iv_program.iv_subtests[l_goto_subtest], mss::c_str(i_target) );
-
- iv_program.iv_subtests[1] = mss::mcbist::goto_subtest<TARGET_TYPE_MCBIST>(l_goto_subtest);
- }
-
- // Initialize the common sections
- FAPI_TRY( base_init() );
-
-fapi_try_exit:
- o_rc = fapi2::current_err;
- return;
-}
-
-///
-/// @brief Super Fast Read Init - used to init all memory behind a target with a given pattern
-/// @note Uses broadcast mode if possible
-/// @param[in] i_target the target behind which all memory should be initialized
-/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
-/// @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_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const uint64_t i_pattern )
-{
- FAPI_INF("superfast init start for %s", mss::c_str(i_target));
-
- uint8_t l_sim = false;
- FAPI_TRY( mss::is_simulation( l_sim) );
-
- if (l_sim)
- {
- // Use some sort of pattern in sim in case the verification folks need to look for something
- // TK. Need a verification pattern. This is a not-good pattern for verification ... We don't really
- // have a good pattern for verification defined.
- FAPI_INF("running mss sim init in place of sf_init for %s", mss::c_str(i_target));
- return mss::mcbist::sim::sf_init(i_target, i_pattern);
- }
- else
- {
- fapi2::ReturnCode l_rc;
- constraints l_const(i_pattern);
- sf_init_operation<TARGET_TYPE_MCBIST> l_init_op(i_target, l_const, l_rc);
-
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_SUPERFAST_INIT_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a sf read %s", mss::c_str(i_target) );
-
- return l_init_op.execute();
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Super Fast Read to End of MCBIST - 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_address mcbist::address representing the address from which to start.
-// Defaults to the first address behind the target
-/// @param[in] i_end whether to end, and where
-/// Defaults to stop after slave rank
-/// @param[in] i_end_address mcbist::address representing the address to end.
-// Defaults to mcbist::address::LARGEST_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::ReturnCode sf_read( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions& i_stop,
- const mss::mcbist::address& i_address,
- const end_boundary i_end,
- const mss::mcbist::address& i_end_address )
-{
- FAPI_INF("superfast read - start for %s", mss::c_str(i_target));
-
- fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, speed::LUDICROUS, i_end, i_address, i_end_address);
- sf_read_operation<TARGET_TYPE_MCBIST> l_read_op(i_target, l_const, l_rc);
-
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_SUPERFAST_READ_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a sf read %s", mss::c_str(i_target) );
-
- return l_read_op.execute();
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @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_speed the speed to scrub
-/// @param[in] i_address mcbist::address representing the port, dimm, rank
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @warning The function is asynchronous, and the caller should be looking for a done attention
-/// @note The operation will fail immediately when a stop condition is encountered
-///
-template<>
-fapi2::ReturnCode background_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions& i_stop,
- const speed i_speed,
- const mss::mcbist::address& i_address )
-{
- FAPI_INF("continuous (background) scrub for %s", mss::c_str(i_target));
-
- fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, i_speed, end_boundary::STOP_AFTER_ADDRESS, i_address);
- continuous_scrub_operation<TARGET_TYPE_MCBIST> l_op(i_target, l_const, l_rc);
-
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_CONTINUOUS_SCRUB_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a continuous scrub %s", mss::c_str(i_target) );
-
- return l_op.execute();
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @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_start_address mcbist::address representing the address from which to start.
-/// @param[in] i_end_address mcbist::address representing the address at which to end.
-/// @param[in] i_end whether to end, and where (defaults to not stop on error)
-/// @return FAPI2_RC_SUCCESS iff everything ok
-/// @note The function is asynchronous, and the caller should be looking for a done attention
-/// @note The caller can use the address range functions to calculate the end address as needed
-///
-template<>
-fapi2::ReturnCode targeted_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const stop_conditions& i_stop,
- const mss::mcbist::address& i_start_address,
- const mss::mcbist::address& i_end_address,
- const end_boundary i_end )
-{
- FAPI_INF("targeted scrub for %s", mss::c_str(i_target));
-
- fapi2::ReturnCode l_rc;
- constraints l_const(i_stop, speed::LUDICROUS, i_end, i_start_address, i_end_address);
- targeted_scrub_operation<TARGET_TYPE_MCBIST> l_op(i_target, l_const, l_rc);
-
- FAPI_ASSERT( l_rc == FAPI2_RC_SUCCESS,
- fapi2::MSS_MEMDIAGS_TARGETED_SCRUB_FAILED_TO_INIT().set_MCBIST_TARGET(i_target),
- "Unable to initialize the MCBIST engine for a targeted scrub %s", mss::c_str(i_target) );
-
- return l_op.execute();
-
-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 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 - SAME_SPEED meaning leave speed untouched)
-/// @return FAPI2_RC_SUCCESS iff ok
-/// @note overloaded as there's no 'invalid' state for thresholds.
-///
-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 )
-{
- // Too long, make shorter
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
- // We can use a local mcbist::program to help with the bit processing, and then write just the registers we touch.
- mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
- fapi2::buffer<uint64_t> l_status;
+} // namespace memdiags
- FAPI_INF("continue_cmd for %s", mss::c_str(i_target));
-
- // 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
-
- 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, 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_end)
- {
- 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 == 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 end_boundary::STOP_AFTER_MASTER_RANK:
- 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 == true));
- break;
-
- 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 == end_boundary::STOP_AFTER_SUBTEST;
- break;
-
- // By default we're not stopped at a boundary we're going to continue from
- default:
- break;
- };
-
- FAPI_ASSERT( l_stopped_at_boundary == false,
- fapi2::MSS_MEMDIAGS_ALREADY_AT_BOUNDARY().set_MCBIST_TARGET(i_target).set_BOUNDARY(i_stop),
- "Asked to stop at a boundary, but we're already there" );
-
- // Ok, if we're here either we need to change the stop and boundary conditions.
- // Read-modify-write the fields in the program.
- FAPI_TRY( mss::getScom(i_target, TT::MCBAGRAQ_REG, l_program.iv_addr_gen) );
-
- // Configure broadcast mode if needed
- FAPI_TRY(mss::mcbist::configure_broadcast_mode(i_target, l_program));
-
- l_program.change_end_boundary(i_end);
-
- FAPI_TRY( mss::mcbist::load_addr_gen(i_target, l_program) );
-
- FAPI_TRY( mss::mcbist::load_config(i_target, l_program) );
- }
-
- // Thresholds
- // According to API definition, 0 means don't change conditions
- if( i_stop != stop_conditions::DONT_CHANGE)
- {
- FAPI_TRY( mss::mcbist::load_thresholds(i_target, i_stop) );
- }
-
- // Setup speed
- FAPI_TRY( l_program.change_speed(i_target, i_speed) );
-
- // Load new speed unless we aren't changing it
- if( i_speed != speed::SAME_SPEED )
- {
- FAPI_TRY( load_mcbparm(i_target, l_program) );
- }
-
- // Tickle the resume from pause
- FAPI_TRY( mss::mcbist::resume(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}
-
-}
+} // namespace mss
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 918342c6c..acaaa75b7 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
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,10 +39,16 @@
#include <fapi2.H>
#include <lib/shared/mss_const.H>
+#include <lib/ecc/ecc_traits.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/address.H>
-#include <lib/mcbist/patterns.H>
-#include <lib/mcbist/settings.H>
+#include <generic/memory/lib/utils/mcbist/gen_mss_memdiags.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_DIMM;
+using fapi2::TARGET_TYPE_SYSTEM;
+using fapi2::FAPI2_RC_SUCCESS;
+using fapi2::FAPI2_RC_INVALID_PARAMETER;
namespace mss
{
@@ -50,309 +56,10 @@ namespace mss
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::constraints;
-using mss::mcbist::speed;
-using mss::mcbist::end_boundary;
-using mss::mcbist::stop_conditions;
-using mss::mcbist::cache_line;
-using mss::mcbist::pattern;
-using mss::mcbist::patterns;
-
-// Why not mss::mcbist::address? Because the fields can't be pulled in via using,
-// and it seems even more confusing to have a memdiags address but have to use
-// mcbist fields. So, we all use mcbist address until such time that its promoted
-// to some other general namespace.
-
-using mss::mcbist::PATTERN_ZEROS;
-using mss::mcbist::PATTERN_0;
-using mss::mcbist::PATTERN_ONES;
-using mss::mcbist::PATTERN_1;
-using mss::mcbist::PATTERN_2;
-using mss::mcbist::PATTERN_3;
-using mss::mcbist::PATTERN_4;
-using mss::mcbist::PATTERN_5;
-using mss::mcbist::PATTERN_6;
-using mss::mcbist::PATTERN_7;
-using mss::mcbist::PATTERN_8;
-using mss::mcbist::PATTERN_RANDOM;
-using mss::mcbist::LAST_PATTERN;
-using mss::mcbist::NO_PATTERN;
-
-///
-/// @brief Stop the current command
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode stop( const fapi2::Target<T>& i_target );
-
-///
-/// @class Base class for memdiags operations
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-class operation
-{
- public:
- ///
- /// @brief memdiags::operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_subtest the proper subtest for this operation
- /// @param[in] i_const mss::constraint structure
- ///
- operation( const fapi2::Target<T>& i_target,
- const mss::mcbist::subtest_t<T> i_subtest,
- const constraints i_const ):
- iv_target(i_target),
- iv_subtest(i_subtest),
- iv_const(i_const)
- {
- FAPI_TRY( mss::is_simulation (iv_sim) );
- return;
-
- fapi_try_exit:
- // Seems like a safe risk to take ...
- FAPI_ERR("Unable to get the attribute ATTR_IS_SIMULATION");
- return;
- }
-
- operation() = delete;
-
- ///
- /// @brief Execute the memdiags operation
- /// @return FAPI2_RC_SUCCESS iff ok
- ///
- inline fapi2::ReturnCode execute()
- {
- return mss::mcbist::execute(iv_target, iv_program);
- }
-
- ///
- /// @brief memdiags::operation destructor
- ///
- virtual ~operation() = default;
-
- ///
- /// @brief memdiags init helper
- /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
- /// in subclassed constructores more easily.
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode base_init();
-
- ///
- /// @brief Configures all subtests for a multiport init
- /// @param[in] i_dimms a vector of DIMM targets
- ///
- void configure_multiport_subtests(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimms);
-
- ///
- /// @brief memdiags multi-port init helper
- /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
- /// in subclassed constructores more easily.
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode multi_port_init();
-
- ///
- /// @brief memdiags multi-port address config helper
- /// Initializes the address configs needed for a multi port operation
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode multi_port_addr();
-
- ///
- /// @brief Single port initializer
- /// Initializes common sections. Broken out rather than the base class ctor to enable checking return codes
- /// in subclassed constructores more easily.
- /// @return FAPI2_RC_SUCCESS iff everything ok
- ///
- fapi2::ReturnCode single_port_init();
-
- ///
- /// @brief get the protected mcbist program - useful for testing
- /// @return a reference to the iv_program member
- /// @note Intentionally not const ref; allows getter to set.
- ///
- mss::mcbist::program<T>& get_program()
- {
- return iv_program;
- }
-
- ///
- /// @brief get the protected mcbist subtest_t - useful for testing
- /// @return a reference to the iv_subtest member
- ///
- const mss::mcbist::subtest_t<T>& get_subtest() const
- {
- return iv_subtest;
- }
-
- protected:
- fapi2::Target<T> iv_target;
- mss::mcbist::subtest_t<T> iv_subtest;
- constraints iv_const;
- mss::mcbist::program<T> iv_program;
- uint8_t iv_sim;
-};
-
-///
-/// @class Class for memdiags' super-fast init
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct sf_init_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::sf_init_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const mss::constraint structure
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- sf_init_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc):
- operation<T>(i_target, mss::mcbist::init_subtest<T>(), i_const)
- {
- // If sf_init was passed the random data pattern, then modify the subtest to use the true random data
- if(i_const.iv_pattern == PATTERN_RANDOM)
- {
- this->iv_subtest.change_data_mode(mss::mcbist::data_mode::RAND_FWD_MAINT);
- }
-
- // We're a multi-port operation
- o_rc = this->multi_port_init();
- }
-
- sf_init_operation() = delete;
-};
-
-///
-/// @class Class for memdiags' super-fast read
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct sf_read_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::sf_read_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const mss::constraint structure
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- sf_read_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc):
- operation<T>(i_target, mss::mcbist::read_subtest<T>(), i_const)
- {
- // We're a multi-port operation
- o_rc = this->multi_port_init();
- }
-
- sf_read_operation() = delete;
-};
-
-///
-/// @class Class for memdiags' super-fast read to end of port
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct sf_read_eop_operation : public operation<T>
-{
- ///
- /// @brief memdiags::sf_read_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const mss::constraint structure
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- sf_read_eop_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc ):
- operation<T>(i_target, mss::mcbist::read_subtest<T>(), i_const)
- {
- // We're a single-port operation
- o_rc = this->single_port_init();
- }
-
- sf_read_eop_operation() = delete;
-};
-
-///
-/// @class Class for memdiags' continuous scrub
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct continuous_scrub_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::continuous_scrub_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const the contraints of the operation
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- continuous_scrub_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc );
-
- continuous_scrub_operation() = delete;
-};
-
///
-/// @class Class for memdiags' targeted scrub
-/// @tparam T fapi2::TargetType of the MCBIST engine
-///
-template< fapi2::TargetType T >
-struct targeted_scrub_operation : public operation<T>
-{
-
- ///
- /// @brief memdiags::targeted_scrub_operation constructor
- /// @param[in] i_target the target of the mcbist engine
- /// @param[in] i_const the contraints of the operation
- /// @param[out] o_rc the fapi2::ReturnCode of the intialization process
- ///
- targeted_scrub_operation( const fapi2::Target<T>& i_target,
- const constraints i_const,
- fapi2::ReturnCode& o_rc ):
- operation<T>(i_target, mss::mcbist::scrub_subtest<T>(), i_const)
- {
- // Scrub operations run 128B
- this->iv_program.change_len64(mss::OFF);
-
- // 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;
-};
-
-///
-/// @brief Super Fast Init - used to init all memory behind a target with a given pattern
-/// @note Uses broadcast mode if possible
-/// @tparam T the fapi2::TargetType of the target
-/// @param[in] i_target the target behind which all memory should be initialized
-/// @param[in] i_pattern an index representing a pattern to use to init memory (defaults to 0)
-/// @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_init( const fapi2::Target<T>& i_target,
- const uint64_t i_pattern = PATTERN_0 );
-
-///
-/// @brief Start address port dimm check - helper for testing
+/// @brief Checks that the starting port/dimm address is in range for broadcast mode - helper for testing
/// @param[in] i_targets a vector of MCA targets
-/// @param[in] i_start_addr the starting port_dimm seelct address
+/// @param[in] i_start_addr the starting port_dimm select address
/// @return FAPI2_RC_SUCCESS iff okay
///
fapi2::ReturnCode broadcast_mode_start_address_check_helper(
@@ -370,82 +77,7 @@ fapi2::ReturnCode broadcast_mode_start_address_check(const fapi2::Target<fapi2::
const uint64_t i_start_addr,
std::vector< fapi2::Target<fapi2::TARGET_TYPE_DIMM> >& o_dimms);
-///
-/// @brief Super Fast Read - used to run superfast read on all memory behind the target
-/// Determines ability to braodcast to all ports behind a target, does so if possible.
-/// @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_address mcbist::address representing the address from which to start.
-// Defaults to the first address behind the target
-/// @param[in] i_end whether to end, and where
-/// Defaults to stop after slave rank
-/// @param[in] i_end_address mcbist::address representing the address to end.
-// Defaults to mcbist::address::LARGEST_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 mss::mcbist::address& i_address = mss::mcbist::address(),
- const end_boundary i_end = end_boundary::STOP_AFTER_SLAVE_RANK,
- const mss::mcbist::address& i_end_address = mss::mcbist::address(mcbist::address::LARGEST_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_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
-/// @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 background_scrub( const fapi2::Target<T>& i_target,
- const stop_conditions& i_stop,
- const speed i_speed,
- const mss::mcbist::address& i_address );
-
-///
-/// @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_speed the speed to scrub
-/// @param[in] i_start_address mcbist::address representing the address from which to start.
-/// @param[in] i_end_address mcbist::address representing the address at which to end.
-/// @param[in] i_end whether to end, and where
-/// @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 targeted_scrub( const fapi2::Target<T>& i_target,
- const stop_conditions& i_stop,
- const mss::mcbist::address& i_start_address,
- const mss::mcbist::address& i_end_address,
- const end_boundary i_end );
-
-///
-/// @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.
-/// @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 - SAME_SPEED 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::DONT_CHANGE,
- const stop_conditions& i_stop = stop_conditions(stop_conditions::DONT_CHANGE),
- const speed i_speed = speed::SAME_SPEED );
-
-} // namespace
+} // ns memdiags
-} // namespace
+} // ns mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C
deleted file mode 100644
index ef65e381a..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C
+++ /dev/null
@@ -1,146 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,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 */
-
-///
-/// @file patterns.C
-/// @brief Static definition of MCBIST patterns
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#include <fapi2.H>
-#include <vector>
-#include <lib/mcbist/patterns.H>
-
-namespace mss
-{
-
-namespace mcbist
-{
-
-/// Vector of cache lines, seaprated in to two 64B chunks
-// TK Real patterns from Marc representing the proper bits for ECC checking
-const std::vector< pattern > patterns =
-{
- // Pattern index 0 (Pattern 1 is this inverted)
- { {0x0000000000000000, 0x0000000000000000},
- {0x0000000000000000, 0x0000000000000000},
- {0x0000000000000000, 0x0000000000000000},
- {0x0000000000000000, 0x0000000000000000},
- },
-
- // Pattern index 2 (Pattern 3 is this inverted)
- { {0x5555555555555555, 0x5555555555555555},
- {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA},
- {0x5555555555555555, 0x5555555555555555},
- {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA},
- },
-
- // Pattern index 4 (Pattern 5 is this inverted)
- { {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
- {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
- {0x0000000000000000, 0x0000000000000000},
- {0x0000000000000000, 0x0000000000000000},
- },
-
- // Pattern index 6 (Pattern 7 is this inverted)
- { {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
- {0x0000000000000000, 0x0000000000000000},
- {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
- {0x0000000000000000, 0x0000000000000000},
- },
-
- // Pattern index 8 Random Seed
- { {0x1234567887654321, 0x8765432112345678},
- {0x1234567887654321, 0x8765432112345678},
- {0x1234567887654321, 0x8765432112345678},
- {0x1234567887654321, 0x8765432112345678},
- },
-
- // Pattern index 10 (Pattern 11 is this inverted), MPR pattern
- { {0x0000000000000000, 0xFFFFFFFFFFFFFFFF},
- {0x0000000000000000, 0xFFFFFFFFFFFFFFFF},
- {0x0000000000000000, 0xFFFFFFFFFFFFFFFF},
- {0x0000000000000000, 0xFFFFFFFFFFFFFFFF},
- },
-};
-
-// TK Want a new RC for random 24
-/// Vector of 24b random data seeds
-const std::vector< random24_data_seed > random24_data_seeds =
-{
- // 24 Bit Pattern index 0 (Pattern 1 is this inverted)
- { {0x010203},
- {0x040506},
- {0x070809},
- },
-
- // 24 Bit Pattern index 2 (Pattern 3 is this inverted)
- { {0x112233},
- {0x445566},
- {0x778899},
- },
-
-};
-
-/// Vector of 24b random data seed mappings
-// Not sure how many mapping we will want, for now it should be sufficient to
-// have all bytes point to a different LFSR or all bytes point to the same LFSR
-const std::vector< random24_seed_map > random24_seed_maps =
-{
- // 8 Bit Pattern index 0
- // This selection maps every data byte to a different random LFSR
- { {0x0},
- {0x1},
- {0x2},
- {0x3},
- {0x4},
- {0x5},
- {0x6},
- {0x7},
- {0x8},
- },
-
- // 8 Bit Pattern index 1
- // This selection maps every data byte to random LFSR 0
- { {0x0},
- {0x0},
- {0x0},
- {0x0},
- {0x0},
- {0x0},
- {0x0},
- {0x0},
- {0x0},
- },
-
-};
-
-}
-
-}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H
deleted file mode 100644
index b5faeeffd..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H
+++ /dev/null
@@ -1,104 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/patterns.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,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 */
-
-///
-/// @file patterns.H
-/// @brief Static definition of MCBIST patterns
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Marc Gollub <gollub@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MCBIST_PATTERNS_
-#define _MSS_MCBIST_PATTERNS_
-
-#include <vector>
-
-namespace mss
-{
-namespace mcbist
-{
-
-/// Memory diagnostic Pattern indexes.
-// Why not an enum? I want to do math on them to generate a proper index in to a vector of
-// patterns and enums really don't like that.
-// Couple of extra symbols in here to keep things easy if desired
-constexpr uint64_t PATTERN_ZEROS = 0;
-constexpr uint64_t PATTERN_0 = PATTERN_ZEROS;
-constexpr uint64_t PATTERN_ONES = 1;
-constexpr uint64_t PATTERN_1 = PATTERN_ONES;
-constexpr uint64_t PATTERN_2 = 2;
-constexpr uint64_t PATTERN_3 = 3;
-constexpr uint64_t PATTERN_4 = 4;
-constexpr uint64_t PATTERN_5 = 5;
-constexpr uint64_t PATTERN_6 = 6;
-constexpr uint64_t PATTERN_7 = 7;
-constexpr uint64_t PATTERN_8 = 8;
-constexpr uint64_t PATTERN_9 = 9;
-constexpr uint64_t PATTERN_10 = 10;
-constexpr uint64_t PATTERN_RANDOM = PATTERN_8;
-constexpr uint64_t LAST_PATTERN = PATTERN_10;
-
-// Don't mess with the patterns
-constexpr uint64_t NO_PATTERN = LAST_PATTERN + 1;
-
-//Pattern references for the 24b random data pattern seeds
-constexpr uint64_t MAX_NUM_RANDOM24_SEEDS = 3;
-constexpr uint64_t RANDOM24_SEEDS_0 = 0;
-constexpr uint64_t RANDOM24_SEEDS_1 = 1;
-constexpr uint64_t RANDOM24_SEEDS_2 = 2;
-constexpr uint64_t RANDOM24_SEEDS_3 = 3;
-constexpr uint64_t LAST_RANDOM24_SEEDS = RANDOM24_SEEDS_3;
-constexpr uint64_t NO_RANDOM24_SEEDS = LAST_RANDOM24_SEEDS + 1;
-
-//Pattern references for the 24b random data pattern seeds
-constexpr uint64_t MAX_NUM_RANDOM24_MAPS = 9;
-constexpr uint64_t RANDOM24_SEED_MAP_0 = 0;
-constexpr uint64_t RANDOM24_SEED_MAP_1 = 1;
-constexpr uint64_t LAST_RANDOM24_SEED_MAP = RANDOM24_SEED_MAP_1;
-constexpr uint64_t NO_RANDOM24_SEED_MAP = LAST_RANDOM24_SEED_MAP + 1;
-constexpr uint64_t RANDOM24_SEED_MAP_FIELD_LEN = 4;
-
-
-/// Vector of cache lines, separated in to two 64B chunks
-typedef std::pair<uint64_t, uint64_t> cache_line;
-typedef std::vector< cache_line > pattern;
-extern const std::vector< pattern > patterns;
-
-// Vector of 24b random data seeds
-typedef std::vector< uint64_t > random24_data_seed;
-extern const std::vector< random24_data_seed > random24_data_seeds;
-
-// Vector of 24b random data seed maps
-typedef std::vector< uint64_t > random24_seed_map;
-extern const std::vector< random24_seed_map > random24_seed_maps;
-
-}// mcbist
-
-}// mss
-#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 3e89ee647..da2e34d1d 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
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,759 +38,11 @@
#include <fapi2.H>
-#include <p9_mc_scom_addresses.H>
-#include <p9_mc_scom_addresses_fld.H>
+#include <lib/shared/mss_const.H>
+#include <lib/ecc/ecc_traits.H>
+#include <lib/mcbist/mcbist_traits.H>
+#include <generic/memory/lib/utils/mcbist/gen_settings.H>
-#include <lib/mcbist/address.H>
-#include <lib/utils/bit_count.H>
+// This file is still necessary to put traits and generic code together
-namespace mss
-{
-
-namespace mcbist
-{
-
-/// End boundaries for MCBIST programs - where to stop when stopping or pausing
-enum end_boundary : uint64_t
-{
- // 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 one 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
-enum speed
-{
- /// As fast as possible, often the default
- LUDICROUS = 0,
-
- /// Background scrubbing speed.
- BG_SCRUB = 1,
-
- /// Used to indicate to the continue current command to not change the speed of the commands
- SAME_SPEED = 4,
-};
-
-///
-/// @class Memory diagnostic subsystem stop-on-error settings and thresholds
-/// @note Matches Nimbus MBSTRQ, but might be changed later for Centaur, or mapped.
-///
-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 MAX_THRESHOLD = 0b1110;
- static constexpr uint64_t DONT_CHANGE = 0;
-
- private:
-
- ///
- /// @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
- ///
- 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.)
- const 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 Stop/Thresholds class ctor
- /// @param[in] uint64_t representing the threshold register contents
- ///
- stop_conditions(const uint64_t i_value):
- iv_value(i_value)
- {
- }
-
- ///
- /// @brief Stop/Thresholds class dtor
- ///
- ~stop_conditions() = default;
-
- ///
- /// @brief uint64_t conversion
- ///
- inline operator uint64_t() const
- {
- return uint64_t(iv_value);
- }
-
- ///
- /// @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
- /// @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>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @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
- /// @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>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @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
- /// @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>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @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
- /// @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>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @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
- /// @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>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @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
- /// @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>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @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
- /// @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>(make_threshold_setting(i_value));
- return *this;
- }
-
- ///
- /// @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
- /// @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>(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_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_on_sce( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_SCE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_mce
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_on_mce( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_MCE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_mpe
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_on_mpe( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_MPE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_ue
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_on_ue( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_UE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_sue
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_on_sue( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_SUE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_aue
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_on_aue( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_AUE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_on_rcd
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_on_rcd( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_ON_RCD>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @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
- /// counters for of 72 symbols Mode 1) MCBIST 4-bit error counters for 18 nibbles x 8
- /// 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 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);
- return *this;
- }
-
- ///
- /// @brief set_nce_soft_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_nce_soft_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_nce_inter_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_nce_inter_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_nce_hard_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_nce_hard_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_mcb_error
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_mcb_error( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_MCB_ERROR>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_pause_mcb_log_full
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_pause_mcb_log_full( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_PAUSE_MCB_LOG_FULL>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_maint_rce_with_ce
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_maint_rce_with_ce( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MAINT_RCE_WITH_CE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_mce_soft_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_mce_soft_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_mce_inter_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_mce_inter_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- ///
- /// @brief set_mce_hard_symbol_count_enable
- /// @param[in] i_on_or_off - the desired state.
- /// 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 stop_conditions& set_mce_hard_symbol_count_enable( const states i_on_or_off )
- {
- iv_value.writeBit<MCBIST_MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off);
- return *this;
- }
-
- private:
-
- fapi2::buffer<uint64_t> iv_value;
-};
-
-///
-/// @class memdiags operational constraints
-///
-struct constraints
-{
- ///
- /// @brief constraints default constructor
- ///
- constraints():
- iv_stop(),
- iv_pattern(NO_PATTERN),
- iv_end_boundary(NONE),
- iv_speed(LUDICROUS),
- iv_start_address(0),
- iv_end_address(mcbist::address::LARGEST_ADDRESS)
- {
- }
-
- ///
- /// @brief constraints constructor
- /// @param[in] i_pattern a pattern to set
- ///
- constraints( const uint64_t i_pattern ):
- constraints()
- {
- iv_pattern = i_pattern;
- FAPI_INF("setting up constraints with pattern %d", i_pattern);
- }
-
- ///
- /// @brief constraints constructor
- /// @param[in] i_stop stop conditions
- ///
- constraints( const stop_conditions& i_stop ):
- constraints()
- {
- iv_stop = i_stop;
- 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_start_address address to start from
- ///
- constraints( const stop_conditions& i_stop,
- const address& i_start_address ):
- constraints(i_stop)
- {
- iv_start_address = 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_speed the speed at which to run
- /// @param[in] i_end_boundary the place to stop on error
- /// @param[in] i_start_address address to start from
- /// @param[in] i_end_address address to end at (optional, run to end)
- ///
- constraints( const stop_conditions& i_stop,
- const speed i_speed,
- const end_boundary i_end_boundary,
- const address& i_start_address,
- const address& i_end_address = mcbist::address(mcbist::address::LARGEST_ADDRESS) ):
- constraints(i_stop, i_start_address)
- {
- iv_end_boundary = i_end_boundary;
- iv_speed = i_speed;
- iv_end_address = i_end_address;
-
- FAPI_INF("setting up constraints with end boundary %d and speed 0x%x", i_end_boundary, i_speed);
-
- // If our end address is 'before' our start address, make the end address the same as the start.
- if (iv_start_address > iv_end_address)
- {
- iv_end_address = iv_start_address;
- }
- }
-
- // Member variable declaration
- stop_conditions iv_stop;
- uint64_t iv_pattern;
- end_boundary iv_end_boundary;
- speed iv_speed;
- mcbist::address iv_start_address;
- mcbist::address iv_end_address;
-};
-
-
-} // namespace
-} // namespace
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C
deleted file mode 100644
index 2fa88eb98..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C
+++ /dev/null
@@ -1,175 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2019 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file mcbist/sim.C
-/// @brief MCBIST/memdiags functions for when we're in simulation mode
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#include <lib/shared/nimbus_defaults.H>
-#include <fapi2.H>
-
-#include <lib/dimm/rank.H>
-#include <lib/mcbist/address.H>
-#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/patterns.H>
-#include <lib/mcbist/sim.H>
-#include <generic/memory/lib/utils/count_dimm.H>
-#include <generic/memory/lib/utils/pos.H>
-
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_SYSTEM;
-using fapi2::FAPI2_RC_SUCCESS;
-
-namespace mss
-{
-
-namespace mcbist
-{
-
-namespace sim
-{
-
-///
-/// @brief Perform a sim version of initializing memory
-/// @param[in] i_target MCBIST
-/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template<>
-fapi2::ReturnCode sf_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- const uint64_t i_pattern )
-{
- FAPI_INF("Start sim init");
-
- // If we're running in the simulator, we want to only touch the addresses which training touched
-
- for (const auto& p : i_target.getChildren<TARGET_TYPE_MCA>())
- {
- std::vector<uint64_t> l_pr;
- mss::mcbist::program<TARGET_TYPE_MCBIST> l_program;
-
- mss::mcbist::address l_start;
- mss::mcbist::address l_end;
-
- size_t l_rank_address_pair = 0;
-
- // No point in bothering if we don't have any DIMM
- if (mss::count_dimm(p) == 0)
- {
- FAPI_INF("No DIMM on %s, not running sf_init", mss::c_str(p));
- continue;
- }
-
- // In sim we know a few things ...
- // Get the primary ranks for this port. We know there can only be 4, and we know we only trained the primary
- // ranks. Therefore, we only need to clean up the primary ranks. And because there's 4 max, we can do it
- // all using the 4 address range registers of tne MCBIST (broadcast currently not considered.)
- // So we can write 0's to those to get their ECC fixed up.
- FAPI_TRY( mss::rank::primary_ranks(p, l_pr) );
- fapi2::Assert( l_pr.size() <= mss::MAX_RANK_PER_DIMM );
-
- for (auto r = l_pr.begin(); r != l_pr.end(); ++l_rank_address_pair, ++r)
- {
- FAPI_INF("sim init %s, rank %d", mss::c_str(p), *r);
-
- // Setup l_start to represent this rank, and then make the end address from that.
- l_start.set_master_rank(*r);
-
- // Set C3 bit to get an entire cache line
- l_start.get_sim_end_address(l_end);
-
- // By default we're in maint address mode, not address counting mode. So we give it a start and end, and ignore
- // anything invalid - that's what maint address mode is all about
- mss::mcbist::config_address_range(i_target, l_start, l_end, l_rank_address_pair);
-
- // Write
- {
- // Run in ECC mode, 64B writes (superfast mode)
-
- mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fw_subtest =
- mss::mcbist::write_subtest<TARGET_TYPE_MCBIST>();
-
- l_fw_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_fw_subtest.change_addr_sel(l_rank_address_pair);
- l_fw_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r));
- l_program.iv_subtests.push_back(l_fw_subtest);
- FAPI_DBG("adding superfast write for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r));
- }
-
- // Read - we do a read here as verification can use this as a tool as we do the write and then the read.
- // If we failed to write properly the read would thow ECC errors. Just a write (which the real hardware would
- // do) doesn't catch that. This takes longer, but it's not terribly long in any event.
- {
- // Run in ECC mode, 64B writes (superfast mode)
- mss::mcbist::subtest_t<TARGET_TYPE_MCBIST> l_fr_subtest =
- mss::mcbist::read_subtest<TARGET_TYPE_MCBIST>();
-
- l_fr_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_fr_subtest.change_addr_sel(l_rank_address_pair);
- l_fr_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r));
- l_program.iv_subtests.push_back(l_fr_subtest);
- FAPI_DBG("adding superfast read for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r));
- }
- }
-
- // Write pattern
- FAPI_TRY( mss::mcbist::load_pattern(i_target, i_pattern) );
-
- // Setup the sim polling based on a heuristic <cough>guess</cough>
- // Looks like ~400ck per address for a write/read program on the sim-dimm, and add a long number of polls
- // On real hardware wait 100ms and then start polling for another 5s
- l_program.iv_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(((l_end - l_start) * l_pr.size()) * 800);
- l_program.iv_poll.iv_initial_delay = 100 * mss::DELAY_1MS;
- l_program.iv_poll.iv_sim_delay = 100000;
- l_program.iv_poll.iv_delay = 10 * mss::DELAY_1MS;
- l_program.iv_poll.iv_poll_count = 500;
-
- // Just one port for now. Per Shelton we need to set this in maint address mode
- // even tho we specify the port/dimm in the subtest.
- fapi2::buffer<uint8_t> l_port;
- l_port.setBit(mss::relative_pos<TARGET_TYPE_MCBIST>(p));
- l_program.select_ports(l_port >> 4);
-
- // Kick it off, wait for a result
- FAPI_TRY( mss::mcbist::execute(i_target, l_program) );
- }
-
-fapi_try_exit:
- FAPI_INF("End sim init");
- return fapi2::current_err;
-}
-
-} // namespace sim
-
-} // namespace mcbist
-
-} // namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H
deleted file mode 100644
index 5e8291a21..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H
+++ /dev/null
@@ -1,64 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,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 */
-
-///
-/// @file mcbist/sim.H
-/// @brief MCBIST/memdiags functions for when we're in simulation mode
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#ifndef _MSS_MCBIST_SIM_H_
-#define _MSS_MCBIST_SIM_H_
-
-#include <fapi2.H>
-
-namespace mss
-{
-
-namespace mcbist
-{
-
-namespace sim
-{
-
-///
-/// @brief Perform a sim version of initializing memory
-/// @param T a fapi2::TargetType
-/// @param[in] i_target
-/// @param[in] i_pattern an index representing a pattern to use to initize memory (defaults to 0)
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode sf_init( const fapi2::Target<T>& i_target, const uint64_t i_pattern );
-
-} // ns sim
-} // ns mcbist
-} // ns mss
-#endif
-
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
index 88337c26c..792e89fb2 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
@@ -58,7 +58,7 @@
#include <generic/memory/lib/utils/find_magic.H>
#include <generic/memory/lib/utils/bit_count.H>
#include <generic/memory/lib/utils/find.H>
-#include <lib/utils/dump_regs.H>
+#include <generic/memory/lib/utils/dump_regs.H>
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/dimm/rank.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
index bf84c1662..5f175b44c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
@@ -51,7 +51,6 @@ enum sizes
MC_PER_MODULE = 2,
MCBIST_PER_MC = 1,
MAX_DIMM_PER_PORT = 2,
- MAX_RANK_PER_DIMM = 4,
PORTS_PER_MODULE = MC_PER_MODULE * MCS_PER_MC * PORTS_PER_MCS,
BITS_PER_DP = 16,
NIBBLES_PER_DP = BITS_PER_DP / BITS_PER_NIBBLE,
@@ -75,10 +74,6 @@ enum sizes
ROW_REPAIR_BYTE_COUNT = 4, ///< Elements in a ROW_REPAIR_DATA attribute array.
- BYTES_PER_GB = 1000000000, ///< Multiplier to go from GB to B
- T_PER_MT = 1000000, ///< Multiplier to go from MT/s to T/s
- CYCLES_PER_CMD = 4, ///< Best case cycles per MCBIST command
-
// All need to be attributes? - BRS
WR_LVL_BIG_STEP = 0b0111,
WR_LVL_SMALL_STEP = 0b000,
@@ -100,10 +95,6 @@ enum sizes
// Largest size a VPD keyword can be
VPD_KEYWORD_MAX = 255,
- // Number of double words in...
- NUM_DW_IN_128B = 16,
- NUM_DW_IN_64B = 8,
-
// MCBIST polling constant for actual HW
// The specific value here is not important, only that it is very large to avoid polling timeouts,
// but not to avoid any actual hardware timeouts
@@ -116,10 +107,6 @@ enum sizes
enum times
{
// Not *exactly* a time but go with i
- BG_SCRUB_IN_HOURS = 12,
-
- CMD_TIMEBASE = 8192, ///< Represents the timebase multiplier for the MCBIST inter cmd gap
- MAX_CMD_GAP = 4095, ///< Represents the maximum (non-multplied) time for MCBIST inter cmd gap
FULL_DLL_CAL_DELAY = 37382, ///< Full DLL calibration (in ddphy_nck cycles)
};
@@ -324,168 +311,6 @@ enum min_max_domains : uint64_t
MAX1_MIN0 = 0b100,
};
-namespace mcbist
-{
-
-enum broadcast_timebase
-{
- // Number of 1024 2:1 cycle timebases to wait starting MCBIST
- // for SRQs to get synced for broadcast mode
- TB_COUNT_2 = 0b0000001,
- TB_COUNT_4 = 0b0000011,
- TB_COUNT_8 = 0b0000111,
- TB_COUNT_16 = 0b0001111,
- TB_COUNT_32 = 0b0011111,
- TB_COUNT_64 = 0b0111111,
- TB_COUNT_128 = 0b1111111,
-};
-
-enum rmw_address
-{
- // 32B block addresses into the maint portion of the rmw buffer
- DW0 = 0b111110000,
- DW1 = 0b111110001,
- DW2 = 0b111110010,
- DW3 = 0b111110011,
- DW4 = 0b111110100,
- DW5 = 0b111110101,
- DW6 = 0b111110110,
- DW7 = 0b111110111,
- DW8 = 0b111111000,
- DW9 = 0b111111001,
- DWA = 0b111111010,
- DWB = 0b111111011,
- DWC = 0b111111100,
- DWD = 0b111111101,
- DWE = 0b111111110,
- DWF = 0b111111111,
-};
-
-enum data_rotate_mode
-{
- // MCBIST data rotate modes refer to register MCBDRCR bits 0:3
- ROTATE_0_BITS = 0b0000,
- ROTATE_1_BITS = 0b0001,
- ROTATE_2_BITS = 0b0010,
- ROTATE_3_BITS = 0b0011,
- ROTATE_4_BITS = 0b0100,
- ROTATE_5_BITS = 0b0101,
- ROTATE_6_BITS = 0b0110,
- ROTATE_7_BITS = 0b0111,
- ROTATE_8_BITS = 0b1000,
- ROTATE_9_BITS = 0b1001,
- ROTATE_10_BITS = 0b1010,
- ROTATE_11_BITS = 0b1011,
- ROTATE_12_BITS = 0b1100,
- ROTATE_13_BITS = 0b1101,
- ROTATE_14_BITS = 0b1110,
- ROTATE_15_BITS = 0b1111,
-};
-
-enum data_seed_mode
-{
- // MCBIST data seed modes refer to register MCBDRCR bits 21:22
- ALL_UNIQUE = 0b00,
- REPEAT_SEED_0 = 0b01,
- REPEAT_SEED_1 = 0b10,
- REPEAT_SEED_2 = 0b11,
-};
-
-enum data_mode
-{
- // MCBIST test data modes
- FIXED_DATA_MODE = 0b000,
- RAND_FWD_MODE = 0b001,
- RAND_REV_MODE = 0b010,
- RAND_FWD_MAINT = 0b011,
- RAND_REV_MAINT = 0b100,
- DATA_EQ_ADDR = 0b101,
- ROTATE_LEFT_MODE = 0b110,
- ROTATE_RIGHT_MODE = 0b111,
-};
-
-// 0:3 Operation Type
-enum op_type
-{
- WRITE = 0b0000, // fast, with no concurrent traffic
- READ = 0b0001, // fast, with no concurrent traffic
- READ_WRITE = 0b0010,
- WRITE_READ = 0b0011,
- READ_WRITE_READ = 0b0100,
- READ_WRITE_WRITE = 0b0101,
- RAND_SEQ = 0b0110,
- READ_READ_WRITE = 0b1000,
- SCRUB_RRWR = 0b1001,
- STEER_RW = 0b1010,
- ALTER = 0b1011, // (W)
- DISPLAY = 0b1100, // (R, slow)
- CCS_EXECUTE = 0b1111,
-
- // if bits 9:11 (Data Mode bits) = 000 (bits 4:8 used to specify which subtest to go to)
- // Refresh only cmd if bits 9:11 (Data Mode bits) /= 000
- GOTO_SUBTEST_N = 0b0111,
-};
-
-
-enum test_type
-{
- USER_MODE = 0,
- CENSHMOO = 1,
- SUREFAIL = 2,
- MEMWRITE = 3,
- MEMREAD = 4,
- CBR_REFRESH = 5,
- MCBIST_SHORT = 6,
- SHORT_SEQ = 7,
- DELTA_I = 8,
- DELTA_I_LOOP = 9,
- SHORT_RAND = 10,
- LONG1 = 11,
- BUS_TAT = 12,
- SIMPLE_FIX = 13,
- SIMPLE_RAND = 14,
- SIMPLE_RAND_2W = 15,
- SIMPLE_RAND_FIXD = 16,
- SIMPLE_RA_RD_WR = 17,
- SIMPLE_RA_RD_R = 18,
- SIMPLE_RA_FD_R = 19,
- SIMPLE_RA_FD_R_INF = 20,
- SIMPLE_SA_FD_R = 21,
- SIMPLE_RA_FD_W = 22,
- INFINITE = 23,
- WR_ONLY = 24,
- W_ONLY = 25,
- R_ONLY = 26,
- W_ONLY_RAND = 27,
- R_ONLY_RAND = 28,
- R_ONLY_MULTI = 29,
- SHORT = 30,
- SIMPLE_RAND_BARI = 31,
- W_R_INFINITE = 32,
- W_R_RAND_INFINITE = 33,
- R_INFINITE1 = 34,
- R_INFINITE_RF = 35,
- MARCH = 36,
- SIMPLE_FIX_RF = 37,
- SHMOO_STRESS = 38,
- SIMPLE_RAND_RA = 39,
- SIMPLE_FIX_RA = 40,
- SIMPLE_FIX_RF_RA = 41,
- TEST_RR = 42,
- TEST_RF = 43,
- W_ONLY_INFINITE_RAND = 44,
- MCB_2D_CUP_SEQ = 45,
- MCB_2D_CUP_RAND = 46,
- SHMOO_STRESS_INFINITE = 47,
- HYNIX_1_COL = 48,
- RMWFIX = 49,
- RMWFIX_I = 50,
- W_INFINITE = 51,
- R_INFINITE = 52,
-};
-
-
-} // namespace mcbist
enum class shmoo_edge : std::size_t
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H
deleted file mode 100644
index 1154694e9..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H
+++ /dev/null
@@ -1,54 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/dump_regs.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,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 */
-
-///
-/// @file dump_regs.H
-/// @brief Dump registers
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-#ifndef _MSS_DUMP_REGS_H_
-#define _MSS_DUMP_REGS_H_
-
-#include <fapi2.H>
-
-namespace mss
-{
-
-///
-/// @brief Dump the registers of a target
-/// @tparam T, the fapi2::TargetType
-/// @param[in] i_target the target in question
-/// @return fapi2::FAPI2_RC_SUCCESS if ok
-///
-template< fapi2::TargetType T >
-fapi2::ReturnCode dump_regs( const fapi2::Target<T>& i_target );
-
-}
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H
deleted file mode 100644
index 051aa214b..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H
+++ /dev/null
@@ -1,55 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/num.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,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 */
-
-///
-/// @file num.H
-/// @brief Miscellaneous number checking functions
-///
-// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-#ifndef _MSS_NUM_H_
-#define _MSS_NUM_H_
-
-namespace mss
-{
-
-///
-/// @brief Return whether or not a number is odd
-/// @param[in] i_number the number to check
-/// @return true if i_number is odd
-///
-template< typename T >
-constexpr bool is_odd(const T i_number)
-{
- return (i_number & 0x1);
-}
-
-
-}
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
index 9316abaa5..1dea8b2c9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C
@@ -66,9 +66,9 @@ namespace mcbist
/// @param[in,out] the MCBIST program to check for read/display replacement
/// @note Useful for testing
///
-void replace_read_helper(mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program)
+void replace_read_helper(mss::mcbist::program<>& io_program)
{
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
+ using TT = mss::mcbistTraits<>;
io_program.change_maint_broadcast_mode(mss::OFF);
io_program.change_end_boundary(mss::mcbist::end_boundary::STOP_AFTER_ADDRESS);
@@ -99,9 +99,9 @@ void replace_read_helper(mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program)
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode end_of_rank( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
- mss::mcbist::program<TARGET_TYPE_MCBIST>& io_program )
+ mss::mcbist::program<>& io_program )
{
- using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>;
+ using TT = mss::mcbistTraits<>;
// If we don't need the mcbist work-around, we're done.
if (! mss::chip_ec_feature_mcbist_end_of_rank(i_target) )
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
index 1e5d9662a..166ecb20f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,7 +55,7 @@ namespace mcbist
/// @param[in] the MCBIST program to check for read/display replacement
/// @note Useful for testing
///
-void replace_read_helper(mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_program);
+void replace_read_helper(mss::mcbist::program<>& i_program);
///
/// @brief End of rank work around
@@ -69,7 +69,7 @@ void replace_read_helper(mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_prog
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode end_of_rank( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
- mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_program );
+ mss::mcbist::program<>& i_program );
///
/// @brief WAT debug attention
diff --git a/src/import/chips/p9/procedures/hwp/memory/mss.H b/src/import/chips/p9/procedures/hwp/memory/mss.H
index f8c5dabf9..7ef9b9c8c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/mss.H
+++ b/src/import/chips/p9/procedures/hwp/memory/mss.H
@@ -52,7 +52,7 @@
#include <generic/memory/lib/utils/index.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <lib/utils/num.H>
+#include <generic/memory/lib/utils/num.H>
#include <generic/memory/lib/utils/pos.H>
#include <generic/memory/lib/utils/buffer_ops.H>
@@ -60,7 +60,7 @@
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/poll.H>
#include <lib/utils/checker.H>
-#include <lib/utils/dump_regs.H>
+#include <generic/memory/lib/utils/dump_regs.H>
#include <lib/ccs/ccs.H>
#include <lib/mcbist/mcbist.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C
index aaf7b6195..06e15b95b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_background_scrub.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,9 +40,8 @@
#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_patterns.H>
#include <lib/mcbist/memdiags.H>
-#include <lib/mcbist/sim.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/fir/memdiags_fir.H>
@@ -77,7 +76,7 @@ fapi2::ReturnCode p9_mss_background_scrub( const fapi2::Target<TARGET_TYPE_MCBIS
{
// Start background scrub
FAPI_TRY ( mss::memdiags::background_scrub( i_target,
- mss::mcbist::stop_conditions(),
+ mss::mcbist::stop_conditions<>(),
mss::mcbist::speed::BG_SCRUB,
mss::mcbist::address() ) );
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 150f725a3..33efe93b5 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
@@ -42,11 +42,10 @@
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/mcbist/address.H>
-#include <lib/mcbist/patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_patterns.H>
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/mcbist.H>
#include <lib/mc/port.H>
-#include <lib/mcbist/sim.H>
#include <lib/ecc/ecc.H>
#include <lib/fir/memdiags_fir.H>
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 b6845295e..6ba472549 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
@@ -40,9 +40,8 @@
#include <lib/dimm/rank.H>
#include <lib/mcbist/address.H>
#include <lib/mcbist/mcbist.H>
-#include <lib/mcbist/patterns.H>
+#include <generic/memory/lib/utils/mcbist/gen_patterns.H>
#include <lib/mcbist/memdiags.H>
-#include <lib/mcbist/sim.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/fir/memdiags_fir.H>
@@ -133,7 +132,7 @@ fapi2::ReturnCode p9_mss_scrub( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targe
// Start background scrub
FAPI_TRY ( mss::memdiags::background_scrub( i_target,
- mss::mcbist::stop_conditions(),
+ mss::mcbist::stop_conditions<>(),
mss::mcbist::speed::BG_SCRUB,
mss::mcbist::address() ) );
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
index 0d7d6c791..f92597389 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
@@ -349,16 +349,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_MCBIST_PROGRAM_TOO_BIG</rc>
- <description>MCBIST program larger than currently supported size</description>
- <ffdc>PROGRAM_LENGTH</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_APB_INVALID_ADDRESS</rc>
<description>PHY APB interface is reporting an invalid address was read or written</description>
<ffdc>PORT_POSITION</ffdc>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml
index b18d42520..fb9567e9c 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_memdiags.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -115,15 +115,6 @@
</callout>
</hwpError>
- <hwpError>
- <rc>RC_MSS_MEMDIAGS_INVALID_PATTERN_INDEX</rc>
- <description>An invalid pattern index was passed to the pattern loader</description>
- <ffdc>INDEX</ffdc>
- <callout>
- <procedure>CODE</procedure>
- <priority>HIGH</priority>
- </callout>
- </hwpError>
<hwpError>
<rc>RC_MSS_MEMDIAGS_ERROR_CHANGING_RANDOM_SEED</rc>
OpenPOWER on IntegriCloud