summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-04-28 10:31:23 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-05-12 10:41:36 -0400
commiteffcd0c0d34e5e4032324e57a4d6d8d881167e32 (patch)
treee63077fc204eeb5995d1b4bbf291f7e23cc37e21
parente22a971e4a78b218aee6c6d6be7e7c9e3886bed9 (diff)
downloadtalos-hostboot-effcd0c0d34e5e4032324e57a4d6d8d881167e32.tar.gz
talos-hostboot-effcd0c0d34e5e4032324e57a4d6d8d881167e32.zip
Add get_pair_from_rank
Change-Id: I39e10b9794a27abca5ac43e33a5897fc0cdd6cb6 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23794 Tested-by: Jenkins Server Tested-by: Hostboot CI Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23795 Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C130
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H23
2 files changed, 136 insertions, 17 deletions
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 ab4926b99..a8ba500f4 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
@@ -32,6 +32,8 @@
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_DIMM;
+using fapi2::FAPI2_RC_SUCCESS;
+using fapi2::FAPI2_RC_INVALID_PARAMETER;
namespace mss
{
@@ -229,6 +231,34 @@ fapi_try_exit:
}
///
+/// @brief Given a target, get the rank pair assignments, based on DIMMs
+/// @tparam T the fapi2::TargetType
+/// @param[in] i_target the target (MCA or MBA?)
+/// @param[out] o_registers the regiter settings for the appropriate rank pairs
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template<>
+fapi2::ReturnCode get_rank_pair_assignments(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ std::pair<uint64_t, uint64_t>& o_registers)
+{
+ // Get the count of rank pairs for all DIMM on the port
+ std::vector<uint8_t> l_rank_count(MAX_DIMM_PER_PORT, 0);
+
+ for (auto d : i_target.getChildren<TARGET_TYPE_DIMM>())
+ {
+ FAPI_TRY( mss::eff_num_ranks_per_dimm(d, l_rank_count[mss::index(d)]) );
+ }
+
+ o_registers = rank_pair_assignments[l_rank_count[1]][l_rank_count[0]];
+
+ FAPI_DBG("rank pair assignments for %s. [%d,%d] (0x%08llx, 0x%08llx)",
+ mss::c_str(i_target), l_rank_count[1], l_rank_count[0], o_registers.first, o_registers.second);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Setup the rank information in the port
/// @tparam T the fapi2::TargetType
/// @param[in] i_target the target (MCA or MBA?)
@@ -247,25 +277,14 @@ fapi2::ReturnCode set_rank_pairs(const fapi2::Target<TARGET_TYPE_MCA>& i_target)
// to set only the bits for the rank pairs configured, or whether 0xff00 will suffice. BRS
fapi2::buffer<uint64_t> l_csid_data(0xFF00);
- fapi2::buffer<uint64_t> l_rp0_register;
- fapi2::buffer<uint64_t> l_rp1_register;
-
- // Get the count of rank pairs for all DIMM on the port
- std::vector<uint8_t> l_rank_count(MAX_DIMM_PER_PORT, 0);
-
- for (auto d : i_target.getChildren<TARGET_TYPE_DIMM>())
- {
- FAPI_TRY( mss::eff_num_ranks_per_dimm(d, l_rank_count[mss::index(d)]) );
- }
-
- l_rp0_register = rank_pair_assignments[l_rank_count[1]][l_rank_count[0]].first;
- l_rp1_register = rank_pair_assignments[l_rank_count[1]][l_rank_count[0]].second;
+ std::pair<uint64_t, uint64_t> l_rp_registers;
+ FAPI_TRY( get_rank_pair_assignments(i_target, l_rp_registers) );
- FAPI_DBG("setting rank pairs for %s. [%d,%d] (0x%08llx, 0x%08llx) csid: 0x%016llx",
- mss::c_str(i_target), l_rank_count[1], l_rank_count[0], l_rp0_register, l_rp1_register, l_csid_data);
+ 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_rp0_register) );
- FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_PC_RANK_PAIR1_P0, l_rp1_register) );
+ 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) );
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
@@ -316,4 +335,81 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Get a rank-pair id from a physical rank
+/// Returns a number representing which rank-pair this rank is a part of
+/// @tparam T the fapi2::TargetType
+/// @param[in] i_target the target (MCA or MBA?)
+/// @param[in] i_rank the physical rank number
+/// @param[out] o_pairs the rank pair
+/// @return FAPI2_RC_SUCCESS if and only if ok, FAPI2_RC_INVALID_PARAMETER if the rank isn't found
+///
+template<>
+fapi2::ReturnCode get_pair_from_rank(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ uint64_t i_rank, uint64_t& o_pair)
+{
+ // Sort of brute-force, but no real good other way to do it. Given the
+ // rank-pair configuration we walk the config looking for our rank, and
+ // return the pair. This is always a small 'search' as there are only
+ // 4 possible rank pair registers
+ // TK this is a std::pair and needs to change to support 3DS
+
+ // So we're being a bit tricky here. The rp fields in the registers have
+ // a 'valid' bit. So, if you think about it, our 'rank' is really 3 bits
+ // of 'rank number' and a set valid-bit. So we move the rank over one
+ // and set the right-most bit. If this matches the 4 bits in the rp register
+ // then this is really the rank pair we're looking for.
+ constexpr uint64_t l_rp_even_primary_mask = 0xF000;
+ constexpr uint64_t l_rp_even_secondary_mask = 0x0F00;
+ constexpr uint64_t l_rp_odd_primary_mask = 0x00F0;
+ constexpr uint64_t l_rp_odd_secondary_mask = 0x000F;
+
+ // Shift rank over to accomoate the valid bit in the field, add one for the valid bit
+ i_rank = (i_rank << 1) + 1;
+
+ std::pair<uint64_t, uint64_t> l_rp_registers;
+ FAPI_TRY( get_rank_pair_assignments(i_target, l_rp_registers) );
+
+ FAPI_DBG("seeing rank pair registers: 0x%016lx 0x%016lx, rank %d (0x%x)",
+ l_rp_registers.first, l_rp_registers.second, i_rank >> 1, i_rank);
+
+ // Check RP0
+ if ((((l_rp_registers.first & l_rp_even_primary_mask) >> 12) == i_rank) ||
+ (((l_rp_registers.first & l_rp_even_secondary_mask) >> 8) == i_rank))
+ {
+ o_pair = 0;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ // Check RP1
+ if ((((l_rp_registers.first & l_rp_odd_primary_mask) >> 4) == i_rank) ||
+ (((l_rp_registers.first & l_rp_odd_secondary_mask) >> 0) == i_rank))
+ {
+ o_pair = 1;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ // Check RP2
+ if ((((l_rp_registers.second & l_rp_even_primary_mask) >> 12) == i_rank) ||
+ (((l_rp_registers.second & l_rp_even_secondary_mask) >> 8) == i_rank))
+ {
+ o_pair = 2;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ // Check RP3
+ if ((((l_rp_registers.second & l_rp_odd_primary_mask) >> 4) == i_rank) ||
+ (((l_rp_registers.second & l_rp_odd_secondary_mask) >> 0) == i_rank))
+ {
+ o_pair = 3;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ // Rank not found
+ return FAPI2_RC_INVALID_PARAMETER;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // namespace
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 1868ce38e..03a3a2efb 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
@@ -72,6 +72,17 @@ bool is_rank_on_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, con
size_t get_dimm_from_rank(const uint64_t i_rank);
///
+/// @brief Given a target, get the rank pair assignments, based on DIMMs
+/// @tparam T the fapi2::TargetType
+/// @param[in] i_target the target (MCA or MBA?)
+/// @param[out] o_registers the regiter settings for the appropriate rank pairs
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< fapi2::TargetType T>
+fapi2::ReturnCode get_rank_pair_assignments(const fapi2::Target<T>& i_target,
+ std::pair<uint64_t, uint64_t>& o_registers);
+
+///
/// @brief Setup the rank information in the port
/// @tparam T the fapi2::TargetType
/// @param[in] i_target the target (MCA or MBA?)
@@ -90,5 +101,17 @@ fapi2::ReturnCode set_rank_pairs(const fapi2::Target<T>& i_target);
template< fapi2::TargetType T>
fapi2::ReturnCode get_rank_pairs(const fapi2::Target<T>& i_target, std::vector<uint64_t>& o_pairs);
+///
+/// @brief Get a rank-pair id from a physical rank
+/// Returns a number representing which rank-pair this rank is a part of
+/// @tparam T the fapi2::TargetType
+/// @param[in] i_target the target (MCA or MBA?)
+/// @param[in] i_rank the physical rank number
+/// @param[out] o_pairs the rank pair
+/// @return FAPI2_RC_SUCCESS if and only if ok, FAPI2_RC_INVALID_PARAMETER if the rank isn't found
+///
+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);
+
}
#endif
OpenPOWER on IntegriCloud