diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-09-28 16:48:11 -0500 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2016-10-04 18:47:54 -0400 |
commit | e1e8610960d9b5124a656b662144ff6b76631e85 (patch) | |
tree | e01487498c3234a8bea113951aeae99288fed12f /src/import/chips | |
parent | 7bc64f60dbbfe24d3c7c0b649a94d1ca77cba86a (diff) | |
download | talos-hostboot-e1e8610960d9b5124a656b662144ff6b76631e85.tar.gz talos-hostboot-e1e8610960d9b5124a656b662144ff6b76631e85.zip |
Add MCBIST workaround super-fast read & 1R DIMM
Change-Id: I6473dfd00e9636797619e0e3d3a6d54eb9cdb5b9
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30553
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30561
Reviewed-by: Hostboot Team <hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import/chips')
5 files changed, 209 insertions, 8 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 1c693bd36..ccd7c2700 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 @@ -36,14 +36,13 @@ #include <fapi2.H> #include <lib/mcbist/mcbist.H> #include <lib/utils/dump_regs.H> +#include <lib/workarounds/mcbist_workarounds.H> using fapi2::TARGET_TYPE_MCBIST; using fapi2::TARGET_TYPE_MCA; namespace mss { -namespace mcbist -{ const std::pair<uint64_t, uint64_t> mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::address_pairs[] = { @@ -53,6 +52,8 @@ const std::pair<uint64_t, uint64_t> mcbistTraits<fapi2::TARGET_TYPE_MCBIST>::add { START_ADDRESS_3, END_ADDRESS_3 }, }; +namespace mcbist +{ /// /// @brief Load a set of MCBIST subtests in to the MCBIST registers @@ -225,6 +226,13 @@ fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, fapi2::MSS_MEMDIAGS_NO_MCBIST_SUBTESTS().set_TARGET(i_target), "Attempt to run an MCBIST program with no subtests on %s", mss::c_str(i_target)); + // Implement any mcbist work-arounds. + // I'm going to do the unthinkable here - and cast away the const of the mcbist program input. + // The work arounds need to change this, and so it needs to not be const. However, I don't want + // to risk general const-correctness by changing the input parameter to non-const. So, I use + // const_cast<> (ducks out of the way of the flying adjectives.) These are work-arounds ... + FAPI_TRY( workarounds::mcbist::end_of_rank(i_target, const_cast<program<TARGET_TYPE_MCBIST>&>(i_program)) ); + FAPI_TRY( clear_errors(i_target) ); // Slam the address generator config diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H index 7f71e1276..333698600 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H @@ -50,8 +50,6 @@ namespace mss { -namespace mcbist -{ // I have a dream that the MCBIST engine code can be shared among controllers. So, I drive the // engine from a set of traits. This might be folly. Allow me to dream. BRS @@ -291,6 +289,9 @@ class mcbistTraits<fapi2::TARGET_TYPE_MCBIST> }; +namespace mcbist +{ + /// /// @class subtest_t /// @brief encapsulation of an MCBIST subtest. @@ -633,6 +634,39 @@ inline subtest_t<T> read_subtest() } /// +/// @brief Return a display subtest - configured simply +/// @tparam T the fapi2::TargetType - derived +/// @tparam TT the mcbistTraits associated with T - derived +/// @return mss::mcbist::subtest_t +/// @note Turns on ECC mode for the returned subtest - caller can turn it off +/// @note Configures for start/end address select bit as address config register 0 +/// +template< fapi2::TargetType T, typename TT = mcbistTraits<T> > +inline subtest_t<T> display_subtest() +{ + // Starts life full of 0's + subtest_t<T> l_subtest; + + // 0:3 = 1100 - we want subtest type to be a DISPLAY (R, slow) + l_subtest.iv_mcbmr.template insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(op_type::DISPLAY); + + // - Not a special subtest, so no other configs associated + // 4 = 0 - we don't want to complement data for our Writes + // 5:6 = 00 - don't know whether we complement 2nd and 3rd subcommand, caller to fix + // 7 = 0 - forward address generation + // 8 = 0 - non random address generation + // - Don't need to set up anything for LFSRs + // 9:11 = 000 - Fixed data mode + + // 14:15 = 0 address select config registers 0 + + // By default we want to turn on ECC. Caller can turn it off. + l_subtest.change_ecc_mode(mss::ON); + + return l_subtest; +} + +/// /// @brief Return a read write subtest - configured simply /// @tparam T the fapi2::TargetType - derived /// @tparam TT the mcbistTraits associated with T - derived @@ -1406,10 +1440,10 @@ class program // asked for a master rank detect. iv_config.insertFromRight<TT::CFG_PAUSE_ON_ERROR_MODE, TT::CFG_PAUSE_ON_ERROR_MODE_LEN>(i_end); - FAPI_INF("i_end 0x%016lx", i_end); uint64_t l_detect_slave = fapi2::buffer<uint64_t>(i_end).getBit<SLAVE_RANK_INDICATED_BIT>(); iv_addr_gen.writeBit<TT::MAINT_DETECT_SRANK_BOUNDARIES>( l_detect_slave ); - FAPI_INF("load MCBIST end boundaries: detect slave? %s", (l_detect_slave == 1 ? "yes" : "no") ); + FAPI_INF("load MCBIST end boundaries 0x%016lx detect slave? %s", + i_end, (l_detect_slave == 1 ? "yes" : "no") ); } /// diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C index e9ab2b992..6066b414e 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/memdiags.C @@ -65,7 +65,7 @@ template<> fapi2::ReturnCode stop( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target ) { // Too long, make shorter - using TT = mss::mcbist::mcbistTraits<TARGET_TYPE_MCBIST>; + using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>; // Poll parameters are defined as TK so that we wait a nice time for operations // For now use the defaults @@ -576,7 +576,7 @@ fapi2::ReturnCode continue_cmd( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targe const speed i_speed ) { // Too long, make shorter - using TT = mss::mcbist::mcbistTraits<TARGET_TYPE_MCBIST>; + using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>; // We can use a local mcbist::program to help with the bit processing, and then write just the registers we touch. mss::mcbist::program<TARGET_TYPE_MCBIST> l_program; diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C index 958e5f464..37217c300 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.C @@ -22,3 +22,107 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mcbist_workarounds.C +/// @brief Workarounds for the MCBISt engine +/// Workarounds are very deivce specific, so there is no attempt to generalize +/// this code in any way. +/// +// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com> +// *HWP HWP Backup: Steven Glancy <sglancy@usi.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#include <fapi2.H> +#include <p9_mc_scom_addresses.H> +#include <p9_mc_scom_addresses_fld.H> + +#include <lib/utils/scom.H> +#include <lib/utils/pos.H> +#include <lib/dimm/kind.H> +#include <lib/workarounds/mcbist_workarounds.H> +#include <lib/mcbist/mcbist.H> + +using fapi2::TARGET_TYPE_MCBIST; +using fapi2::TARGET_TYPE_DIMM; +using fapi2::FAPI2_RC_SUCCESS; + +namespace mss +{ + +namespace workarounds +{ + +namespace mcbist +{ + +/// +/// @brief Replace reads with displays in the passed in MCBIST program +/// @param[in] the MCBIST program to check for read/display replacement +/// @note Useful for testing +/// +void replace_read_helper(mss::mcbist::program<TARGET_TYPE_MCBIST>& i_program) +{ + using TT = mss::mcbistTraits<TARGET_TYPE_MCBIST>; + + i_program.change_maint_broadcast_mode(mss::OFF); + i_program.change_end_boundary(mss::mcbist::end_boundary::STOP_AFTER_ADDRESS); + + for (auto& st : i_program.iv_subtests) + { + uint64_t l_op = 0; + st.iv_mcbmr.extractToRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_op); + + if (l_op == mss::mcbist::op_type::READ) + { + l_op = mss::mcbist::op_type::DISPLAY; + } + + st.iv_mcbmr.insertFromRight<TT::OP_TYPE, TT::OP_TYPE_LEN>(l_op); + } +} + +/// +/// @brief End of rank work around +/// For Nimbus DD1 the MCBIST engine doesn't detect the end of rank properly +/// for a 1R DIMM during a super-fast read. To work around this, we check the +/// MCBIST to see if any port has a 1R DIMM on it and if so we change our stop +/// conditions to immediate. However, because that doesn't work (by design) with +/// read, we also must change all reads to displays (slow read.) +/// @param[in] i_target the fapi2 target of the mcbist +/// @param[in] i_program the mcbist program to check +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode end_of_rank( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target, + mss::mcbist::program<TARGET_TYPE_MCBIST>& i_program ) +{ + // TODO RTC:160353 - implement DD1 checking when that attribute is available + + // First things first - lets find out if we have an 1R DIMM on our side of the chip. + const auto l_dimm_kinds = dimm::kind::vector( mss::find_targets<TARGET_TYPE_DIMM>(i_target) ); + auto l_kind = std::find_if(l_dimm_kinds.begin(), l_dimm_kinds.end(), [](const dimm::kind & k) -> bool + { + // If total ranks are 1, we have a 1R DIMM, SDP. This is the fellow of concern + return k.iv_total_ranks == 1; + }); + + // If we don't find the fellow of concern, we can get outta here + if (l_kind == l_dimm_kinds.end()) + { + FAPI_INF("no 1R SDP DIMM on this MCBIST (%s), we're ok", mss::c_str(i_target)); + return FAPI2_RC_SUCCESS; + } + + // If we're here, we need to fix up our program. We need to set our stop to stop immediate, which implies + // we don't do broadcasts and we can't do read, we have to do display. + replace_read_helper(i_program); + + return fapi2::FAPI2_RC_SUCCESS; +} + +} // close namespace mcbist +} // close namespace workarounds +} // close namespace mss + diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H index e3320f13f..0f8e9c978 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/mcbist_workarounds.H @@ -22,3 +22,58 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mcbist_workarounds.H +/// @brief Workarounds for the MCBISt engine +/// Workarounds are very deivce specific, so there is no attempt to generalize +/// this code in any way. +/// +// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com> +// *HWP HWP Backup: Steven Glancy <sglancy@usi.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_WORKAROUNDS_MCBIST_H_ +#define _MSS_WORKAROUNDS_MCBIST_H_ + +#include <fapi2.H> +#include <lib/mcbist/mcbist.H> + +namespace mss +{ + +namespace workarounds +{ + +namespace mcbist +{ + +/// +/// @brief Replace reads with displays in the passed in MCBIST program +/// @param[in] the MCBIST program to check for read/display replacement +/// @note Useful for testing +/// +void replace_read_helper(mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_program); + +/// +/// @brief End of rank work around +/// For Nimbus DD1 the MCBIST engine doesn't detect the end of rank properly +/// for a 1R DIMM during a super-fast read. To work around this, we check the +/// MCBIST to see if any port has a 1R DIMM on it and if so we change our stop +/// conditions to immediate. However, because that doesn't work (by design) with +/// read, we also must change all reads to displays (slow read.) +/// @param[in] i_target the fapi2 target of the mcbist +/// @param[in] i_program the mcbist program to check +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok +/// +fapi2::ReturnCode end_of_rank( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target, + mss::mcbist::program<fapi2::TARGET_TYPE_MCBIST>& i_program ); + +} // close namespace mcbist +} // close namespace workarounds +} // close namespace mss + +#endif + |