summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2017-09-07 16:38:20 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-11-01 15:35:48 -0400
commitd110f5634137d979a14eb4b0b5e9c803aa413a7d (patch)
treea3e42f46c649143f381435a8a43f00efc71714dd /src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
parent6f456343a42a3def8d14637b2f8ffc90832ee563 (diff)
downloadtalos-hostboot-d110f5634137d979a14eb4b0b5e9c803aa413a7d.tar.gz
talos-hostboot-d110f5634137d979a14eb4b0b5e9c803aa413a7d.zip
Adds in broadcast support for memdiags
Change-Id: I168b8a285a0e8509c8cf92e170ec3d1ea8607e6b Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46032 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Dev-Ready: STEPHEN GLANCY <sglancy@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/46037 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
index bd9ac2b89..f97ef924e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
@@ -679,6 +679,187 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Checks if broadcast mode is capable of being enabled on this vector of targets
+/// @param[in] i_targets the vector of targets to analyze - specialization for MCA target type
+/// @return l_capable - yes iff these vector of targets are broadcast capable
+///
+template< >
+const mss::states is_broadcast_capable(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>& i_targets)
+{
+ // If we don't have MCA's exit out
+ if(i_targets.size() == 0)
+ {
+ FAPI_INF("No MCA's found. Not broadcast capable, exiting...");
+ return mss::states::NO;
+ }
+
+ // Now the fun begins
+ // First, get the number of DIMM's on the 0th MCA
+ const uint64_t l_first_mca_num_dimm = mss::count_dimm(i_targets[0]);
+
+ // Now, find if we have any MCA's that have a different number of DIMM's
+ const auto l_mca_it = std::find_if(i_targets.begin(),
+ i_targets.end(),
+ [l_first_mca_num_dimm]( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_rhs) -> bool
+ {
+ // Count the number of DIMM and compare to the expected
+ const uint64_t l_num_dimm = mss::count_dimm(i_rhs);
+
+ // If they're different, we found the MCA that is different
+ return (l_first_mca_num_dimm != l_num_dimm);
+ });
+
+ // If no MCA was found that have a different number of DIMMs (aka a different drop), then we are broadcast capable
+ if(l_mca_it == i_targets.end())
+ {
+ const auto l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_targets[0]);
+ FAPI_INF("MCA vector from %s has the same number of DIMMs per port: %lu - is broadcast capable",
+ mss::c_str(l_mcbist), l_first_mca_num_dimm);
+ return mss::states::YES;
+ }
+
+ // Otherwise, note the MCA that differs and return that this is not broadcast capable
+ FAPI_INF("MCA %s differs on the number of DIMMs per port: (number of DIMMs from i_targets[0] %lu, found %lu) - is NOT broadcast capable",
+ mss::c_str(*l_mca_it), l_first_mca_num_dimm, mss::count_dimm(*l_mca_it));
+ return mss::states::NO;
+}
+
+///
+/// @brief Checks if broadcast mode is capable of being enabled on this target
+/// @param[in] i_target the target to effect - specialization for MCBIST target type
+/// @return l_capable - yes iff these vector of targets are broadcast capable
+///
+template< >
+const mss::states is_broadcast_capable(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target)
+{
+ // Steps to determine if this MCBIST is broadcastable
+ // 1) Check the number of DIMM's on each MCA - true only if they all match
+ // 2) Check that all of the DIMM kinds are equal - if the are, then we can do broadcast mode
+ // 3) if both 1 and 2 are true, then broadcast capable, otherwise false
+
+ // 1) Check the number of DIMM's on each MCA - if they don't match, then no
+ const auto l_mca_check = is_broadcast_capable(mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target));
+
+ // 2) Check that all of the DIMM kinds are equal - if the are, then we can do broadcast mode
+ const auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target);
+ const auto l_dimm_kinds = mss::dimm::kind::vector(l_dimms);
+ const auto l_dimm_kind_check = is_broadcast_capable(l_dimm_kinds);
+
+ // 3) if both 1/2 are true, then broadcastable, otherwise false
+ const auto l_capable = (l_mca_check == mss::states::YES && l_dimm_kind_check == mss::states::YES) ?
+ mss::states::YES : mss::states::NO;
+
+ FAPI_INF("%s %s broadcast capable", mss::c_str(i_target), (l_capable == mss::states::YES) ? "is" : "is not");
+ return l_capable;
+}
+
+///
+/// @brief Checks if broadcast mode is capable of being enabled on this vector of targets
+/// @param[in] i_target the target to effect
+/// @return l_capable - yes iff these vector of targets are broadcast capable
+///
+const mss::states is_broadcast_capable(const std::vector<mss::dimm::kind>& i_kinds)
+{
+ // If we don't have any DIMM kinds exit out
+ if(i_kinds.size() == 0)
+ {
+ FAPI_INF("No DIMM kinds are located. Not broadcast capable, exiting...");
+ return mss::states::NO;
+ }
+
+ // Now the fun begins
+ // First, get the starting kind - the 0th kind in the vector
+ const auto l_expected_kind = i_kinds[0];
+
+ // Now, find if we have any kinds that differ from our first kind
+ const auto l_kind_it = std::find_if(i_kinds.begin(),
+ i_kinds.end(), [&l_expected_kind]( const mss::dimm::kind & i_rhs) -> bool
+ {
+ // If they're different, we found a DIMM that is differs
+ return (l_expected_kind != i_rhs);
+ });
+
+ // If no DIMM kind was found that differs, then we are broadcast capable
+ if(l_kind_it == i_kinds.end())
+ {
+ FAPI_INF("DIMM kinds vector starting with %s has the kinds for all DIMM's - is broadcast capable",
+ mss::c_str(l_expected_kind.iv_target));
+ return mss::states::YES;
+ }
+
+ // Otherwise, note the MCA that differs and return that this is not broadcast capable
+ FAPI_INF("DIMM kinds vector differs with %s has the kinds for all DIMM's - is not broadcast capable",
+ mss::c_str(l_kind_it->iv_target));
+ return mss::states::NO;
+}
+
+///
+/// @brief Configures all of the ports for broadcast mode
+/// @param[in] i_target the target to effect - MCBIST specialization
+/// @param[out] o_port_select - the configuration of the selected ports
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< >
+fapi2::ReturnCode setup_broadcast_port_select(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ uint64_t& o_port_select)
+{
+ // Starting location - the MCBIST type takes in ports as a right justified uint64_t value
+ // As we have 4 ports per-MCBIST, they occupy 60-63
+ // START contains the starting offset for each port
+ constexpr uint64_t START = 60;
+
+ // Loops through all the ports and adds them to the broadcast value
+ fapi2::buffer<uint64_t> l_port_select;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ for(const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
+ {
+ // Configures each port individually
+ const uint64_t l_offset = mss::relative_pos<TARGET_TYPE_MCBIST>(l_mca);
+ FAPI_TRY(l_port_select.setBit(START + l_offset),
+ "%s setBit error for relative pos of %lu",
+ mss::c_str(l_mca), l_offset);
+ }
+
+ // Assigns the returned value
+ o_port_select = l_port_select;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Enables broadcast mode
+/// @param[in] i_target the target to effect - MCBIST specialization
+/// @param[in,out] io_program the mcbist::program - MCBIST specialization
+/// @return FAPI2_RC_SUCCSS iff ok
+///
+template< >
+fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ mcbist::program<fapi2::TARGET_TYPE_MCBIST>& io_program)
+{
+ // constexpr's for beautification
+ constexpr bool ENABLE = true;
+ constexpr auto BROADCAST_SYNC_ENABLE = mss::states::ON;
+ constexpr auto MAX_BROADCAST_SYNC_WAIT = mss::mcbist::broadcast_timebase::TB_COUNT_128;
+
+ // First, enable broadcast mode
+ io_program.change_maint_broadcast_mode(ENABLE);
+
+ // Second, configure broadcast mode on all enabled ports
+ uint64_t l_port_select = 0;
+ FAPI_TRY(setup_broadcast_port_select(i_target, l_port_select));
+ io_program.select_ports(l_port_select);
+
+ // Finally, enable broadcast sync mode and max out the wait to avoid timeout issues
+ io_program.broadcast_sync_enable(BROADCAST_SYNC_ENABLE);
+ io_program.change_broadcast_timebase(MAX_BROADCAST_SYNC_WAIT);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // namespace MCBIST
// Note: outside of the mcbist namespace
OpenPOWER on IntegriCloud