summaryrefslogtreecommitdiffstats
path: root/src/import
diff options
context:
space:
mode:
authorLouis Stermole <stermole@us.ibm.com>2018-10-02 10:41:42 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2018-12-04 11:09:10 -0600
commit6a6ee6a74bce17f8ee9dd2c6729392dc62763896 (patch)
treec5b4b536b42e49b0c679120a0300f39ac014400b /src/import
parent8b6b1b256035236d5434760729a1263305939a1f (diff)
downloadtalos-hostboot-6a6ee6a74bce17f8ee9dd2c6729392dc62763896.tar.gz
talos-hostboot-6a6ee6a74bce17f8ee9dd2c6729392dc62763896.zip
Move MSS volt attr setters to generic folder
Change-Id: I0011160cb34c1dffe54ff5eee3b629e91e3578c2 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67103 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@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: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67296 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C65
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H58
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C96
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C1
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H41
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C53
-rw-r--r--src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H101
-rw-r--r--src/import/generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H52
-rw-r--r--src/import/generic/procedures/xml/error_info/generic_error.xml12
9 files changed, 305 insertions, 174 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C
deleted file mode 100644
index ce42c0b28..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C
+++ /dev/null
@@ -1,65 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.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 attr_setters.C
-/// @brief Create setter functions for mss attributes
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-
-#include <fapi2.H>
-#include <generic/memory/lib/utils/find.H>
-#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <generic/memory/lib/data_engine/pre_data_init.H>
-
-namespace mss
-{
-
-///
-/// @brief Set ATTR_MSS_VOLT_VDDR and ATTR_MSS_VOLT_VPP
-/// @param[in] i_target_mcs the MCS target
-/// @param[in] i_selected_dram_voltage the voltage in millivolts for nominal voltage
-/// @param[in] i_selected_dram_voltage_vpp voltage in millivolts for the VPP
-/// @note dram_voltage and dram_voltage_vpp are not const due to FAPI_ATTR_SET template deduction
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode set_voltage_attributes(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs,
- uint32_t i_selected_dram_voltage,
- uint32_t i_selected_dram_voltage_vpp)
-{
- const auto l_target_mcbist = find_target<fapi2::TARGET_TYPE_MCBIST>(i_target_mcs);
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VDDR, l_target_mcbist, i_selected_dram_voltage) );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VPP, l_target_mcbist, i_selected_dram_voltage_vpp) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-} // mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H
deleted file mode 100644
index 8b703f72e..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H
+++ /dev/null
@@ -1,58 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H $ */
-/* */
-/* 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 attr_setters.H
-/// @brief Create setter functions for mss attributes
-///
-// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-#ifndef _MSS_ATTR_SETTERS_H_
-#define _MSS_ATTR_SETTERS_H_
-
-#include <fapi2.H>
-
-namespace mss
-{
-
-///
-/// @brief Set ATTR_MSS_VOLT_VDDR and ATTR_MSS_VOLT_VPP
-/// @param[in] i_target_mcs the MCS target
-/// @param[in] i_selected_dram_voltage the voltage in millivolts for nominal voltage
-/// @param[in] i_selected_dram_voltage_vpp voltage in millivolts for the VPP
-/// @note dram_voltage and dram_voltage_vpp are not const due to FAPI_ATTR_SET template deduction
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode set_voltage_attributes(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs,
- uint32_t i_selected_dram_voltage,
- uint32_t i_selected_dram_voltage_vpp);
-} // mss
-
-#endif
-
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C
index 220853338..d895897ca 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_mss_voltage.C
@@ -22,3 +22,99 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file nimbus_mss_voltage.C
+/// @brief Nimbus specializations for voltage library
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#include <fapi2.H>
+#include <vector>
+
+// Memory libraries
+#include <lib/mss_attribute_accessors.H>
+#include <lib/shared/mss_const.H>
+
+// Generic libraries
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H>
+#include <generic/memory/lib/utils/voltage/gen_mss_volt.H>
+
+namespace mss
+{
+
+using TT = mss::voltage_traits<mss::mc_type::NIMBUS, mss::spd::device_type::DDR4>;
+
+// List of attribute setter functions for setting voltage rail values
+// Note that this list needs to be ordered the same way as the list returned by mss::get_supported_voltages
+const std::vector<fapi2::ReturnCode (*)(const fapi2::Target<TT::VOLTAGE_TARGET_TYPE>&, uint32_t)> TT::voltage_setters =
+{
+ &set_volt_vddr,
+ &set_volt_vpp,
+};
+
+///
+/// @brief Determine what voltages are supported for the given memory controller and DRAM generation
+/// @param[in] i_target the target for setting voltage attributes
+/// @param[out] o_supported_dram_voltages vector of supported rail voltages in millivolts to be used in set_voltage_attributes
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note NIMBUS, DDR4 specialization
+///
+template<>
+fapi2::ReturnCode get_supported_voltages<mss::mc_type::NIMBUS, mss::spd::device_type::DDR4>
+(const fapi2::Target<TT::SPD_TARGET_TYPE>& i_target,
+ std::vector<uint32_t>& o_supported_dram_voltages)
+{
+ o_supported_dram_voltages.clear();
+
+ FAPI_INF("Populating decoder cache for %s", mss::c_str(i_target));
+
+ //Factory cache is per MCS
+ std::vector< mss::spd::facade > l_spd_facades;
+ FAPI_TRY( get_spd_decoder_list(i_target, l_spd_facades) );
+
+ // Get dimms for each MCS
+ for ( const auto& l_cache : l_spd_facades )
+ {
+ const auto l_dimm = l_cache.get_dimm_target();
+ uint8_t l_dimm_nominal = 0;
+ uint8_t l_dimm_endurant = 0;
+
+ // Read nominal and endurant bits from SPD, 0 = 1.2V is not operable and endurant, 1 = 1.2 is valid
+ FAPI_TRY( l_cache.operable_nominal_voltage(l_dimm_nominal) );
+ FAPI_TRY( l_cache.endurant_nominal_voltage(l_dimm_endurant) );
+
+ // Check to make sure 1.2 V is both operable and endurant, fail if it is not
+ FAPI_ASSERT ( (l_dimm_nominal == mss::spd::OPERABLE) && (l_dimm_endurant == mss::spd::ENDURANT),
+ fapi2::MSS_VOLT_DDR_TYPE_REQUIRED_VOLTAGE().
+ set_ACTUAL_OPERABLE(l_dimm_nominal).
+ set_ACTUAL_ENDURANT(l_dimm_endurant).
+ set_EXPECTED_OPERABLE(mss::spd::OPERABLE).
+ set_EXPECTED_ENDURANT(mss::spd::ENDURANT).
+ set_DIMM_TARGET(l_dimm),
+ "%s: DIMM is not operable (%d) expected (%d)"
+ " and/or endurant (%d) expected (%d) at 1.2V",
+ mss::c_str(l_dimm),
+ l_dimm_nominal,
+ mss::spd::OPERABLE,
+ l_dimm_endurant,
+ mss::spd::ENDURANT);
+ } // l_dimm
+
+ // Set the attributes for this MCS, values are in mss_const.H
+ // The ordering of voltages is specified in the selected voltage_traits specialization
+ o_supported_dram_voltages.push_back(mss::DDR4_NOMINAL_VOLTAGE);
+ o_supported_dram_voltages.push_back(mss::DDR4_VPP_VOLTAGE);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns mss
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
index c93559ed5..986a7031f 100644
--- 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
@@ -35,7 +35,6 @@
#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>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
index ee405528b..201b1ee39 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
@@ -483,6 +483,47 @@ fapi_try_exit:
return false;
}
+///
+/// @brief ATTR_MSS_VOLT_VDDR setter
+/// @tparam T the fapi2 target type of the target
+/// @param[in] i_target const ref to the TARGET_TYPE_MCBIST
+/// @param[in] i_value value to set - cannot be const because FAPI_ATTR_SET expects non-const
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode set_volt_vddr(const fapi2::Target<T>& i_target, uint32_t i_value)
+{
+ const auto l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VDDR, l_mcbist, i_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed setting ATTR_MSS_VOLT_VDDR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_VOLT_VPP setter
+/// @tparam T the fapi2 target type of the target
+/// @param[in] i_target const ref to the TARGET_TYPE_MCBIST
+/// @param[in] i_value value to set - cannot be const because FAPI_ATTR_SET expects non-const
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK
+///
+template< fapi2::TargetType T >
+inline fapi2::ReturnCode set_volt_vpp(const fapi2::Target<T>& i_target, uint32_t i_value)
+{
+ const auto l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VPP, l_mcbist, i_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed setting ATTR_MSS_VOLT_VPP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
} // close mss namespace
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C
index 0c8f9d98a..d5d499a1e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C
@@ -42,18 +42,10 @@
#include <fapi2.H>
// mss lib
-#include <generic/memory/lib/spd/spd_facade.H>
-#include <lib/eff_config/attr_setters.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/pos.H>
-#include <generic/memory/lib/utils/find.H>
-#include <lib/utils/checker.H>
+#include <generic/memory/lib/utils/voltage/gen_mss_volt.H>
-using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_DIMM;
-using fapi2::FAPI2_RC_SUCCESS;
extern "C"
{
@@ -65,52 +57,13 @@ extern "C"
///
fapi2::ReturnCode p9_mss_volt( const std::vector< fapi2::Target<TARGET_TYPE_MCS> >& i_targets )
{
- // Loop through MCS
for (const auto& l_mcs : i_targets)
{
- FAPI_INF("Populating decoder cache for %s", mss::c_str(l_mcs));
-
- //Factory cache is per MCS
- std::vector< mss::spd::facade > l_spd_facades;
- FAPI_TRY( get_spd_decoder_list(l_mcs, l_spd_facades) );
-
- // Get dimms for each MCS
- for ( const auto& l_cache : l_spd_facades )
- {
- const auto l_dimm = l_cache.get_dimm_target();
- uint8_t l_dimm_nominal = 0;
- uint8_t l_dimm_endurant = 0;
-
- // Read nominal and endurant bits from SPD, 0 = 1.2V is not operable and endurant, 1 = 1.2 is valid
- FAPI_TRY( l_cache.operable_nominal_voltage(l_dimm_nominal) );
- FAPI_TRY( l_cache.endurant_nominal_voltage(l_dimm_endurant) );
-
- //Check to make sure 1.2 V is both operable and endurant, fail if it is not
- FAPI_ASSERT ( (l_dimm_nominal == mss::spd::OPERABLE) && (l_dimm_endurant == mss::spd::ENDURANT),
- fapi2::MSS_VOLT_DDR_TYPE_REQUIRED_VOLTAGE().
- set_ACTUAL_OPERABLE(l_dimm_nominal).
- set_ACTUAL_ENDURANT(l_dimm_endurant).
- set_EXPECTED_OPERABLE(mss::spd::OPERABLE).
- set_EXPECTED_ENDURANT(mss::spd::ENDURANT).
- set_DIMM_TARGET(l_dimm),
- "%s: DIMM is not operable (%d) expected (%d)"
- " and/or endurant (%d) expected (%d) at 1.2V",
- mss::c_str(l_dimm),
- l_dimm_nominal,
- mss::spd::OPERABLE,
- l_dimm_endurant,
- mss::spd::ENDURANT);
- } // l_dimm
-
- // Set the attributes for this MCS, values are in mss_const.H
- FAPI_TRY (mss::set_voltage_attributes (l_mcs,
- mss::DDR4_NOMINAL_VOLTAGE,
- mss::DDR4_VPP_VOLTAGE),
- "Failed to set volt attributes");
+ FAPI_TRY( (mss::setup_voltage_rail_values<mss::mc_type::NIMBUS, mss::spd::device_type::DDR4>(l_mcs)),
+ "Failed setup_voltage_rail_values for %s", mss::c_str(l_mcs) );
} // mcs
FAPI_INF("End mss volt");
- return FAPI2_RC_SUCCESS;
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H b/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H
index 644e50e70..284995546 100644
--- a/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H
+++ b/src/import/generic/memory/lib/utils/voltage/gen_mss_volt.H
@@ -22,3 +22,104 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_volt.H
+/// @brief Functions used by mss_volt procedure
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _GEN_MSS_VOLT_H_
+#define _GEN_MSS_VOLT_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H>
+
+namespace mss
+{
+
+///
+/// @brief Determine what voltages are supported for the given memory controller and DRAM generation
+/// @tparam M mss::mc_type memory controller type
+/// @tparam D mss::spd::device_type DRAM device type (generation)
+/// @tparam TT mss::voltage_traits voltage traits for the given mc_type/device_type pairing
+/// @param[in] i_target the target for accessing voltage attributes from SPD
+/// @param[out] o_supported_dram_voltages vector of supported rail voltages in millivolts to be used in set_voltage_attributes
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::mc_type M, mss::spd::device_type D, typename TT = mss::voltage_traits<M, D>>
+fapi2::ReturnCode get_supported_voltages(const fapi2::Target<TT::SPD_TARGET_TYPE>& i_target,
+ std::vector<uint32_t>& o_supported_dram_voltages);
+
+///
+/// @brief Set voltage rail attributes
+/// @tparam M mss::mc_type memory controller type
+/// @tparam D mss::spd::device_type DRAM device type (generation)
+/// @tparam TT mss::voltage_traits voltage traits for the given mc_type/device_type pairing
+/// @param[in] i_target the target for setting voltage attributes
+/// @param[in] i_selected_dram_voltages vector of selected rail voltages in millivolts for nominal voltage
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::mc_type M, mss::spd::device_type D, typename TT = mss::voltage_traits<M, D>>
+inline fapi2::ReturnCode set_voltage_attributes(const fapi2::Target<TT::VOLTAGE_TARGET_TYPE>& i_target,
+ const std::vector<uint32_t>& i_selected_dram_voltages)
+{
+ // Check that the number of supplied voltage values is correct
+ const auto l_num_setters = TT::voltage_setters.size();
+ const auto l_num_supplied_voltages = i_selected_dram_voltages.size();
+
+ FAPI_ASSERT(l_num_supplied_voltages == l_num_setters,
+ fapi2::MSS_VOLT_WRONG_NUMBER_OF_VOLTAGES().
+ set_SUPPLIED_NUMBER(l_num_supplied_voltages).
+ set_EXPECTED_NUMBER(l_num_setters).
+ set_VOLT_TARGET(i_target),
+ "%s: Incorrect number of voltages supplied to set_voltage_attributes function: %d (expected %d)",
+ mss::c_str(i_target),
+ l_num_supplied_voltages,
+ l_num_setters);
+
+ for (size_t l_setter_index = 0; l_setter_index < l_num_setters; ++l_setter_index)
+ {
+ FAPI_TRY( (*TT::voltage_setters[l_setter_index])(i_target, i_selected_dram_voltages[l_setter_index]) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Setup and save off rail voltages
+/// @tparam M mss::mc_type memory controller type
+/// @tparam D mss::spd::device_type DRAM device type (generation)
+/// @tparam TT mss::voltage_traits voltage traits for the given mc_type/device_type pairing
+/// @param[in] i_target the target for accessing voltage attributes from SPD
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::mc_type M, mss::spd::device_type D, typename TT = mss::voltage_traits<M, D>>
+inline fapi2::ReturnCode setup_voltage_rail_values(const fapi2::Target<TT::SPD_TARGET_TYPE>& i_target)
+{
+ const auto l_voltage_target = mss::find_target<TT::VOLTAGE_TARGET_TYPE>(i_target);
+ const auto l_spd_target = mss::find_target<TT::SPD_TARGET_TYPE>(i_target);
+ std::vector<uint32_t> l_dram_voltages;
+
+ FAPI_TRY( (mss::get_supported_voltages<M, D>(l_spd_target, l_dram_voltages)),
+ "Failed to get supported voltages for %s", mss::c_str(l_spd_target) );
+
+ FAPI_TRY( (mss::set_voltage_attributes<M, D>(l_voltage_target, l_dram_voltages)),
+ "Failed to set volt attributes for %s", mss::c_str(l_voltage_target) );
+
+ FAPI_INF("%s End setup_voltage_rail_values", mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // mss
+
+#endif
diff --git a/src/import/generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H b/src/import/generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H
index 738554c1a..baa9c693a 100644
--- a/src/import/generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H
+++ b/src/import/generic/memory/lib/utils/voltage/gen_mss_voltage_traits.H
@@ -22,3 +22,55 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_mss_voltage_traits.H
+/// @brief Contains voltage traits information
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP FW Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: CI
+
+#ifndef _GEN_MSS_VOLTAGE_TRAITS_H_
+#define _GEN_MSS_VOLTAGE_TRAITS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+
+///
+/// @class Traits and policy class for voltage code
+/// @tparam M mss::mc_type memory controller type
+/// @tparam D mss::spd::device_type DRAM device type (generation)
+///
+template< mss::mc_type M, mss::spd::device_type D >
+class voltage_traits;
+
+///
+/// @class Traits and policy class for voltage code - specialization for the NIMBUS memory controller type
+///
+template<>
+class voltage_traits<mss::mc_type::NIMBUS, mss::spd::device_type::DDR4>
+{
+ public:
+ //////////////////////////////////////////////////////////////
+ // Target types
+ //////////////////////////////////////////////////////////////
+ static constexpr fapi2::TargetType VOLTAGE_TARGET_TYPE = fapi2::TARGET_TYPE_MCBIST;
+ static constexpr fapi2::TargetType SPD_TARGET_TYPE = fapi2::TARGET_TYPE_MCS;
+
+ //////////////////////////////////////////////////////////////
+ // Traits values
+ //////////////////////////////////////////////////////////////
+ // List of attribute setter functions for setting voltage rail values
+ // This vector is defined in the p9 space: lib/eff_config/nimbus_mss_voltage.C
+ static const std::vector<fapi2::ReturnCode (*)(const fapi2::Target<VOLTAGE_TARGET_TYPE>&, uint32_t)> voltage_setters;
+};
+
+
+} // ns mss
+#endif
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 611aa111d..2315fe6a3 100644
--- a/src/import/generic/procedures/xml/error_info/generic_error.xml
+++ b/src/import/generic/procedures/xml/error_info/generic_error.xml
@@ -280,6 +280,18 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_VOLT_WRONG_NUMBER_OF_VOLTAGES</rc>
+ <description>Incorrect number of voltages supplied to set_voltage_attributes function</description>
+ <ffdc>VOLT_TARGET</ffdc>
+ <ffdc>SUPPLIED_NUMBER</ffdc>
+ <ffdc>EXPECTED_NUMBER</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_PORT_DOES_NOT_SUPPORT_MAJORITY_FREQ</rc>
<description>
When considering the frequencies in the MRW and the max supported
OpenPOWER on IntegriCloud