From 03fc49941aa7e1a35183bf367e55d202cf1aff40 Mon Sep 17 00:00:00 2001 From: Alvin Wang Date: Tue, 7 May 2019 10:12:40 +0800 Subject: Add trap_adress class in mcbist library Change-Id: I5f078adb708128629e9e0c4a776cc32387cf84c8 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77095 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Louis Stermole Reviewed-by: STEPHEN GLANCY Tested-by: Hostboot CI Tested-by: HWSV CI Reviewed-by: Thi N. Tran Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77105 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Christian R. Geddes --- .../generic/memory/lib/utils/mcbist/gen_address.H | 571 -------------- .../memory/lib/utils/mcbist/gen_mss_mcbist.H | 16 +- .../lib/utils/mcbist/gen_mss_mcbist_address.H | 672 +++++++++++++++++ .../lib/utils/mcbist/gen_mss_mcbist_patterns.C | 122 +++ .../lib/utils/mcbist/gen_mss_mcbist_patterns.H | 79 ++ .../lib/utils/mcbist/gen_mss_mcbist_settings.H | 791 ++++++++++++++++++++ .../lib/utils/mcbist/gen_mss_mcbist_traits.H | 2 +- .../memory/lib/utils/mcbist/gen_mss_memdiags.H | 8 +- .../generic/memory/lib/utils/mcbist/gen_patterns.C | 146 ---- .../generic/memory/lib/utils/mcbist/gen_patterns.H | 103 --- .../generic/memory/lib/utils/mcbist/gen_settings.H | 816 --------------------- src/import/generic/memory/lib/utils/mss_rank.H | 6 +- 12 files changed, 1677 insertions(+), 1655 deletions(-) delete mode 100644 src/import/generic/memory/lib/utils/mcbist/gen_address.H delete mode 100644 src/import/generic/memory/lib/utils/mcbist/gen_patterns.C delete mode 100644 src/import/generic/memory/lib/utils/mcbist/gen_patterns.H delete mode 100644 src/import/generic/memory/lib/utils/mcbist/gen_settings.H (limited to 'src/import/generic') diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_address.H b/src/import/generic/memory/lib/utils/mcbist/gen_address.H deleted file mode 100644 index ca95feb71..000000000 --- a/src/import/generic/memory/lib/utils/mcbist/gen_address.H +++ /dev/null @@ -1,571 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_address.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 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 gen_address.H -/// @brief Class for mcbist related addresses (addresses below the hash translation) -/// -// *HWP HWP Owner: Stephen Glancy -// *HWP HWP Backup: Andre Marin -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -#ifndef _GEN_MSS_MCBIST_ADDRESS_H_ -#define _GEN_MSS_MCBIST_ADDRESS_H_ - -#include -#include - - -namespace mss -{ - -// Forward declaration - -/// -/// @class mcbistMCTraits -/// @tparam MC the mc type -/// @brief A MC to MC_TARGET_TYPE mapping -/// -template< mss::mc_type MC > -class mcbistMCTraits; - -/// -/// @class mcbistTraits -/// @tparam MC the mc type of the T -/// @tparam T the fapi2::TargetType - derived -/// @brief a collection of traits associated with the MCBIST engine or hardware -/// -template< mss::mc_type MC, fapi2::TargetType T > -class mcbistTraits; - -namespace ecc -{ - -namespace fwms -{ - -/// -/// @class address -/// @brief Converts Firmware Mark Store ADDRESS field into mcbist::address -/// @tparam MC the mc type of the T -/// @tparam T fapi2 Target Type defaults to fapi2::TARGET_TYPE_MCA or TARGET_TYPE_MEM_PORT -/// @tparam TT traits type defaults to eccTraits -/// @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< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits > -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 -{ - public: - - // How far over we shift to align the address in either the register or a buffer - static constexpr uint64_t MAGIC_PAD = 26; - - // first is the start bit of the field, second is the length - using field = std::pair; - - 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; - - /// - /// @brief default ctor - /// - address() = default; - - // 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 - /// TODO: Exploer trap address format is different from the mcbist::address format. Need to implement it for Explorer - address( const uint64_t i_value ): - iv_address(i_value << MAGIC_PAD) - { - } - - /// - /// @brief Construct an address from an ecc::fwms::address - /// @tparam MC the mc type - /// @param[in] i_address representing an address field from a firmware mark store register - /// - template< mss::mc_type MC = DEFAULT_MC_TYPE > - address( const ecc::fwms::address& i_address ) - { - fapi2::buffer l_value = uint64_t(i_address); - uint64_t l_temp = 0; - l_value.extractToRight::DIMM.first, ecc::fwms::address::DIMM.second>(l_temp); - this->set_field(l_temp); - l_value.extractToRight::MRANK.first, ecc::fwms::address::MRANK.second>(l_temp); - this->set_field(l_temp); - l_value.extractToRight::SRANK.first, ecc::fwms::address::SRANK.second>(l_temp); - this->set_field(l_temp); - l_value.extractToRight::BANK_GROUP.first, ecc::fwms::address::BANK_GROUP.second>(l_temp); - this->set_field(l_temp); - l_value.extractToRight::BANK.first, ecc::fwms::address::BANK.second>(l_temp); - this->set_field(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(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(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(); - } - - - /// - /// @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. - // TODO: this will have to change for explorer. it's algorithm dependent. - // we'll need to talk to the microchip about this - constexpr uint64_t l_magic_sim_number = 0b1000000; - - get_range(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(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(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(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(); - } - - /// - /// @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(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(); - } - - /// - /// @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 i_value ) - { - uint64_t l_read_port = 0; - - i_value.extractToRight(l_read_port); - return set_dimm(i_value.getBit()).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 l_value; - - l_value.insertFromRight(get_port()); - l_value.writeBit(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(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(); - } - - - /// - /// @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(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(); - } - - - /// - /// @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(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(); - } - - - /// - /// @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(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(); - } - - - /// - /// @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(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(); - } - - /// - /// @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(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(); - } - - private: - // We use a fapi2 buffer as it has static compile-time support - fapi2::buffer iv_address; -}; - -} // close namespace mcbist - -// Documented above in its declaration. -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -class ecc::fwms::address -{ - public: - // first is the start bit of the field, second is the length - using field = std::pair; - - 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(i_mcbist_address.get_field()); - iv_value.insertFromRight(i_mcbist_address.get_field()); - iv_value.insertFromRight(i_mcbist_address.get_field()); - iv_value.insertFromRight - (i_mcbist_address.get_field()); - iv_value.insertFromRight(i_mcbist_address.get_field()); - } - - /// - /// @brief Conversion operator to uint64_t - /// - inline operator uint64_t() const - { - uint64_t l_temp = 0; - iv_value.extract(l_temp); - return l_temp; - } - - private: - fapi2::buffer iv_value; -}; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address::DIMM; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address::MRANK; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address::SRANK; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address::BANK_GROUP; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address::BANK; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address::LAST_VALID; - -} // close namespace mss - -#endif diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H index 3b8b68b83..6ac15c3c3 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H @@ -40,8 +40,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -340,11 +340,7 @@ class subtest_t /// inline void enable_dimm( const uint64_t i_dimm ) { - if (TT::MULTI_DIMMS == mss::states::YES) - { - iv_mcbmr.template writeBit(i_dimm); - } - + iv_mcbmr.template writeBit(i_dimm); return; } @@ -372,10 +368,8 @@ class subtest_t /// inline uint64_t get_dimm() const { - if (TT::MULTI_DIMMS == mss::states::YES) - { - return iv_mcbmr.template getBit() ? 1 : 0; - } + + return iv_mcbmr.template getBit() ? 1 : 0; return 0; } diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H index bd90b1a19..b87cacba1 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H @@ -22,3 +22,675 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file gen_mss_mcbist_address.H +/// @brief Class for mcbist related addresses (addresses below the hash translation) +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _GEN_MSS_MCBIST_ADDRESS_H_ +#define _GEN_MSS_MCBIST_ADDRESS_H_ + +#include +#include + + +namespace mss +{ + +// Forward declaration + +/// +/// @class mcbistMCTraits +/// @tparam MC the mc type +/// @brief A MC to MC_TARGET_TYPE mapping +/// +template< mss::mc_type MC > +class mcbistMCTraits; + +/// +/// @class mcbistTraits +/// @tparam MC the mc type of the T +/// @tparam T the fapi2::TargetType - derived +/// @brief a collection of traits associated with the MCBIST engine or hardware +/// +template< mss::mc_type MC, fapi2::TargetType T > +class mcbistTraits; + +namespace ecc +{ + +/// +/// @class trap_address +/// @brief Converts trap address into mcbist::address +/// @tparam MC the mc type of the T +/// @tparam T fapi2 Target Type defaults to fapi2::TARGET_TYPE_MCA or TARGET_TYPE_MEM_PORT +/// @tparam TT traits type defaults to eccTraits +/// +// See declaration below +template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits > +class trap_address; + +namespace fwms +{ + +/// +/// @class address +/// @brief Converts Firmware Mark Store ADDRESS field into mcbist::address +/// @tparam MC the mc type of the T +/// @tparam T fapi2 Target Type defaults to fapi2::TARGET_TYPE_MCA or TARGET_TYPE_MEM_PORT +/// @tparam TT traits type defaults to eccTraits +/// @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< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits > +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 +{ + public: + + // How far over we shift to align the address in either the register or a buffer + static constexpr uint64_t MAGIC_PAD = 26; + + // first is the start bit of the field, second is the length + using field = std::pair; + + 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; + + /// + /// @brief default ctor + /// + address() = default; + + // 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 + /// @param[in] i_value representing an address + /// + address( const uint64_t i_value ): + iv_address(i_value << MAGIC_PAD) + { + } + + /// + /// @brief Construct an address from an ecc::trap_address + /// @tparam MC the mc type + /// @param[in] i_address representing an address field from a trap address + /// + template< mss::mc_type MC = DEFAULT_MC_TYPE > + address( const ecc::trap_address& i_address ) + { + this->set_field(i_address.get_field::PORT>()); + this->set_field(i_address.get_field::DIMM>()); + this->set_field(i_address.get_field::MRANK>()); + this->set_field(i_address.get_field::SRANK>()); + this->set_field(i_address.get_field::ROW>()); + this->set_field(i_address.get_field::COL>()); + this->set_field(i_address.get_field::BANK>()); + this->set_field(i_address.get_field::BANK_GROUP>()); + } + + /// + /// @brief Construct an address from an ecc::fwms::address + /// @tparam MC the mc type + /// @param[in] i_address representing an address field from a firmware mark store register + /// + template< mss::mc_type MC = DEFAULT_MC_TYPE > + address( const ecc::fwms::address& i_address ) + { + this->set_field(i_address.get_field::DIMM>()); + this->set_field(i_address.get_field::MRANK>()); + this->set_field(i_address.get_field::SRANK>()); + this->set_field(i_address.get_field::BANK_GROUP>()); + this->set_field(i_address.get_field::BANK>()); + } + + /// + /// @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(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(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(); + } + + + /// + /// @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. + // TODO: this will have to change for explorer. it's algorithm dependent. + // we'll need to talk to the microchip about this + constexpr uint64_t l_magic_sim_number = 0b1000000; + + get_range(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(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(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(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(); + } + + /// + /// @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(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(); + } + + /// + /// @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 i_value ) + { + uint64_t l_read_port = 0; + + i_value.extractToRight(l_read_port); + return set_dimm(i_value.getBit()).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 l_value; + + l_value.insertFromRight(get_port()); + l_value.writeBit(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(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(); + } + + + /// + /// @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(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(); + } + + + /// + /// @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(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(); + } + + + /// + /// @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(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(); + } + + + /// + /// @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(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(); + } + + /// + /// @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(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(); + } + + private: + // We use a fapi2 buffer as it has static compile-time support + fapi2::buffer iv_address; +}; + +} // close namespace mcbist + +// Documented above in its declaration. +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +class ecc::fwms::address +{ + public: + // first is the start bit of the field, second is the length + using field = std::pair; + + 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}; + + 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(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight + (i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + } + + /// + /// @brief Conversion operator to uint64_t + /// + inline operator uint64_t() const + { + uint64_t l_temp = 0; + iv_value.extract(l_temp); + return l_temp; + } + + /// + /// @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_value.extractToRight(l_value); + return l_value; + } + + private: + fapi2::buffer iv_value; + +}; + +using field = std::pair; +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address::DIMM; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address::MRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address::SRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address::BANK_GROUP; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address::BANK; + +// Documented above in its declaration. +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +class ecc::trap_address +{ + public: + // first is the start bit of the field, second is the length + using field = std::pair; + + constexpr static field PORT = {TT::TRAP_ADDRESS_PORT, TT::TRAP_ADDRESS_PORT_LEN}; + constexpr static field DIMM = {TT::TRAP_ADDRESS_DIMM, TT::TRAP_ADDRESS_DIMM_LEN}; + constexpr static field MRANK = {TT::TRAP_ADDRESS_MRANK, TT::TRAP_ADDRESS_MRANK_LEN}; + constexpr static field SRANK = {TT::TRAP_ADDRESS_SRANK, TT::TRAP_ADDRESS_SRANK_LEN}; + constexpr static field ROW = {TT::TRAP_ADDRESS_ROW, TT::TRAP_ADDRESS_ROW_LEN}; + constexpr static field COL = {TT::TRAP_ADDRESS_COL, TT::TRAP_ADDRESS_COL_LEN}; + constexpr static field BANK = {TT::TRAP_ADDRESS_BANK, TT::TRAP_ADDRESS_BANK_LEN}; + constexpr static field BANK_GROUP = {TT::TRAP_ADDRESS_BANK_GROUP, TT::TRAP_ADDRESS_BANK_GROUP_LEN}; + + trap_address() = default; + + /// + /// @brief Construct an address from a uint64_t (scom'ed value) + /// @param[in] i_value representing raw value from FWMS register + /// + trap_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::trap_address + /// @note located in mcbist::address class + /// + trap_address( const mcbist::address& i_mcbist_address ) + { + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight(i_mcbist_address.get_field()); + iv_value.insertFromRight + (i_mcbist_address.get_field()); + } + + /// + /// @brief Conversion operator to uint64_t + /// + inline operator uint64_t() const + { + uint64_t l_temp = 0; + iv_value.extract(l_temp); + return l_temp; + } + + /// + /// @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_value.extractToRight(l_value); + return l_value; + } + + private: + fapi2::buffer iv_value; +}; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::PORT; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::DIMM; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::MRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::SRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::ROW; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::COL; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::BANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address::BANK_GROUP; + +} // close namespace mss + +#endif diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C index 49ba731a4..81988c3d9 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.C @@ -22,3 +22,125 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + + +/// +/// @file gen_mss_mcbist_patterns.C +/// @brief Static definition of MCBIST patterns +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include + +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}, + }, + +}; + +} //namespace mcbist +} //namespace mss diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H index e0ac2c5fd..cfb4a532d 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H @@ -22,3 +22,82 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file gen_mss_mcbist_patterns.H +/// @brief Static definition of MCBIST patterns +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_GEN_MCBIST_PATTERNS_ +#define _MSS_GEN_MCBIST_PATTERNS_ + +#include + +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 +using cache_line = std::pair ; +using pattern = std::vector< cache_line > ; +extern const std::vector< pattern > patterns; + +// Vector of 24b random data seeds +using random24_data_seed = std::vector< uint64_t > ; +extern const std::vector< random24_data_seed > random24_data_seeds; + +// Vector of 24b random data seed maps +using random24_seed_map = std::vector< uint64_t >; +extern const std::vector< random24_seed_map > random24_seed_maps; + +}// mcbist + +}// mss +#endif diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H index 6c9575bf1..6f570fbad 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H @@ -22,3 +22,794 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file gen_mss_mcbist_settings.H +/// @brief MCBIST settings, like stop conditions, thresholds, etc +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _GEN_MSS_MCBIST_SETTINGS_H_ +#define _GEN_MSS_MCBIST_SETTINGS_H_ + +#include + +#include +#include +#include +#include + +namespace mss +{ + +namespace mcbist +{ +/// +/// @brief 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, +}; + +/// +/// @brief 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 +/// @tparam MC the mc type of the T +/// @tparam T the fapi2::TargetType - derived +/// @tparam TT the mcbistTraits associated with T - derived +/// @note Matches Nimbus MBSTRQ, but might be changed later for Centaur, or mapped. +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits::MC_TARGET_TYPE , typename TT = mss::mcbistTraits > +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& 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(DISABLE); + return *this; + } + + uint64_t l_thresh = 0; + iv_value.extractToRight(l_thresh); + + if (l_thresh == DISABLE) + { + // Note the threshold field is an exponent, so this is 2^0, or 1 count + iv_value.insertFromRight(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_on_sce( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_on_mce( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_on_mpe( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_on_ue( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_on_sue( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_on_aue( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_on_rcd( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_symbol_counter_mode( const uint64_t i_value ) + { + iv_value.insertFromRight(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& 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(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& 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(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& 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(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_mcb_error( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_pause_mcb_log_full( const states i_on_or_off ) + { + iv_value.writeBit(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& this->iv_value useful for method chaining + /// + inline stop_conditions& set_maint_rce_with_ce( const states i_on_or_off ) + { + iv_value.writeBit(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& 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(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& 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(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& 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(i_on_or_off); + return *this; + } + + private: + + fapi2::buffer iv_value; +}; + +template< mss::mc_type MC, fapi2::TargetType T, typename TT> +constexpr uint64_t stop_conditions::DISABLE; + +template< mss::mc_type MC, fapi2::TargetType T, typename TT> +constexpr uint64_t stop_conditions::MAX_THRESHOLD; + +template< mss::mc_type MC, fapi2::TargetType T, typename TT> +constexpr uint64_t stop_conditions::DONT_CHANGE; + +/// +/// @class memdiags operational constraints +/// @tparam MC the mc type of the T +/// @tparam T the fapi2::TargetType - derived +/// @tparam TT the mcbistTraits associated with T - derived +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits::MC_TARGET_TYPE , typename TT = mcbistTraits > +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(TT::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(TT::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/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H index 72efa0f3d..cd0bc5163 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H @@ -39,7 +39,7 @@ #include #include -#include +#include namespace mss { diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H index 6e3ceb03f..7464675a5 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_memdiags.H @@ -24,7 +24,7 @@ /* IBM_PROLOG_END_TAG */ /// -/// @file memdiags.H +/// @file gen_mss_memdiags.H /// @brief API for memory diagnostics /// // *HWP HWP Owner: Stephen Glancy @@ -41,9 +41,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.C b/src/import/generic/memory/lib/utils/mcbist/gen_patterns.C deleted file mode 100644 index 95f9aaba1..000000000 --- a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.C +++ /dev/null @@ -1,146 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_patterns.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 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 gen_patterns.C -/// @brief Static definition of MCBIST patterns -/// -// *HWP HWP Owner: Stephen Glancy -// *HWP HWP Backup: Andre Marin -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: FSP:HB - -#include -#include -#include - -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}, - }, - -}; - -} //namespace mcbist -} //namespace mss diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.H b/src/import/generic/memory/lib/utils/mcbist/gen_patterns.H deleted file mode 100644 index ba4ca5c2e..000000000 --- a/src/import/generic/memory/lib/utils/mcbist/gen_patterns.H +++ /dev/null @@ -1,103 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_patterns.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 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 gen_patterns.H -/// @brief Static definition of MCBIST patterns -/// -// *HWP HWP Owner: Stephen Glancy -// *HWP HWP Backup: Andre Marin -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: FSP:HB - -#ifndef _MSS_GEN_MCBIST_PATTERNS_ -#define _MSS_GEN_MCBIST_PATTERNS_ - -#include - -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 -using cache_line = std::pair ; -using pattern = std::vector< cache_line > ; -extern const std::vector< pattern > patterns; - -// Vector of 24b random data seeds -using random24_data_seed = std::vector< uint64_t > ; -extern const std::vector< random24_data_seed > random24_data_seeds; - -// Vector of 24b random data seed maps -using random24_seed_map = std::vector< uint64_t >; -extern const std::vector< random24_seed_map > random24_seed_maps; - -}// mcbist - -}// mss -#endif diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_settings.H b/src/import/generic/memory/lib/utils/mcbist/gen_settings.H deleted file mode 100644 index 9c4392d0b..000000000 --- a/src/import/generic/memory/lib/utils/mcbist/gen_settings.H +++ /dev/null @@ -1,816 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/utils/mcbist/gen_settings.H $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 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 gen_settings.H -/// @brief MCBIST settings, like stop conditions, thresholds, etc -/// -// *HWP HWP Owner: Stephen Glancy -// *HWP HWP Backup: Andre Marin -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -#ifndef _GEN_MSS_MCBIST_SETTINGS_H_ -#define _GEN_MSS_MCBIST_SETTINGS_H_ - -#include - -#include -#include -#include -#include -#include - -namespace mss -{ - -namespace mcbist -{ -/// -/// @brief 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, -}; - -/// -/// @brief 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 -/// @tparam MC the mc type of the T -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the mcbistTraits associated with T - derived -/// @note Matches Nimbus MBSTRQ, but might be changed later for Centaur, or mapped. -/// -template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits::MC_TARGET_TYPE , typename TT = mss::mcbistTraits > -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& 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(DISABLE); - return *this; - } - - uint64_t l_thresh = 0; - iv_value.extractToRight(l_thresh); - - if (l_thresh == DISABLE) - { - // Note the threshold field is an exponent, so this is 2^0, or 1 count - iv_value.insertFromRight(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& 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(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_on_sce( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_on_mce( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_on_mpe( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_on_ue( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_on_sue( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_on_aue( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_on_rcd( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_symbol_counter_mode( const uint64_t i_value ) - { - iv_value.insertFromRight(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& 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(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& 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(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& 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(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_mcb_error( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_pause_mcb_log_full( const states i_on_or_off ) - { - iv_value.writeBit(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& this->iv_value useful for method chaining - /// - inline stop_conditions& set_maint_rce_with_ce( const states i_on_or_off ) - { - iv_value.writeBit(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& 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(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& 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(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& 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(i_on_or_off); - return *this; - } - - private: - - fapi2::buffer iv_value; -}; - -template< mss::mc_type MC, fapi2::TargetType T, typename TT> -constexpr uint64_t stop_conditions::DISABLE; - -template< mss::mc_type MC, fapi2::TargetType T, typename TT> -constexpr uint64_t stop_conditions::MAX_THRESHOLD; - -template< mss::mc_type MC, fapi2::TargetType T, typename TT> -constexpr uint64_t stop_conditions::DONT_CHANGE; - -/// -/// @class memdiags operational constraints -/// @tparam MC the mc type of the T -/// @tparam T the fapi2::TargetType - derived -/// @tparam TT the mcbistTraits associated with T - derived -/// -template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits::MC_TARGET_TYPE , typename TT = mcbistTraits > -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(TT::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(TT::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/generic/memory/lib/utils/mss_rank.H b/src/import/generic/memory/lib/utils/mss_rank.H index 42cd7a25e..caf514a2b 100644 --- a/src/import/generic/memory/lib/utils/mss_rank.H +++ b/src/import/generic/memory/lib/utils/mss_rank.H @@ -33,13 +33,13 @@ // *HWP Level: 2 // *HWP Consumed by: HB:FSP -#ifndef _MSS_RANK_H_ -#define _MSS_RANK_H_ +#ifndef _MSS_GENERIC_RANK_H_ +#define _MSS_GENERIC_RANK_H_ #include #include #include -#include +#include #include namespace mss -- cgit v1.2.1