summaryrefslogtreecommitdiffstats
path: root/src/import
diff options
context:
space:
mode:
authorLouis Stermole <stermole@us.ibm.com>2016-09-08 06:57:10 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2016-09-20 12:31:14 -0400
commitfdc14c69e7367e34b00df532de7094586f5935f6 (patch)
tree656f4897ddb705143446f617689ff2aecfda7b05 /src/import
parent50c1a970cfdc69dd6dc77c1b1c50d44190b8e55d (diff)
downloadtalos-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')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C46
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H584
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/sim.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C2
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
//
OpenPOWER on IntegriCloud