summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H20
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C166
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H50
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_plug_rules.xml125
4 files changed, 356 insertions, 5 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H
index 907bd329b..048ec591d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/kind.H
@@ -90,6 +90,8 @@ class kind
iv_size = i_rhs.iv_size;
iv_mfgid = i_rhs.iv_mfgid;
iv_stack_type = i_rhs.iv_stack_type;
+ iv_hybrid = i_rhs.iv_hybrid;
+ iv_hybrid_memory_type = i_rhs.iv_hybrid_memory_type;
return *this;
}
@@ -98,6 +100,7 @@ class kind
/// @param[in] i_rhs the right hand side of the comparison statement
/// @return bool true iff the two kind are of the same kind
/// @warning this does not compare the targets (iv_target,) just the values
+ /// Also does not compare the mfgid as that's not really part of the DIMM kind but is additional information
///
inline bool operator==(const kind& i_rhs) const
{
@@ -108,7 +111,10 @@ class kind
(iv_dram_generation == i_rhs.iv_dram_generation) &&
(iv_dimm_type == i_rhs.iv_dimm_type) &&
(iv_rows == i_rhs.iv_rows) &&
- (iv_size == i_rhs.iv_size));
+ (iv_size == i_rhs.iv_size) &&
+ (iv_stack_type == i_rhs.iv_stack_type) &&
+ (iv_hybrid == i_rhs.iv_hybrid) &&
+ (iv_hybrid_memory_type == i_rhs.iv_hybrid_memory_type));
}
///
@@ -139,6 +145,8 @@ class kind
FAPI_TRY( mss::eff_dimm_size(i_target, iv_size) );
FAPI_TRY( mss::eff_dram_mfg_id(i_target, iv_mfgid) );
FAPI_TRY( mss::eff_prim_stack_type( i_target, iv_stack_type) );
+ FAPI_TRY( mss::eff_hybrid( i_target, iv_hybrid ));
+ FAPI_TRY( mss::eff_hybrid_memory_type( i_target, iv_hybrid_memory_type ));
return;
fapi_try_exit:
@@ -170,7 +178,9 @@ class kind
const uint8_t i_rows,
const uint32_t i_size,
const uint16_t i_mfgid = 0,
- const uint8_t i_stack_type = fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP):
+ const uint8_t i_stack_type = fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP,
+ const uint8_t i_hybrid = fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID,
+ const uint8_t i_hybrid_memory_type = fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE):
iv_target(0),
iv_master_ranks(i_master_ranks),
iv_total_ranks(i_total_ranks),
@@ -182,7 +192,9 @@ class kind
// TK consider calculating size rather than requiring it be set.
iv_size(i_size),
iv_mfgid(i_mfgid),
- iv_stack_type(i_stack_type)
+ iv_stack_type(i_stack_type),
+ iv_hybrid(i_hybrid),
+ iv_hybrid_memory_type(i_hybrid_memory_type)
{
// Bit of an idiot-check to be sure a hand-crafted dimm::kind make sense wrt slaves, masters, packages, etc.
// Both of these are checked in eff_config. If they are messed up, they should be caught there
@@ -214,6 +226,8 @@ class kind
uint32_t iv_size;
uint16_t iv_mfgid;
uint8_t iv_stack_type;
+ uint8_t iv_hybrid;
+ uint8_t iv_hybrid_memory_type;
};
}
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 26b391976..29689c59d 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;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
index 5ac502b09..d258f2c71 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
@@ -69,7 +69,8 @@ fapi2::ReturnCode enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCA>
/// @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);
///
/// @brief Enforces the DEAD LOAD rules
@@ -148,6 +149,53 @@ fapi2::ReturnCode check_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
const std::vector<dimm::kind>& i_kinds,
const uint64_t i_ranks_override);
+///
+/// @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);
+
+///
+/// @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);
+
+///
+/// @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);
+
+// Adding in code based plug rules - as supporting code gets added, the following checks can be deleted
+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 );
+
+} // code
+
} // plug_rule
} // mss
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_plug_rules.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_plug_rules.xml
index 9ee12499e..9c8f265e2 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_plug_rules.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_plug_rules.xml
@@ -59,6 +59,131 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_PLUG_RULES_INVALID_DRAM_WIDTH_MIX</rc>
+ <description>
+ Two different widths of DIMMs are installed on port
+ </description>
+ <ffdc>DIMM_SLOT_ZERO</ffdc>
+ <ffdc>DIMM_SLOT_ONE</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_PLUG_RULES_INVALID_STACK_TYPE_MIX</rc>
+ <description>
+ Two DIMMs with incompatable stack types are installed on port
+ </description>
+ <ffdc>DIMM_SLOT_ZERO</ffdc>
+ <ffdc>DIMM_SLOT_ONE</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_PLUG_RULES_INVALID_HYBRID_MIX</rc>
+ <description>
+ Two DIMMs with incompatable hybrid types are plugged
+ </description>
+ <ffdc>DIMM_SLOT_ZERO</ffdc>
+ <ffdc>DIMM_SLOT_ONE</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_PLUG_RULES_INVALID_HYBRID_MEMORY_TYPE_MIX</rc>
+ <description>
+ Two DIMMs with incompatable hybrid memory types
+ </description>
+ <ffdc>DIMM_SLOT_ZERO</ffdc>
+ <ffdc>DIMM_SLOT_ONE</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <childTargets>
+ <parent>MCA_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_PLUG_RULES_LRDIMM_UNSUPPORTED</rc>
+ <description>
+ The DIMM is an LRDIMM and that is currently not supported
+ </description>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ <gard>
+ <target>DIMM_TARGET</target>
+ </gard>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_DEAD_LOAD_ON_PORT</rc>
<description>
A DIMM is deconfigured on a dual-drop port that has two DIMMS installed
OpenPOWER on IntegriCloud