From fdc14c69e7367e34b00df532de7094586f5935f6 Mon Sep 17 00:00:00 2001 From: Louis Stermole Date: Thu, 8 Sep 2016 06:57:10 -0500 Subject: 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 Tested-by: Hostboot CI Reviewed-by: STEPHEN GLANCY Reviewed-by: Brian R. Silver Reviewed-by: JACOB L. HARVEY Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29374 Tested-by: FSP CI Jenkins Reviewed-by: Christian R. Geddes --- .../hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C | 2 +- .../chips/p9/procedures/hwp/memory/lib/dimm/rank.C | 46 +- .../chips/p9/procedures/hwp/memory/lib/dimm/rank.H | 584 +++++++++++++++++++++ .../hwp/memory/lib/eff_config/eff_config.C | 6 +- .../chips/p9/procedures/hwp/memory/lib/mc/port.C | 4 +- .../p9/procedures/hwp/memory/lib/mcbist/sim.C | 10 +- .../p9/procedures/hwp/memory/lib/phy/ddr_phy.C | 6 +- 7 files changed, 641 insertions(+), 17 deletions(-) (limited to 'src/import/chips/p9/procedures/hwp/memory/lib') 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& 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::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::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::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::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::RANK_PAIR_FIELD_MAP = { 0, 0, 1, 1 }; +const std::vector< uint64_t > rankPairTraits::RANK_PAIR_FIELD_MAP = { 0, 0, 1, 1 }; +const std::vector< uint64_t > rankPairTraits::RANK_PAIR_FIELD_MAP = { 0, 0, 1, 1 }; +const std::vector< uint64_t > rankPairTraits::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& 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 #include +#include +#include +#include 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& i_target, std::vector fapi2::ReturnCode get_pair_from_rank(const fapi2::Target& 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 +/// @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 > +inline fapi2::ReturnCode read_rank_pair_reg( const fapi2::Target& i_target, fapi2::buffer& 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 +/// @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 > +inline fapi2::ReturnCode write_rank_pair_reg( const fapi2::Target& i_target, const fapi2::buffer& 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 +/// @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 > +inline void set_rank_field( fapi2::buffer& io_data, const uint64_t i_value ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + io_data.insertFromRight(i_value); + // also set valid field + io_data.writeBit(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 +/// @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 > +inline fapi2::ReturnCode set_rank_field( fapi2::buffer& io_data, + const uint64_t i_rank, + const uint64_t i_value ) +{ + switch (i_rank) + { + case(0): + set_rank_field(io_data, i_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + set_rank_field(io_data, i_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + set_rank_field(io_data, i_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + set_rank_field(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 +/// @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 > +inline void get_rank_field( const fapi2::buffer& i_data, uint64_t& o_value ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + i_data.extractToRight(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 +/// @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 > +inline fapi2::ReturnCode get_rank_field( fapi2::buffer& i_data, + const uint64_t i_rank, + uint64_t& o_value ) +{ + switch (i_rank) + { + case(0): + get_rank_field(i_data, o_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + get_rank_field(i_data, o_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + get_rank_field(i_data, o_value); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + get_rank_field(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 +/// @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 > +inline void set_pair_valid( fapi2::buffer& io_data, const mss::states i_state ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + io_data.writeBit(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 +/// @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 > +inline fapi2::ReturnCode set_pair_valid( fapi2::buffer& io_data, + const uint64_t i_rank, + const mss::states i_state ) +{ + switch (i_rank) + { + case(0): + set_pair_valid(io_data, i_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + set_pair_valid(io_data, i_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + set_pair_valid(io_data, i_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + set_pair_valid(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 +/// @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 > +inline void get_pair_valid( const fapi2::buffer& i_data, mss::states& o_state ) +{ + static_assert((R < TT::NUM_RANKS_IN_PAIR), "Rank index failed range check"); + o_state = (i_data.getBit() == 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 +/// @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 > +inline fapi2::ReturnCode get_pair_valid( fapi2::buffer& i_data, + const uint64_t i_rank, + mss::states& o_state ) +{ + switch (i_rank) + { + case(0): + get_pair_valid(i_data, o_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(1): + get_pair_valid(i_data, o_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(2): + get_pair_valid(i_data, o_state); + return fapi2::FAPI2_RC_SUCCESS; + + case(3): + get_pair_valid(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 +/// @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 > +fapi2::ReturnCode set_ranks_in_pair( const fapi2::Target& i_target, + const std::vector 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> 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(l_data.at(TT::RANK_PAIR_FIELD_MAP[l_ordinal]), l_ordinal, mss::NO) ); + } + else + { + FAPI_TRY( set_rank_field(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 +/// @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 > +fapi2::ReturnCode get_ranks_in_pair( const fapi2::Target& i_target, + std::vector& o_ranks ) +{ + o_ranks.clear(); + + // Read the rank pair register(s) + std::vector> 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(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(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 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& 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& i_target, l_fw_subtest.enable_port(mss::relative_pos(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& i_target, l_fr_subtest.enable_port(mss::relative_pos(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& 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& 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) ); -- cgit v1.2.1