summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C11
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.C60
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rank.H14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C54
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml30
5 files changed, 120 insertions, 49 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C
index 2dd57df9d..bae1e2a45 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/latch_wr_vref.C
@@ -103,7 +103,8 @@ fapi2::ReturnCode latch_wr_vref_commands_by_rank_pair( const fapi2::Target<fapi2
{
// Declares variables
const auto l_mcbist = find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
- const auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target);
+ // Warning: l_dimm is not a valid Target and will crash Cronus if used before it gets filled in by mss::rank::get_dimm_target_from_rank
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
mss::ccs::program<fapi2::TARGET_TYPE_MCBIST, fapi2::TARGET_TYPE_MCA> l_program;
std::vector<uint64_t> l_ranks;
@@ -111,16 +112,16 @@ fapi2::ReturnCode latch_wr_vref_commands_by_rank_pair( const fapi2::Target<fapi2
FAPI_TRY(mss::rank::get_ranks_in_pair( i_target, i_rank_pair, l_ranks));
// Adds in latching commands for all ranks
- for( const auto& l_rank : l_ranks)
+ for (const auto& l_rank : l_ranks)
{
// Skips this rank if no rank is configured
- if( l_rank == NO_RANK)
+ if (l_rank == NO_RANK)
{
continue;
}
- // Sets up the DIMM target
- const auto l_dimm = (l_rank < MAX_RANK_PER_DIMM) ? l_dimms[0] : l_dimms[1];
+ // Ensures we get a valid DIMM target / rank combo
+ FAPI_TRY( mss::rank::get_dimm_target_from_rank(i_target, l_rank, l_dimm) );
// Adds the latching commands to the CCS program for this current rank
FAPI_TRY(setup_latch_wr_vref_commands_by_rank(l_dimm,
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 011f801b5..c7300bc71 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
@@ -175,6 +175,63 @@ size_t get_dimm_from_rank(const uint64_t i_rank)
}
///
+/// @brief Return the DIMM target which posesses this rank on a given port
+/// @param[in] i_target the MCA port target
+/// @param[in] i_rank the rank number
+/// @param[out] o_dimm the DIMM target
+/// @return FAPI2_RC_SUCCESS iff all is ok, FAPI2_RC_INVALID_PARAMETER otherwise
+///
+template<>
+fapi2::ReturnCode get_dimm_target_from_rank(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_rank,
+ fapi2::Target<TARGET_TYPE_DIMM>& o_dimm)
+{
+ const size_t l_dimm_idx = get_dimm_from_rank(i_rank);
+ const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
+ bool l_got_one = false;
+
+ // Make sure we get a valid DIMM index. If not, this is a programming error.
+ FAPI_ASSERT( (l_dimm_idx < l_dimms.size()),
+ fapi2::MSS_BAD_DIMM_INDEX_FOR_GIVEN_RANK()
+ .set_RANK(i_rank)
+ .set_DIMM_INDEX(l_dimm_idx)
+ .set_TARGET(i_target),
+ "Invalid DIMM index (%d) found for provided rank (%d) in get_dimm_target_from_rank: %s",
+ l_dimm_idx,
+ i_rank,
+ mss::c_str(i_target));
+
+ for (const auto& l_dimm : l_dimms)
+ {
+ if (mss::index(l_dimm) == l_dimm_idx)
+ {
+ FAPI_DBG("Found DIMM target for rank %d: %s", i_rank, mss::c_str(l_dimm));
+ o_dimm = l_dimm;
+ l_got_one = true;
+ }
+ }
+
+ if (l_got_one)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Assert if we don't have a DIMM configured that matches the DIMM index (this shouldn't happen)
+ FAPI_ASSERT( false,
+ fapi2::MSS_NO_DIMM_FOR_GIVEN_DIMM_INDEX()
+ .set_RANK(i_rank)
+ .set_DIMM_INDEX(l_dimm_idx)
+ .set_TARGET(i_target),
+ "Couldn't find a DIMM to match given rank (%d) and DIMM position (%d): %s",
+ i_rank,
+ l_dimm_idx,
+ mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Return a vector of rank numbers which represent the primary rank pairs for this port
/// @tparam T the target type
/// @param[in] i_target TARGET_TYPE_MCA
@@ -443,8 +500,9 @@ fapi2::ReturnCode get_rank_pairs(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
if (*rp_iter != NO_RANK)
{
o_pairs.push_back(l_index);
- l_index += 1;
}
+
+ l_index += 1;
}
fapi_try_exit:
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 9ae319a16..9442c6639 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
@@ -616,6 +616,20 @@ 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 Return the DIMM target which posesses this rank on a given port
+/// @tparam T the fapi2::TargetType of the port
+/// @tparam D the fapi2::TargetType of the DIMM
+/// @param[in] i_target the port target
+/// @param[in] i_rank the rank number
+/// @param[out] o_dimm the DIMM target
+/// @return FAPI2_RC_SUCCESS iff all is ok, FAPI2_RC_INVALID_PARAMETER otherwise
+///
+template< fapi2::TargetType T, fapi2::TargetType D >
+fapi2::ReturnCode get_dimm_target_from_rank(const fapi2::Target<T>& i_target,
+ const uint64_t i_rank,
+ fapi2::Target<D>& o_dimm);
+
+///
/// @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?)
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 f2ee912bf..75d85d165 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
@@ -408,63 +408,33 @@ fapi_try_exit:
/// @param[in] i_target the MCA target
/// @param[in] i_rp the rank pair
/// @param[out] o_dimm fapi2::Target<TARGET_TYPE_DIMM>
-/// @return FAPI2_RC_SUCCESS iff ok
+/// @return FAPI2_RC_SUCCESS iff ok, FAPI2_RC_INVALID_PARAMETER if rank pair mapping problem
///
template<>
fapi2::ReturnCode rank_pair_primary_to_dimm( const fapi2::Target<TARGET_TYPE_MCA>& i_target,
const uint64_t i_rp,
fapi2::Target<TARGET_TYPE_DIMM>& o_dimm)
{
- fapi2::buffer<uint64_t> l_data;
- fapi2::buffer<uint64_t> l_rank;
- uint64_t l_rank_on_dimm;
-
- const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
+ std::vector<uint64_t> l_ranks_in_rp = {NO_RANK};
// Sanity check the rank pair
FAPI_INF("%s rank pair: %d", mss::c_str(i_target), i_rp);
fapi2::Assert(i_rp < MAX_RANK_PER_DIMM);
- // We need to get the register containing the specification for this rank pair,
- // and fish out the primary rank for this rank pair
- switch(i_rp)
- {
- case 0:
- FAPI_TRY( mss::getScom(i_target, MCA_DDRPHY_PC_RANK_PAIR0_P0, l_data) );
- l_data.extractToRight<MCA_DDRPHY_PC_RANK_PAIR0_P0_PRI,
- MCA_DDRPHY_PC_RANK_PAIR0_P0_PRI_LEN>(l_rank);
- break;
-
- case 1:
- FAPI_TRY( mss::getScom(i_target, MCA_DDRPHY_PC_RANK_PAIR0_P0, l_data) );
- l_data.extractToRight<MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_PRI,
- MCA_DDRPHY_PC_RANK_PAIR0_P0_PAIR1_PRI_LEN>(l_rank);
- break;
-
- case 2:
- FAPI_TRY( mss::getScom(i_target, MCA_DDRPHY_PC_RANK_PAIR1_P0, l_data) );
- l_data.extractToRight<MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_PRI,
- MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR2_PRI_LEN>(l_rank);
- break;
-
- case 3:
- FAPI_TRY( mss::getScom(i_target, MCA_DDRPHY_PC_RANK_PAIR1_P0, l_data) );
- l_data.extractToRight<MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_PRI,
- MCA_DDRPHY_PC_RANK_PAIR1_P0_PAIR3_PRI_LEN>(l_rank);
- break;
- };
-
- // 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 = mss::rank::get_dimm_from_rank(l_rank);
+ // Get the rp's primary rank, and figure out which DIMM it's on
+ FAPI_TRY( mss::rank::get_ranks_in_pair(i_target, i_rp, l_ranks_in_rp) );
- // 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());
+ // Make sure we have a valid rank
+ if (l_ranks_in_rp[0] == NO_RANK)
+ {
+ FAPI_ERR("%s No primary rank in rank pair %d", mss::c_str(i_target), i_rp);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ }
- fapi2::Assert(l_rank_on_dimm < l_dimms.size());
+ FAPI_TRY( mss::rank::get_dimm_target_from_rank(i_target, l_ranks_in_rp[0], o_dimm) );
- o_dimm = l_dimms[l_rank_on_dimm];
+ FAPI_INF("%s rank pair %d is on dimm: %s", mss::c_str(i_target), i_rp, mss::c_str(o_dimm));
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
index 5f3659f5f..c55868f1e 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_lib.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2016 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2017 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -408,4 +408,32 @@
</callout>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_BAD_DIMM_INDEX_FOR_GIVEN_RANK</rc>
+ <description>Indicates a fail when attempting to get a DIMM index for a given rank</description>
+ <ffdc>RANK</ffdc>
+ <ffdc>DIMM_INDEX</ffdc>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_NO_DIMM_FOR_GIVEN_DIMM_INDEX</rc>
+ <description>Indicates a fail when attempting to get a DIMM target for a given DIMM index</description>
+ <ffdc>RANK</ffdc>
+ <ffdc>DIMM_INDEX</ffdc>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
</hwpErrors>
OpenPOWER on IntegriCloud