summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2017-10-02 09:02:35 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-09-18 22:39:30 -0500
commitbb0c1121374cac632988e090dee4c37d38d0376f (patch)
tree3bde7918980f3248bda6babd626709e052eb3dbf
parent8b1a3dcf482e171e7b026cdd180f27ab15357941 (diff)
downloadtalos-hostboot-bb0c1121374cac632988e090dee4c37d38d0376f.tar.gz
talos-hostboot-bb0c1121374cac632988e090dee4c37d38d0376f.zip
Updates memory plug rules
Plug rules to update 1) NO LRDIMM's allowed - currently not supported by code 2) No 3DS/non-3DS mixing - hardware workaround 3) No DRAM width mixing - from DRAM technical leadership 4) No hybrid/non-hybrid DIMM mixing Change-Id: I4f5126e10d935a34b3dfa549779fa7ba5c2b11de Original-Change-Id: I5505e37a1ccd2b96860b4c1fef0fdaba0a7f9b21 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/47013 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66311 Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Tested-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C166
1 files changed, 165 insertions, 1 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
index cc6f0721c..b8f23cd1a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
@@ -55,6 +55,157 @@ namespace mss
namespace plug_rule
{
+namespace code
+{
+
+///
+/// @brief Checks for invalid LRDIMM plug combinations
+/// @param[in] i_kinds a vector of DIMM (sorted while procesing)
+/// @return fapi2::FAPI2_RC_SUCCESS if no LRDIMM, otherwise a MSS_PLUG_RULE error code
+/// @note This function will commit error logs representing the mixing failure
+///
+fapi2::ReturnCode check_lrdimm( const std::vector<dimm::kind>& i_kinds )
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // If we have 0 DIMMs on the port, we don't care
+ for(const auto& l_kind : i_kinds)
+ {
+ FAPI_ASSERT( l_kind.iv_dimm_type != fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM,
+ fapi2::MSS_PLUG_RULES_LRDIMM_UNSUPPORTED()
+ .set_DIMM_TARGET(l_kind.iv_target),
+ "%s has an LRDIMM plugged and is currently unsupported",
+ mss::c_str(l_kind.iv_target) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // code
+
+///
+/// @brief Enforce DRAM width checks
+/// @note DIMM0's width needs to equal DIMM1's width
+/// @param[in] i_target the port
+/// @param[in] i_kinds a vector of DIMM (sorted while processing)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Expects the kind array to represent the DIMM on the port.
+///
+fapi2::ReturnCode check_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const std::vector<dimm::kind>& i_kinds)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Only do this check if we have the maximum number DIMM kinds
+ if(i_kinds.size() == MAX_DIMM_PER_PORT)
+ {
+ FAPI_ASSERT( i_kinds[0].iv_dram_width == i_kinds[1].iv_dram_width,
+ fapi2::MSS_PLUG_RULES_INVALID_DRAM_WIDTH_MIX()
+ .set_DIMM_SLOT_ZERO(i_kinds[0].iv_dram_width)
+ .set_DIMM_SLOT_ONE(i_kinds[1].iv_dram_width)
+ .set_MCA_TARGET(i_target),
+ "%s has DIMM's with two different DRAM widths installed of type %d and of type %d. Cannot mix DIMM of different widths on a single port",
+ mss::c_str(i_target), i_kinds[0].iv_dram_width, i_kinds[1].iv_dram_width );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Enforce hybrid DIMM checks
+/// @note No hybrid/non-hybrid and no different hybrid types
+/// @param[in] i_target the port
+/// @param[in] i_kinds a vector of DIMM (sorted while processing)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Expects the kind array to represent the DIMM on the port.
+///
+fapi2::ReturnCode check_hybrid(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const std::vector<dimm::kind>& i_kinds)
+{
+ // Make sure we don't get a stale error
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Skip the below checks if we have less than the maximum number of DIMM's
+ if(i_kinds.size() < MAX_DIMM_PER_PORT)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Assert that we do not have an error
+ FAPI_ASSERT( i_kinds[0].iv_hybrid == i_kinds[1].iv_hybrid,
+ fapi2::MSS_PLUG_RULES_INVALID_HYBRID_MIX()
+ .set_DIMM_SLOT_ZERO(i_kinds[0].iv_hybrid)
+ .set_DIMM_SLOT_ONE(i_kinds[1].iv_hybrid)
+ .set_MCA_TARGET(i_target),
+ "%s has DIMM's with two different hybrid types installed (type %d and type %d). Cannot mix DIMM of different hybrid types on a single port",
+ mss::c_str(i_target), i_kinds[0].iv_hybrid, i_kinds[1].iv_hybrid );
+
+ // Only do the below check if the DIMM's are hybrid DIMM's
+ if(i_kinds[0].iv_hybrid == fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID)
+ {
+ // Assert that we do not have an error
+ FAPI_ASSERT( i_kinds[0].iv_hybrid_memory_type == i_kinds[1].iv_hybrid_memory_type,
+ fapi2::MSS_PLUG_RULES_INVALID_HYBRID_MEMORY_TYPE_MIX()
+ .set_DIMM_SLOT_ZERO(i_kinds[0].iv_hybrid_memory_type)
+ .set_DIMM_SLOT_ONE(i_kinds[1].iv_hybrid_memory_type)
+ .set_MCA_TARGET(i_target),
+ "%s has DIMM's with two different hybrid memory types installed (type %d and type %d). Cannot mix DIMM of different hybrid memory types on a single port",
+ mss::c_str(i_target), i_kinds[0].iv_hybrid_memory_type, i_kinds[1].iv_hybrid_memory_type );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Enforce DRAM stack type checks
+/// @note No 3DS and non-3DS DIMM's can mix
+/// @param[in] i_target the port
+/// @param[in] i_kinds a vector of DIMM (sorted while processing)
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+/// @note Expects the kind array to represent the DIMM on the port.
+///
+fapi2::ReturnCode check_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const std::vector<dimm::kind>& i_kinds)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Only do this check if we have the maximum number DIMM kinds
+ if(i_kinds.size() == MAX_DIMM_PER_PORT)
+ {
+ // Only do the assert if we have any 3DS DIMM, as the chip bug is for mixed config between DIMM that use and do not use CID
+ // Note: we should be able to mix SDP and DDP ok, as both DIMM's do not use CID
+ const bool l_has_3ds = (i_kinds[0].iv_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS) ||
+ (i_kinds[1].iv_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS);
+
+ // We have an error if we have the below scenario of 3DS and the stack types not being equal
+ const auto l_error = l_has_3ds && i_kinds[0].iv_stack_type != i_kinds[1].iv_stack_type;
+
+ FAPI_DBG("%s %s 3DS. Stack types are %s (%u,%u). configuration %s ok.",
+ mss::c_str(i_target),
+ l_has_3ds ? "has" : "does not have",
+ (i_kinds[0].iv_stack_type != i_kinds[1].iv_stack_type) ? "not equal" : "equal",
+ i_kinds[0].iv_stack_type,
+ i_kinds[1].iv_stack_type,
+ l_error ? "isn't" : "is"
+ );
+
+ // Assert that we do not have an error
+ FAPI_ASSERT( !l_error,
+ fapi2::MSS_PLUG_RULES_INVALID_STACK_TYPE_MIX()
+ .set_DIMM_SLOT_ZERO(i_kinds[0].iv_stack_type)
+ .set_DIMM_SLOT_ONE(i_kinds[1].iv_stack_type)
+ .set_MCA_TARGET(i_target),
+ "%s has DIMM's with two different stack types installed (type %d and type %d). Cannot mix DIMM of different stack types on a single port",
+ mss::c_str(i_target), i_kinds[0].iv_stack_type, i_kinds[1].iv_stack_type );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
///
/// @brief Helper to evaluate the unsupported rank config override attribute
/// @param[in] i_dimm0_ranks count of the ranks on DIMM in slot 0
@@ -63,7 +214,8 @@ namespace plug_rule
/// @return true iff this rank config is supported according to the unsupported attribute
/// @note not to be used to enforce populated/unpopulated - e.g., 0 ranks in both slots is ignored
///
-bool unsupported_rank_helper(const uint64_t i_dimm0_ranks, const uint64_t i_dimm1_ranks,
+bool unsupported_rank_helper(const uint64_t i_dimm0_ranks,
+ const uint64_t i_dimm1_ranks,
const fapi2::buffer<uint64_t>& i_attr)
{
// Quick - if the attribute is 0 (typically is) then we're out.
@@ -497,6 +649,18 @@ fapi2::ReturnCode plug_rule::enforce_plug_rules(const fapi2::Target<fapi2::TARGE
// to check here.
FAPI_TRY( plug_rule::check_rank_config(i_target, l_dimm_kinds, l_ranks_override) );
+ // Ensures that the port has a valid combination of DRAM widths
+ FAPI_TRY( plug_rule::check_dram_width(i_target, l_dimm_kinds) );
+
+ // Ensures that the port has a valid combination of stack types
+ FAPI_TRY( plug_rule::check_stack_type(i_target, l_dimm_kinds) );
+
+ // Ensures that the port has a valid combination of hybrid DIMM
+ FAPI_TRY( plug_rule::check_hybrid(i_target, l_dimm_kinds) );
+
+ // Checks to see if any DIMM are LRDIMM
+ FAPI_TRY( plug_rule::code::check_lrdimm(l_dimm_kinds) );
+
fapi_try_exit:
return fapi2::current_err;
}
OpenPOWER on IntegriCloud