diff options
Diffstat (limited to 'src/import/chips/ocmb/explorer/procedures/hwp/memory/lib')
5 files changed, 266 insertions, 81 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H index f52897bf3..eca4bc6ee 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_attribute_accessors_manual.H @@ -48,40 +48,72 @@ namespace mss { /// -/// @brief Gets whether the OCMB will be configred to enterprise mode -/// @param[in] i_target OCMB target on which to operate -/// @param[out] o_is_enterprise_mode true if the part is in enterprise mode -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK +/// @brief Unit-testable half dimm mode helper function. Calculates half dimm mode based on input params +/// @param[in] i_target OCMB chip +/// @param[in] i_is_enterprise enterprise mode is enabled +/// @param[in] i_half_dimm_attr half dimm mode as obtained from attribute +/// @param[in] i_half_dimm_override_attr half dimm mode override from attribute +/// @param[out] o_is_half_dimm_mode resulting value for half dimm mode after calculations +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code /// -inline fapi2::ReturnCode enterprise_mode( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& - i_target, - bool& o_is_enterprise_mode ) +inline fapi2::ReturnCode half_dimm_mode_helper( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const bool i_is_enterprise, + const uint8_t i_half_dimm_attr, + const uint8_t i_half_dimm_override_attr, + bool& o_is_half_dimm_mode ) { - // Constexprs for beautification - constexpr uint8_t ENTERPRISE = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_ENTERPRISE; - constexpr uint8_t NO_OVERRIDE = fapi2::ENUM_ATTR_MSS_OCMB_NONENTERPRISE_MODE_OVERRIDE_NO_OVERRIDE; + o_is_half_dimm_mode = false; - // Variables - o_is_enterprise_mode = false; - uint8_t l_enterprise = 0; - uint8_t l_override = 0; + bool l_is_half_dimm = 0; + + // First let's assert that ocmb_half_dimm_mode isn't HALF_DIMM when ENTERPRISE is 0 + // Even though this could theoretically be overridden back to FULL_DIMM, we should + // check that the initial value is also valid. + FAPI_ASSERT(!i_half_dimm_attr || i_is_enterprise, + fapi2::MSS_EXP_HALF_DIMM_MODE_NOT_SUPPORTED() + .set_ENTERPRISE_SETTING(i_is_enterprise) + .set_HALF_DIMM_SETTING(i_half_dimm_attr) + .set_OCMB_TARGET(i_target), + "%s Invalid configuration: ATTR_MSS_OCMB_HALF_DIMM_MODE set to HALF_DIMM while enterprise is disabled", + mss::c_str(i_target)); - FAPI_TRY( mss::attr::get_ocmb_enterprise_mode(i_target, l_enterprise) ); - FAPI_TRY( mss::attr::get_ocmb_nonenterprise_mode_override(i_target, l_override) ); + // This might be overwritten below by overrides + l_is_half_dimm = (i_half_dimm_attr == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_HALF_DIMM); + // Now let's apply the override + if (i_half_dimm_override_attr == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_OVERRIDE_HALF_DIMM) { - const bool l_enterprise_mode = l_enterprise == ENTERPRISE; - const bool l_no_override = l_override == NO_OVERRIDE; - // We will be in enterprise mode (true) IF - // 1) the chip is in enterprise mode (we can't run in enterprise mode if the part is non-enterprise capable) AND - // 2) we do not have the override to non-enterprise mode - o_is_enterprise_mode = l_enterprise_mode && l_no_override; - - FAPI_INF("%s is in %s mode. (OCMB chip is %s, with %s)", mss::c_str(i_target), - o_is_enterprise_mode ? "enterprise" : "non-enterprise", l_enterprise_mode ? "enterprise" : "non-enterprise", - l_no_override ? "no override" : "override to non-enterprise"); + l_is_half_dimm = true; + + // Assert once more that this is valid + FAPI_ASSERT(!l_is_half_dimm || i_is_enterprise, + fapi2::MSS_EXP_HALF_DIMM_MODE_NOT_SUPPORTED() + .set_ENTERPRISE_SETTING(i_is_enterprise) + .set_HALF_DIMM_SETTING(l_is_half_dimm) + .set_OCMB_TARGET(i_target), + "%s Invalid configuration: HALF_DIMM_MODE overridden to HALF_DIMM while enterprise is disabled", + mss::c_str(i_target)); + + FAPI_DBG("%s overridden to HALF_DIMM_MODE", mss::c_str(i_target)); } + else if (i_half_dimm_override_attr == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_OVERRIDE_FULL_DIMM) + { + l_is_half_dimm = false; + FAPI_DBG("%s overridden to FULL_DIMM_MODE", mss::c_str(i_target)); + } + + o_is_half_dimm_mode = l_is_half_dimm; + + FAPI_INF("%s %s in enterprise mode, and %s override is present. The chip is in %s (attribute %u)", + mss::c_str(i_target), + i_is_enterprise ? "is" : "is not", + i_half_dimm_override_attr > 0 ? "an" : "no", + o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_is_half_dimm); + + return fapi2::FAPI2_RC_SUCCESS; + fapi_try_exit: return fapi2::current_err; } @@ -92,45 +124,22 @@ fapi_try_exit: /// @param[out] o_is_half_dimm_mode true if the part is in half-DIMM mode /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK /// -inline fapi2::ReturnCode half_dimm_mode( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& - i_target, - bool& o_is_half_dimm_mode ) +inline fapi2::ReturnCode half_dimm_mode( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const bool i_is_enterprise_mode, + bool& o_is_half_dimm_mode ) { // Variables o_is_half_dimm_mode = false; - bool l_is_enterprise = false; - uint8_t l_half_dimm = 0; - uint8_t l_override = 0; - - FAPI_TRY( enterprise_mode(i_target, l_is_enterprise) ); - - // We're in full DIMM mode if we're in non-enterprise mode - if(!l_is_enterprise) - { - o_is_half_dimm_mode = false; - FAPI_INF("%s is in full-DIMM since the chip is in non-enterprise mode", mss::c_str(i_target)); - return fapi2::FAPI2_RC_SUCCESS; - } - - // Now that we're not in enterprise mode, check for overrides - FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode_override(i_target, l_override) ); - - // If we have an override, set based upon the override - if(l_override != fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_NO_OVERRIDE) - { - o_is_half_dimm_mode = l_override == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_OVERRIDE_OVERRIDE_HALF_DIMM; - FAPI_INF("%s is in enterprise mode, and %s override is present. The chip is in %s (attribute %u)", mss::c_str(i_target), - "an", o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_override); - return fapi2::FAPI2_RC_SUCCESS; - } + uint8_t l_half_dimm_attr = 0; + uint8_t l_override_attr = 0; - // No override, so go with the attribute derived from the ECID - FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode(i_target, l_half_dimm) ); + FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode(i_target, l_half_dimm_attr) ); + FAPI_TRY( mss::attr::get_ocmb_half_dimm_mode_override(i_target, l_override_attr) ); - // Set half DIMM mode based upon the the normal attribute - o_is_half_dimm_mode = l_half_dimm == fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_HALF_DIMM; - FAPI_INF("%s is in enterprise mode, and %s override is present. The chip is in %s (attribute %u)", mss::c_str(i_target), - "no", o_is_half_dimm_mode ? "half-DIMM mode" : "full-DIMM mode", l_half_dimm); + // o_is_half_dimm_mode will be set by the helper function + FAPI_TRY( mss::half_dimm_mode_helper(i_target, i_is_enterprise_mode, l_half_dimm_attr, l_override_attr, + o_is_half_dimm_mode)); fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C index 86eb99850..8c0d62f4e 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.C @@ -50,32 +50,21 @@ namespace ecid { /// -/// @brief Determines enterprise and half dimm states from explorer FUSE +/// @brief Determines enterprise state from explorer FUSE /// @param[in] i_target the controller /// @param[out] o_enterprise_mode state -/// @param[out] o_half_dimm_mode state /// @return FAPI2_RC_SUCCESS iff ok /// -fapi2::ReturnCode get_enterprise_and_half_dimm_from_fuse( +fapi2::ReturnCode get_enterprise_from_fuse( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - uint8_t& o_enterprise_mode, - uint8_t& o_half_dimm_mode) + bool& o_enterprise_mode) { fapi2::buffer<uint64_t> l_reg_resp_buffer; FAPI_TRY(fapi2::getScom( i_target, static_cast<uint64_t>(EXPLR_EFUSE_IMAGE_OUT_0), l_reg_resp_buffer ), "exp_getecid: could not read explorer fuse register 0x%08x", EXPLR_EFUSE_IMAGE_OUT_0); - // Default to disabled - o_enterprise_mode = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_NON_ENTERPRISE; // 0 - - // If we support enterprise mode, enable it until otherwise overridden in OMI_SETUP - if(!l_reg_resp_buffer.getBit <EXPLR_EFUSE_IMAGE_OUT_0_ENTERPRISE_MODE_DIS> ()) - { - o_enterprise_mode = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_MODE_ENTERPRISE; // 1, enabled - } - - // half_dimm_mode will remain disabled for P systems - o_half_dimm_mode = fapi2::ENUM_ATTR_MSS_OCMB_HALF_DIMM_MODE_FULL_DIMM; // 0, disabled + // Since the bit is a disable bit, take the opposite to get enable=true, disable=false + o_enterprise_mode = !(l_reg_resp_buffer.getBit<EXPLR_EFUSE_IMAGE_OUT_0_ENTERPRISE_MODE_DIS>()); fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H index cb8600c04..7b8fdfac9 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/exp_getecid_utils.H @@ -47,16 +47,14 @@ namespace ecid { /// -/// @brief Determines enterprise and half dimm states from explorer FUSE +/// @brief Determines enterprise state from explorer FUSE /// @param[in] i_target the controller /// @param[out] o_enterprise_mode state -/// @param[out] o_half_dimm_mode state /// @return FAPI2_RC_SUCCESS iff ok /// -fapi2::ReturnCode get_enterprise_and_half_dimm_from_fuse( +fapi2::ReturnCode get_enterprise_from_fuse( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, - uint8_t& o_enterprise_mode, - uint8_t& o_half_dimm_mode); + bool& o_enterprise_mode); /// /// @brief Reads ECID into output array from fuse diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C index 1d48e9d4f..7d833b2ff 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.C @@ -22,3 +22,134 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_plug_rules.C +/// @brief Plug rules enforcement for explorer +/// +// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#include <fapi2.H> +#include <lib/plug_rules/exp_plug_rules.H> +#include <mss_explorer_attribute_getters.H> + +namespace mss +{ +namespace exp +{ +namespace plug_rule +{ + +/// +/// @brief Determine enterprise mode from given attribute/fuse values +/// +/// @param[in] i_target OCMB chip target +/// @param[in] i_enterprise_fuse enterprise as determined from fuse +/// @param[in] i_enterprise_policy enterprise policy system attribute value +/// @param[in] i_non_enterprise_override override attribute value +/// @param[out] o_is_enterprise_mode resulting state for enterprise mode +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code +/// @note this helper function exists for unit testing purposes +/// +fapi2::ReturnCode enterprise_mode_helper( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const bool i_enterprise_fuse, + const uint8_t i_enterprise_policy, + const uint8_t i_non_enterprise_override, + bool& o_is_enterprise_mode) +{ + o_is_enterprise_mode = false; + + // Constexprs to make things easier on the eyes + constexpr uint8_t REQUIRE_ENTERPRISE = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_POLICY_REQUIRE_ENTERPRISE; + constexpr uint8_t FORCE_NONENTERPRISE = fapi2::ENUM_ATTR_MSS_OCMB_ENTERPRISE_POLICY_FORCE_NONENTERPRISE; + + // Truth table: + // Enterprise (fuse): 0=Disabled 1=Enabled (inverted from fuse logic) + // Policy: 0=ALLOW_ENTERPRISE (allow any) 1=REQUIRE_ENTERPRISE 2=FORCE_NONENTERPRISE + // Override OFF: 0=NO_OVERRIDE 1=OVERRIDE_TO_NONENTERPRISE + // + // Enterprise (fuse) Policy Override OFF Result Description + // 0 0 0 0 + // 0 0 1 0 + // 1 0 0 1 + // 1 0 1 0 + // 0 1 0 Error: We don't support enterprise + // 0 1 1 Error: We don't support enterprise + // 1 1 0 1 + // 1 1 1 0 Override beats policy + // 0 2 0 0 + // 0 2 1 0 + // 1 2 0 Error: Policy does not allow for enterprise dimm plugged in + // 1 2 1 Error: Policy does not allow for enterprise dimm plugged in + + // Check if we have one of the error configurations + const bool l_invalid_config = ((!i_enterprise_fuse) && (i_enterprise_policy == REQUIRE_ENTERPRISE)) || + ((i_enterprise_fuse) && (i_enterprise_policy == FORCE_NONENTERPRISE)); + + // For the below assert, i_enterprise_policy must be 1 or 2 to assert out, + // so we can use the ternary operator to generate a string description from these two cases + FAPI_ASSERT(!l_invalid_config, + fapi2::MSS_EXP_ENTERPRISE_INVALID_CONFIGURATION() + .set_OCMB_TARGET(i_target) + .set_ENTERPRISE_SUPPORTED(i_enterprise_fuse) + .set_POLICY(i_enterprise_policy), + "%s The enterprise supported bit from the Explorer efuse: %u conflicts with the enterprise " + "policy attribute setting: %s", + mss::c_str(i_target), + i_enterprise_fuse, + (i_enterprise_policy == FORCE_NONENTERPRISE ? "FORCE_NONENTERPRISE" : "REQUIRE_ENTERPRISE")); + + // Now generate the resulting value from the remaining truth table entries + // We are non-enterprise whenever i_enterprise_policy is 2, or i_non_enterprise_override. + // Otherwise, we use the value of i_enterprise_fuse + o_is_enterprise_mode = i_enterprise_fuse && !((i_enterprise_policy == FORCE_NONENTERPRISE) + || (i_non_enterprise_override)); + + FAPI_INF("%s is in %s mode. (OCMB chip is %s, with %s)", + mss::c_str(i_target), + o_is_enterprise_mode ? "enterprise" : "non-enterprise", + i_enterprise_fuse ? "enterprise" : "non-enterprise", + i_non_enterprise_override ? "override to non-enterprise" : "no override"); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Gets whether the OCMB will be configred to enterprise mode, will assert out if policy/override do not agree +/// @param[in] i_target OCMB target on which to operate +/// @param[in] i_enterprise_fuse enterprise as determined from fuse +/// @param[out] o_is_enterprise_mode true if the part is in enterprise mode +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK +/// +fapi2::ReturnCode enterprise_mode( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const bool i_enterprise_fuse, + bool& o_is_enterprise_mode ) +{ + o_is_enterprise_mode = false; + + // Variables + uint8_t l_enterprise_policy = 0; + uint8_t l_override_attr = 0; + + FAPI_TRY( mss::attr::get_ocmb_enterprise_policy(l_enterprise_policy) ); + FAPI_TRY( mss::attr::get_ocmb_nonenterprise_mode_override(i_target, l_override_attr) ); + + // This function will populate o_is_enterprise_mode accordingly + FAPI_TRY(enterprise_mode_helper(i_target, i_enterprise_fuse, l_enterprise_policy, l_override_attr, + o_is_enterprise_mode)); + +fapi_try_exit: + return fapi2::current_err; +} +} // plug_rule +} // exp +} // mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H index a9230f765..2fbc0d7df 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/plug_rules/exp_plug_rules.H @@ -22,3 +22,61 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_plug_rules.H +/// @brief Plug rules enforcement for explorer +/// +// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#ifndef _EXP_PLUG_RULES_H_ +#define _EXP_PLUG_RULES_H_ + +#include <fapi2.H> + +namespace mss +{ +namespace exp +{ +namespace plug_rule +{ + +/// +/// @brief Determine enterprise mode from given attribute/fuse values +/// +/// @param[in] i_target OCMB chip target +/// @param[in] i_enterprise_fuse enterprise as determined from fuse +/// @param[in] i_enterprise_policy enterprise policy system attribute value +/// @param[in] i_non_enterprise_override override attribute value +/// @param[out] o_is_enterprise_mode resulting state for enterprise mode +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success, else error code +/// @note this helper function exists for unit testing purposes +/// +fapi2::ReturnCode enterprise_mode_helper( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const bool i_enterprise_fuse, + const uint8_t i_enterprise_policy, + const uint8_t i_non_enterprise_override, + bool& o_is_enterprise_mode); + +/// +/// @brief Gets whether the OCMB will be configred to enterprise mode, will assert out if policy/override do not agree +/// @param[in] i_target OCMB target on which to operate +/// @param[in] i_enterprise_fuse enterprise as determined from fuse +/// @param[out] o_is_enterprise_mode true if the part is in enterprise mode +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK +/// +fapi2::ReturnCode enterprise_mode( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + const bool i_enterprise_fuse, + bool& o_is_enterprise_mode ); + +} // plug_rule +} // exp +} // mss + +#endif |