diff options
author | Alvin Wang <wangat@tw.ibm.com> | 2019-05-07 10:12:40 +0800 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2019-05-29 14:48:59 -0500 |
commit | 03fc49941aa7e1a35183bf367e55d202cf1aff40 (patch) | |
tree | 2be5336f0c6dbd4100b6af66870e5148c65aac03 /src/import/generic | |
parent | 8bde2e5cb164f08a25aa45dc9d3e991b3d66d9f5 (diff) | |
download | talos-hostboot-03fc49941aa7e1a35183bf367e55d202cf1aff40.tar.gz talos-hostboot-03fc49941aa7e1a35183bf367e55d202cf1aff40.zip |
Add trap_adress class in mcbist library
Change-Id: I5f078adb708128629e9e0c4a776cc32387cf84c8
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77095
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77105
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/generic')
12 files changed, 1677 insertions, 1655 deletions
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 <sglancy@us.ibm.com> -// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -#ifndef _GEN_MSS_MCBIST_ADDRESS_H_ -#define _GEN_MSS_MCBIST_ADDRESS_H_ - -#include <fapi2.H> -#include <utility> - - -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<T> -/// @note template argument defaults are in forward declaration in lib/mcbist/address.H -/// @note 12 = dimm -/// @note 13:14 = mrank -/// @note 15:17 = srank -/// @note 18:19 = bank group -/// @note 20:22 = bank -/// -// See declaration below -template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits<T> > -class address; - -} // close namespace fwms -} // close namespace ecc - -namespace mcbist -{ - -/// -/// @class address -/// @brief Represents a physical address in memory -/// @note -/// 0:1 port select -/// 2 dimm select -/// 3:4 mrank(0 to 1) -/// 5:7 srank(0 to 2) -/// 8:25 row(0 to 17) -/// 26:32 col(3 to 9) -/// 33:35 bank(0 to 2) -/// 36:37 bank_group(0 to 1) -/// -class address -{ - 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<uint64_t, uint64_t>; - - 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<MC>& i_address ) - { - fapi2::buffer<uint64_t> l_value = uint64_t(i_address); - uint64_t l_temp = 0; - l_value.extractToRight<ecc::fwms::address<MC>::DIMM.first, ecc::fwms::address<MC>::DIMM.second>(l_temp); - this->set_field<DIMM>(l_temp); - l_value.extractToRight<ecc::fwms::address<MC>::MRANK.first, ecc::fwms::address<MC>::MRANK.second>(l_temp); - this->set_field<MRANK>(l_temp); - l_value.extractToRight<ecc::fwms::address<MC>::SRANK.first, ecc::fwms::address<MC>::SRANK.second>(l_temp); - this->set_field<SRANK>(l_temp); - l_value.extractToRight<ecc::fwms::address<MC>::BANK_GROUP.first, ecc::fwms::address<MC>::BANK_GROUP.second>(l_temp); - this->set_field<BANK_GROUP>(l_temp); - l_value.extractToRight<ecc::fwms::address<MC>::BANK.first, ecc::fwms::address<MC>::BANK.second>(l_temp); - this->set_field<BANK>(l_temp); - } - - /// - /// @brief Conversion operator to uint64_t - /// @warn Right-aligns the address - /// - inline operator uint64_t() const - { - return iv_address >> MAGIC_PAD; - } - - /// - /// @brief Set a field for an address - /// @tparam F the field to set - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// - template< const field& F > - inline address& set_field( const uint64_t i_value ) - { - iv_address.insertFromRight<F.first, F.second>(i_value); - return *this; - } - - /// - /// @brief Get a field from an address - /// @tparam F the field to get - /// @return right-aligned uint64_t representing the value - /// - template< const field& F > - inline uint64_t get_field() const - { - uint64_t l_value = 0; - iv_address.extractToRight<F.first, F.second>(l_value); - return l_value; - } - - /// - /// @brief Get a range of addresses. - /// @tparam[in] F the left-most valid field. So, if the address was for master rank, - /// the left-most valid field would be MRANK - /// @param[out] o_end representing an address to end at - /// @note this pointer is the start address - /// - template< const field& F > - inline void get_range( address& o_end ) const - { - constexpr uint64_t START = F.first + F.second; - constexpr uint64_t LEN = (LAST_VALID.first + LAST_VALID.second) - START; - - // All we need to do is fill in the bits to the right of the last valid field - o_end.iv_address = iv_address; - o_end.iv_address.setBit<START, LEN>(); - } - - - /// - /// @brief Get an end address for sim mode - /// @param[out] o_end representing an address to end at - /// @note this pointer is the start address - /// - inline void get_sim_end_address( address& o_end ) const - { - // This magic number represents a range of addresses which cover all - // cache lines the training algorithms touch. By effecting 0 - this end - // address you'll effect everything which has bad ECC in the sim. - // 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<COL>(o_end); - o_end.set_column(l_magic_sim_number); - return; - } - - /// - /// @brief Get a range of addresses given a master rank - /// @param[in] i_start representing an address to start from - /// @param[out] o_end representing an address to end at - /// - inline static void get_mrank_range( const address& i_start, address& o_end ) - { - i_start.get_range<MRANK>(o_end); - } - - /// - /// @brief Get a range of addresses given a master rank - /// @param[in] i_port representing the port for the starting address - /// @param[in] i_dimm representing the dimm for the starting address - /// @param[in] i_mrank representing the master rank for the starting address - /// @param[out] o_start representing an address to start from - /// @param[out] o_end representing an address to end at - /// - inline static void get_mrank_range( const uint64_t i_port, - const uint64_t i_dimm, - const uint64_t i_mrank, - address& o_start, - address& o_end ) - { - o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank); - get_mrank_range(o_start, o_end); - } - - /// - /// @brief Get a range of addresses given a slave rank - /// @param[in] i_start representing an address to start from - /// @param[out] o_end representing an address to end at - /// - inline static void get_srank_range( const address& i_start, address& o_end ) - { - i_start.get_range<SRANK>(o_end); - } - - /// - /// @brief Get a range of addresses given a slave rank - /// @param[in] i_port representing the port for the starting address - /// @param[in] i_dimm representing the dimm for the starting address - /// @param[in] i_mrank representing the master rank for the starting address - /// @param[in] i_srank representing the slave rank for the starting address - /// @param[out] o_start representing an address to start from - /// @param[out] o_end representing an address to end at - /// - inline static void get_srank_range( const uint64_t i_port, const uint64_t i_dimm, - const uint64_t i_mrank, const uint64_t i_srank, - address& o_start, - address& o_end ) - { - o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank).set_slave_rank(i_srank); - get_srank_range(o_start, o_end); - } - - /// - /// @brief Set the port value for an address - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// - inline address& set_port( const uint64_t i_value ) - { - return set_field<PORT>(i_value); - } - - /// - /// @brief Get the port value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_port() const - { - return get_field<PORT>(); - } - - /// - /// @brief Set the DIMM value for an address - /// @param[in] i_value the value to set - /// @note 0 is the DIMM[0] != 0 is DIMM[1] - /// @return address& for method chaining - /// - inline address& set_dimm( const uint64_t i_value ) - { - return set_field<DIMM>(i_value); - } - - /// - /// @brief Get the DIMM value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_dimm() const - { - return get_field<DIMM>(); - } - - /// - /// @brief Set the port and DIMM value for an address - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// @note Useful for indexing all ports/DIMM on a controller - /// - inline address& set_port_dimm( const fapi2::buffer<uint64_t> i_value ) - { - uint64_t l_read_port = 0; - - i_value.extractToRight<PORT_START, PORT_LEN>(l_read_port); - return set_dimm(i_value.getBit<DIMM_BIT>()).set_port(l_read_port); - } - - /// - /// @brief Get the port and DIMM value for an address - /// @return right-aligned uint64_t representing the value - /// @note Useful for indexing all ports/DIMM on a controller - /// - inline uint64_t get_port_dimm() const - { - fapi2::buffer<uint64_t> l_value; - - l_value.insertFromRight<PORT_START, PORT_LEN>(get_port()); - l_value.writeBit<DIMM_BIT>(get_dimm()); - - return l_value; - } - - /// - /// @brief Set the master rank value for an address - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// - inline address& set_master_rank( const uint64_t i_value ) - { - return set_field<MRANK>(i_value); - } - - /// - /// @brief Get the master rank value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_master_rank() const - { - return get_field<MRANK>(); - } - - - /// - /// @brief Set the slave rank value for an address - /// @param[in] i_value the value to set - /// - inline void set_slave_rank( const uint64_t i_value ) - { - set_field<SRANK>(i_value); - } - - /// - /// @brief Get the slave rank value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_slave_rank() const - { - return get_field<SRANK>(); - } - - - /// - /// @brief Set the row value for an address - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// - inline address& set_row( const uint64_t i_value ) - { - return set_field<ROW>(i_value); - } - - /// - /// @brief Get the row value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_row() const - { - return get_field<ROW>(); - } - - - /// - /// @brief Set the column value for an address - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// - inline address& set_column( const uint64_t i_value ) - { - return set_field<COL>(i_value); - } - - /// - /// @brief Get the column value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_column() const - { - return get_field<COL>(); - } - - - /// - /// @brief Set the bank value for an address - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// - inline address& set_bank( const uint64_t i_value ) - { - return set_field<BANK>(i_value); - } - - /// - /// @brief Get the bank value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_bank() const - { - return get_field<BANK>(); - } - - /// - /// @brief Set the bank group value for an address - /// @param[in] i_value the value to set - /// @return address& for method chaining - /// - inline address& set_bank_group( const uint64_t i_value ) - { - return set_field<BANK_GROUP>(i_value); - } - - /// - /// @brief Get the bank group value for an address - /// @return right-aligned uint64_t representing the value - /// - inline uint64_t get_bank_group() const - { - return get_field<BANK_GROUP>(); - } - - private: - // We use a fapi2 buffer as it has static compile-time support - fapi2::buffer<uint64_t> iv_address; -}; - -} // close namespace mcbist - -// Documented above in its declaration. -template< 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<uint64_t, uint64_t>; - - constexpr static field DIMM = {TT::FIRMWARE_MS_ADDRESS, 1}; - constexpr static field MRANK = {TT::FIRMWARE_MS_ADDRESS + 1, 2}; - constexpr static field SRANK = {TT::FIRMWARE_MS_ADDRESS + 3, 3}; - constexpr static field BANK_GROUP = {TT::FIRMWARE_MS_ADDRESS + 6, 2}; - constexpr static field BANK = {TT::FIRMWARE_MS_ADDRESS + 8, 3}; - constexpr static field LAST_VALID = BANK; - - address() = default; - - /// - /// @brief Construct an address from a uint64_t (scom'ed value) - /// @param[in] i_value representing raw value from FWMS register - /// - address( const uint64_t& i_value ): - iv_value(i_value) - { - } - - /// - /// @brief Construct an address from an mcbist::address - /// @param[in] i_mcbist_address mcbist formatted address - /// @note Construction of mcbist::address from ecc::fwms::address - /// @note located in mcbist::address class - /// - address( const mcbist::address& i_mcbist_address ) - { - iv_value.insertFromRight<DIMM.first, DIMM.second>(i_mcbist_address.get_field<mcbist::address::DIMM>()); - iv_value.insertFromRight<MRANK.first, MRANK.second>(i_mcbist_address.get_field<mcbist::address::MRANK>()); - iv_value.insertFromRight<SRANK.first, SRANK.second>(i_mcbist_address.get_field<mcbist::address::SRANK>()); - iv_value.insertFromRight<BANK_GROUP.first, BANK_GROUP.second> - (i_mcbist_address.get_field<mcbist::address::BANK_GROUP>()); - iv_value.insertFromRight<BANK.first, BANK.second>(i_mcbist_address.get_field<mcbist::address::BANK>()); - } - - /// - /// @brief Conversion operator to uint64_t - /// - inline operator uint64_t() const - { - uint64_t l_temp = 0; - iv_value.extract<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_temp); - return l_temp; - } - - private: - fapi2::buffer<uint64_t> iv_value; -}; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address<MC, T, TT>::DIMM; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address<MC, T, TT>::MRANK; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address<MC, T, TT>::SRANK; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address<MC, T, TT>::BANK_GROUP; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address<MC, T, TT>::BANK; - -template< mss::mc_type MC, fapi2::TargetType T , typename TT > -constexpr mss::mcbist::address::field ecc::fwms::address<MC, T, TT>::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 <generic/memory/lib/utils/poll.H> #include <generic/memory/lib/utils/memory_size.H> -#include <generic/memory/lib/utils/mcbist/gen_patterns.H> -#include <generic/memory/lib/utils/mcbist/gen_settings.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H> #include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H> #include <generic/memory/lib/utils/num.H> #include <generic/memory/lib/utils/mc/gen_mss_port.H> @@ -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<TT::COMPL_3RD_CMD>(i_dimm); - } - + iv_mcbmr.template writeBit<TT::COMPL_3RD_CMD>(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<TT::COMPL_3RD_CMD>() ? 1 : 0; - } + + return iv_mcbmr.template getBit<TT::COMPL_3RD_CMD>() ? 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 <sglancy@us.ibm.com> +// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _GEN_MSS_MCBIST_ADDRESS_H_ +#define _GEN_MSS_MCBIST_ADDRESS_H_ + +#include <fapi2.H> +#include <utility> + + +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<T> +/// +// See declaration below +template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits<T> > +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<T> +/// @note template argument defaults are in forward declaration in lib/mcbist/address.H +/// @note 12 = dimm +/// @note 13:14 = mrank +/// @note 15:17 = srank +/// @note 18:19 = bank group +/// @note 20:22 = bank +/// +// See declaration below +template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T = mss::mcbistMCTraits<MC>::FWMS_ADDR_TARGET_TYPE, typename TT = mss::eccTraits<T> > +class address; + +} // close namespace fwms +} // close namespace ecc + +namespace mcbist +{ + +/// +/// @class address +/// @brief Represents a physical address in memory +/// @note +/// 0:1 port select +/// 2 dimm select +/// 3:4 mrank(0 to 1) +/// 5:7 srank(0 to 2) +/// 8:25 row(0 to 17) +/// 26:32 col(3 to 9) +/// 33:35 bank(0 to 2) +/// 36:37 bank_group(0 to 1) +/// +class address +{ + 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<uint64_t, uint64_t>; + + 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<MC>& i_address ) + { + this->set_field<PORT >(i_address.get_field<ecc::trap_address<MC>::PORT>()); + this->set_field<DIMM >(i_address.get_field<ecc::trap_address<MC>::DIMM>()); + this->set_field<MRANK >(i_address.get_field<ecc::trap_address<MC>::MRANK>()); + this->set_field<SRANK >(i_address.get_field<ecc::trap_address<MC>::SRANK>()); + this->set_field<ROW >(i_address.get_field<ecc::trap_address<MC>::ROW>()); + this->set_field<COL >(i_address.get_field<ecc::trap_address<MC>::COL>()); + this->set_field<BANK >(i_address.get_field<ecc::trap_address<MC>::BANK>()); + this->set_field<BANK_GROUP>(i_address.get_field<ecc::trap_address<MC>::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<MC>& i_address ) + { + this->set_field<DIMM >(i_address.get_field<ecc::fwms::address<MC>::DIMM>()); + this->set_field<MRANK >(i_address.get_field<ecc::fwms::address<MC>::MRANK>()); + this->set_field<SRANK >(i_address.get_field<ecc::fwms::address<MC>::SRANK>()); + this->set_field<BANK_GROUP>(i_address.get_field<ecc::fwms::address<MC>::BANK_GROUP>()); + this->set_field<BANK >(i_address.get_field<ecc::fwms::address<MC>::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<F.first, F.second>(i_value); + return *this; + } + + /// + /// @brief Get a field from an address + /// @tparam F the field to get + /// @return right-aligned uint64_t representing the value + /// + template< const field& F > + inline uint64_t get_field() const + { + uint64_t l_value = 0; + iv_address.extractToRight<F.first, F.second>(l_value); + return l_value; + } + + /// + /// @brief Get a range of addresses. + /// @tparam[in] F the left-most valid field. So, if the address was for master rank, + /// the left-most valid field would be MRANK + /// @param[out] o_end representing an address to end at + /// @note this pointer is the start address + /// + template< const field& F > + inline void get_range( address& o_end ) const + { + constexpr uint64_t START = F.first + F.second; + constexpr uint64_t LEN = (LAST_VALID.first + LAST_VALID.second) - START; + + // All we need to do is fill in the bits to the right of the last valid field + o_end.iv_address = iv_address; + o_end.iv_address.setBit<START, LEN>(); + } + + + /// + /// @brief Get an end address for sim mode + /// @param[out] o_end representing an address to end at + /// @note this pointer is the start address + /// + inline void get_sim_end_address( address& o_end ) const + { + // This magic number represents a range of addresses which cover all + // cache lines the training algorithms touch. By effecting 0 - this end + // address you'll effect everything which has bad ECC in the sim. + // 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<COL>(o_end); + o_end.set_column(l_magic_sim_number); + return; + } + + /// + /// @brief Get a range of addresses given a master rank + /// @param[in] i_start representing an address to start from + /// @param[out] o_end representing an address to end at + /// + inline static void get_mrank_range( const address& i_start, address& o_end ) + { + i_start.get_range<MRANK>(o_end); + } + + /// + /// @brief Get a range of addresses given a master rank + /// @param[in] i_port representing the port for the starting address + /// @param[in] i_dimm representing the dimm for the starting address + /// @param[in] i_mrank representing the master rank for the starting address + /// @param[out] o_start representing an address to start from + /// @param[out] o_end representing an address to end at + /// + inline static void get_mrank_range( const uint64_t i_port, + const uint64_t i_dimm, + const uint64_t i_mrank, + address& o_start, + address& o_end ) + { + o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank); + get_mrank_range(o_start, o_end); + } + + /// + /// @brief Get a range of addresses given a slave rank + /// @param[in] i_start representing an address to start from + /// @param[out] o_end representing an address to end at + /// + inline static void get_srank_range( const address& i_start, address& o_end ) + { + i_start.get_range<SRANK>(o_end); + } + + /// + /// @brief Get a range of addresses given a slave rank + /// @param[in] i_port representing the port for the starting address + /// @param[in] i_dimm representing the dimm for the starting address + /// @param[in] i_mrank representing the master rank for the starting address + /// @param[in] i_srank representing the slave rank for the starting address + /// @param[out] o_start representing an address to start from + /// @param[out] o_end representing an address to end at + /// + inline static void get_srank_range( const uint64_t i_port, const uint64_t i_dimm, + const uint64_t i_mrank, const uint64_t i_srank, + address& o_start, + address& o_end ) + { + o_start.set_port(i_port).set_dimm(i_dimm).set_master_rank(i_mrank).set_slave_rank(i_srank); + get_srank_range(o_start, o_end); + } + + /// + /// @brief Set the port value for an address + /// @param[in] i_value the value to set + /// @return address& for method chaining + /// + inline address& set_port( const uint64_t i_value ) + { + return set_field<PORT>(i_value); + } + + /// + /// @brief Get the port value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_port() const + { + return get_field<PORT>(); + } + + /// + /// @brief Set the DIMM value for an address + /// @param[in] i_value the value to set + /// @note 0 is the DIMM[0] != 0 is DIMM[1] + /// @return address& for method chaining + /// + inline address& set_dimm( const uint64_t i_value ) + { + return set_field<DIMM>(i_value); + } + + /// + /// @brief Get the DIMM value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_dimm() const + { + return get_field<DIMM>(); + } + + /// + /// @brief Set the port and DIMM value for an address + /// @param[in] i_value the value to set + /// @return address& for method chaining + /// @note Useful for indexing all ports/DIMM on a controller + /// + inline address& set_port_dimm( const fapi2::buffer<uint64_t> i_value ) + { + uint64_t l_read_port = 0; + + i_value.extractToRight<PORT_START, PORT_LEN>(l_read_port); + return set_dimm(i_value.getBit<DIMM_BIT>()).set_port(l_read_port); + } + + /// + /// @brief Get the port and DIMM value for an address + /// @return right-aligned uint64_t representing the value + /// @note Useful for indexing all ports/DIMM on a controller + /// + inline uint64_t get_port_dimm() const + { + fapi2::buffer<uint64_t> l_value; + + l_value.insertFromRight<PORT_START, PORT_LEN>(get_port()); + l_value.writeBit<DIMM_BIT>(get_dimm()); + + return l_value; + } + + /// + /// @brief Set the master rank value for an address + /// @param[in] i_value the value to set + /// @return address& for method chaining + /// + inline address& set_master_rank( const uint64_t i_value ) + { + return set_field<MRANK>(i_value); + } + + /// + /// @brief Get the master rank value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_master_rank() const + { + return get_field<MRANK>(); + } + + + /// + /// @brief Set the slave rank value for an address + /// @param[in] i_value the value to set + /// + inline void set_slave_rank( const uint64_t i_value ) + { + set_field<SRANK>(i_value); + } + + /// + /// @brief Get the slave rank value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_slave_rank() const + { + return get_field<SRANK>(); + } + + + /// + /// @brief Set the row value for an address + /// @param[in] i_value the value to set + /// @return address& for method chaining + /// + inline address& set_row( const uint64_t i_value ) + { + return set_field<ROW>(i_value); + } + + /// + /// @brief Get the row value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_row() const + { + return get_field<ROW>(); + } + + + /// + /// @brief Set the column value for an address + /// @param[in] i_value the value to set + /// @return address& for method chaining + /// + inline address& set_column( const uint64_t i_value ) + { + return set_field<COL>(i_value); + } + + /// + /// @brief Get the column value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_column() const + { + return get_field<COL>(); + } + + + /// + /// @brief Set the bank value for an address + /// @param[in] i_value the value to set + /// @return address& for method chaining + /// + inline address& set_bank( const uint64_t i_value ) + { + return set_field<BANK>(i_value); + } + + /// + /// @brief Get the bank value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_bank() const + { + return get_field<BANK>(); + } + + /// + /// @brief Set the bank group value for an address + /// @param[in] i_value the value to set + /// @return address& for method chaining + /// + inline address& set_bank_group( const uint64_t i_value ) + { + return set_field<BANK_GROUP>(i_value); + } + + /// + /// @brief Get the bank group value for an address + /// @return right-aligned uint64_t representing the value + /// + inline uint64_t get_bank_group() const + { + return get_field<BANK_GROUP>(); + } + + private: + // We use a fapi2 buffer as it has static compile-time support + fapi2::buffer<uint64_t> iv_address; +}; + +} // close namespace mcbist + +// Documented above in its declaration. +template< 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<uint64_t, uint64_t>; + + 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<DIMM.first, DIMM.second>(i_mcbist_address.get_field<mcbist::address::DIMM>()); + iv_value.insertFromRight<MRANK.first, MRANK.second>(i_mcbist_address.get_field<mcbist::address::MRANK>()); + iv_value.insertFromRight<SRANK.first, SRANK.second>(i_mcbist_address.get_field<mcbist::address::SRANK>()); + iv_value.insertFromRight<BANK_GROUP.first, BANK_GROUP.second> + (i_mcbist_address.get_field<mcbist::address::BANK_GROUP>()); + iv_value.insertFromRight<BANK.first, BANK.second>(i_mcbist_address.get_field<mcbist::address::BANK>()); + } + + /// + /// @brief Conversion operator to uint64_t + /// + inline operator uint64_t() const + { + uint64_t l_temp = 0; + iv_value.extract<TT::FIRMWARE_MS_ADDRESS, TT::FIRMWARE_MS_ADDRESS_LEN, TT::FIRMWARE_MS_ADDRESS>(l_temp); + return l_temp; + } + + /// + /// @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<F.first, F.second>(l_value); + return l_value; + } + + private: + fapi2::buffer<uint64_t> iv_value; + +}; + +using field = std::pair<uint64_t, uint64_t>; +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address<MC, T, TT>::DIMM; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address<MC, T, TT>::MRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address<MC, T, TT>::SRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address<MC, T, TT>::BANK_GROUP; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::fwms::address<MC, T, TT>::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<uint64_t, uint64_t>; + + 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<PORT.first, PORT.second>(i_mcbist_address.get_field<mcbist::address::PORT>()); + iv_value.insertFromRight<DIMM.first, DIMM.second>(i_mcbist_address.get_field<mcbist::address::DIMM>()); + iv_value.insertFromRight<MRANK.first, MRANK.second>(i_mcbist_address.get_field<mcbist::address::MRANK>()); + iv_value.insertFromRight<SRANK.first, SRANK.second>(i_mcbist_address.get_field<mcbist::address::SRANK>()); + iv_value.insertFromRight<ROW.first, ROW.second>(i_mcbist_address.get_field<mcbist::address::ROW>()); + iv_value.insertFromRight<COL.first, COL.second>(i_mcbist_address.get_field<mcbist::address::COL>()); + iv_value.insertFromRight<BANK.first, BANK.second>(i_mcbist_address.get_field<mcbist::address::BANK>()); + iv_value.insertFromRight<BANK_GROUP.first, BANK_GROUP.second> + (i_mcbist_address.get_field<mcbist::address::BANK_GROUP>()); + } + + /// + /// @brief Conversion operator to uint64_t + /// + inline operator uint64_t() const + { + uint64_t l_temp = 0; + iv_value.extract<TT::TRAP_ADDRESS, TT::TRAP_ADDRESS_LEN, TT::TRAP_ADDRESS>(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<F.first, F.second>(l_value); + return l_value; + } + + private: + fapi2::buffer<uint64_t> iv_value; +}; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::PORT; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::DIMM; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::MRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::SRANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::ROW; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::COL; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::BANK; + +template< mss::mc_type MC, fapi2::TargetType T , typename TT > +constexpr field ecc::trap_address<MC, T, TT>::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 <sglancy@us.ibm.com> +// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include <fapi2.H> +#include <vector> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H> + +namespace mss +{ + +namespace mcbist +{ + +/// Vector of cache lines, seaprated in to two 64B chunks +// TK Real patterns from Marc representing the proper bits for ECC checking +const std::vector< pattern > patterns = +{ + // Pattern index 0 (Pattern 1 is this inverted) + { {0x0000000000000000, 0x0000000000000000}, + {0x0000000000000000, 0x0000000000000000}, + {0x0000000000000000, 0x0000000000000000}, + {0x0000000000000000, 0x0000000000000000}, + }, + + // Pattern index 2 (Pattern 3 is this inverted) + { {0x5555555555555555, 0x5555555555555555}, + {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA}, + {0x5555555555555555, 0x5555555555555555}, + {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA}, + }, + + // Pattern index 4 (Pattern 5 is this inverted) + { {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x0000000000000000, 0x0000000000000000}, + {0x0000000000000000, 0x0000000000000000}, + }, + + // Pattern index 6 (Pattern 7 is this inverted) + { {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x0000000000000000, 0x0000000000000000}, + {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, + {0x0000000000000000, 0x0000000000000000}, + }, + + // Pattern index 8 Random Seed + { {0x1234567887654321, 0x8765432112345678}, + {0x1234567887654321, 0x8765432112345678}, + {0x1234567887654321, 0x8765432112345678}, + {0x1234567887654321, 0x8765432112345678}, + }, + + // Pattern index 10 (Pattern 11 is this inverted), MPR pattern + { {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, + {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, + {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, + {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, + }, +}; + +// TK Want a new RC for random 24 +/// Vector of 24b random data seeds +const std::vector< random24_data_seed > random24_data_seeds = +{ + // 24 Bit Pattern index 0 (Pattern 1 is this inverted) + { {0x010203}, + {0x040506}, + {0x070809}, + }, + + // 24 Bit Pattern index 2 (Pattern 3 is this inverted) + { {0x112233}, + {0x445566}, + {0x778899}, + }, + +}; + +/// Vector of 24b random data seed mappings +// Not sure how many mapping we will want, for now it should be sufficient to +// have all bytes point to a different LFSR or all bytes point to the same LFSR +const std::vector< random24_seed_map > random24_seed_maps = +{ + // 8 Bit Pattern index 0 + // This selection maps every data byte to a different random LFSR + { {0x0}, + {0x1}, + {0x2}, + {0x3}, + {0x4}, + {0x5}, + {0x6}, + {0x7}, + {0x8}, + }, + + // 8 Bit Pattern index 1 + // This selection maps every data byte to random LFSR 0 + { {0x0}, + {0x0}, + {0x0}, + {0x0}, + {0x0}, + {0x0}, + {0x0}, + {0x0}, + {0x0}, + }, + +}; + +} //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 <sglancy@us.ibm.com> +// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_GEN_MCBIST_PATTERNS_ +#define _MSS_GEN_MCBIST_PATTERNS_ + +#include <vector> + +namespace mss +{ +namespace mcbist +{ + +/// Memory diagnostic Pattern indexes. +// Why not an enum? I want to do math on them to generate a proper index in to a vector of +// patterns and enums really don't like that. +// Couple of extra symbols in here to keep things easy if desired +constexpr uint64_t PATTERN_ZEROS = 0; +constexpr uint64_t PATTERN_0 = PATTERN_ZEROS; +constexpr uint64_t PATTERN_ONES = 1; +constexpr uint64_t PATTERN_1 = PATTERN_ONES; +constexpr uint64_t PATTERN_2 = 2; +constexpr uint64_t PATTERN_3 = 3; +constexpr uint64_t PATTERN_4 = 4; +constexpr uint64_t PATTERN_5 = 5; +constexpr uint64_t PATTERN_6 = 6; +constexpr uint64_t PATTERN_7 = 7; +constexpr uint64_t PATTERN_8 = 8; +constexpr uint64_t PATTERN_9 = 9; +constexpr uint64_t PATTERN_10 = 10; +constexpr uint64_t PATTERN_RANDOM = PATTERN_8; +constexpr uint64_t LAST_PATTERN = PATTERN_10; + +// Don't mess with the patterns +constexpr uint64_t NO_PATTERN = LAST_PATTERN + 1; + +//Pattern references for the 24b random data pattern seeds +constexpr uint64_t MAX_NUM_RANDOM24_SEEDS = 3; +constexpr uint64_t RANDOM24_SEEDS_0 = 0; +constexpr uint64_t RANDOM24_SEEDS_1 = 1; +constexpr uint64_t RANDOM24_SEEDS_2 = 2; +constexpr uint64_t RANDOM24_SEEDS_3 = 3; +constexpr uint64_t LAST_RANDOM24_SEEDS = RANDOM24_SEEDS_3; +constexpr uint64_t NO_RANDOM24_SEEDS = LAST_RANDOM24_SEEDS + 1; + +//Pattern references for the 24b random data pattern seeds +constexpr uint64_t MAX_NUM_RANDOM24_MAPS = 9; +constexpr uint64_t RANDOM24_SEED_MAP_0 = 0; +constexpr uint64_t RANDOM24_SEED_MAP_1 = 1; +constexpr uint64_t LAST_RANDOM24_SEED_MAP = RANDOM24_SEED_MAP_1; +constexpr uint64_t NO_RANDOM24_SEED_MAP = LAST_RANDOM24_SEED_MAP + 1; +constexpr uint64_t RANDOM24_SEED_MAP_FIELD_LEN = 4; + + +/// Vector of cache lines, separated in to two 64B chunks +using cache_line = std::pair<uint64_t, uint64_t> ; +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 <sglancy@us.ibm.com> +// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _GEN_MSS_MCBIST_SETTINGS_H_ +#define _GEN_MSS_MCBIST_SETTINGS_H_ + +#include <fapi2.H> + +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H> +#include <generic/memory/lib/utils/bit_count.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H> + +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>::MC_TARGET_TYPE , typename TT = mss::mcbistTraits<MC, T> > +class stop_conditions +{ + public: + + // Many of the config fields share a disable bit pattern, so we define it here + static constexpr uint64_t DISABLE = 0b1111; + static constexpr uint64_t MAX_THRESHOLD = 0b1110; + static constexpr uint64_t DONT_CHANGE = 0; + + private: + + /// + /// @brief Little helper to convert threshold inputs to exponents + /// @param[in] i_value, the value of the threshold (presumably) + /// @return a value n such that 2^n <= i_value && n < 15 + /// + uint64_t make_threshold_setting( const uint64_t i_value ) + { + // If the user passes in DISABLE, let it past. This prevents callers from having to + // do the conditional. Zero is none which is disable + if ((i_value == DISABLE) || (i_value == 0)) + { + return DISABLE; + } + + // Find the first bit set. This represents the largest power of 2 this input can represent + // The subtraction from 63 switches from a left-count to a right-count (e.g., 0 (left most + // bit) is really bit 63 if you start on the right.) + const uint64_t l_largest = 63 - first_bit_set(i_value); + + // If the first bit set is off in space and greater than 2^14, we just return 0b1110 + // Otherwise, l_largest is the droid we're looking for + return l_largest >= MAX_THRESHOLD ? MAX_THRESHOLD : l_largest; + } + + /// + /// @brief Generic pause on threshold + /// @tparam F, the bit field to manipulate + /// @tparam L, the length of F + /// @param[in] the state of the error - mss::ON or mss::OFF + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + template< uint64_t F, uint64_t L > + inline stop_conditions<MC, T, TT>& set_pause_on_threshold( const states i_on_or_off ) + { + if (i_on_or_off == mss::OFF) + { + iv_value.insertFromRight<F, L>(DISABLE); + return *this; + } + + uint64_t l_thresh = 0; + iv_value.extractToRight<F, L>(l_thresh); + + if (l_thresh == DISABLE) + { + // Note the threshold field is an exponent, so this is 2^0, or 1 count + iv_value.insertFromRight<F, L>(0); + } + + return *this; + } + + public: + /// + /// @brief Stop/Thresholds class ctor + /// + stop_conditions(): + iv_value(0) + { + // By default we want to start everything in 'don't stop' mode. This means disabling + // the errors which contain thresholds + set_thresh_nce_int(DISABLE) + .set_thresh_nce_soft(DISABLE) + .set_thresh_nce_hard(DISABLE) + .set_thresh_rce(DISABLE) + .set_thresh_ice(DISABLE) + .set_thresh_mce_int(DISABLE) + .set_thresh_mce_soft(DISABLE) + .set_thresh_mce_hard(DISABLE); + } + + /// + /// @brief Stop/Thresholds class ctor + /// @param[in] uint64_t representing the threshold register contents + /// + stop_conditions(const uint64_t i_value): + iv_value(i_value) + { + } + + /// + /// @brief Stop/Thresholds class dtor + /// + ~stop_conditions() = default; + + /// + /// @brief uint64_t conversion + /// + inline operator uint64_t() const + { + return uint64_t(iv_value); + } + + /// + /// @brief set_thresh_nce_int + /// @param[in] i_value the value of the field + /// NCE intermittent error threshold magnitude to trigger for triggering pause. If + /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will + /// pause if it takes sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_nce_int( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT, + TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_nce_int - enable NCE intermittent error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_nce_int( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT, + TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(i_on_or_off); + } + + /// + /// @brief set_thresh_nce_soft + /// @param[in] i_value the value of the field + /// NCE soft error threshold magnitude to trigger for triggering pause. If 1111, + /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it + /// takes sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_nce_soft( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT, + TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_nce_int - enable NCE soft error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_nce_soft( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT, + TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(i_on_or_off); + } + + /// + /// @brief set_thresh_nce_hard + /// @param[in] i_value the value of the field + /// NCE hard error threshold magnitude to trigger for triggering pause. If 1111, + /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it + /// takes sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_nce_hard( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD, + TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_nce_hard - enable NCE hard error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_nce_hard( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD, + TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(i_on_or_off); + } + + /// + /// @brief set_thresh_rce + /// @param[in] i_value the value of the field + /// RCE error threshold magnitude to trigger for triggering pause. If 1111, then + /// pause will never be triggered (disabled). Else, then MCBIST will pause if it takes + /// sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_rce( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_RCE, + TT::MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_rce - enable RCE error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_rce( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_RCE, + TT::MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(i_on_or_off); + } + + /// + /// @brief set_thresh_ice + /// @param[in] i_value the value of the field + /// ICE (IMPE) error threshold magnitude to trigger for triggering pause. If 1111, + /// then pause will never be triggered (disabled). Else, then MCBIST will pause if + /// it takes sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_ice( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_ICE, + TT::MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_ice - enable ICE (IMPE) error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_ice( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_ICE, + TT::MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(i_on_or_off); + } + + /// + /// @brief set_thresh_mce_int + /// @param[in] i_value the value of the field + /// MCE intermittent error threshold magnitude to trigger for triggering pause. If + /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will + /// pause if it takes sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_mce_int( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT, + TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_mce_int - enable MCE intermittent error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_mce_int( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT, + TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(i_on_or_off); + } + + /// + /// @brief set_thresh_mce_soft + /// @param[in] i_value the value of the field + /// MCE soft error threshold magnitude to trigger for triggering pause. If 1111, + /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it + /// takes sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_mce_soft( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT, + TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_mce_soft - enable MCE soft error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_mce_soft( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT, + TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(i_on_or_off); + } + + /// + /// @brief set_thresh_mce_hard + /// @param[in] i_value the value of the field + /// MCE hard error threshold magnitude to trigger for triggering pause. If 1111, + /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it + /// takes sees 2^[this value] number of errors of this type. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note The register field is actually an exponent. The hardware will count 2^n for the + /// threshold. However, the input represents a count - how many. Thus we need to convert + /// the input to a power of 2 to get a proper exponent. Your input will be rounded down + /// to the nearest power of 2 which is less than 2^15 before being set in the register. + /// + inline stop_conditions<MC, T, TT>& set_thresh_mce_hard( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD, + TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(make_threshold_setting(i_value)); + return *this; + } + + /// + /// @brief set_pause_on_mce_hard - enable MCE hard error + /// @param[in] i_on_or_off - the desired state. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// @note If the input is mss::ON, this method enables the error, it's corresponding + /// threshold defines the threshold at which the engine will stop. If no threshold is + /// defined (the error is disabled) this method will set the threshold to 1. A previously + /// defined threshold (i.e., not disabled) will be left intact. If the input + /// is mss::OFF, this method will disable the error by setting the threshold to disabled. + /// + inline stop_conditions<MC, T, TT>& set_pause_on_mce_hard( const states i_on_or_off ) + { + return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD, + TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(i_on_or_off); + } + + /// + /// @brief set_pause_on_sce + /// @param[in] i_on_or_off - the desired state. + /// Enable pause on SCE error. When enabled, MCBIST will pause at the boundary + /// configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_on_sce( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_SCE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_on_mce + /// @param[in] i_on_or_off - the desired state. + /// Enable pause on MCE error. When enabled, MCBIST will pause at the boundary + /// configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_on_mce( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_MCE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_on_mpe + /// @param[in] i_on_or_off - the desired state. + /// Enable pause on MPE error. When enabled, MCBIST will pause at the boundary + /// configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_on_mpe( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_MPE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_on_ue + /// @param[in] i_on_or_off - the desired state. + /// Enable pause on UE error. When enabled, MCBIST will pause at the boundary + /// configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_on_ue( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_UE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_on_sue + /// @param[in] i_on_or_off - the desired state. + /// Enable pause on SUE error. When enabled, MCBIST will pause at the boundary + /// configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_on_sue( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_SUE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_on_aue + /// @param[in] i_on_or_off - the desired state. + /// Enable pause on AUE error. When enabled, MCBIST will pause at the boundary + /// configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_on_aue( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_AUE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_on_rcd + /// @param[in] i_on_or_off - the desired state. + /// Enable pause on RCD error. When enabled, MCBIST will pause at the boundary + /// configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_on_rcd( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_RCD>(i_on_or_off); + return *this; + } + + /// + /// @brief set_symbol_counter_mode + /// @param[in] i_value the value of the field + /// Selects which mode to use symbol counter latches: Mode 0) MAINT 8-bit error + /// counters for of 72 symbols Mode 1) MCBIST 4-bit error counters for 18 nibbles x 8 + /// ranks (port agnostic) Mode 2) MCBIST 4-bit error counters for 18 nibbles x 4 + /// ports (rank agnostic) and 1-bit error rank map for 18 nibbles x 4 ports + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_symbol_counter_mode( const uint64_t i_value ) + { + iv_value.insertFromRight<TT::MBSTRQ_CFG_SYMBOL_COUNTER_MODE, + TT::MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN>(i_value); + return *this; + } + + /// + /// @brief set_nce_soft_symbol_count_enable + /// @param[in] i_on_or_off - the desired state. + /// Enables soft NCEs to trigger per symbol NCE error counting Only applies to + /// scrub where we have different types of NCE. Non scrub counts all NCE. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_nce_soft_symbol_count_enable( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_nce_inter_symbol_count_enable + /// @param[in] i_on_or_off - the desired state. + /// Enables intermittent NCEs to trigger per symbol NCE error counting Only applies + /// to scrub where we have different types of NCE. Non scrub counts all NCE. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_nce_inter_symbol_count_enable( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_nce_hard_symbol_count_enable + /// @param[in] i_on_or_off - the desired state. + /// Enables hard NCEs to trigger per symbol NCE error counting Only applies to + /// scrub where we have different types of NCE. Non scrub counts all NCE. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_nce_hard_symbol_count_enable( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_mcb_error + /// @param[in] i_on_or_off - the desired state. + /// Enable pause when MCBIST error is logged. When enabled, MCBIST will pause at + /// the boundary configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_mcb_error( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_MCB_ERROR>(i_on_or_off); + return *this; + } + + /// + /// @brief set_pause_mcb_log_full + /// @param[in] i_on_or_off - the desired state. + /// Enable pause when MCBIST log is full. When enabled, MCBIST will pause at the + /// boundary configured if this error is seen. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_pause_mcb_log_full( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_MCB_LOG_FULL>(i_on_or_off); + return *this; + } + + /// + /// @brief set_maint_rce_with_ce + /// @param[in] i_on_or_off - the desired state. + /// cfg_maint_rce_with_ce - not implemented. Need to investigate if needed for nimbus. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_maint_rce_with_ce( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_MAINT_RCE_WITH_CE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_mce_soft_symbol_count_enable + /// @param[in] i_on_or_off - the desired state. + /// Enables soft MCEs to trigger per symbol MCE error counting Only applies to + /// scrub where we have different types of MCE. Non scrub counts all MCE. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_mce_soft_symbol_count_enable( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_mce_inter_symbol_count_enable + /// @param[in] i_on_or_off - the desired state. + /// Enables intermittent MCEs to trigger per symbol MCE error counting Only applies + /// to scrub where we have different types of MCE. Non scrub counts all MCE. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_mce_inter_symbol_count_enable( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off); + return *this; + } + + /// + /// @brief set_mce_hard_symbol_count_enable + /// @param[in] i_on_or_off - the desired state. + /// Enables hard MCEs to trigger per symbol MCE error counting Only applies to + /// scrub where we have different types of MCE. Non scrub counts all MCE. + /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining + /// + inline stop_conditions<MC, T, TT>& set_mce_hard_symbol_count_enable( const states i_on_or_off ) + { + iv_value.writeBit<TT::MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off); + return *this; + } + + private: + + fapi2::buffer<uint64_t> iv_value; +}; + +template< mss::mc_type MC, fapi2::TargetType T, typename TT> +constexpr uint64_t stop_conditions<MC, T, TT>::DISABLE; + +template< mss::mc_type MC, fapi2::TargetType T, typename TT> +constexpr uint64_t stop_conditions<MC, T, TT>::MAX_THRESHOLD; + +template< mss::mc_type MC, fapi2::TargetType T, typename TT> +constexpr uint64_t stop_conditions<MC, T, TT>::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>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> > +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<MC, T, TT>& 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<MC, T, TT>& 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<MC, T, TT>& 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<MC, T, TT> 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 <fapi2.H> #include <generic/memory/lib/utils/shared/mss_generic_consts.H> -#include <generic/memory/lib/utils/mcbist/gen_address.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H> 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 <sglancy@us.ibm.com> @@ -41,9 +41,9 @@ #include <generic/memory/lib/mss_generic_system_attribute_getters.H> #include <generic/memory/lib/utils/shared/mss_generic_consts.H> #include <generic/memory/lib/utils/mcbist/gen_mss_mcbist.H> -#include <generic/memory/lib/utils/mcbist/gen_address.H> -#include <generic/memory/lib/utils/mcbist/gen_patterns.H> -#include <generic/memory/lib/utils/mcbist/gen_settings.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_address.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_patterns.H> +#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_settings.H> #include <generic/memory/lib/utils/fir/gen_mss_unmask.H> #include <generic/memory/lib/utils/count_dimm.H> #include <generic/memory/lib/utils/conversions.H> 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 <sglancy@us.ibm.com> -// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: FSP:HB - -#include <fapi2.H> -#include <vector> -#include <generic/memory/lib/utils/mcbist/gen_patterns.H> - -namespace mss -{ - -namespace mcbist -{ - -/// Vector of cache lines, seaprated in to two 64B chunks -// TK Real patterns from Marc representing the proper bits for ECC checking -const std::vector< pattern > patterns = -{ - // Pattern index 0 (Pattern 1 is this inverted) - { {0x0000000000000000, 0x0000000000000000}, - {0x0000000000000000, 0x0000000000000000}, - {0x0000000000000000, 0x0000000000000000}, - {0x0000000000000000, 0x0000000000000000}, - }, - - // Pattern index 2 (Pattern 3 is this inverted) - { {0x5555555555555555, 0x5555555555555555}, - {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA}, - {0x5555555555555555, 0x5555555555555555}, - {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA}, - }, - - // Pattern index 4 (Pattern 5 is this inverted) - { {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0x0000000000000000, 0x0000000000000000}, - {0x0000000000000000, 0x0000000000000000}, - }, - - // Pattern index 6 (Pattern 7 is this inverted) - { {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0x0000000000000000, 0x0000000000000000}, - {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}, - {0x0000000000000000, 0x0000000000000000}, - }, - - // Pattern index 8 Random Seed - { {0x1234567887654321, 0x8765432112345678}, - {0x1234567887654321, 0x8765432112345678}, - {0x1234567887654321, 0x8765432112345678}, - {0x1234567887654321, 0x8765432112345678}, - }, - - // Pattern index 10 (Pattern 11 is this inverted), MPR pattern - { {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, - {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, - {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, - {0x0000000000000000, 0xFFFFFFFFFFFFFFFF}, - }, -}; - -// TK Want a new RC for random 24 -/// Vector of 24b random data seeds -const std::vector< random24_data_seed > random24_data_seeds = -{ - // 24 Bit Pattern index 0 (Pattern 1 is this inverted) - { {0x010203}, - {0x040506}, - {0x070809}, - }, - - // 24 Bit Pattern index 2 (Pattern 3 is this inverted) - { {0x112233}, - {0x445566}, - {0x778899}, - }, - -}; - -/// Vector of 24b random data seed mappings -// Not sure how many mapping we will want, for now it should be sufficient to -// have all bytes point to a different LFSR or all bytes point to the same LFSR -const std::vector< random24_seed_map > random24_seed_maps = -{ - // 8 Bit Pattern index 0 - // This selection maps every data byte to a different random LFSR - { {0x0}, - {0x1}, - {0x2}, - {0x3}, - {0x4}, - {0x5}, - {0x6}, - {0x7}, - {0x8}, - }, - - // 8 Bit Pattern index 1 - // This selection maps every data byte to random LFSR 0 - { {0x0}, - {0x0}, - {0x0}, - {0x0}, - {0x0}, - {0x0}, - {0x0}, - {0x0}, - {0x0}, - }, - -}; - -} //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 <sglancy@us.ibm.com> -// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: FSP:HB - -#ifndef _MSS_GEN_MCBIST_PATTERNS_ -#define _MSS_GEN_MCBIST_PATTERNS_ - -#include <vector> - -namespace mss -{ -namespace mcbist -{ - -/// Memory diagnostic Pattern indexes. -// Why not an enum? I want to do math on them to generate a proper index in to a vector of -// patterns and enums really don't like that. -// Couple of extra symbols in here to keep things easy if desired -constexpr uint64_t PATTERN_ZEROS = 0; -constexpr uint64_t PATTERN_0 = PATTERN_ZEROS; -constexpr uint64_t PATTERN_ONES = 1; -constexpr uint64_t PATTERN_1 = PATTERN_ONES; -constexpr uint64_t PATTERN_2 = 2; -constexpr uint64_t PATTERN_3 = 3; -constexpr uint64_t PATTERN_4 = 4; -constexpr uint64_t PATTERN_5 = 5; -constexpr uint64_t PATTERN_6 = 6; -constexpr uint64_t PATTERN_7 = 7; -constexpr uint64_t PATTERN_8 = 8; -constexpr uint64_t PATTERN_9 = 9; -constexpr uint64_t PATTERN_10 = 10; -constexpr uint64_t PATTERN_RANDOM = PATTERN_8; -constexpr uint64_t LAST_PATTERN = PATTERN_10; - -// Don't mess with the patterns -constexpr uint64_t NO_PATTERN = LAST_PATTERN + 1; - -//Pattern references for the 24b random data pattern seeds -constexpr uint64_t MAX_NUM_RANDOM24_SEEDS = 3; -constexpr uint64_t RANDOM24_SEEDS_0 = 0; -constexpr uint64_t RANDOM24_SEEDS_1 = 1; -constexpr uint64_t RANDOM24_SEEDS_2 = 2; -constexpr uint64_t RANDOM24_SEEDS_3 = 3; -constexpr uint64_t LAST_RANDOM24_SEEDS = RANDOM24_SEEDS_3; -constexpr uint64_t NO_RANDOM24_SEEDS = LAST_RANDOM24_SEEDS + 1; - -//Pattern references for the 24b random data pattern seeds -constexpr uint64_t MAX_NUM_RANDOM24_MAPS = 9; -constexpr uint64_t RANDOM24_SEED_MAP_0 = 0; -constexpr uint64_t RANDOM24_SEED_MAP_1 = 1; -constexpr uint64_t LAST_RANDOM24_SEED_MAP = RANDOM24_SEED_MAP_1; -constexpr uint64_t NO_RANDOM24_SEED_MAP = LAST_RANDOM24_SEED_MAP + 1; -constexpr uint64_t RANDOM24_SEED_MAP_FIELD_LEN = 4; - - -/// Vector of cache lines, separated in to two 64B chunks -using cache_line = std::pair<uint64_t, uint64_t> ; -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 <sglancy@us.ibm.com> -// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -#ifndef _GEN_MSS_MCBIST_SETTINGS_H_ -#define _GEN_MSS_MCBIST_SETTINGS_H_ - -#include <fapi2.H> - -#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H> -#include <generic/memory/lib/utils/mcbist/gen_address.H> -#include <generic/memory/lib/utils/bit_count.H> -#include <generic/memory/lib/utils/mcbist/gen_mss_mcbist_traits.H> -#include <generic/memory/lib/utils/mcbist/gen_patterns.H> - -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>::MC_TARGET_TYPE , typename TT = mss::mcbistTraits<MC, T> > -class stop_conditions -{ - public: - - // Many of the config fields share a disable bit pattern, so we define it here - static constexpr uint64_t DISABLE = 0b1111; - static constexpr uint64_t MAX_THRESHOLD = 0b1110; - static constexpr uint64_t DONT_CHANGE = 0; - - private: - - /// - /// @brief Little helper to convert threshold inputs to exponents - /// @param[in] i_value, the value of the threshold (presumably) - /// @return a value n such that 2^n <= i_value && n < 15 - /// - uint64_t make_threshold_setting( const uint64_t i_value ) - { - // If the user passes in DISABLE, let it past. This prevents callers from having to - // do the conditional. Zero is none which is disable - if ((i_value == DISABLE) || (i_value == 0)) - { - return DISABLE; - } - - // Find the first bit set. This represents the largest power of 2 this input can represent - // The subtraction from 63 switches from a left-count to a right-count (e.g., 0 (left most - // bit) is really bit 63 if you start on the right.) - const uint64_t l_largest = 63 - first_bit_set(i_value); - - // If the first bit set is off in space and greater than 2^14, we just return 0b1110 - // Otherwise, l_largest is the droid we're looking for - return l_largest >= MAX_THRESHOLD ? MAX_THRESHOLD : l_largest; - } - - /// - /// @brief Generic pause on threshold - /// @tparam F, the bit field to manipulate - /// @tparam L, the length of F - /// @param[in] the state of the error - mss::ON or mss::OFF - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - template< uint64_t F, uint64_t L > - inline stop_conditions<MC, T, TT>& set_pause_on_threshold( const states i_on_or_off ) - { - if (i_on_or_off == mss::OFF) - { - iv_value.insertFromRight<F, L>(DISABLE); - return *this; - } - - uint64_t l_thresh = 0; - iv_value.extractToRight<F, L>(l_thresh); - - if (l_thresh == DISABLE) - { - // Note the threshold field is an exponent, so this is 2^0, or 1 count - iv_value.insertFromRight<F, L>(0); - } - - return *this; - } - - public: - /// - /// @brief Stop/Thresholds class ctor - /// - stop_conditions(): - iv_value(0) - { - // By default we want to start everything in 'don't stop' mode. This means disabling - // the errors which contain thresholds - set_thresh_nce_int(DISABLE) - .set_thresh_nce_soft(DISABLE) - .set_thresh_nce_hard(DISABLE) - .set_thresh_rce(DISABLE) - .set_thresh_ice(DISABLE) - .set_thresh_mce_int(DISABLE) - .set_thresh_mce_soft(DISABLE) - .set_thresh_mce_hard(DISABLE); - } - - /// - /// @brief Stop/Thresholds class ctor - /// @param[in] uint64_t representing the threshold register contents - /// - stop_conditions(const uint64_t i_value): - iv_value(i_value) - { - } - - /// - /// @brief Stop/Thresholds class dtor - /// - ~stop_conditions() = default; - - /// - /// @brief uint64_t conversion - /// - inline operator uint64_t() const - { - return uint64_t(iv_value); - } - - /// - /// @brief set_thresh_nce_int - /// @param[in] i_value the value of the field - /// NCE intermittent error threshold magnitude to trigger for triggering pause. If - /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will - /// pause if it takes sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_nce_int( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT, - TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_nce_int - enable NCE intermittent error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_nce_int( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT, - TT::MBSTRQ_CFG_THRESH_MAG_NCE_INT_LEN>(i_on_or_off); - } - - /// - /// @brief set_thresh_nce_soft - /// @param[in] i_value the value of the field - /// NCE soft error threshold magnitude to trigger for triggering pause. If 1111, - /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it - /// takes sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_nce_soft( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT, - TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_nce_int - enable NCE soft error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_nce_soft( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT, - TT::MBSTRQ_CFG_THRESH_MAG_NCE_SOFT_LEN>(i_on_or_off); - } - - /// - /// @brief set_thresh_nce_hard - /// @param[in] i_value the value of the field - /// NCE hard error threshold magnitude to trigger for triggering pause. If 1111, - /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it - /// takes sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_nce_hard( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD, - TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_nce_hard - enable NCE hard error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_nce_hard( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD, - TT::MBSTRQ_CFG_THRESH_MAG_NCE_HARD_LEN>(i_on_or_off); - } - - /// - /// @brief set_thresh_rce - /// @param[in] i_value the value of the field - /// RCE error threshold magnitude to trigger for triggering pause. If 1111, then - /// pause will never be triggered (disabled). Else, then MCBIST will pause if it takes - /// sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_rce( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_RCE, - TT::MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_rce - enable RCE error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_rce( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_RCE, - TT::MBSTRQ_CFG_THRESH_MAG_RCE_LEN>(i_on_or_off); - } - - /// - /// @brief set_thresh_ice - /// @param[in] i_value the value of the field - /// ICE (IMPE) error threshold magnitude to trigger for triggering pause. If 1111, - /// then pause will never be triggered (disabled). Else, then MCBIST will pause if - /// it takes sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_ice( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_ICE, - TT::MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_ice - enable ICE (IMPE) error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_ice( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_ICE, - TT::MBSTRQ_CFG_THRESH_MAG_ICE_LEN>(i_on_or_off); - } - - /// - /// @brief set_thresh_mce_int - /// @param[in] i_value the value of the field - /// MCE intermittent error threshold magnitude to trigger for triggering pause. If - /// 1111, then pause will never be triggered (disabled). Else, then MCBIST will - /// pause if it takes sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_mce_int( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT, - TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_mce_int - enable MCE intermittent error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_mce_int( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT, - TT::MBSTRQ_CFG_THRESH_MAG_MCE_INT_LEN>(i_on_or_off); - } - - /// - /// @brief set_thresh_mce_soft - /// @param[in] i_value the value of the field - /// MCE soft error threshold magnitude to trigger for triggering pause. If 1111, - /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it - /// takes sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_mce_soft( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT, - TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_mce_soft - enable MCE soft error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_mce_soft( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT, - TT::MBSTRQ_CFG_THRESH_MAG_MCE_SOFT_LEN>(i_on_or_off); - } - - /// - /// @brief set_thresh_mce_hard - /// @param[in] i_value the value of the field - /// MCE hard error threshold magnitude to trigger for triggering pause. If 1111, - /// then pause will never be triggered (disabled). Else, then MCBIST will pause if it - /// takes sees 2^[this value] number of errors of this type. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note The register field is actually an exponent. The hardware will count 2^n for the - /// threshold. However, the input represents a count - how many. Thus we need to convert - /// the input to a power of 2 to get a proper exponent. Your input will be rounded down - /// to the nearest power of 2 which is less than 2^15 before being set in the register. - /// - inline stop_conditions<MC, T, TT>& set_thresh_mce_hard( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD, - TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(make_threshold_setting(i_value)); - return *this; - } - - /// - /// @brief set_pause_on_mce_hard - enable MCE hard error - /// @param[in] i_on_or_off - the desired state. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// @note If the input is mss::ON, this method enables the error, it's corresponding - /// threshold defines the threshold at which the engine will stop. If no threshold is - /// defined (the error is disabled) this method will set the threshold to 1. A previously - /// defined threshold (i.e., not disabled) will be left intact. If the input - /// is mss::OFF, this method will disable the error by setting the threshold to disabled. - /// - inline stop_conditions<MC, T, TT>& set_pause_on_mce_hard( const states i_on_or_off ) - { - return set_pause_on_threshold<TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD, - TT::MBSTRQ_CFG_THRESH_MAG_MCE_HARD_LEN>(i_on_or_off); - } - - /// - /// @brief set_pause_on_sce - /// @param[in] i_on_or_off - the desired state. - /// Enable pause on SCE error. When enabled, MCBIST will pause at the boundary - /// configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_on_sce( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_SCE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_on_mce - /// @param[in] i_on_or_off - the desired state. - /// Enable pause on MCE error. When enabled, MCBIST will pause at the boundary - /// configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_on_mce( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_MCE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_on_mpe - /// @param[in] i_on_or_off - the desired state. - /// Enable pause on MPE error. When enabled, MCBIST will pause at the boundary - /// configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_on_mpe( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_MPE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_on_ue - /// @param[in] i_on_or_off - the desired state. - /// Enable pause on UE error. When enabled, MCBIST will pause at the boundary - /// configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_on_ue( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_UE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_on_sue - /// @param[in] i_on_or_off - the desired state. - /// Enable pause on SUE error. When enabled, MCBIST will pause at the boundary - /// configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_on_sue( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_SUE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_on_aue - /// @param[in] i_on_or_off - the desired state. - /// Enable pause on AUE error. When enabled, MCBIST will pause at the boundary - /// configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_on_aue( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_AUE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_on_rcd - /// @param[in] i_on_or_off - the desired state. - /// Enable pause on RCD error. When enabled, MCBIST will pause at the boundary - /// configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_on_rcd( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_ON_RCD>(i_on_or_off); - return *this; - } - - /// - /// @brief set_symbol_counter_mode - /// @param[in] i_value the value of the field - /// Selects which mode to use symbol counter latches: Mode 0) MAINT 8-bit error - /// counters for of 72 symbols Mode 1) MCBIST 4-bit error counters for 18 nibbles x 8 - /// ranks (port agnostic) Mode 2) MCBIST 4-bit error counters for 18 nibbles x 4 - /// ports (rank agnostic) and 1-bit error rank map for 18 nibbles x 4 ports - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_symbol_counter_mode( const uint64_t i_value ) - { - iv_value.insertFromRight<TT::MBSTRQ_CFG_SYMBOL_COUNTER_MODE, - TT::MBSTRQ_CFG_SYMBOL_COUNTER_MODE_LEN>(i_value); - return *this; - } - - /// - /// @brief set_nce_soft_symbol_count_enable - /// @param[in] i_on_or_off - the desired state. - /// Enables soft NCEs to trigger per symbol NCE error counting Only applies to - /// scrub where we have different types of NCE. Non scrub counts all NCE. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_nce_soft_symbol_count_enable( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_NCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_nce_inter_symbol_count_enable - /// @param[in] i_on_or_off - the desired state. - /// Enables intermittent NCEs to trigger per symbol NCE error counting Only applies - /// to scrub where we have different types of NCE. Non scrub counts all NCE. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_nce_inter_symbol_count_enable( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_NCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_nce_hard_symbol_count_enable - /// @param[in] i_on_or_off - the desired state. - /// Enables hard NCEs to trigger per symbol NCE error counting Only applies to - /// scrub where we have different types of NCE. Non scrub counts all NCE. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_nce_hard_symbol_count_enable( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_NCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_mcb_error - /// @param[in] i_on_or_off - the desired state. - /// Enable pause when MCBIST error is logged. When enabled, MCBIST will pause at - /// the boundary configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_mcb_error( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_MCB_ERROR>(i_on_or_off); - return *this; - } - - /// - /// @brief set_pause_mcb_log_full - /// @param[in] i_on_or_off - the desired state. - /// Enable pause when MCBIST log is full. When enabled, MCBIST will pause at the - /// boundary configured if this error is seen. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_pause_mcb_log_full( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_PAUSE_MCB_LOG_FULL>(i_on_or_off); - return *this; - } - - /// - /// @brief set_maint_rce_with_ce - /// @param[in] i_on_or_off - the desired state. - /// cfg_maint_rce_with_ce - not implemented. Need to investigate if needed for nimbus. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_maint_rce_with_ce( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_MAINT_RCE_WITH_CE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_mce_soft_symbol_count_enable - /// @param[in] i_on_or_off - the desired state. - /// Enables soft MCEs to trigger per symbol MCE error counting Only applies to - /// scrub where we have different types of MCE. Non scrub counts all MCE. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_mce_soft_symbol_count_enable( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_MCE_SOFT_SYMBOL_COUNT_ENABLE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_mce_inter_symbol_count_enable - /// @param[in] i_on_or_off - the desired state. - /// Enables intermittent MCEs to trigger per symbol MCE error counting Only applies - /// to scrub where we have different types of MCE. Non scrub counts all MCE. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_mce_inter_symbol_count_enable( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_MCE_INTER_SYMBOL_COUNT_ENABLE>(i_on_or_off); - return *this; - } - - /// - /// @brief set_mce_hard_symbol_count_enable - /// @param[in] i_on_or_off - the desired state. - /// Enables hard MCEs to trigger per symbol MCE error counting Only applies to - /// scrub where we have different types of MCE. Non scrub counts all MCE. - /// @return fapi2::buffer<uint64_t>& this->iv_value useful for method chaining - /// - inline stop_conditions<MC, T, TT>& set_mce_hard_symbol_count_enable( const states i_on_or_off ) - { - iv_value.writeBit<TT::MBSTRQ_CFG_MCE_HARD_SYMBOL_COUNT_ENABLE>(i_on_or_off); - return *this; - } - - private: - - fapi2::buffer<uint64_t> iv_value; -}; - -template< mss::mc_type MC, fapi2::TargetType T, typename TT> -constexpr uint64_t stop_conditions<MC, T, TT>::DISABLE; - -template< mss::mc_type MC, fapi2::TargetType T, typename TT> -constexpr uint64_t stop_conditions<MC, T, TT>::MAX_THRESHOLD; - -template< mss::mc_type MC, fapi2::TargetType T, typename TT> -constexpr uint64_t stop_conditions<MC, T, TT>::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>::MC_TARGET_TYPE , typename TT = mcbistTraits<MC, T> > -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<MC, T, TT>& 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<MC, T, TT>& 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<MC, T, TT>& 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<MC, T, TT> 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 <fapi2.H> #include <generic/memory/lib/utils/pos.H> #include <generic/memory/lib/utils/find.H> -#include <mss_generic_attribute_getters.H> +#include <generic/memory/lib/mss_generic_attribute_getters.H> #include <generic/memory/lib/utils/shared/mss_generic_consts.H> namespace mss |