diff options
author | Louis Stermole <stermole@us.ibm.com> | 2016-09-08 06:57:10 -0500 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2016-09-20 12:31:14 -0400 |
commit | fdc14c69e7367e34b00df532de7094586f5935f6 (patch) | |
tree | 656f4897ddb705143446f617689ff2aecfda7b05 /src/import/chips/p9/procedures | |
parent | 50c1a970cfdc69dd6dc77c1b1c50d44190b8e55d (diff) | |
download | talos-hostboot-fdc14c69e7367e34b00df532de7094586f5935f6.tar.gz talos-hostboot-fdc14c69e7367e34b00df532de7094586f5935f6.zip |
Add register API for PHY Rank Pair registers
Fix access_delay_regs ut by choosing rank based on given rank pair
Put rank functions into a rank namespace
Change-Id: I57e0dc54e78c7b72df346fb902d5188330503919
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29372
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: Brian R. Silver <bsilver@us.ibm.com>
Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29374
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures')
8 files changed, 642 insertions, 18 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C index 540ae5b8c..de6208ebc 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C @@ -79,7 +79,7 @@ fapi2::ReturnCode mrs_load( const fapi2::Target<TARGET_TYPE_DIMM>& i_target, }; std::vector< uint64_t > l_ranks; - FAPI_TRY( mss::ranks(i_target, l_ranks) ); + FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); FAPI_TRY( mss::tdllk(i_target, tDLLK) ); // Load MRS diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C index ea496a62c..9b18c4a8b 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C @@ -44,6 +44,43 @@ using fapi2::FAPI2_RC_INVALID_PARAMETER; namespace mss { +// Definition of the Nimbus PHY rank_pair0 config registers +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 0>::RANK_PAIR_REGS = +{ + MCA_DDRPHY_PC_RANK_PAIR0_P0, + MCA_DDRPHY_PC_RANK_PAIR2_P0, +}; + +// Definition of the Nimbus PHY rank_pair1 config registers +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 1>::RANK_PAIR_REGS = +{ + MCA_DDRPHY_PC_RANK_PAIR0_P0, + MCA_DDRPHY_PC_RANK_PAIR2_P0, +}; + +// Definition of the Nimbus PHY rank_pair2 config registers +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 2>::RANK_PAIR_REGS = +{ + MCA_DDRPHY_PC_RANK_PAIR1_P0, + MCA_DDRPHY_PC_RANK_PAIR3_P0, +}; + +// Definition of the Nimbus PHY rank_pair3 config registers +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 3>::RANK_PAIR_REGS = +{ + MCA_DDRPHY_PC_RANK_PAIR1_P0, + MCA_DDRPHY_PC_RANK_PAIR3_P0, +}; + +// Definition of mappings for which fields (primary, secondary, ...) go into which regs +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 0>::RANK_PAIR_FIELD_MAP = { 0, 0, 1, 1 }; +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 1>::RANK_PAIR_FIELD_MAP = { 0, 0, 1, 1 }; +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 2>::RANK_PAIR_FIELD_MAP = { 0, 0, 1, 1 }; +const std::vector< uint64_t > rankPairTraits<TARGET_TYPE_MCA, 3>::RANK_PAIR_FIELD_MAP = { 0, 0, 1, 1 }; + +namespace rank +{ + // // Static table of rank pair assignments. Some of thoem won't be valid depending on // the plug rules (which may be OpenPOWER, IBM, etc.) Some also won't make sense @@ -290,8 +327,9 @@ fapi2::ReturnCode set_rank_pairs(const fapi2::Target<TARGET_TYPE_MCA>& i_target) FAPI_DBG("setting rank pairs for %s. 0x%08llx, 0x%08llx csid: 0x%016llx", mss::c_str(i_target), l_rp_registers.first, l_rp_registers.second, l_csid_data); - FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_PC_RANK_PAIR0_P0, l_rp_registers.first) ); - FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_PC_RANK_PAIR1_P0, l_rp_registers.second) ); + // need an extra pair of parens to make FAPI_TRY parsing work correctly + FAPI_TRY( (mss::rank::write_rank_pair_reg< 0, 0 >(i_target, l_rp_registers.first)) ); + FAPI_TRY( (mss::rank::write_rank_pair_reg< 0, 1 >(i_target, l_rp_registers.second)) ); FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_PC_CSID_CFG_P0, l_csid_data) ); // HACK HACK HACK: put this in the code properly!! BRS @@ -419,4 +457,6 @@ fapi_try_exit: return fapi2::current_err; } -} // namespace +} // namespace rank + +} // namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H index 5f546a8c8..96eda09f5 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H @@ -38,10 +38,221 @@ #include <fapi2.H> #include <lib/mss_attribute_accessors.H> +#include <p9_mc_scom_addresses.H> +#include <p9_mc_scom_addresses_fld.H> +#include <lib/utils/scom.H> namespace mss { +enum +{ + PRIMARY = 0, + SECONDARY = 1, + TERTIARY = 2, + QUATERNARY = 3, + NO_RANK = 999, +}; + +/// +/// @class rankPairTraits +/// @brief a collection of traits associated with rank pairs +/// @tparam T fapi2::TargetType representing the PHY +/// @tparam RP the rank pair +/// +template< fapi2::TargetType T, uint64_t RP > +class rankPairTraits; + +/// +/// @class rankPairTraits +/// @brief a collection of traits associated with the Centaur PHY +/// +template< uint64_t RP > +class rankPairTraits< fapi2::TARGET_TYPE_MBA, RP > +{ +}; + +/// +/// @class rankPairTraits +/// @brief a collection of traits associated with the Nimbus PHY rank pair 0 +/// +// TODO RTC:160869 Clean up rank utility functions, edd enums where appropriate +template<> +class rankPairTraits< fapi2::TARGET_TYPE_MCA, 0 > +{ + public: + enum + { + NUM_RANK_PAIR_REGS = 2, + NUM_RANKS_IN_PAIR = 4, + }; + + // MCA rank config registers + static const std::vector< uint64_t > RANK_PAIR_REGS; + + // Mapping for which fields below (primary, secondary, ...) go into which regs + static const std::vector< uint64_t > RANK_PAIR_FIELD_MAP; + + // MCA rank and valid fields. + constexpr static const uint64_t RANK_PAIR_FIELDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR0_P0_PRI, + MCA_DDRPHY_PC_RANK_PAIR0_P0_SEC, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR0_TER, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR0_QUA, + }; + constexpr static const uint64_t RANK_PAIR_LENGTHS[] = + { + MCA_DDRPHY_PC_RANK_PAIR0_P0_PRI_LEN, + MCA_DDRPHY_PC_RANK_PAIR0_P0_SEC_LEN, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR0_TER_LEN, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR0_QUA_LEN, + }; + constexpr static const uint64_t RANK_PAIR_VALIDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR0_P0_PRI_V, + MCA_DDRPHY_PC_RANK_PAIR0_P0_SEC_V, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR0_TER_V, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR0_QUA_V, + }; +}; + +/// +/// @class rankPairTraits +/// @brief a collection of traits associated with the Nimbus PHY rank pair 1 +/// +template<> +class rankPairTraits< fapi2::TARGET_TYPE_MCA, 1 > +{ + public: + enum + { + NUM_RANK_PAIR_REGS = 2, + NUM_RANKS_IN_PAIR = 4, + }; + + // MCA rank config registers + static const std::vector< uint64_t > RANK_PAIR_REGS; + + // Mapping for which fields below (primary, secondary, ...) go into which regs + static const std::vector< uint64_t > RANK_PAIR_FIELD_MAP; + + // MCA rank and valid fields. + constexpr static const uint64_t RANK_PAIR_FIELDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_PRI, + MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_SEC, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR1_TER, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR1_QUA, + }; + constexpr static const uint64_t RANK_PAIR_LENGTHS[] = + { + MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_PRI_LEN, + MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_SEC_LEN, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR1_TER_LEN, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR1_QUA_LEN, + }; + constexpr static const uint64_t RANK_PAIR_VALIDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_PRI_V, + MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_SEC_V, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR1_TER_V, + MCA_DDRPHY_PC_RANK_PAIR2_P0_PAIR1_QUA_V, + }; +}; + +/// +/// @class rankPairTraits +/// @brief a collection of traits associated with the Nimbus PHY rank pair 2 +/// +template<> +class rankPairTraits< fapi2::TARGET_TYPE_MCA, 2 > +{ + public: + enum + { + NUM_RANK_PAIR_REGS = 2, + NUM_RANKS_IN_PAIR = 4, + }; + + // MCA rank config registers + static const std::vector< uint64_t > RANK_PAIR_REGS; + + // Mapping for which fields below (primary, secondary, ...) go into which regs + static const std::vector< uint64_t > RANK_PAIR_FIELD_MAP; + + // MCA rank and valid fields. + constexpr static const uint64_t RANK_PAIR_FIELDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_PRI, + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_SEC, + MCA_DDRPHY_PC_RANK_PAIR3_P0_PAIR2_TER, + MCA_DDRPHY_PC_RANK_PAIR3_P0_PAIR2_QUA, + }; + constexpr static const uint64_t RANK_PAIR_LENGTHS[] = + { + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_PRI_LEN, + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_SEC_LEN, + MCA_DDRPHY_PC_RANK_PAIR3_P0_PAIR2_TER_LEN, + MCA_DDRPHY_PC_RANK_PAIR3_P0_PAIR2_QUA_LEN, + }; + constexpr static const uint64_t RANK_PAIR_VALIDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_PRI_V, + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_SEC_V, + MCA_DDRPHY_PC_RANK_PAIR3_P0_PAIR2_TER_V, + MCA_DDRPHY_PC_RANK_PAIR3_P0_PAIR2_QUA_V, + }; +}; + +/// +/// @class rankPairTraits +/// @brief a collection of traits associated with the Nimbus PHY rank pair 3 +/// +template<> +class rankPairTraits< fapi2::TARGET_TYPE_MCA, 3 > +{ + public: + enum + { + NUM_RANK_PAIR_REGS = 2, + NUM_RANKS_IN_PAIR = 4, + }; + + // MCA rank config registers + static const std::vector< uint64_t > RANK_PAIR_REGS; + + // Mapping for which fields below (primary, secondary, ...) go into which regs + static const std::vector< uint64_t > RANK_PAIR_FIELD_MAP; + + // MCA rank and valid fields. + constexpr static const uint64_t RANK_PAIR_FIELDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_PRI, + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_SEC, + MCA_DDRPHY_PC_RANK_PAIR3_P0_TER, + MCA_DDRPHY_PC_RANK_PAIR3_P0_QUA, + }; + constexpr static const uint64_t RANK_PAIR_LENGTHS[] = + { + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_PRI_LEN, + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_SEC_LEN, + MCA_DDRPHY_PC_RANK_PAIR3_P0_TER_LEN, + MCA_DDRPHY_PC_RANK_PAIR3_P0_QUA_LEN, + }; + constexpr static const uint64_t RANK_PAIR_VALIDS[] = + { + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_PRI_V, + MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_SEC_V, + MCA_DDRPHY_PC_RANK_PAIR3_P0_TER_V, + MCA_DDRPHY_PC_RANK_PAIR3_P0_QUA_V, + }; +}; + +// TODO RTC:160717 Tidy up function names in mss::rank namespace +namespace rank +{ + /// /// @brief Return a vector of rank numbers which represent the ranks for this dimm /// @tparam T the target type you'd like the associated ranks for @@ -119,5 +330,378 @@ fapi2::ReturnCode get_rank_pairs(const fapi2::Target<T>& i_target, std::vector<u template< fapi2::TargetType T> fapi2::ReturnCode get_pair_from_rank(const fapi2::Target<T>& i_target, const uint64_t i_rank, uint64_t& o_pair); +/// +/// @brief Read PC Rank Pair register +/// @tparam RP rank pair index +/// @tparam N register index +/// @tparam T fapi2 Target Type - derived from i_target's type +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_target the fapi2 target of the mc +/// @param[out] o_data the value of the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t RP, uint64_t N, fapi2::TargetType T, typename TT = rankPairTraits<T, RP> > +inline fapi2::ReturnCode read_rank_pair_reg( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data ) +{ + static_assert((N < TT::NUM_RANK_PAIR_REGS), "Rank pair register index failed range check"); + FAPI_TRY( mss::getScom(i_target, TT::RANK_PAIR_REGS[N], o_data) ); + FAPI_INF("read_rank_pair_reg: 0x%016lx", o_data); +fapi_try_exit: + return fapi2::current_err; } + +/// +/// @brief Write PC Rank Pair register +/// @tparam RP rank pair register index +/// @tparam N register index +/// @tparam T fapi2 Target Type - derived from i_target's type +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_target the fapi2 target of the mc +/// @param[in] i_data the value to write to the register +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t RP, uint64_t N, fapi2::TargetType T, typename TT = rankPairTraits<T, RP> > +inline fapi2::ReturnCode write_rank_pair_reg( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data ) +{ + static_assert((N < TT::NUM_RANK_PAIR_REGS), "Rank pair register index failed range check"); + FAPI_TRY( mss::putScom(i_target, TT::RANK_PAIR_REGS[N], i_data) ); + FAPI_INF("write_rank_pair_reg:: 0x%016lx", i_data); +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief set_rank_field +/// @tparam RP rank pair (group) index +/// @tparam R rank index in pair (PRIMARY, SECONDARY, etc) +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in, out] io_data the register value +/// @param[in] i_value rank number +/// @note When configured for a protocol that only supports a single rank system, the rankpair 0 primary +/// rank must be set to 0 +/// +template< uint64_t RP, uint64_t R, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline void set_rank_field( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + io_data.insertFromRight<TT::RANK_PAIR_FIELDS[R], TT::RANK_PAIR_LENGTHS[R]>(i_value); + // also set valid field + io_data.writeBit<TT::RANK_PAIR_VALIDS[R]>(mss::YES); + + FAPI_INF("set_rank_field: 0x%01lx", i_value); +} + +/// +/// @brief set_rank_field +/// @tparam RP rank pair (group) index +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in, out] io_data the register value +/// @param[i] i_rank rank index in pair (PRIMARY, SECONDARY, etc) +/// @param[in] i_value rank number +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// @note When configured for a protocol that only supports a single rank system, the rankpair 0 primary +/// rank must be set to 0 +/// +template< uint64_t RP, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline fapi2::ReturnCode set_rank_field( fapi2::buffer<uint64_t>& io_data, + const uint64_t i_rank, + const uint64_t i_value ) +{ + switch (i_rank) + { + case(0): + set_rank_field<RP, 0>(io_data, i_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + set_rank_field<RP, 1>(io_data, i_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + set_rank_field<RP, 2>(io_data, i_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + set_rank_field<RP, 3>(io_data, i_value); + return fapi2::FAPI2_RC_SUCCESS; + + default: + return fapi2::FAPI2_RC_INVALID_PARAMETER; + } +} + +/// +/// @brief get_rank_field +/// @tparam RP rank pair (group) index +/// @tparam R rank index in pair (PRIMARY, SECONDARY, etc) +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_data the register value +/// @param[out] o_value rank number +/// +template< uint64_t RP, uint64_t R, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline void get_rank_field( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + i_data.extractToRight<TT::RANK_PAIR_FIELDS[R], TT::RANK_PAIR_LENGTHS[R]>(o_value); + + FAPI_INF("get_rank_field: 0x%01lx", o_value); +} + +/// +/// @brief get_rank_field +/// @tparam RP rank pair (group) index +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_data the register value +/// @param[i] i_rank rank index in pair (PRIMARY, SECONDARY, etc) +/// @param[out] o_value rank number +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t RP, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline fapi2::ReturnCode get_rank_field( fapi2::buffer<uint64_t>& i_data, + const uint64_t i_rank, + uint64_t& o_value ) +{ + switch (i_rank) + { + case(0): + get_rank_field<RP, 0>(i_data, o_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + get_rank_field<RP, 1>(i_data, o_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + get_rank_field<RP, 2>(i_data, o_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + get_rank_field<RP, 3>(i_data, o_value); + return fapi2::FAPI2_RC_SUCCESS; + + default: + return fapi2::FAPI2_RC_INVALID_PARAMETER; + } +} + +/// +/// @brief set_pair_valid +/// @tparam RP rank pair (group) index +/// @tparam R rank index in pair (PRIMARY, SECONDARY, etc) +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in, out] io_data the register value +/// @param[in] i_state mss::YES or mss::NO - desired state +/// @note Indicates value in the RANK_PAIR field is valid +/// +template< uint64_t RP, uint64_t R, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline void set_pair_valid( fapi2::buffer<uint64_t>& io_data, const mss::states i_state ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + io_data.writeBit<TT::RANK_PAIR_VALIDS[R]>(i_state); + + FAPI_INF("set_pair_valid: 0x%01lx", i_state); +} + +/// +/// @brief set_pair_valid +/// @tparam RP rank pair (group) index +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in, out] io_data the register value +/// @param[in] i_rank rank index in pair (PRIMARY, SECONDARY, etc) +/// @param[in] i_state mss::YES or mss::NO - desired state +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// @note Indicates value in the RANK_PAIR field is valid +/// +template< uint64_t RP, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline fapi2::ReturnCode set_pair_valid( fapi2::buffer<uint64_t>& io_data, + const uint64_t i_rank, + const mss::states i_state ) +{ + switch (i_rank) + { + case(0): + set_pair_valid<RP, 0>(io_data, i_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + set_pair_valid<RP, 1>(io_data, i_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + set_pair_valid<RP, 2>(io_data, i_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + set_pair_valid<RP, 3>(io_data, i_state); + return fapi2::FAPI2_RC_SUCCESS; + + default: + return fapi2::FAPI2_RC_INVALID_PARAMETER; + } +} + +/// +/// @brief get_pair_valid +/// @tparam RP rank pair (group) index +/// @tparam R rank index in pair (PRIMARY, SECONDARY, etc) +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_data the register value +/// @param[out] o_state mss::YES or mss::NO - representing the state of the field +/// @note Indicates value in the RANK_PAIR field is valid +/// +template< uint64_t RP, uint64_t R, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline void get_pair_valid( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + o_state = (i_data.getBit<TT::RANK_PAIR_VALIDS[R]>() == false) ? mss::NO : mss::YES; + + FAPI_INF("get_pair_valid: 0x%01lx", o_state); +} + +/// +/// @brief get_pair_valid +/// @tparam RP rank pair (group) index +/// @tparam T fapi2 Target Type defaults to TARGET_TYPE_MCA +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_data the register value +/// @param[in] i_rank rank index in pair (PRIMARY, SECONDARY, etc) +/// @param[out] o_state mss::YES or mss::NO - representing the state of the field +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// @note Indicates value in the RANK_PAIR field is valid +/// +template< uint64_t RP, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = rankPairTraits<T, RP> > +inline fapi2::ReturnCode get_pair_valid( fapi2::buffer<uint64_t>& i_data, + const uint64_t i_rank, + mss::states& o_state ) +{ + switch (i_rank) + { + case(0): + get_pair_valid<RP, 0>(i_data, o_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + get_pair_valid<RP, 1>(i_data, o_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + get_pair_valid<RP, 2>(i_data, o_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + get_pair_valid<RP, 3>(i_data, o_state); + return fapi2::FAPI2_RC_SUCCESS; + + default: + return fapi2::FAPI2_RC_INVALID_PARAMETER; + } +} + +/// +/// @brief set_ranks_in_pair +/// @tparam RP rank pair (group) index +/// @tparam T fapi2 Target Type - derived from i_target's type +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_target the fapi2 target of the mc +/// @param[in] i_ranks vector of rank numbers (primary, secondary, tertiary, quaternary) +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// @note All ranks will be marked as valid in the pair, unless specified as enum NO_RANK +/// +template< uint64_t RP, fapi2::TargetType T, typename TT = rankPairTraits<T, RP> > +fapi2::ReturnCode set_ranks_in_pair( const fapi2::Target<T>& i_target, + const std::vector<uint64_t> i_ranks ) +{ + // make sure i_ranks has all four ranks + if (i_ranks.size() != TT::NUM_RANKS_IN_PAIR) + { + FAPI_ERR("rank vector incorrect size"); + return fapi2::FAPI2_RC_INVALID_PARAMETER; + } + + // Read the rank pair register(s) + std::vector<fapi2::buffer<uint64_t>> l_data; + uint64_t l_ordinal = 0; + + FAPI_TRY( scom_suckah(i_target, TT::RANK_PAIR_REGS, l_data) ); + + // Modify + for (const auto l_rank : i_ranks) + { + if (l_rank == NO_RANK) + { + FAPI_TRY( set_pair_valid<RP>(l_data.at(TT::RANK_PAIR_FIELD_MAP[l_ordinal]), l_ordinal, mss::NO) ); + } + else + { + FAPI_TRY( set_rank_field<RP>(l_data.at(TT::RANK_PAIR_FIELD_MAP[l_ordinal]), l_ordinal, l_rank) ); + } + + ++l_ordinal; + } + + // Write + FAPI_TRY( scom_blastah(i_target, TT::RANK_PAIR_REGS, l_data) ); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief get_ranks_in_pair +/// @tparam RP rank pair (group) index +/// @tparam T fapi2 Target Type - derived from i_target's type +/// @tparam TT traits type defaults to rankPairTraits<T, RP> +/// @param[in] i_target the fapi2 target of the mc +/// @param[out] o_ranks vector of rank numbers (primary, secondary, tertiary, quaternary) +/// @note Any ranks not marked as valid in the pair will be returned as enum NO_RANK +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +template< uint64_t RP, fapi2::TargetType T, typename TT = rankPairTraits<T, RP> > +fapi2::ReturnCode get_ranks_in_pair( const fapi2::Target<T>& i_target, + std::vector<uint64_t>& o_ranks ) +{ + o_ranks.clear(); + + // Read the rank pair register(s) + std::vector<fapi2::buffer<uint64_t>> l_data; + + FAPI_TRY( scom_suckah(i_target, TT::RANK_PAIR_REGS, l_data) ); + + // Get data + for (uint64_t l_ordinal = 0; l_ordinal < TT::NUM_RANKS_IN_PAIR; ++l_ordinal) + { + mss::states l_state = mss::NO; + + FAPI_TRY( get_pair_valid<RP>(l_data.at(TT::RANK_PAIR_FIELD_MAP[l_ordinal]), l_ordinal, l_state) ); + + if (l_state == mss::NO) + { + o_ranks.push_back(NO_RANK); + } + else + { + uint64_t l_rank = 0; + FAPI_TRY( get_rank_field<RP>(l_data.at(TT::RANK_PAIR_FIELD_MAP[l_ordinal]), l_ordinal, l_rank) ); + o_ranks.push_back(l_rank); + } + } + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +} // namespace rank + +} // namespace mss #endif diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C index 2abb529a8..74b6c39d7 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C @@ -2144,7 +2144,7 @@ fapi2::ReturnCode eff_config::vref_dq_train_value(const fapi2::Target<TARGET_TYP // Attribute to set num dimm ranks is a pre-requisite FAPI_TRY( eff_vref_dq_train_value(l_mcs, &l_attrs_vref_dq_train_val[0][0][0]) ); - FAPI_TRY( mss::ranks(i_target, l_ranks) ); + FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); for(const auto& l_rank : l_ranks) { @@ -2176,7 +2176,7 @@ fapi2::ReturnCode eff_config::vref_dq_train_enable(const fapi2::Target<TARGET_TY // Attribute to set num dimm ranks is a pre-requisite FAPI_TRY( eff_vref_dq_train_enable(l_mcs, &l_attrs_vref_dq_train_enable[0][0][0]) ); - FAPI_TRY( mss::ranks(i_target, l_ranks) ); + FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); for(const auto& l_rank : l_ranks) { @@ -2215,7 +2215,7 @@ fapi2::ReturnCode eff_config::vref_dq_train_range(const fapi2::Target<TARGET_TYP //gets the current value of train_range FAPI_TRY( eff_vref_dq_train_range(l_mcs, &l_attrs_vref_dq_train_range[0][0][0]) ); - FAPI_TRY( mss::ranks(i_target, l_ranks) ); + FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); for(const auto& l_rank : l_ranks) { diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C index 83dd37ad9..1ee2353bb 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C @@ -163,7 +163,7 @@ fapi2::ReturnCode enable_periodic_cal( const fapi2::Target<fapi2::TARGET_TYPE_MC // // Setup PER_ZCAL_CONFIG based on the number of ranks on the DIMM in either slot. - FAPI_TRY( mss::ranks(i_target, l_ranks) ); + FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); for (auto r : l_ranks) { @@ -209,7 +209,7 @@ fapi2::ReturnCode enable_periodic_cal( const fapi2::Target<fapi2::TARGET_TYPE_MC // need to do it twice for the PHY? BRS fapi2::buffer<uint64_t> l_rank_config; - FAPI_TRY( mss::get_rank_pairs(i_target, l_pairs) ); + FAPI_TRY( mss::rank::get_rank_pairs(i_target, l_pairs) ); for (auto pair : l_pairs) { diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C index c85bee5fd..50d79b40b 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C @@ -84,7 +84,7 @@ fapi2::ReturnCode sf_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, // ranks. Therefore, we only need to clean up the primary ranks. And because there's 4 max, we can do it // all using the 4 address range registers of tne MCBIST (broadcast currently not considered.) // So we can write 0's to those to get their ECC fixed up. - FAPI_TRY( mss::primary_ranks(p, l_pr) ); + FAPI_TRY( mss::rank::primary_ranks(p, l_pr) ); fapi2::Assert( l_pr.size() <= mss::MAX_RANK_PER_DIMM ); for (auto r = l_pr.begin(); r != l_pr.end(); ++l_rank_address_pair, ++r) @@ -110,9 +110,9 @@ fapi2::ReturnCode sf_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, l_fw_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p)); l_fw_subtest.change_addr_sel(l_rank_address_pair); - l_fw_subtest.enable_dimm(mss::get_dimm_from_rank(*r)); + l_fw_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r)); l_program.iv_subtests.push_back(l_fw_subtest); - FAPI_DBG("adding superfast write for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::get_dimm_from_rank(*r)); + FAPI_DBG("adding superfast write for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r)); } // Read - we do a read here as verification can use this as a tool as we do the write and then the read. @@ -125,9 +125,9 @@ fapi2::ReturnCode sf_init( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, l_fr_subtest.enable_port(mss::relative_pos<TARGET_TYPE_MCBIST>(p)); l_fr_subtest.change_addr_sel(l_rank_address_pair); - l_fr_subtest.enable_dimm(mss::get_dimm_from_rank(*r)); + l_fr_subtest.enable_dimm(mss::rank::get_dimm_from_rank(*r)); l_program.iv_subtests.push_back(l_fr_subtest); - FAPI_DBG("adding superfast read for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::get_dimm_from_rank(*r)); + FAPI_DBG("adding superfast read for %s rank %d (dimm %d)", mss::c_str(p), *r, mss::rank::get_dimm_from_rank(*r)); } } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C index fec38cd93..32900b643 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C @@ -369,7 +369,7 @@ fapi2::ReturnCode rank_pair_primary_to_dimm( const fapi2::Target<TARGET_TYPE_MCA // Now we need to figure out which DIMM this rank is on. It's either on DIMM0 or DIMM1, and DIMM0 // has ranks 0-3 and DIMM1 has ranks 4-7. Return the DIMM associated. - l_rank_on_dimm = get_dimm_from_rank(l_rank); + l_rank_on_dimm = mss::rank::get_dimm_from_rank(l_rank); // Sanity check the DIMM list FAPI_INF("%s rank is on dimm: %d, number of dimms: %d", mss::c_str(i_target), l_rank_on_dimm, l_dimms.size()); @@ -591,7 +591,7 @@ fapi2::ReturnCode phy_scominit(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target // Section 5.2.1.3 PC Rank Pair 0 on page 177 // Section 5.2.1.4 PC Rank Pair 1 on page 179 - FAPI_TRY( mss::set_rank_pairs(p) ); + FAPI_TRY( mss::rank::set_rank_pairs(p) ); // Section 5.2.4.1 DP16 Data Bit Enable 0 on page 284 // Section 5.2.4.2 DP16 Data Bit Enable 1 on page 285 @@ -600,7 +600,7 @@ fapi2::ReturnCode phy_scominit(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target FAPI_TRY( mss::dp16::reset_data_bit_enable(p) ); FAPI_TRY( mss::dp16::reset_bad_bits(p) ); - FAPI_TRY( mss::get_rank_pairs(p, l_pairs) ); + FAPI_TRY( mss::rank::get_rank_pairs(p, l_pairs) ); // Section 5.2.4.8 DP16 Write Clock Enable & Clock Selection on page 301 FAPI_TRY( mss::dp16::reset_write_clock_enable(p, l_pairs) ); diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C index 23546af61..eacd67862 100644 --- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C +++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C @@ -133,7 +133,7 @@ extern "C" // • Section 5.2.6.3 WC Configuration 2 Register on page 438 // Get our rank pairs. - FAPI_TRY( mss::get_rank_pairs(p, l_pairs) ); + FAPI_TRY( mss::rank::get_rank_pairs(p, l_pairs) ); // Setup the config register // |