From 504aa7ff8248d95884495e9d1ef7c774237eb7a9 Mon Sep 17 00:00:00 2001 From: Bradley Pepper Date: Fri, 20 Dec 2019 16:46:00 -0500 Subject: [PATCH] Adds plug rule for dependent DIMM slots on Swift Change-Id: Ia528660b05e8a01186376dfaae26e6ea9258457b Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/89032 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Tested-by: PPE CI Tested-by: HWSV CI Reviewed-by: Mark Pizzutillo Reviewed-by: NICOLAS R FAJARDO Tested-by: Hostboot CI Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/91336 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Daniel M Crowell --- .../hwp/memory/lib/utils/explorer_pos.C | 18 ++- .../memory/lib/plug_rules/p9a_plug_rules.C | 150 +++++++++++++++++- .../memory/lib/plug_rules/p9a_plug_rules.H | 58 ++++++- .../hwp/memory/lib/shared/axone_consts.H | 26 ++- .../p9a/procedures/hwp/memory/p9a_mss_freq.C | 6 + .../xml/error_info/generic_error.xml | 21 +++ 6 files changed, 274 insertions(+), 5 deletions(-) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C index 18bb2557de9..d03360d601d 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C @@ -99,8 +99,22 @@ posTraits::pos_type relative_pos(const fapi2::Target& i_target) { typedef mcTypeTraits TT; - return fapi_pos(i_target) % (TT::PORTS_PER_OCMB * TT::OCMB_PER_OMI * TT::OMI_PER_MCC * TT::MCC_PER_MI * TT::MI_PER_MC * - TT::MC_PER_PROC); + return fapi_pos(i_target) % (TT::PORTS_PER_OCMB * TT::OCMB_PER_OMI * TT::OMI_PER_MCC * TT::MCC_PER_MI * + TT::MI_PER_MC * TT::MC_PER_PROC); +} + +/// +/// @brief Return an OCMB's relative position from a proc_chip +/// @param[in] i_target a target representing the target in question +/// @return The position relative to chiplet R +/// +template<> +posTraits::pos_type +relative_pos(const fapi2::Target& i_target) +{ + typedef mcTypeTraits TT; + return fapi_pos(i_target) % (TT::OCMB_PER_OMI * TT::OMI_PER_MCC * TT::MCC_PER_MI * + TT::MI_PER_MC * TT::MC_PER_PROC); } /// diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C index e27f6cef5f2..3c5c89c73b8 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2020 */ +/* Contributors Listed Below - COPYRIGHT 2019,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,3 +22,151 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file p9a_plug_rules.C +/// @brief Enforcement of rules for plugging in DIMM +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +namespace mss +{ + +namespace plug_rule +{ + +/// +/// @brief Helper function for channel_a_before_channel_b unit testing +/// @param[in] i_target ocmb chip target +/// @param[in] i_pos ocmb chip position +/// @param[in] i_ocmbs vector of all configured ocmb chips under proc chip +/// @param[out] o_channel_a_pos ocmb chip position +/// @param[out] o_pass true if plug rule passes, false otherwise +/// @return fapi2::FAPI2_RC_SUCCESS if okay +/// +fapi2::ReturnCode channel_a_before_channel_b_helper(const fapi2::Target& i_target, + const uint64_t i_pos, + const std::vector>& i_ocmbs, + uint64_t& o_channel_a_pos, + bool& o_pass) +{ + // Create a vector of the channel A position for each OCMB (according to Swift Design Workbook v1.1 29May2019.pdf) + static const std::vector l_dependencies = {0, 0, 0, 2, 0, 6, 0, 4, 0, 9, 0, 11, 0, 12, 0, 14}; + uint64_t l_dependency = 0; + auto l_ocmb_it = i_ocmbs.begin(); + + // Comparator lambda expression + const auto compare = [&l_dependency](const fapi2::Target& i_lhs) + { + return (mss::relative_pos(i_lhs) == l_dependency); + }; + + FAPI_ASSERT(i_pos < mss::axone::MAX_DIMM_PER_PROC, + fapi2::MSS_OUT_OF_BOUNDS_INDEXING() + .set_TARGET(i_target) + .set_INDEX(i_pos) + .set_LIST_SIZE(l_dependencies.size()) + .set_FUNCTION(mss::axone::CHANNEL_A_BEFORE_CHANNEL_B), + "%s has an invalid position index (%d)", mss::c_str(i_target), i_pos); + + o_channel_a_pos = l_dependencies[i_pos]; + + // All even positions are channel A, so they are ok + if (!is_odd(i_pos)) + { + o_pass = true; + return fapi2::FAPI2_RC_SUCCESS; + } + + // Check the channel A dependency for i_pos + l_dependency = l_dependencies[i_pos]; + + // Find iterator to matching key (make sure OCMB for channel A is configured) + l_ocmb_it = std::find_if(i_ocmbs.begin(), + i_ocmbs.end(), + compare); + + o_pass = l_ocmb_it != i_ocmbs.end(); + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Enforce plug order dependencies +/// @param[in] i_target proc chip target +/// @return fapi2::FAPI2_RC_SUCCESS if okay +/// +fapi2::ReturnCode channel_a_before_channel_b(const fapi2::Target& i_target) +{ + typedef mcTypeTraits TT; + + fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; + const auto l_ocmbs = mss::find_targets(i_target); + const uint64_t l_pos_offset = mss::fapi_pos(i_target) * + (TT::OCMB_PER_OMI * TT::OMI_PER_MCC * TT::MCC_PER_MI * TT::MI_PER_MC * TT::MC_PER_PROC); + + for ( const auto& l_ocmb : l_ocmbs ) + { + // Find the position of the ocmb chip + const auto l_pos = mss::relative_pos(l_ocmb); + uint64_t l_channel_a_pos = 0; + bool l_pass = false; + + FAPI_TRY(channel_a_before_channel_b_helper(l_ocmb, l_pos, l_ocmbs, l_channel_a_pos, l_pass)); + + // Call out this OCMB if it's channel A partner is not configured + FAPI_ASSERT( l_pass, + fapi2::MSS_PLUG_RULES_SINGLE_DDIMM_IN_WRONG_SLOT() + .set_SLOT_POSITION(l_pos + l_pos_offset) + .set_CHANNEL_A_SLOT_POSITION(l_channel_a_pos + l_pos_offset) + .set_TARGET(l_ocmb), + "%s DDIMM is plugged into the wrong slot. Must plug into channel A slot first (%d)", mss::c_str(l_ocmb), + (l_channel_a_pos + l_pos_offset) ); + } + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Enforce the plug-rules we can do before mss_freq +/// @param[in] i_target FAPI2 target (proc chip) +/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code +/// +fapi2::ReturnCode enforce_pre_freq(const fapi2::Target& i_target) +{ + // If there are no DIMM, we can just get out. + if (mss::count_dimm(mss::find_targets(i_target)) == 0) + { + FAPI_INF("Skipping plug rule check on %s because it has no DIMM configured", mss::c_str(i_target)); + return fapi2::FAPI2_RC_SUCCESS; + } + + // Check channel A versus B plug order dependencies + FAPI_TRY( channel_a_before_channel_b(i_target) ); + +fapi_try_exit: + return fapi2::current_err; +} + +} // ns plug_rule + +} // ns mss diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H index 8ccc4ab9c01..ce99f26918d 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/plug_rules/p9a_plug_rules.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2020 */ +/* Contributors Listed Below - COPYRIGHT 2019,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,3 +22,59 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file p9a_plug_rules.H +/// @brief Enforcement of rules for plugging in DIMM +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _P9A_PLUG_RULES_H_ +#define _P9A_PLUG_RULES_H_ + +#include +#include + +namespace mss +{ + +namespace plug_rule +{ + +/// +/// @brief Enforce the plug-rules we can do before mss_freq +/// @param[in] i_target FAPI2 target (proc chip) +/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code +/// +fapi2::ReturnCode enforce_pre_freq(const fapi2::Target& i_target); + +/// +/// @brief Enforce having Channel A plugged before Channel B +/// @param[in] i_target proc chip target +/// @return fapi2::FAPI2_RC_SUCCESS if okay +/// +fapi2::ReturnCode channel_a_before_channel_b(const fapi2::Target& i_target); + +/// +/// @brief Helper function for channel_a_before_channel_b unit testing +/// @param[in] i_target ocmb chip target +/// @param[in] i_pos ocmb chip position +/// @param[in] i_ocmbs vector of all configured ocmb chips under proc chip +/// @param[out] o_channel_a_pos ocmb chip position +/// @param[out] o_pass true if plug rule passes, false otherwise +/// @return fapi2::FAPI2_RC_SUCCESS if okay +/// +fapi2::ReturnCode channel_a_before_channel_b_helper(const fapi2::Target& i_target, + const uint64_t i_pos, + const std::vector>& i_ocmbs, + uint64_t& o_channel_a_pos, + bool& o_pass); + +} // ns plug_rule +} // ns mss + +#endif // _P9A_PLUG_RULES_H_ diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H b/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H index dcca78fa06b..5c992e00251 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H +++ b/src/import/chips/p9a/procedures/hwp/memory/lib/shared/axone_consts.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2019 */ +/* Contributors Listed Below - COPYRIGHT 2019,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -43,4 +43,28 @@ const uint8_t MAX_MC_SIDES_PER_PROC = 2; // MC01, MC23 const uint8_t MAX_MC_PER_PROC = 4; // MC0, MC1, MC2, MC3 const uint8_t MAX_MC_PER_SIDE = 2; // MC0, MC1 or MC2, MC3 +namespace mss +{ +namespace axone +{ + +/// +/// @brief common axone sizes +/// +enum sizes +{ + MAX_DIMM_PER_PROC = 16, +}; + +/// +/// @brief explorer ffdc codes +/// +enum ffdc_codes +{ + CHANNEL_A_BEFORE_CHANNEL_B = 0x9000, +}; + +} // axone +} // mss + #endif diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C index 4e8db714217..40948638472 100644 --- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C +++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C @@ -48,6 +48,7 @@ #include #include #include +#include /// /// @brief Calculate and save off DIMM frequencies @@ -94,6 +95,11 @@ fapi2::ReturnCode p9a_mss_freq( const fapi2::Target(i_target)); fapi_try_exit: diff --git a/src/import/generic/procedures/xml/error_info/generic_error.xml b/src/import/generic/procedures/xml/error_info/generic_error.xml index 86114f82a33..840ce68494f 100644 --- a/src/import/generic/procedures/xml/error_info/generic_error.xml +++ b/src/import/generic/procedures/xml/error_info/generic_error.xml @@ -1292,4 +1292,25 @@ + + RC_MSS_PLUG_RULES_SINGLE_DDIMM_IN_WRONG_SLOT + + A single DIMM was plugged into a secondary channel slot without + one plugged into the primary channel slot. + + SLOT_POSITION + CHANNEL_A_SLOT_POSITION + + MEMORY_PLUGGING_ERROR + HIGH + + + TARGET + LOW + + + TARGET + + +