summaryrefslogtreecommitdiffstats
path: root/src/import/chips
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2018-09-18 15:47:24 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-09-18 22:36:25 -0500
commitf23a93b5944f91f74fab7d0dbb35115f0179329c (patch)
treeafee6c96644553b34e8df180a51632abbd2cca4d /src/import/chips
parentbbad6ad29aab4c1aab253d3a33adecffb0e37960 (diff)
downloadtalos-hostboot-f23a93b5944f91f74fab7d0dbb35115f0179329c.tar.gz
talos-hostboot-f23a93b5944f91f74fab7d0dbb35115f0179329c.zip
Remove to remirror
src/import/chips/p9/procedures/hwp/memory/lib/eff_config/ plug_rules.C nimbus_pre_data_engine.C Change-Id: Ia5e7b3298b13a9906249ef3d00590c5d57fbb497 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66300 Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Tested-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C239
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C851
2 files changed, 0 insertions, 1090 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C
deleted file mode 100644
index 7cf3b7b3d..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C
+++ /dev/null
@@ -1,239 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file nimbus_pre_data_engine.C
-/// @brief pre_data_engine implimentation for Nimbus
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: CI
-
-#include <generic/memory/lib/utils/index.H>
-#include <lib/mss_attribute_accessors.H>
-#include <lib/eff_config/attr_setters.H>
-#include <generic/memory/lib/data_engine/pre_data_init.H>
-#include <generic/memory/lib/utils/find.H>
-
-namespace mss
-{
-
-// =========================================================
-// DDR4 SPD Document Release 4
-// Byte 2 (0x002): Key Byte / DRAM Device Type
-// =========================================================
-const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::DRAM_GEN_MAP =
-{
- //{key value, dram gen}
- {0x0C, fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4}
- // Other key bytes reserved or not supported
-};
-
-// =========================================================
-// DDR4 SPD Document Release 4
-// Byte 3 (0x003): Key Byte / Module Type - Hybrid
-// =========================================================
-const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::HYBRID_MAP =
-{
- //{key byte, dimm type}
- {0, fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID},
- {1, fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID},
- // All others reserved or not supported
-};
-
-
-// =========================================================
-// DDR4 SPD Document Release 4
-// Byte 3 (0x003): Key Byte / Module Type - Hybrid
-// =========================================================
-const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::HYBRID_MEMORY_TYPE_MAP =
-{
-
- //{key byte, dimm type}
- {0, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE},
- {1, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM},
- // All others reserved or not supported
-};
-
-// =========================================================
-// DDR4 SPD Document Release 4
-// Byte 3 (0x003): Key Byte / Module Type
-// =========================================================
-const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::BASE_MODULE_TYPE_MAP =
-{
- //{key byte, dimm type}
- {1, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM},
- {2, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM},
- {4, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM},
- // All others reserved or not supported
-};
-
-// =========================================================
-// DDR4 SPD Document Release 4
-// Byte 12 (0x00C): Module Organization
-// =========================================================
-const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::NUM_PACKAGE_RANKS_MAP =
-{
- // {key byte, num of package ranks per DIMM (package ranks)}
- {0, 1},
- {1, 2},
- {2, 3},
- {3, 4},
- {4, 5},
- {5, 6},
- {6, 7},
- {7, 8},
-};
-
-///
-/// @brief ctor
-/// @param[in] i_target the DIMM target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_rc ReturnCode for failure to init object
-///
-pre_data_engine<NIMBUS>::pre_data_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const spd::facade& i_spd_data,
- fapi2::ReturnCode& o_rc):
- iv_dimm(i_target),
- iv_spd_data(i_spd_data)
-{
- // Sets up commonly used member variables
- uint8_t l_master_ranks = 0;
- FAPI_TRY(iv_spd_data.num_package_ranks_per_dimm(l_master_ranks));
- FAPI_TRY(lookup_table_check(i_target, NUM_PACKAGE_RANKS_MAP, PRE_DATA_ENGINE_CTOR, l_master_ranks, iv_master_ranks));
-
- o_rc = fapi2::FAPI2_RC_SUCCESS;
- return;
-
-fapi_try_exit:
- o_rc = fapi2::current_err;
- return;
-}
-
-///
-/// @brief Set ATTR_EFF_DIMM_TYPE
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dimm_type()
-{
- uint8_t l_base_module_type = 0;
- uint8_t l_dimm_type = 0;
-
- FAPI_TRY(iv_spd_data.base_module(l_base_module_type));
- FAPI_TRY(lookup_table_check(iv_dimm, BASE_MODULE_TYPE_MAP, SET_ATTR_DIMM_TYPE, l_base_module_type, l_dimm_type));
- FAPI_TRY( (set_field<NIMBUS, DIMM_TYPE>(iv_dimm, l_dimm_type)) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set ATTR_EFF_DRAM_GEN
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dram_gen()
-{
- uint8_t l_device_type = 0;
- uint8_t l_dram_gen = 0;
-
- FAPI_TRY(iv_spd_data.device_type(l_device_type));
- FAPI_TRY(lookup_table_check(iv_dimm, DRAM_GEN_MAP, SET_ATTR_DRAM_GEN, l_device_type, l_dram_gen));
-
- FAPI_TRY( (set_field<NIMBUS, DRAM_GEN>(iv_dimm, l_dram_gen)) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set ATTR_EFF_HYBRID
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode pre_data_engine<NIMBUS>::set_hybrid()
-{
- uint8_t l_spd_hybrid_type = 0;
- uint8_t l_hybrid = 0;
-
- FAPI_TRY(iv_spd_data.hybrid(l_spd_hybrid_type));
- FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_type, l_hybrid));
-
- FAPI_TRY( (set_field<NIMBUS, HYBRID>(iv_dimm, l_hybrid)) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set ATTR_EFF_HYBRID_MEMORY_TYPE
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode pre_data_engine<NIMBUS>::set_hybrid_media()
-{
- uint8_t l_hybrid_media = 0;
- uint8_t l_spd_hybrid_media = 0;
-
- FAPI_TRY(iv_spd_data.hybrid_media(l_spd_hybrid_media));
- FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_media, l_hybrid_media));
-
- FAPI_TRY( (set_field<NIMBUS, HYBRID_MEDIA>(iv_dimm, l_hybrid_media)) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Set ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode pre_data_engine<NIMBUS>::set_master_ranks()
-{
- FAPI_TRY( (set_field<NIMBUS, MRANKS>(iv_dimm, iv_master_ranks)) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Sets ATTR_EFF_DIMM_RANKS_CONFIGED
-/// @return FAPI2_RC_SUCCESS iff okay
-///
-fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dimm_ranks_configured()
-{
- // Set configed ranks. Set the bit representing the master rank configured (0 being left most.) So,
- // a 4R DIMM would be 0b11110000 (0xF0). This is used by PRD.
- fapi2::buffer<uint8_t> l_ranks_configed;
-
- FAPI_TRY( l_ranks_configed.setBit(0, iv_master_ranks),
- "%s. Failed to setBit", spd::c_str(iv_dimm) );
-
- FAPI_TRY( (set_field<NIMBUS, DIMM_RANKS_CNFG>(iv_dimm, uint8_t(l_ranks_configed))) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}//mss
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
deleted file mode 100644
index a5f019823..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C
+++ /dev/null
@@ -1,851 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file plug_rules.C
-/// @brief Enforcement of rules for plugging in DIMM
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: FSP:HB
-
-#include <fapi2.H>
-#include <vpd_access.H>
-#include <mss.H>
-#include <lib/mss_vpd_decoder.H>
-
-#include <lib/dimm/rank.H>
-#include <lib/utils/assert_noexit.H>
-#include <lib/eff_config/plug_rules.H>
-
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-using fapi2::FAPI2_RC_SUCCESS;
-using fapi2::FAPI2_RC_INVALID_PARAMETER;
-
-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
- // TK:LRDIMM Create appropriate check for LRDIMM(s) here
- 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;
-}
-
-///
-/// @brief Enforce equivalent rank and row configs
-/// Enforces configurations which will produce equivalent xlate register settings
-/// @param[in] i_target the port
-/// @param[in] i_kinds a vector of DIMM
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note Expects the kind array to represent the DIMM on the port.
-///
-fapi2::ReturnCode check_xlate_config(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
-{
- if (i_kinds.size() > 1)
- {
- FAPI_ASSERT( i_kinds[0].equal_config(i_kinds[1]) == true,
- fapi2::MSS_PLUG_RULES_DIFFERENT_XLATE()
- .set_MASTER_RANKS_ON_DIMM0(i_kinds[0].iv_master_ranks)
- .set_MASTER_RANKS_ON_DIMM1(i_kinds[1].iv_master_ranks)
- .set_TOTAL_RANKS_ON_DIMM0(i_kinds[0].iv_total_ranks)
- .set_TOTAL_RANKS_ON_DIMM1(i_kinds[1].iv_total_ranks)
- .set_DRAM_DENSITY_ON_DIMM0(i_kinds[0].iv_dram_density)
- .set_DRAM_DENSITY_ON_DIMM1(i_kinds[1].iv_dram_density)
- .set_DRAM_WIDTH_ON_DIMM0(i_kinds[0].iv_dram_width)
- .set_DRAM_WIDTH_ON_DIMM1(i_kinds[1].iv_dram_width)
- .set_DRAM_GEN_ON_DIMM0(i_kinds[0].iv_dram_generation)
- .set_DRAM_GEN_ON_DIMM1(i_kinds[1].iv_dram_generation)
- .set_DIMM_TYPE_ON_DIMM0(i_kinds[0].iv_dimm_type)
- .set_DIMM_TYPE_ON_DIMM1(i_kinds[1].iv_dimm_type)
- .set_ROWS_ON_DIMM0(i_kinds[0].iv_rows)
- .set_ROWS_ON_DIMM1(i_kinds[1].iv_rows)
- .set_SIZE_ON_DIMM0(i_kinds[0].iv_size)
- .set_SIZE_ON_DIMM1(i_kinds[1].iv_size)
- .set_MCA_TARGET(i_target),
- "%s has two different configurations of DIMM installed. mranks=%d,%d ranks=%d,%d density=%d,%d width=%d,%d gen=%d,%d type=%d,%d rows=%d,%d size=%d,%d Cannot mix DIMM configurations on port",
- mss::c_str(i_target), i_kinds[0].iv_master_ranks, i_kinds[1].iv_master_ranks,
- i_kinds[0].iv_total_ranks, i_kinds[1].iv_total_ranks,
- i_kinds[0].iv_dram_density, i_kinds[1].iv_dram_density,
- i_kinds[0].iv_dram_width, i_kinds[1].iv_dram_width,
- i_kinds[0].iv_dram_generation, i_kinds[1].iv_dram_generation,
- i_kinds[0].iv_dimm_type, i_kinds[1].iv_dimm_type,
- i_kinds[0].iv_rows, i_kinds[1].iv_rows,
- i_kinds[0].iv_size, i_kinds[1].iv_size);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-} // code
-
-///
-/// @brief Enforce DRAM width system support checks
-/// @param[in] i_target the port
-/// @param[in] i_kind a DIMM kind
-/// @param[in] i_mrw_supported_list the MRW bitmap's value
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note The DIMM kind should be a DIMM on the MCA
-///
-fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const dimm::kind& i_kind,
- const fapi2::buffer<uint8_t>& i_mrw_supported_list)
-{
- // Contains a mapping of the DRAM width to the bitmap value to be checked for support
- // If the DRAM's width is not found in this map, we'll error out with a special error
- static const std::vector<std::pair<uint8_t, uint8_t>> DRAM_WIDTH_MAP =
- {
- {fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4, fapi2::ENUM_ATTR_MSS_MRW_SUPPORTED_DRAM_WIDTH_X4},
- {fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8, fapi2::ENUM_ATTR_MSS_MRW_SUPPORTED_DRAM_WIDTH_X8},
- };
- // Gets the bitmap value for this DIMM's DRAM's width
- uint8_t l_bitmap_value = 0;
- const auto l_found = mss::find_value_from_key(DRAM_WIDTH_MAP, i_kind.iv_dram_width, l_bitmap_value);
-
- // We didn't find this DRAM width as supported in the above list
- FAPI_ASSERT(l_found,
- fapi2::MSS_PLUG_RULES_DRAM_WIDTH_NOT_SUPPORTED()
- .set_DRAM_WIDTH(i_kind.iv_dram_width)
- .set_MCA_TARGET(i_target),
- "%s failed to find DRAM width of %u in the supported DRAM widths vector",
- mss::c_str(i_kind.iv_target), i_kind.iv_dram_width);
-
- // We didn't find this DRAM width as supported in the MRW attribute
- FAPI_ASSERT(i_mrw_supported_list.getBit(l_bitmap_value),
- fapi2::MSS_PLUG_RULES_MRW_DRAM_WIDTH_NOT_SUPPORTED()
- .set_DRAM_WIDTH(i_kind.iv_dram_width)
- .set_MRW_SUPPORTED_LIST(i_mrw_supported_list)
- .set_BITMAP_VALUE(l_bitmap_value)
- .set_MCA_TARGET(i_target),
- "%s failed! 0x%02x is not in MRW suppored value of 0x%02x for DRAM width of %u",
- mss::c_str(i_kind.iv_target), l_bitmap_value, i_mrw_supported_list, i_kind.iv_dram_width);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Enforce DRAM width system support checks
-/// @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.
-/// This function will commit error logs if a DIMM has an unsupported DRAM width
-///
-fapi2::ReturnCode check_system_supported_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;
-
- uint8_t l_mrw_supported_list = 0;
- FAPI_TRY(mss::mrw_supported_dram_width(l_mrw_supported_list));
-
- // Loops through the DIMM and checks for unsupported DRAM widths
- for(const auto& l_kind : i_kinds)
- {
- FAPI_TRY(check_system_supported_dram_width(i_target, l_kind, l_mrw_supported_list));
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @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 Helper function to determine if a given DIMM slot can support an NVDIMM
-/// @param[in] const ref to the DIMM target
-/// @param[out] o_is_capable true if the DIMM slot is NVDIMM capable
-/// @return bool FAPI2_RC_SUCCESS iff we pass without errors
-///
-fapi2::ReturnCode dimm_slot_is_nv_capable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- bool& o_is_capable)
-{
- const auto l_pos = mss::pos(i_target);
-
- fapi2::buffer<uint64_t> l_plug_rules_bitmap = 0;
-
- FAPI_TRY( mss::mrw_nvdimm_plug_rules(l_plug_rules_bitmap) );
-
- o_is_capable = l_plug_rules_bitmap.getBit(l_pos);
-
- FAPI_INF("failed accessing ATTR_MSS_MRW_NVDIMM_PLUG_RULES: 0x%016lx %s capable (target: %s)",
- l_plug_rules_bitmap, o_is_capable ? "is" : "isn't", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Enforces that NVDIMM are plugged in the proper location
-/// @note NVDIMM can only be plugged in locations where the MRW attribute bitmap is set
-/// @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_nvdimm(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // Note: NVDIMM + non-NVDIMM mixing is checked in check hybrid
- for(const auto& l_kind : i_kinds)
- {
- bool l_nvdimm_supported = true;
- FAPI_TRY(dimm_slot_is_nv_capable(l_kind.iv_target, l_nvdimm_supported));
-
- // We're always good if NVDIMM is supported OR we're not an NVDIMM, otherwise, throw an error
- FAPI_ASSERT( (l_nvdimm_supported) || (l_kind.iv_hybrid_memory_type != fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM),
- fapi2::MSS_PLUG_RULES_NVDIMM_PLUG_ERROR()
- .set_DIMM_TARGET(l_kind.iv_target)
- .set_DIMM_POS(mss::pos(l_kind.iv_target))
- .set_MCA_TARGET(i_target),
- "%s is an NVDIMM plugged into a DIMM slot where NVDIMM are not supported",
- mss::c_str(l_kind.iv_target) );
- }
-
-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
-/// @param[in] i_dimm1_ranks count of the ranks on DIMM in slot 1
-/// @param[in] i_attr value of the attribute containing the unsupported rank configs
-/// @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,
- const fapi2::buffer<uint64_t>& i_attr)
-{
- // Quick - if the attribute is 0 (typically is) then we're out.
- if (i_attr == 0)
- {
- FAPI_INF("(%d, %d) is supported, override empty", i_dimm0_ranks, i_dimm1_ranks);
- return true;
- }
-
- // Quick - if both rank configs are 0 (no ranks seen in any slots) we return true. This is always OK.
- if ((i_dimm0_ranks == 0) && (i_dimm1_ranks == 0))
- {
- FAPI_INF("(%d, %d) is always supported", i_dimm0_ranks, i_dimm1_ranks);
- return true;
- }
-
- // We use 8 bits to represent a config in the unsupported ranks attribute. Each 'config' is a byte in
- // the attribute. The left nibble is the count of ranks on DIMM0, right nibble is the count of unsupported
- // ranks on DIMM1. Total ranks so we need the bits to represent stacks too.
- uint64_t l_current_byte = 0;
-
- do
- {
- uint8_t l_config = 0;
- uint64_t l_current_dimm0 = 0;
- uint64_t l_current_dimm1 = 0;
-
- i_attr.extractToRight(l_config, l_current_byte * BITS_PER_BYTE, BITS_PER_BYTE);
-
- fapi2::buffer<uint8_t>(l_config).extractToRight<0, BITS_PER_NIBBLE>(l_current_dimm0);
- fapi2::buffer<uint8_t>(l_config).extractToRight<BITS_PER_NIBBLE, BITS_PER_NIBBLE>(l_current_dimm1);
-
- FAPI_INF("Seeing 0x%x for unsupported rank config (%d, %d)", l_config, l_current_dimm0, l_current_dimm1);
-
- if ((l_current_dimm0 == i_dimm0_ranks) && (l_current_dimm1 == i_dimm1_ranks))
- {
- FAPI_INF("(%d, %d) is unsupported", i_dimm0_ranks, i_dimm1_ranks);
- return false;
- }
-
- }
- while (++l_current_byte < sizeof(uint64_t));
-
- FAPI_INF("(%d, %d) is supported", i_dimm0_ranks, i_dimm1_ranks);
- return true;
-}
-
-///
-/// @brief Enforce no mixing DIMM types
-/// @param[in] i_target port target
-/// @param[in] i_kinds a vector of DIMMs plugged into target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note This function will commit error logs representing the mixing failure
-///
-fapi2::ReturnCode dimm_type_mixing(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- //If we have 1 or 0 DIMMs on the port, we don't care
- if (i_kinds.size() == MAX_DIMM_PER_PORT)
- {
- FAPI_ASSERT( i_kinds[0].iv_dimm_type == i_kinds[1].iv_dimm_type,
- fapi2::MSS_PLUG_RULES_INVALID_DIMM_TYPE_MIX()
- .set_DIMM_SLOT_ZERO(i_kinds[0].iv_dimm_type)
- .set_DIMM_SLOT_ONE(i_kinds[1].iv_dimm_type)
- .set_MCA_TARGET(i_target),
- "%s has two different types of DIMM installed of type %d and of type %d. Cannot mix DIMM types on port",
- mss::c_str(i_target), i_kinds[0].iv_dimm_type, i_kinds[1].iv_dimm_type );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Enforce having one solitary DIMM plugged into slot 0
-/// @param[in] i_target port target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-template<>
-fapi2::ReturnCode empty_slot_zero(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
-
- // If there's one dimm, make sure it's in slot 0
- if ( l_dimms.size() == 1 )
- {
- FAPI_ASSERT( mss::index(l_dimms[0]) == 0,
- fapi2::MSS_PLUG_RULES_SINGLE_DIMM_IN_WRONG_SLOT()
- .set_MCA_TARGET(i_target)
- .set_DIMM_TARGET(l_dimms[0]),
- "%s DIMM is plugged into the wrong slot. Must plug into slot 0", mss::c_str(l_dimms[0]) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Enforce having one solitary DIMM plugged into slot 0
-/// @param[in] i_target the MCS
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-template<>
-fapi2::ReturnCode empty_slot_zero( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target)
-{
- fapi2::ReturnCode l_rc(fapi2::current_err);
-
- for (const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target) )
- {
- FAPI_TRY( empty_slot_zero( p ) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Enforces the DEAD LOAD rules
-/// @param[in] i_target the MCA/ port target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note This function will deconfigure the port if it's dual drop and one of the dimms is deconfigured
-///
-template<>
-fapi2::ReturnCode check_dead_load( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
-{
- const auto l_plugged_dimms = i_target.getChildren<TARGET_TYPE_DIMM>(fapi2::TARGET_STATE_PRESENT);
- const auto l_functional_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // If we have one deconfigured dimm and one functional dimm, we need to deconfigure the functional dimm
- FAPI_DBG(" Plugged dimm size is %d functional dimms size is %d",
- l_plugged_dimms.size(),
- l_functional_dimms.size());
-
-
- // So we check to see if there are functional dimms on the port,
- // if so, we check to see if there are less functional dimms than plugged in dimms (meaning one was deconfigured)
- // Third let's just double check we have two plugged dimms
- // The last check is for clarity
- if ( (l_functional_dimms.size() != 0)
- && (l_plugged_dimms.size() != l_functional_dimms.size())
- && (l_plugged_dimms.size() == 2) )
- {
- auto l_dead_dimm = l_plugged_dimms[0];
- auto l_live_dimm = l_plugged_dimms[1];
-
- // Now we determine if present_dimm[0] is functional by searching functional dimms
- const auto l_found = std::find(l_functional_dimms.begin(), l_functional_dimms.end(), l_dead_dimm);
-
- // if we don't find the dimm in the list of functional dimms, then it's deconfigured and the guess was good
- // Otherwise, we swap because our first guess was wrong
- l_dead_dimm = ( l_found == l_functional_dimms.end() ) ? l_dead_dimm : l_plugged_dimms[1];
- l_live_dimm = ( l_found == l_functional_dimms.end() ) ? l_live_dimm : l_plugged_dimms[0];
-
- FAPI_ASSERT( false,
- fapi2::MSS_DEAD_LOAD_ON_PORT()
- .set_FUNCTIONAL_DIMM(l_live_dimm),
- "%s has two DIMMs installed, but one is deconfigured (%d), so deconfiguring the other (%d) because of dead load",
- mss::c_str(i_target), mss::index(l_dead_dimm), mss::index(l_live_dimm));
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Enforces the DEAD LOAD rules
-/// @param[in] i_target the MCA/ port target
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-template<>
-fapi2::ReturnCode check_dead_load( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target)
-{
- for (const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target) )
- {
- FAPI_TRY( check_dead_load( p ) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Function to check the DRAM generation for DDR4
-/// @param[in] i_kinds a vector of DIMM kind structs
-/// @return fapi2::ReturnCode
-///
-fapi2::ReturnCode check_gen( const std::vector<dimm::kind>& i_kinds )
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- for (const auto& k : i_kinds)
- {
- // This should never fail ... but Just In Case a little belt-and-suspenders never hurt.
- // TODO RTC:160395 This needs to change for controllers which support different generations
- // Nimbus only supports DDR4 for now
- FAPI_ASSERT( k.iv_dram_generation == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4 ||
- k.iv_dram_generation == fapi2::ENUM_ATTR_EFF_DRAM_GEN_EMPTY,
- fapi2::MSS_PLUG_RULES_INVALID_DRAM_GEN()
- .set_DRAM_GEN(k.iv_dimm_type)
- .set_DIMM_TARGET(k.iv_target),
- "%s is not DDR4 it is %d", mss::c_str(k.iv_target), k.iv_dram_generation );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Enforce rank configs
-/// Enforces rank configurations which are not part of the VPD/rank config thing.
-/// @note Reads an MRW attribute to further limit rank configs.
-/// @param[in] i_target the port
-/// @param[in] i_kinds a vector of DIMM (sorted while processing)
-/// @param[in] i_ranks_override value of mrw_unsupported_rank_config attribute
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note Expects the kind array to represent the DIMM on the port.
-///
-fapi2::ReturnCode check_rank_config(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
- const std::vector<dimm::kind>& i_kinds,
- const uint64_t i_ranks_override)
-{
- // We need to keep track of current_err ourselves as the FAPI_ASSERT_NOEXIT macro doesn't.
- fapi2::current_err = FAPI2_RC_SUCCESS;
-
-
- // The user can avoid plug rules with an attribute. This is handy in partial good scenarios
- uint8_t l_ignore_plug_rules = 0;
- FAPI_TRY( mss::ignore_plug_rules(mss::find_target<TARGET_TYPE_MCS>(i_target), l_ignore_plug_rules) );
-
- if (fapi2::ENUM_ATTR_MSS_IGNORE_PLUG_RULES_YES == l_ignore_plug_rules)
- {
- FAPI_INF("attribute set to ignore plug rules");
- return FAPI2_RC_SUCCESS;
- }
-
- // If we have one DIMM, make sure it's in slot 0 and we're done.
- if (i_kinds.size() == 1)
- {
- // Sets fapi2::current_err
- FAPI_ASSERT( mss::index(i_kinds[0].iv_target) == 0,
- fapi2::MSS_PLUG_RULES_SINGLE_DIMM_IN_WRONG_SLOT()
- .set_MCA_TARGET(i_target)
- .set_DIMM_TARGET(i_kinds[0].iv_target),
- "%s is in slot 1, should be in slot 0", mss::c_str(i_kinds[0].iv_target));
-
- // Check to see if the override attribute limits this single slot configuration. Since we assert above
- // we know now i_kinds[0].iv_target is the DIMM in slot 0
- FAPI_ASSERT( unsupported_rank_helper(i_kinds[0].iv_total_ranks, 0, i_ranks_override) == true,
- fapi2::MSS_PLUG_RULES_OVERRIDDEN_RANK_CONFIG()
- .set_RANKS_ON_DIMM0(i_kinds[0].iv_total_ranks)
- .set_RANKS_ON_DIMM1(0)
- .set_TARGET(i_target),
- "MRW overrides this rank configuration (single DIMM) ranks: %d %s",
- i_kinds[0].iv_total_ranks, mss::c_str(i_target) );
- }
-
- // So if we're here we know we have more than one DIMM on this port.
- else
- {
- // Total up the number of ranks on this port. If it's more than MAX_PRIMARY_RANKS_PER_PORT we have a problem.
- // Notice that totaling up the ranks and using that as a metric also catches the 4R-is-not-the-only-DIMM case
- // (really probably that's the only case it catches but <shhhhh>.)
- // I don't think f/w supports std::count ... There aren't many DIMM on this port ...
- uint64_t l_rank_count = 0;
- const dimm::kind* l_dimm0_kind = nullptr;
- const dimm::kind* l_dimm1_kind = nullptr;
-
- for (const auto& k : i_kinds)
- {
- // While we're here, lets look for the DIMM on slots 0/1 - we'll need them later
- if (mss::index(k.iv_target) == 0)
- {
- l_dimm0_kind = &k;
- }
- else
- {
- l_dimm1_kind = &k;
- }
-
- l_rank_count += k.iv_master_ranks;
- }
-
- // If we get here and we see there's no DIMM in slot 0, we did something very wrong. We shouldn't have
- // passed the i_kinds.size() == 1 test above. So lets assert, shouldn't happen, but tracking the nullptr
- // dereference is harder <grin>
- if ((l_dimm0_kind == nullptr) || (l_dimm1_kind == nullptr))
- {
- FAPI_ERR("seeing a nullptr for DIMM0 or DIMM1, which is terrible %s %d", mss::c_str(i_target), i_kinds.size() );
- fapi2::Assert(false);
- }
-
- // Belt-and-suspenders as we make this assumption below
- if (i_kinds.size() > 2)
- {
- FAPI_ERR("seeing more than 2 DIMM on this port %s %d", mss::c_str(i_target), i_kinds.size() );
- fapi2::Assert(false);
- }
-
- // Safe to use l_dimm0_kind.
- MSS_ASSERT_NOEXIT( l_rank_count <= MAX_PRIMARY_RANKS_PER_PORT,
- fapi2::MSS_PLUG_RULES_INVALID_PRIMARY_RANK_COUNT()
- .set_TOTAL_RANKS(l_rank_count)
- .set_DIMM_ZERO_MASTER_RANKS(l_dimm0_kind->iv_master_ranks)
- .set_DIMM_ONE_MASTER_RANKS(l_dimm1_kind->iv_master_ranks)
- .set_MCA_TARGET(i_target),
- "There are more than %d master ranks on %s (%d)",
- MAX_PRIMARY_RANKS_PER_PORT, mss::c_str(i_target), l_rank_count );
-
- FAPI_INF("DIMM in slot 0 %s has %d master ranks, DIMM1 has %d",
- mss::c_str(l_dimm0_kind->iv_target), l_dimm0_kind->iv_master_ranks, l_dimm1_kind->iv_master_ranks);
-
- // The DIMMs master ranks have to be the same, we allow different slave ranks
- FAPI_ASSERT( l_dimm0_kind->iv_master_ranks == l_dimm1_kind->iv_master_ranks,
- fapi2::MSS_PLUG_RULES_INVALID_RANK_CONFIG()
- .set_RANKS_ON_DIMM0(l_dimm0_kind->iv_master_ranks)
- .set_RANKS_ON_DIMM1(l_dimm1_kind->iv_master_ranks)
- .set_TARGET(i_target),
- "The DIMM configuration on %s is incorrect. Master ranks on [1][0]: %d,%d",
- mss::c_str(i_target), l_dimm0_kind->iv_master_ranks, l_dimm1_kind->iv_master_ranks );
-
- // Check to see if the override attribute limits this configuration.
- FAPI_ASSERT( unsupported_rank_helper(l_dimm0_kind->iv_total_ranks,
- l_dimm1_kind->iv_total_ranks,
- i_ranks_override) == true,
- fapi2::MSS_PLUG_RULES_OVERRIDDEN_RANK_CONFIG()
- .set_RANKS_ON_DIMM0(l_dimm0_kind->iv_total_ranks)
- .set_RANKS_ON_DIMM1(l_dimm1_kind->iv_total_ranks)
- .set_TARGET(i_target),
- "MRW overrides this rank configuration ranks: %d, %d %s",
- l_dimm0_kind->iv_total_ranks, l_dimm1_kind->iv_total_ranks, mss::c_str(i_target) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-} // close namespace plug_rule
-
-///
-/// @brief Enforce the plug-rules per MCS
-/// @param[in] i_target FAPI2 target (MCS)
-/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
-///
-fapi2::ReturnCode plug_rule::enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target)
-{
- // Check per-MCS plug rules. If those all pass, check each of our MCA
- const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
- fapi2::ReturnCode l_rc (fapi2::FAPI2_RC_SUCCESS);
-
- // Check to see that we have DIMM on this MCS. If we don't, just carry on - this is valid.
- // Cronus does this often; they don't deconfigure empty ports or controllers. However, f/w
- // does. So if we're here we're running on Cronus or f/w has a bug <grin>
- if (l_dimms.size() == 0)
- {
- FAPI_INF("No DIMM configured for MCS %s, but it itself seems configured", mss::c_str(i_target));
- return FAPI2_RC_SUCCESS;
- }
-
- // The user can avoid plug rules with an attribute. This is handy in partial good scenarios
- uint8_t l_ignore_plug_rules = 0;
- FAPI_TRY( mss::ignore_plug_rules(i_target, l_ignore_plug_rules) );
-
- if (fapi2::ENUM_ATTR_MSS_IGNORE_PLUG_RULES_YES == l_ignore_plug_rules)
- {
- FAPI_INF("attribute set to ignore plug rules");
- return FAPI2_RC_SUCCESS;
- }
-
- for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
- {
- // Difference between cronus and hostboot make it really annoying to loop over the targets,
- // So we'll just error out if we find a bad port, this could make 2 deconfig loops instead of one,
- // but it's worth for proper behavior and really shouldn't happen often
- FAPI_TRY( enforce_plug_rules(p) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Enforce the plug-rules per MCA
-/// @param[in] i_target FAPI2 target (MCA)
-/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
-///
-fapi2::ReturnCode plug_rule::enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target)
-{
- const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
-
- // Check to see that we have DIMM on this MCA. If we don't, just carry on - this is valid.
- // Cronus does this often; they don't deconfigure empty ports or controllers. However, f/w
- // does. So if we're here we're running on Cronus or f/w has a bug <grin>
- if (l_dimms.size() == 0)
- {
- FAPI_INF("No DIMM configured for MCA %s, but it itself seems configured", mss::c_str(i_target));
- return FAPI2_RC_SUCCESS;
- }
-
- // Safe, even though the VPD decoder can get us here before the rest of eff_config has completed.
- // We'll only use the master rank information to enforce the rank config rules (which will have been
- // decoded and are valid before VPD was asked for.)
- const auto l_dimm_kinds = mss::dimm::kind::vector(l_dimms);
-
- uint64_t l_ranks_override = 0;
-
- // The user can avoid plug rules with an attribute. This is handy in partial good scenarios
- uint8_t l_ignore_plug_rules = 0;
- FAPI_TRY( mss::ignore_plug_rules(mss::find_target<TARGET_TYPE_MCS>(i_target), l_ignore_plug_rules) );
-
- if (fapi2::ENUM_ATTR_MSS_IGNORE_PLUG_RULES_YES == l_ignore_plug_rules)
- {
- FAPI_INF("attribute set to ignore plug rules");
- return FAPI2_RC_SUCCESS;
- }
-
- FAPI_TRY( check_gen( l_dimm_kinds ) );
-
- FAPI_TRY( dimm_type_mixing( i_target, l_dimm_kinds ) );
-
- // Get the MRW blacklist for rank configurations
- FAPI_TRY( mss::mrw_unsupported_rank_config(i_target, l_ranks_override) );
-
- // Note that we do limited rank config checking here. Most of the checking is done via VPD decoding,
- // meaning that if the VPD decoded the config then there's only a few rank related issues we need
- // 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 system as a whole supports a given DRAM width
- FAPI_TRY( plug_rule::check_system_supported_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 if NVDIMM are properly plugged for this system
- FAPI_TRY( plug_rule::check_nvdimm(i_target, l_dimm_kinds) );
-
- // Checks to see if any DIMM are LRDIMM
- FAPI_TRY( plug_rule::code::check_lrdimm(l_dimm_kinds) );
-
- // Temporary check that xlate settings will be the same if there are two DIMM in the port
- FAPI_TRY( plug_rule::code::check_xlate_config(i_target, l_dimm_kinds) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-}// mss
OpenPOWER on IntegriCloud