summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Stermole <stermole@us.ibm.com>2019-01-24 13:36:56 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2019-04-15 12:11:18 -0500
commit2b26420e72477835ffeacb2dab9970266ef07566 (patch)
tree005fff430a99823e7d1fcd11bc66fb043f160c68
parent0d3c3c752b95d3ddc42d82bb2a66ea9ff4f0c6b1 (diff)
downloadtalos-hostboot-2b26420e72477835ffeacb2dab9970266ef07566.tar.gz
talos-hostboot-2b26420e72477835ffeacb2dab9970266ef07566.zip
Add p9a_mss_freq procedure
Change-Id: I764e1ade2f63cabb7f6e5cf2b39e89811ea432c4 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70989 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/75567 Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Tested-by: Christian R. Geddes <crgeddes@us.ibm.com>
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H16
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C14
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C1
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H71
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C143
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C16
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H9
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/assert_noexit.H61
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/freq_workarounds.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C7
-rwxr-xr-xsrc/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml19
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml44
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H70
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C427
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C250
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H180
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C24
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C28
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H3
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.mk4
-rw-r--r--src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml112
-rw-r--r--src/import/generic/memory/lib/data_engine/data_engine_traits_def.H3
-rw-r--r--src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H78
-rw-r--r--src/import/generic/memory/lib/data_engine/pre_data_init.H1
-rw-r--r--src/import/generic/memory/lib/mss_generic_attribute_getters.H4199
-rw-r--r--src/import/generic/memory/lib/utils/assert_noexit.H37
-rw-r--r--src/import/generic/memory/lib/utils/freq/cas_latency.H4
-rw-r--r--src/import/generic/memory/lib/utils/freq/gen_mss_freq.H225
-rw-r--r--src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H51
-rw-r--r--src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H4
-rw-r--r--src/import/generic/memory/lib/utils/mss_math.H38
-rw-r--r--src/import/generic/memory/lib/utils/shared/mss_generic_consts.H18
-rw-r--r--src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml19
-rw-r--r--src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml24
-rw-r--r--src/import/generic/procedures/xml/error_info/generic_error.xml16
37 files changed, 5879 insertions, 355 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H
index 61c941f53..3476d51e5 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/eff_config/explorer_attr_engine_traits.H
@@ -58,23 +58,11 @@ struct setTimingTraits< exp::attr_eff_engine_fields, exp::SPD_TAA_MIN >
{
static constexpr const char* TIMING_NAME = "tAAmin";
- static spd_facade_fptr get_timing_in_mtb;
- static spd_facade_fptr get_timing_in_ftb;
+ static constexpr spd_facade_fptr get_timing_in_mtb = &spd::facade::min_taa;
+ static constexpr spd_facade_fptr get_timing_in_ftb = &spd::facade::fine_offset_min_taa;
};
///
-/// @brief Alias for function pointer to spd_facade timing methods for SPD_TAA_MIN
-///
-spd_facade_fptr setTimingTraits<exp::attr_eff_engine_fields,
- exp::SPD_TAA_MIN>::get_timing_in_mtb = &spd::facade::min_taa;
-
-///
-/// @brief Alias for function pointer to spd_facade timing methods for SPD_TAA_MIN
-///
-spd_facade_fptr setTimingTraits<exp::attr_eff_engine_fields,
- exp::SPD_TAA_MIN>::get_timing_in_ftb = &spd::facade::fine_offset_min_taa;
-
-///
/// @brief Traits for attr_engine
/// @class attrEngineTraits
/// @note attr_eff_engine_fields, ATTR_EFF_BASE_CASE specialization
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C
index 4a3f7c703..9d1393cb4 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/utils/explorer_pos.C
@@ -54,7 +54,6 @@ relative_pos<fapi2::TARGET_TYPE_MEM_PORT>(const fapi2::Target<fapi2::TARGET_TYPE
///
/// @brief Return a DIMM's relative position from an OCMB
-/// @tparam MC the type of memory controller (defaults to DEFAULT_MC_TYPE)
/// @param[in] i_target a target representing the target in question
/// @return The position relative to chiplet R
///
@@ -68,7 +67,6 @@ relative_pos<fapi2::TARGET_TYPE_OCMB_CHIP>(const fapi2::Target<fapi2::TARGET_TYP
///
/// @brief Return an MEM_PORT's relative position from an OCMB
-/// @tparam MC the type of memory controller (defaults to DEFAULT_MC_TYPE)
/// @param[in] i_target a target representing the target in question
/// @return The position relative to chiplet R
///
@@ -80,4 +78,16 @@ relative_pos<fapi2::TARGET_TYPE_OCMB_CHIP>(const fapi2::Target<fapi2::TARGET_TYP
return pos(i_target) % TT::PORTS_PER_OCMB;
}
+///
+/// @brief Return an MEM_PORT's relative position from itself
+/// @param[in] i_target a target representing the target in question
+/// @return The position relative to chiplet R
+///
+template<>
+posTraits<fapi2::TARGET_TYPE_MEM_PORT>::pos_type
+relative_pos<fapi2::TARGET_TYPE_MEM_PORT>(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target)
+{
+ return 0;
+}
+
}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
index b62574bdc..33780c16f 100755
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
@@ -36,6 +36,7 @@
#include <utility>
// mss lib
+#include <lib/freq/nimbus_freq_traits.H>
#include <lib/utils/fake_vpd.H>
#include <lib/mss_vpd_decoder.H>
#include <generic/memory/lib/spd/common/rcw_settings.H>
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 20231cfcd..2d9882a15 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
@@ -40,7 +40,7 @@
#include <lib/mss_vpd_decoder.H>
#include <lib/dimm/rank.H>
-#include <lib/utils/assert_noexit.H>
+#include <generic/memory/lib/utils/assert_noexit.H>
#include <lib/eff_config/plug_rules.H>
using fapi2::TARGET_TYPE_MCA;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C
index 889c8e013..83f99bc09 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C
@@ -42,7 +42,7 @@
#include <generic/memory/lib/utils/scom.H>
#include <lib/fir/fir.H>
#include <lib/fir/check.H>
-#include <lib/utils/assert_noexit.H>
+#include <generic/memory/lib/utils/assert_noexit.H>
#include <generic/memory/lib/utils/find.H>
using fapi2::TARGET_TYPE_MCBIST;
@@ -231,7 +231,7 @@ fapi2::ReturnCode during_draminit_training( const fapi2::Target<fapi2::TARGET_TY
fapi_try_exit:
// Handle any fails seen above accordingly
- return mss::check::fir_or_pll_fail<mss::mc_type::NIMBUS>( l_mca, fapi2::current_err, l_check_fir);
+ return mss::check::fir_or_pll_fail( l_mca, fapi2::current_err, l_check_fir);
}
// Declares FIR registers that are re-used between multiple functions
@@ -378,7 +378,7 @@ fapi2::ReturnCode bad_fir_bits<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2:
// Note: we return out if any FIR is bad
for(const auto& l_fir_reg : MCBIST_FIR_REGS)
{
- FAPI_TRY(fir_with_mask<mss::mc_type::NIMBUS>(i_target, l_fir_reg, o_fir_error));
+ FAPI_TRY(fir_with_mask(i_target, l_fir_reg, o_fir_error));
// Log the error if need be
log_fir_helper(i_target, o_fir_error, io_rc);
@@ -395,7 +395,7 @@ fapi2::ReturnCode bad_fir_bits<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2:
{
for(const auto& l_fir_reg : MCA_FIR_REGS)
{
- FAPI_TRY(fir_with_mask<mss::mc_type::NIMBUS>(l_mca, l_fir_reg, o_fir_error));
+ FAPI_TRY(fir_with_mask(l_mca, l_fir_reg, o_fir_error));
// Log the error if need be
log_fir_helper(l_mca, o_fir_error, io_rc);
@@ -441,7 +441,7 @@ fapi2::ReturnCode bad_fir_bits<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2:
// Note: we return out if any FIR is bad
for(const auto& l_fir_reg : MCBIST_FIR_REGS)
{
- FAPI_TRY(fir_with_mask<mss::mc_type::NIMBUS>(l_mcbist, l_fir_reg, o_fir_error));
+ FAPI_TRY(fir_with_mask(l_mcbist, l_fir_reg, o_fir_error));
// Log the error if need be
log_fir_helper(l_mcbist, o_fir_error, io_rc);
@@ -456,7 +456,7 @@ fapi2::ReturnCode bad_fir_bits<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2:
// Loop through all MCA FIR's
for(const auto& l_fir_reg : MCA_FIR_REGS)
{
- FAPI_TRY(fir_with_mask<mss::mc_type::NIMBUS>(i_target, l_fir_reg, o_fir_error));
+ FAPI_TRY(fir_with_mask(i_target, l_fir_reg, o_fir_error));
// Log the error if need be
log_fir_helper(i_target, o_fir_error, io_rc);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H
index 6c9d47a34..4818eeeb1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_freq_traits.H
@@ -22,3 +22,74 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file nimbus_freq_traits.H
+/// @brief Contains frequency traits information for Nimbus
+///
+// *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 _NIMBUS_FREQ_TRAITS_H_
+#define _NIMBUS_FREQ_TRAITS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/freq/gen_mss_freq_traits.H>
+#include <vpd_access.H>
+#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
+
+namespace mss
+{
+
+///
+/// @class Traits and policy class for frequency and synchronous code - specialization for the NIMBUS processor type
+///
+template<>
+class frequency_traits<mss::proc_type::NIMBUS>
+{
+ public:
+ //////////////////////////////////////////////////////////////
+ // Target types
+ //////////////////////////////////////////////////////////////
+ static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
+ static constexpr fapi2::TargetType FREQ_TARGET_TYPE = fapi2::TARGET_TYPE_MCBIST;
+ static constexpr fapi2::TargetType VPD_TARGET_TYPE = fapi2::TARGET_TYPE_MCS;
+
+ //////////////////////////////////////////////////////////////
+ // Traits values
+ //////////////////////////////////////////////////////////////
+ static const std::vector<uint64_t> SUPPORTED_FREQS;
+ // MCBIST is our frequency domain. So 4 ports per MCBIST
+ static constexpr uint64_t PORTS_PER_FREQ_DOMAIN = 4;
+ // Max DIMM's per port
+ static constexpr uint64_t MAX_DIMM_PER_PORT = 2;
+ // Maxium number of primary ranks on a DIMM
+ static constexpr uint64_t MAX_PRIMARY_RANK_PER_DIMM = 4;
+ // MC type for Nimbus is constant - NIMBUS
+ static constexpr mss::mc_type MC = mss::mc_type::NIMBUS;
+ static constexpr const char* PROC_STR = "NIMBUS";
+
+ // VPD traits values
+ // VPD keyword max is slightly repeated (it's in NIMBUS consts too)
+ static constexpr uint64_t VPD_KEYWORD_MAX = 255;
+ static constexpr const char* VPD_BLOB_NAME = "MR";
+ static constexpr auto VPD_BLOB = fapi2::MemVpdData::MR;
+ static constexpr auto LRDIMM_TYPE = fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM;
+
+ // Coding minion, why have these explicitly defined frequency values?
+ // Isn't the supported frequency vector used for this purpose?
+ // Well, we need to callout the specific frequency values that are allowed on a given system
+ // As we can't callout a vector in error callouts and each traits might have a different number of allowable traits,
+ // the below values are hardcoded specifically for the error callouts
+ static constexpr uint64_t SUPPORTED_FREQ0 = DIMM_SPEED_1866;
+ static constexpr uint64_t SUPPORTED_FREQ1 = DIMM_SPEED_2133;
+ static constexpr uint64_t SUPPORTED_FREQ2 = DIMM_SPEED_2400;
+ static constexpr uint64_t SUPPORTED_FREQ3 = DIMM_SPEED_2666;
+};
+
+} // ns mss
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C
index 0a1f6b8b7..37a13275b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/nimbus_mss_freq.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,14 +39,14 @@
// Memory libraries
#include <lib/mss_attribute_accessors.H>
-#include <lib/utils/assert_noexit.H>
#include <lib/shared/mss_const.H>
+#include <lib/freq/nimbus_freq_traits.H>
#include <lib/freq/sync.H>
#include <lib/workarounds/freq_workarounds.H>
// Generic libraries
+#include <generic/memory/lib/utils/assert_noexit.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <generic/memory/lib/utils/freq/gen_mss_freq_traits.H>
#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
@@ -94,7 +94,7 @@ fapi2::ReturnCode set_CL_attr<mss::proc_type::NIMBUS>(
FAPI_ASSERT( l_temp[l_index] == i_cas_latency,
fapi2::MSS_BAD_CL_CAST()
.set_CL(i_cas_latency)
- .set_MCA_TARGET(i_target),
+ .set_PORT_TARGET(i_target),
"%s bad cast for cas latency from %d to %d",
mss::c_str(i_target),
i_cas_latency,
@@ -169,6 +169,133 @@ fapi2::ReturnCode get_dimm_type<mss::proc_type::NIMBUS>(
}
///
+/// @brief Calls out the code if we calculated a bad frequency for the domain - specialization for NIMBUS and MCBIST
+/// @param[in] i_target target on which to operate
+/// @param[in] i_final_freq frequency calculated for domain
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode callout_bad_freq_calculated<mss::proc_type::NIMBUS>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const uint64_t i_final_freq)
+{
+ using TT = mss::frequency_traits<mss::proc_type::NIMBUS>;
+
+ // Declaring temporary variables to avoid linker errors associated with FAPI_ASSERT
+ const auto FREQ0 = TT::SUPPORTED_FREQ0;
+ const auto FREQ1 = TT::SUPPORTED_FREQ1;
+ const auto FREQ2 = TT::SUPPORTED_FREQ2;
+ const auto FREQ3 = TT::SUPPORTED_FREQ3;
+
+ // If we don't find a valid frequency OR don't get a 0 (nothing configured on this clock domain), then error out
+ FAPI_ASSERT( std::binary_search(TT::SUPPORTED_FREQS.begin(), TT::SUPPORTED_FREQS.end(), i_final_freq) ||
+ i_final_freq == 0,
+ fapi2::MSS_BAD_FREQ_CALCULATED()
+ .set_MSS_FREQ(i_final_freq)
+ .set_TARGET(i_target)
+ .set_PROC_TYPE(mss::proc_type::NIMBUS)
+ .set_SUPPORTED_FREQ_0(FREQ0)
+ .set_SUPPORTED_FREQ_1(FREQ1)
+ .set_SUPPORTED_FREQ_2(FREQ2)
+ .set_SUPPORTED_FREQ_3(FREQ3),
+ "%s: Calculated FREQ (%d) isn't supported",
+ mss::c_str(i_target),
+ i_final_freq);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configures the number of ranks in the VPD accessor - specialization for Nimbus and MCBIST
+/// @param[in] i_target the target on which to set the frequency values
+/// @param[in,out] io_vpd_info VPD information that needs to be configured
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode configure_vpd_ranks<mss::proc_type::NIMBUS>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS>& io_vpd_info)
+{
+ using TT = mss::frequency_traits<mss::proc_type::NIMBUS>;
+
+ uint8_t l_rank_count_dimm[TT::MAX_DIMM_PER_PORT] = {};
+ uint8_t l_dimm_type[TT::MAX_DIMM_PER_PORT] = {};
+
+ // ATTR to update
+ // Note: this flat out assumes that we have two DIMM per port max.
+ // This goes against the directive to have arrays be dynamic in length and derived from ATTR's
+ FAPI_TRY( get_master_rank_per_dimm<mss::proc_type::NIMBUS>(i_target, &(l_rank_count_dimm[0])) );
+ FAPI_TRY( get_dimm_type<mss::proc_type::NIMBUS>(i_target, &(l_dimm_type[0])) );
+
+ // So for LRDIMM, our SI works a bit differently than for non-LRDIMM
+ // LRDIMM's have buffers that operate on a per-DIMM basis across multiple ranks
+ // As such, they act as a single load, similar to a 1R DIMM would
+ // per the IBM signal integrity team, the 1R DIMM settings should be used for LRDIMM's
+ // So, if we are LRDIMM's and have ranks, we want to only note it as a 1R DIMM for purposes of querying the VPD
+ FAPI_DBG("%s for DIMM 0 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+ FAPI_DBG("%s for DIMM 1 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+
+ l_rank_count_dimm[0] = ((l_dimm_type[0] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[0] > 0)) ? 1 : l_rank_count_dimm[0];
+ l_rank_count_dimm[1] = ((l_dimm_type[1] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[1] > 0)) ? 1 : l_rank_count_dimm[1];
+
+ FAPI_DBG("after LR modification %s for DIMM 0 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+ FAPI_DBG("after LR modification %s for DIMM 1 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+
+ io_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0];
+ io_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1];
+
+ FAPI_INF("%s. VPD info - rank count for dimm_0: %d, dimm_1: %d",
+ mss::c_str(i_target), io_vpd_info.iv_rank_count_dimm_0, io_vpd_info.iv_rank_count_dimm_1);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check VPD config for support of a given freq - specialization for NIMBUS
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_proposed_freq frequency to check for support
+/// @param[out] o_supported true if VPD supports the proposed frequency
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode check_freq_support_vpd<mss::proc_type::NIMBUS>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const uint64_t i_proposed_freq,
+ bool& o_supported)
+{
+ using TT = mss::frequency_traits<mss::proc_type::NIMBUS>;
+
+ o_supported = false;
+
+ fapi2::VPDInfo<TT::VPD_TARGET_TYPE> l_vpd_info(TT::VPD_BLOB);
+
+ const auto& l_vpd_target = mss::find_target<TT::VPD_TARGET_TYPE>(i_target);
+
+ // Configures the number of ranks for the VPD configuration
+ FAPI_TRY( configure_vpd_ranks<mss::proc_type::NIMBUS>(i_target, l_vpd_info),
+ "%s failed to configure VPD ranks", mss::c_str(i_target));
+ l_vpd_info.iv_is_config_ffdc_enabled = false;
+
+ l_vpd_info.iv_freq_mhz = i_proposed_freq;
+ FAPI_INF("VPD info - DDR frequency: %d MT/s", i_proposed_freq);
+
+ // Checks if this VPD configuration is supported
+ FAPI_TRY(is_vpd_config_supported<mss::proc_type::NIMBUS>(l_vpd_target, i_proposed_freq, l_vpd_info, o_supported),
+ "%s failed to determine if %u freq is supported", mss::c_str(i_target), i_proposed_freq);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Update supported frequency scoreboard according to processor limits - specialization for NIMBUS and MCBIST
/// @param[in] i_target processor frequency domain
/// @param[in,out] io_scoreboard scoreboard of port targets supporting each frequency
@@ -211,10 +338,10 @@ fapi2::ReturnCode num_master_ranks_per_dimm<mss::proc_type::NIMBUS>(const fapi2:
/// @return FAPI2_RC_SUCCESS iff ok
///
template<>
-fapi2::ReturnCode callout_no_common_freq<mss::proc_type::NIMBUS>(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>&
- i_target,
- const bool l_supported_freq,
- const uint64_t i_num_ports)
+fapi2::ReturnCode callout_no_common_freq<mss::proc_type::NIMBUS>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ const bool l_supported_freq,
+ const uint64_t i_num_ports)
{
std::vector<uint32_t> l_max_mrw_freqs(NUM_MAX_FREQS, 0);
uint8_t l_req_sync_mode = 0;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
index 9b864695a..8c9b1ccc5 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,17 +40,17 @@
#include <map>
// Memory libraries
+#include <lib/freq/nimbus_freq_traits.H>
#include <lib/freq/sync.H>
#include <lib/mss_attribute_accessors.H>
-#include <lib/utils/assert_noexit.H>
// Generic libraries
+#include <generic/memory/lib/utils/assert_noexit.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/spd/spd_facade.H>
#include <generic/memory/lib/spd/spd_utils.H>
#include <generic/memory/lib/utils/conversions.H>
-#include <generic/memory/lib/utils/freq/gen_mss_freq_traits.H>
#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
@@ -97,7 +97,7 @@ fapi2::ReturnCode dimm_speed_map(const std::vector< fapi2::Target<TARGET_TYPE_MC
// Getting error cross initializing with the Assert
// find_if should work if passed in an empty vector. begin() and end() will match and it'll exit without trying freq()
FAPI_ASSERT( !i_targets.empty(),
- fapi2::MSS_EMPTY_MCBIST_VECTOR_PASSED(),
+ fapi2::MSS_EMPTY_FREQ_TARGET_VECTOR_PASSED(),
"Empty MCBIST target vector found when constructing dimm speed mapping!" );
@@ -109,7 +109,7 @@ fapi2::ReturnCode dimm_speed_map(const std::vector< fapi2::Target<TARGET_TYPE_MC
// It has a valid freq
// Thus, this shouldn't ever happen, but let's check anyways
FAPI_ASSERT( l_found_comp != i_targets.end(),
- fapi2::MSS_ALL_MCBIST_HAVE_0_FREQ()
+ fapi2::MSS_ALL_TARGETS_HAVE_0_FREQ()
.set_VECTOR_SIZE(i_targets.size()),
"All MCBIST have 0 MSS_FREQ, but there are dimms?");
@@ -178,10 +178,10 @@ bool deconfigure(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
l_is_hw_deconfigured = true;
MSS_ASSERT_NOEXIT(false,
- fapi2::MSS_FREQ_NOT_EQUAL_NEST_FREQ()
+ fapi2::MSS_FREQ_NOT_EQUAL_MAX_DOMAIN_FREQ()
.set_MSS_FREQ(i_dimm_speed)
- .set_NEST_FREQ(i_nest_freq)
- .set_MCS_TARGET(l_mcs),
+ .set_DOMAIN_FREQ(i_nest_freq)
+ .set_DOMAIN_TARGET(l_mcs),
"Deconfiguring %s due to unequal frequencies: mss: %d, nest: %d",
mss::c_str(l_mcs),
i_dimm_speed,
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
index 7a780c310..4f8624890 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,6 +39,7 @@
#include <vector>
#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
#include <generic/memory/lib/utils/c_str.H>
@@ -67,12 +68,6 @@ inline bool is_nest_freq_valid (const uint64_t i_proposed_freq)
return ( std::binary_search(NIMBUS_NEST_FREQS.begin(), NIMBUS_NEST_FREQS.end(), i_proposed_freq) );
}
-enum class speed_equality : uint8_t
-{
- NOT_EQUAL_DIMM_SPEEDS = 0, ///< denotes all DIMMs don't have the same speed
- EQUAL_DIMM_SPEEDS = 1, ///< denotes all DIMMs have the same speed
-};
-
///
/// @brief Retrieves a mapping of MSS frequency values per mcbist target
/// @param[in] i_targets vector of controller targets
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/assert_noexit.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/assert_noexit.H
deleted file mode 100644
index 35f0b68d4..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/assert_noexit.H
+++ /dev/null
@@ -1,61 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/assert_noexit.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
-/* [+] 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 assert_noexit.H
-/// @brief MSS specific assert, but don't exit macro
-///
-// *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: HB:FSP
-
-#ifndef _MSS_ASSERT_NOEXIT_H_
-#define _MSS_ASSERT_NOEXIT_H_
-
-#include <fapi2.H>
-
-///
-/// @brief Create an error log based on __conditional__,
-/// the FFDC gathering function is called and the
-/// trace is output as a FAPI error trace. An error log
-/// is created. fapi2::current_err is set to indicate there was
-/// an error so the caller can ripple thru accordingly
-/// The caller is responsible for handling the error object.
-///
-/// @param[in] __conditional__ the condition to assert
-/// @param[in] __ffdc__ the FFDC gathering function
-/// @param[in] ... varargs, as input to FAPI_ERR
-///
-#define MSS_ASSERT_NOEXIT( __conditional__, __ffdc__, ... ) \
- if (! (__conditional__)) \
- { \
- __ffdc__.execute(fapi2::FAPI2_ERRL_SEV_UNDEFINED, true); \
- FAPI_ERR(__VA_ARGS__); \
- fapi2::current_err = fapi2::FAPI2_RC_FALSE; \
- }
-
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/freq_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/freq_workarounds.C
index 40b6ed54c..ff1aa8588 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/freq_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/freq_workarounds.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,7 @@
#include <mss.H>
#include <lib/workarounds/freq_workarounds.H>
-#include <lib/utils/assert_noexit.H>
+#include <generic/memory/lib/utils/assert_noexit.H>
namespace mss
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
index 34eae3e9b..7d770fc13 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -45,8 +45,10 @@
#include <fapi2.H>
// mss lib
+#include <lib/freq/nimbus_freq_traits.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
+#include <generic/memory/lib/data_engine/pre_data_init.H>
using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_MCA;
@@ -81,6 +83,9 @@ extern "C"
return FAPI2_RC_SUCCESS;
}
+ // We will first set pre-eff_config attributes
+ FAPI_TRY(mss::set_pre_init_attrs<mss::proc_type::NIMBUS>(l_mcbist));
+
FAPI_TRY(mss::generate_freq<mss::proc_type::NIMBUS>(l_mcbist));
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
index 2e8fb7167..b4ab25916 100755
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
@@ -530,25 +530,6 @@
</attribute>
<attribute>
- <id>ATTR_MSS_MRW_SUPPORTED_FREQ</id>
- <targetType>TARGET_TYPE_SYSTEM</targetType>
- <description>
- List of memory frequencies supported by the current system.
- </description>
- <valueType>uint32</valueType>
- <array>4</array>
- <platInit/>
- <!-- Note, mirrors ATTR_MSS_FREQ -->
- <enum>
- MT1866 = 1866,
- MT2133 = 2133,
- MT2400 = 2400,
- MT2666 = 2666
- </enum>
- <default> 1866, 2133, 2400, 2666 </default>
- </attribute>
-
- <attribute>
<id>ATTR_MSS_MRW_UNSUPPORTED_RANK_CONFIG</id>
<targetType>TARGET_TYPE_MCS</targetType>
<description>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml
index 8eac08abd..4a1b6f51f 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_freq.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2015,2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2015,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -47,7 +47,7 @@
</callout>
<callout>
<childTargets>
- <parent>MCA_TARGET</parent>
+ <parent>PORT_TARGET</parent>
<childType>TARGET_TYPE_DIMM</childType>
</childTargets>
<priority>MEDIUM</priority>
@@ -55,27 +55,47 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_FREQ_NOT_EQUAL_NEST_FREQ</rc>
+ <rc>RC_MSS_BAD_FREQ_CALCULATED</rc>
+ <description>
+ No frequency found for MC Either bad mrw attribute or no DIMMS installed?
+ Should be a code bug if we get here
+ </description>
+ <ffdc>MSS_FREQ</ffdc>
+ <ffdc>SUPPORTED_FREQ_0</ffdc>
+ <ffdc>SUPPORTED_FREQ_1</ffdc>
+ <ffdc>SUPPORTED_FREQ_2</ffdc>
+ <ffdc>SUPPORTED_FREQ_3</ffdc>
+ <ffdc>TARGET</ffdc>
+ <ffdc>PROC_TYPE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_FREQ_NOT_EQUAL_MAX_DOMAIN_FREQ</rc>
<description>
Case when mss_freq speeds are different and sync mode is required,
- and mss_freq is not equal to nest freq.
+ and mss_freq is not equal to max freq in domain.
</description>
<ffdc>MSS_FREQ</ffdc>
- <ffdc>NEST_FREQ</ffdc>
+ <ffdc>DOMAIN_FREQ</ffdc>
+ <ffdc>DOMAIN_TARGET</ffdc>
<callout>
<procedure>CODE</procedure>
<priority>MEDIUM</priority>
</callout>
<callout>
<childTargets>
- <parent>MCS_TARGET</parent>
+ <parent>DOMAIN_TARGET</parent>
<childType>TARGET_TYPE_DIMM</childType>
</childTargets>
<priority>HIGH</priority>
</callout>
<deconfigure>
<childTargets>
- <parent>MCS_TARGET</parent>
+ <parent>DOMAIN_TARGET</parent>
<childType>TARGET_TYPE_DIMM</childType>
</childTargets>
</deconfigure>
@@ -96,9 +116,9 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_EMPTY_MCBIST_VECTOR_PASSED</rc>
+ <rc>RC_MSS_EMPTY_FREQ_TARGET_VECTOR_PASSED</rc>
<description>
- Empty MCBIST target vector found when constructing dimm speed mapping
+ Empty freq target vector found when constructing dimm speed mapping
</description>
<callout>
<procedure>CODE</procedure>
@@ -144,9 +164,9 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_ALL_MCBIST_HAVE_0_FREQ</rc>
+ <rc>RC_MSS_ALL_TARGETS_HAVE_0_FREQ</rc>
<description>
- All MCBIST have 0 MSS_FREQ, but there are dimms still configured?
+ All targets in the freq domain (MCBIST or port) have 0 MSS_FREQ, but there are dimms still configured?
</description>
<ffdc>VECTOR_SIZE</ffdc>
<callout>
@@ -275,7 +295,7 @@
</callout>
<callout>
<childTargets>
- <parent>MCA_TARGET</parent>
+ <parent>PORT_TARGET</parent>
<childType>TARGET_TYPE_DIMM</childType>
</childTargets>
<priority>MEDIUM</priority>
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H
index ae17d925d..1b4f96d0c 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_freq_traits.H
@@ -22,3 +22,73 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file axone_freq_traits.H
+/// @brief Contains frequency traits information for Axone
+///
+// *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 _AXONE_FREQ_TRAITS_H_
+#define _AXONE_FREQ_TRAITS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/freq/gen_mss_freq_traits.H>
+#include <vpd_access.H>
+
+namespace mss
+{
+
+///
+/// @class Traits and policy class for frequency and synchronous code - specialization for the AXONE processor type
+///
+template<>
+class frequency_traits<mss::proc_type::AXONE>
+{
+ public:
+ //////////////////////////////////////////////////////////////
+ // Target types
+ //////////////////////////////////////////////////////////////
+ static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+ static constexpr fapi2::TargetType FREQ_TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
+ static constexpr fapi2::TargetType VPD_TARGET_TYPE = fapi2::TARGET_TYPE_OCMB_CHIP;
+
+ //////////////////////////////////////////////////////////////
+ // Traits values
+ //////////////////////////////////////////////////////////////
+ static const std::vector<uint64_t> SUPPORTED_FREQS;
+ // MEM_PORT is our frequency domain. So 1 port per domain
+ static constexpr uint64_t PORTS_PER_FREQ_DOMAIN = 1;
+ // Max DIMM's per port
+ static constexpr uint64_t MAX_DIMM_PER_PORT = 2;
+ // Maxium number of primary ranks on a DIMM
+ static constexpr uint64_t MAX_PRIMARY_RANK_PER_DIMM = 4;
+ // MC type for Axone is constant - EXPLORER
+ static constexpr mss::mc_type MC = mss::mc_type::EXPLORER;
+ static constexpr const char* PROC_STR = "AXONE";
+
+ // VPD traits values
+ // TK Resolve these when we know what they are for Axone
+ static constexpr uint64_t VPD_KEYWORD_MAX = 255;
+ static constexpr const char* VPD_BLOB_NAME = "EFD";
+ static constexpr auto VPD_BLOB = fapi2::MemVpdData::EFD;
+ static constexpr auto LRDIMM_TYPE = fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM;
+
+ // Coding minion, why have these explicitly defined frequency values?
+ // Isn't the supported frequency vector used for this purpose?
+ // Well, we need to callout the specific frequency values that are allowed on a given system
+ // As we can't callout a vector in error callouts and each traits might have a different number of allowable traits,
+ // the below values are hardcoded specifically for the error callouts
+ static constexpr uint64_t SUPPORTED_FREQ0 = DIMM_SPEED_2666;
+ static constexpr uint64_t SUPPORTED_FREQ1 = DIMM_SPEED_2933;
+ static constexpr uint64_t SUPPORTED_FREQ2 = DIMM_SPEED_3200;
+};
+
+
+} // ns mss
+#endif
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C
index d9dcbda4a..23d6481ad 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_mss_freq.C
@@ -22,3 +22,430 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file axone_mss_freq.C
+/// @brief Axone specializations for frequency 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 <vpd_access.H>
+#include <vector>
+
+// Memory libraries
+#include <lib/freq/axone_freq_traits.H>
+#include <lib/shared/axone_consts.H>
+#include <lib/freq/axone_sync.H>
+
+// Generic libraries
+#include <mss_generic_attribute_getters.H>
+#include <mss_generic_attribute_setters.H>
+#include <mss_generic_system_attribute_getters.H>
+#include <generic/memory/lib/utils/assert_noexit.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
+#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
+
+namespace mss
+{
+
+const std::vector< uint64_t > frequency_traits<mss::proc_type::AXONE>::SUPPORTED_FREQS =
+{
+ mss::DIMM_SPEED_2666,
+ mss::DIMM_SPEED_2933,
+ mss::DIMM_SPEED_3200,
+};
+
+///
+/// @brief Sets DRAM CAS latency attributes - specialization for Axone and MEM_PORT
+/// @param[in] i_target the controller target for the cas_latency value
+/// @param[in] i_cas_latency cas latency to update
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode set_CL_attr<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_cas_latency)
+{
+ const auto l_temp = static_cast<uint8_t>(i_cas_latency);
+
+ //Check for rounding issues. Going from a uint64_t to a uint8_t
+ FAPI_ASSERT( l_temp == i_cas_latency,
+ fapi2::MSS_BAD_CL_CAST()
+ .set_CL(i_cas_latency)
+ .set_PORT_TARGET(i_target),
+ "%s bad cast for cas latency from %d to %d",
+ mss::c_str(i_target),
+ i_cas_latency,
+ l_temp);
+
+ FAPI_INF( "Final Chosen CL: %d for %s", l_temp, mss::c_str(i_target));
+
+ FAPI_TRY( mss::attr::set_dram_cl(i_target, l_temp) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets the frequency value - specialization for Axone and MEM_PORT
+/// @param[in] i_target the target on which to set the frequency values
+/// @param[in] i_freq frequency value to set
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode set_freq<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_freq)
+{
+ FAPI_TRY( mss::attr::set_freq(i_target, i_freq) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Gets the number of master ranks per DIMM - specialization for Axone and MEM_PORT
+/// @param[in] i_target the target on which to get the number of master ranks per DIMM
+/// @param[out] o_master_ranks number of master ranks per DIMM
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode get_master_rank_per_dimm<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t* o_master_ranks)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+
+ uint8_t l_master_ranks[TT::MAX_DIMM_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_target, l_master_ranks));
+ std::copy(&l_master_ranks[0], &l_master_ranks[0] + TT::MAX_DIMM_PER_PORT, &o_master_ranks[0]);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Gets the attribute for the maximum - specialization for Axone
+/// @param[out] o_allowed_dimm_freq allowed dimm frequency
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode max_allowed_dimm_freq<mss::proc_type::AXONE>(uint32_t* o_allowed_dimm_freq)
+{
+ uint32_t l_allowed_dimm_freq[NUM_MAX_FREQS] = {0};
+ FAPI_TRY(mss::attr::get_max_allowed_dimm_freq(l_allowed_dimm_freq));
+ std::copy(&l_allowed_dimm_freq[0], &l_allowed_dimm_freq[0] + NUM_MAX_FREQS, &o_allowed_dimm_freq[0]);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Gets the DIMM type - specialization for Axone and MEM_PORT
+/// @param[in] i_target the target on which to get the DIMM types
+/// @param[out] o_dimm_type DIMM types
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode get_dimm_type<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t* o_dimm_type)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+
+ uint8_t l_dimm_type[TT::MAX_DIMM_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_dimm_type(i_target, l_dimm_type));
+ std::copy(&l_dimm_type[0], &l_dimm_type[0] + TT::MAX_DIMM_PER_PORT, &o_dimm_type[0]);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calls out the code if we calculated a bad frequency for the domain - specialization for Axone and MEM_PORT
+/// @param[in] i_target target on which to operate
+/// @param[in] i_final_freq frequency calculated for domain
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode callout_bad_freq_calculated<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_final_freq)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+
+ // Declaring temporary variables to avoid linker errors associated with FAPI_ASSERT
+ const auto FREQ0 = TT::SUPPORTED_FREQ0;
+ const auto FREQ1 = TT::SUPPORTED_FREQ1;
+ const auto FREQ2 = TT::SUPPORTED_FREQ2;
+
+ // If we don't find a valid frequency OR don't get a 0 (nothing configured on this clock domain), then error out
+ FAPI_ASSERT( std::binary_search(TT::SUPPORTED_FREQS.begin(), TT::SUPPORTED_FREQS.end(), i_final_freq) ||
+ i_final_freq == 0,
+ fapi2::P9A_MSS_BAD_FREQ_CALCULATED()
+ .set_MSS_FREQ(i_final_freq)
+ .set_TARGET(i_target)
+ .set_PROC_TYPE(mss::proc_type::AXONE)
+ .set_SUPPORTED_FREQ_0(FREQ0)
+ .set_SUPPORTED_FREQ_1(FREQ1)
+ .set_SUPPORTED_FREQ_2(FREQ2),
+ "%s: Calculated FREQ (%d) isn't supported",
+ mss::c_str(i_target),
+ i_final_freq);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Return a list of configured ranks on a MEM_PORT
+/// @param[in] i_target the port target
+/// @param[out] o_ranks list of valid ranks on the port
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+// TK this function should get replaced by our rank API when available
+fapi2::ReturnCode get_ranks_for_vpd(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ std::vector<uint64_t>& o_ranks)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+
+ uint8_t l_rank_count_dimm[TT::MAX_DIMM_PER_PORT] = {};
+ uint8_t l_dimm_type[TT::MAX_DIMM_PER_PORT] = {};
+
+ o_ranks.clear();
+
+ FAPI_TRY( get_master_rank_per_dimm<mss::proc_type::AXONE>(i_target, &(l_rank_count_dimm[0])) );
+ FAPI_TRY( get_dimm_type<mss::proc_type::AXONE>(i_target, &(l_dimm_type[0])) );
+
+ // So for LRDIMM, our SI works a bit differently than for non-LRDIMM
+ // LRDIMM's have buffers that operate on a per-DIMM basis across multiple ranks
+ // As such, they act as a single load, similar to a 1R DIMM would
+ // per the IBM signal integrity team, the 1R DIMM settings should be used for LRDIMM's
+ // So, if we are LRDIMM's and have ranks, we want to only note it as a 1R DIMM for purposes of querying the VPD
+ FAPI_DBG("%s for DIMM 0 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+ FAPI_DBG("%s for DIMM 1 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+
+ l_rank_count_dimm[0] = ((l_dimm_type[0] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[0] > 0)) ? 1 : l_rank_count_dimm[0];
+ l_rank_count_dimm[1] = ((l_dimm_type[1] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[1] > 0)) ? 1 : l_rank_count_dimm[1];
+
+ FAPI_DBG("after LR modification %s for DIMM 0 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+ FAPI_DBG("after LR modification %s for DIMM 1 rank count %u dimm type %u %s",
+ mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
+
+ // Add DIMM0's ranks
+ for (uint64_t l_rank = 0; l_rank < l_rank_count_dimm[0]; ++l_rank)
+ {
+ o_ranks.push_back(l_rank);
+ }
+
+ // Add DIMM1's ranks
+ for (uint64_t l_rank = 0; l_rank < l_rank_count_dimm[1]; ++l_rank)
+ {
+ o_ranks.push_back(l_rank + TT::MAX_PRIMARY_RANK_PER_DIMM);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Check VPD config for support of a given freq - Axone specialization
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_proposed_freq frequency to check for support
+/// @param[out] o_supported true if VPD supports the proposed frequency
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode check_freq_support_vpd<mss::proc_type::AXONE>( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>&
+ i_target,
+ const uint64_t i_proposed_freq,
+ bool& o_supported)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+ o_supported = false;
+
+ std::vector<uint64_t> l_ranks;
+ fapi2::VPDInfo<TT::VPD_TARGET_TYPE> l_vpd_info(TT::VPD_BLOB);
+
+ const auto& l_vpd_target = mss::find_target<TT::VPD_TARGET_TYPE>(i_target);
+
+ l_vpd_info.iv_is_config_ffdc_enabled = false;
+
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(i_target, i_proposed_freq, l_vpd_info.iv_omi_freq_mhz));
+ FAPI_INF("Setting VPD info OMI frequency: %d Gbps, for DDR frequency %d MT/s",
+ l_vpd_info.iv_omi_freq_mhz, i_proposed_freq);
+
+ // DDIMM SPD can contain different SI settings for each master rank.
+ // To determine which frequencies are supported, we have to check for each valid
+ // master rank on the port's DIMMs
+ FAPI_TRY(get_ranks_for_vpd(i_target, l_ranks));
+
+ for (const auto l_rank : l_ranks)
+ {
+ l_vpd_info.iv_rank = l_rank;
+ FAPI_INF("%s. VPD info - checking rank: %d",
+ mss::c_str(i_target), l_rank);
+
+ // Check if this VPD configuration is supported
+ FAPI_TRY(is_vpd_config_supported<mss::proc_type::AXONE>(l_vpd_target, i_proposed_freq, l_vpd_info, o_supported),
+ "%s failed to determine if %u freq is supported", mss::c_str(i_target), i_proposed_freq);
+
+
+ // If we fail any of the ranks, then this VPD configuration is not supported
+ if(o_supported == false)
+ {
+ FAPI_INF("%s is not supported on rank%u exiting...", mss::c_str(i_target), l_rank);
+ break;
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Update supported frequency scoreboard according to processor limits - specialization for Axone and MEM_PORT
+/// @param[in] i_target processor frequency domain
+/// @param[in,out] io_scoreboard scoreboard of port targets supporting each frequency
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode limit_freq_by_processor<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ freq_scoreboard& io_scoreboard)
+{
+ std::vector<uint64_t> l_converted_omi_freqs;
+
+ // OCMB always needs to be in sync between OMI and DDR, by the given ratio
+ // so we convert the supported OMI freqs and remove every other DDR freq
+ // from the scoreboard
+ for (const auto l_omi_freq : AXONE_OMI_FREQS)
+ {
+ uint64_t l_ddr_freq = 0;
+ FAPI_TRY(convert_omi_freq_to_ddr_freq(i_target, l_omi_freq, l_ddr_freq));
+ l_converted_omi_freqs.push_back(l_ddr_freq);
+ }
+
+ FAPI_TRY(io_scoreboard.remove_freqs_not_on_list(0, l_converted_omi_freqs));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Gets the number of master ranks on each DIMM - specialization for the Axone processor type
+/// @param[in] i_target DIMM target
+/// @param[out] o_master_ranks number of master ranks
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode num_master_ranks_per_dimm<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_master_ranks)
+{
+ return mss::attr::get_num_master_ranks_per_dimm(i_target, o_master_ranks);
+}
+
+///
+/// @brief Calls out the target if no DIMM frequencies are supported - specialization for Axone and MEM_PORT
+/// @param[in] i_target target on which to operate
+/// @param[in] i_supported_freq true if any FREQ's are supported
+/// @param[in,out] i_num_ports number of configured ports (always 1 for Axone)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode callout_no_common_freq<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const bool i_supported_freq,
+ const uint64_t i_num_ports)
+{
+ uint32_t l_max_mrw_freqs[NUM_MAX_FREQS] = {0};
+ FAPI_TRY( mss::attr::get_max_allowed_dimm_freq(l_max_mrw_freqs) );
+
+ FAPI_ASSERT(i_supported_freq,
+ fapi2::P9A_MSS_NO_SUPPORTED_FREQ()
+ .set_MEM_PORT_TARGET(i_target)
+ .set_MRW_MAX_FREQ_0(l_max_mrw_freqs[0])
+ .set_MRW_MAX_FREQ_1(l_max_mrw_freqs[1])
+ .set_MRW_MAX_FREQ_2(l_max_mrw_freqs[2])
+ .set_MRW_MAX_FREQ_3(l_max_mrw_freqs[3])
+ .set_MRW_MAX_FREQ_4(l_max_mrw_freqs[4]),
+ "%s didn't find a frequency that was supported on any ports", mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calls out the target if no DIMM frequencies are supported - specialization for Axone and MEM_PORT
+/// @param[in] i_target target on which to operate
+/// @param[in] i_vpd_supported_freqs VPD supported frequencies for the callout
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<>
+fapi2::ReturnCode callout_max_freq_empty_set<mss::proc_type::AXONE>(
+ const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const std::vector<std::vector<uint32_t>>& i_vpd_supported_freqs)
+{
+
+ std::vector<uint32_t> l_port_vpd_max_freq;
+
+ // Get the max freq supported on each port
+ for ( const auto& l_port_supported_freqs : i_vpd_supported_freqs )
+ {
+ l_port_vpd_max_freq.push_back(l_port_supported_freqs.back());
+ }
+
+ uint32_t l_max_mrw_freqs[NUM_MAX_FREQS] = {0};
+ FAPI_TRY( mss::attr::get_max_allowed_dimm_freq(l_max_mrw_freqs) );
+
+ FAPI_ASSERT(false,
+ fapi2::P9A_MSS_MRW_FREQ_MAX_FREQ_EMPTY_SET()
+ .set_MSS_VPD_FREQ_0(l_port_vpd_max_freq[0])
+ .set_MSS_VPD_FREQ_1(l_port_vpd_max_freq[1])
+ .set_MSS_VPD_FREQ_2(l_port_vpd_max_freq[2])
+ .set_MSS_MAX_FREQ_0(l_max_mrw_freqs[0])
+ .set_MSS_MAX_FREQ_1(l_max_mrw_freqs[1])
+ .set_MSS_MAX_FREQ_2(l_max_mrw_freqs[2])
+ .set_MSS_MAX_FREQ_3(l_max_mrw_freqs[3])
+ .set_MSS_MAX_FREQ_4(l_max_mrw_freqs[4])
+ .set_OMI_FREQ_0(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_21_33GBPS)
+ .set_OMI_FREQ_1(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_23_46GBPS)
+ .set_OMI_FREQ_2(fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_25_60GBPS)
+ .set_PORT_TARGET(i_target),
+ "%s didn't find a supported frequency for the port", mss::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+namespace check
+{
+
+///
+/// @brief Checks the final frequency for the system type - Axone and MEM_PORT specialization
+/// @param[in] i_target the target on which to operate
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note This function was needed in Nimbus to enforce a frequency limit due to a hardware limitation
+/// and is not needed here.
+///
+template<>
+fapi2::ReturnCode final_freq<mss::proc_type::AXONE>(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target)
+{
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+} // ns check
+
+} // ns mss
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C
index a2ea450e7..311e12cf7 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.C
@@ -22,3 +22,253 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file axone_sync.C
+/// @brief Synchronous function implementations for Axone
+///
+// *HWP HWP Owner: Andre Marin <aamarin@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 <vpd_access.H>
+#include <algorithm>
+#include <vector>
+#include <map>
+
+// Memory libraries
+#include <lib/freq/axone_freq_traits.H>
+#include <lib/freq/axone_sync.H>
+#include <mss_explorer_attribute_getters.H>
+
+// Generic libraries
+#include <mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/assert_noexit.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/spd/spd_utils.H>
+#include <generic/memory/lib/utils/conversions.H>
+#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
+#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
+
+namespace mss
+{
+
+///
+/// @brief Retrieves a mapping of MSS frequency values per port target
+/// @param[in] i_targets vector of port targets
+/// @param[out] o_freq_map dimm speed map <key, value> = (port target, frequency)
+/// @param[out] o_is_speed_equal holds whether map dimm speed is equal
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode dimm_speed_map(const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >& i_targets,
+ std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& o_freq_map,
+ speed_equality& o_is_speed_equal)
+{
+ o_freq_map.clear();
+
+ // The find_if loop is meant to find the "first" good (non-zero) freq value
+ // so I can compare it against all other freq values from the MEM_PORT vector
+ // I am checking to make sure I don't get a value of 0
+ // Since Cronus can hand me back a MEM_PORT w/no DIMMs
+ // Which would give ATTR_MSS_FREQ value of 0 in p9_mss_freq
+ uint64_t l_comparator = 0;
+ fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_FALSE);
+
+ const auto l_found_comp = std::find_if(i_targets.begin(), i_targets.end(),
+ [&l_rc, &l_comparator] (const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target)->bool
+ {
+ l_rc = mss::attr::get_freq(i_target, l_comparator);
+ return l_comparator != 0;
+ });
+
+ // Getting error cross initializing with the Assert
+ // find_if should work if passed in an empty vector. begin() and end() will match and it'll exit without trying freq()
+ FAPI_ASSERT( !i_targets.empty(),
+ fapi2::MSS_EMPTY_FREQ_TARGET_VECTOR_PASSED(),
+ "Empty MEM_PORT target vector found when constructing dimm speed mapping!" );
+
+ FAPI_TRY(l_rc, "Failed accessor mss::freq()");
+
+ // If all MEM_PORTs are 0 we go no further
+ // We shouldn't get here though. We check for DIMMS in freq_system. If no DIMMS, we exit
+ // We can assume if there is a dimm configured at this point (after mss_freq)
+ // It has a valid freq
+ // Thus, this shouldn't ever happen, but let's check anyways
+ FAPI_ASSERT( l_found_comp != i_targets.end(),
+ fapi2::MSS_ALL_TARGETS_HAVE_0_FREQ()
+ .set_VECTOR_SIZE(i_targets.size()),
+ "All MEM_PORTs have 0 MSS_FREQ, but there are dimms?");
+
+ // DIMM speed is equal until we deduce otherwise
+ o_is_speed_equal = speed_equality::EQUAL_DIMM_SPEEDS;
+
+ // Make sure to stick the first one we found in the freq map.
+ o_freq_map.emplace( std::make_pair(*l_found_comp, l_comparator) );
+
+ // Loop through all MEM_PORTs and store dimm speeds
+ // Starting from 1st known good freq (non-zero) value
+ // I found above to avoid double looping target vector
+ for (auto l_iter = l_found_comp + 1; l_iter != i_targets.end(); ++l_iter)
+ {
+ uint64_t l_dimm_speed = 0;
+ FAPI_TRY( mss::attr::get_freq(*l_iter, l_dimm_speed), "Failed accessor to mss_freq" );
+
+ // In FW, parents are deconfigured if they have no children
+ // So there is no way to get a MEM_PORT w/no DIMMs.
+ // This isn't true for Cronus so I am skipping map
+ // insertion and check for dimm speed equality
+ // to avoid incorrect settings
+ if( l_dimm_speed != 0)
+ {
+ // At least one mismatch freq value occurred
+ if(l_comparator != l_dimm_speed)
+ {
+ o_is_speed_equal = speed_equality::NOT_EQUAL_DIMM_SPEEDS;
+ }
+
+ FAPI_INF("%s: Dimm speed %d MT/s", c_str(*l_iter), l_dimm_speed);
+
+ o_freq_map.emplace( std::make_pair(*l_iter, l_dimm_speed) );
+ }
+ }
+
+ // Idiot check - most certainly a programming error
+ FAPI_ASSERT( o_freq_map.size() != 0,
+ fapi2::MSS_ERROR_FINDING_DIMM_SPEED_MAP(),
+ "freq system freq map is empty? found port: %s",
+ mss::c_str(*l_found_comp) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Deconfigures MEM_PORT targets
+/// @param[in] i_target the port target
+/// @param[in] i_dimm_speed dimm speed in MT/s
+/// @param[in] i_max_freq maximum dimm freq in MT/s of freq domain
+/// @return true if hardware was deconfigured
+///
+bool deconfigure(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_dimm_speed,
+ const uint32_t i_max_freq)
+{
+ bool l_is_hw_deconfigured = (i_dimm_speed != i_max_freq);
+
+ MSS_ASSERT_NOEXIT(!l_is_hw_deconfigured,
+ fapi2::MSS_FREQ_NOT_EQUAL_MAX_DOMAIN_FREQ()
+ .set_MSS_FREQ(i_dimm_speed)
+ .set_DOMAIN_FREQ(i_max_freq)
+ .set_DOMAIN_TARGET(i_target),
+ "Deconfiguring %s due to unequal frequencies: this port: %d, Max in freq domain: %d",
+ mss::c_str(i_target),
+ i_dimm_speed,
+ i_max_freq );
+
+ return l_is_hw_deconfigured;
+}
+
+///
+/// @brief Selects synchronous mode and performs requirements enforced by selected port frequency
+/// @param[in] i_freq_map dimm speed mapping
+/// @param[in] i_equal_dimm_speed tracks whether map has equal dimm speeds
+/// @param[in] i_omi_freq OMI frequency
+/// @param[out] o_selected_sync_mode final synchronous mode
+/// @param[out] o_selected_omi_freq final freq selected, only valid if final sync mode is in-sync
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& i_freq_map,
+ const speed_equality i_equal_dimm_speed,
+ const uint32_t i_omi_freq,
+ uint8_t& o_selected_sync_mode,
+ uint64_t& o_selected_omi_freq)
+{
+ FAPI_INF("---- In select_sync_mode ----");
+
+ switch(i_equal_dimm_speed)
+ {
+ // If we have a port which has resolved to equal speeds ...
+ case speed_equality::EQUAL_DIMM_SPEEDS:
+ {
+ // Return back the resulting speed. It doesn't matter which we select from the map as they're all equal
+ // If we end up not in sync in the conditional below, thats ok - this parameter is ignored by the
+ // caller if we're not in sync mode
+ const auto l_ddr_freq = i_freq_map.begin()->second;
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(i_freq_map.begin()->first, l_ddr_freq, o_selected_omi_freq));
+
+ // When we selected ATTR_MSS_FREQ, we made sure that we didn't
+ // select a DIMM freq the OMI couldn't support.
+ o_selected_sync_mode = fapi2::ENUM_ATTR_MC_SYNC_MODE_IN_SYNC;
+ // On Cronus if the o_selected_omi_freq != i_omi_freq we've got a mismatch. Note that p9a_mss_freq ensures
+ // we don't select an invalid freq, but doesn't ensure we select the current OMI freq.
+#ifndef __HOSTBOOT_MODULE
+ FAPI_ASSERT(o_selected_omi_freq == i_omi_freq,
+ fapi2::P9A_MSS_FAILED_SYNC_MODE()
+ .set_OMI_FREQ(i_omi_freq)
+ .set_MEM_FREQ(o_selected_omi_freq),
+ "The DIMM freq (%d) and the OMI freq (%d) don't align",
+ o_selected_omi_freq, i_omi_freq);
+#endif
+ return fapi2::FAPI2_RC_SUCCESS;
+ break;
+ }
+
+ case speed_equality::NOT_EQUAL_DIMM_SPEEDS:
+ {
+ // When we selected ATTR_MSS_FREQ, we made sure that we didn't
+ // select a DIMM freq the OMI couldn't support. That means that the fastest of the ports
+ // is the one that rules the roost (the OMI can support it too.) So find that, and set it to
+ // the selected frequency. Then deconfigure the slower port (unless we're in Cronus in which
+ // case we just bomb out.)
+#ifdef __HOSTBOOT_MODULE
+ uint64_t l_max_dimm_speed = 0;
+ fapi2::Target<TARGET_TYPE_MEM_PORT> l_fastest_port_target = i_freq_map.begin()->first;
+ std::for_each(i_freq_map.begin(), i_freq_map.end(),
+ [&l_max_dimm_speed](const std::pair<fapi2::Target<TARGET_TYPE_MEM_PORT>, uint64_t>& m)
+ {
+ l_max_dimm_speed = std::max(l_max_dimm_speed, m.second);
+ l_fastest_port_target = m.first;
+ });
+
+ std::for_each(i_freq_map.begin(), i_freq_map.end(),
+ [&l_max_dimm_speed](const std::pair<fapi2::Target<TARGET_TYPE_MEM_PORT>, uint64_t>& m)
+ {
+ deconfigure(m.first, m.second, l_max_dimm_speed);
+ });
+
+ o_selected_sync_mode = fapi2::ENUM_ATTR_MC_SYNC_MODE_IN_SYNC;
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(l_fastest_port_target, l_max_dimm_speed, o_selected_omi_freq));
+ return fapi2::FAPI2_RC_SUCCESS;
+#else
+ // Cronus only
+ FAPI_ASSERT(false,
+ fapi2::P9A_MSS_FAILED_SYNC_MODE()
+ .set_OMI_FREQ(i_omi_freq),
+ "DIMM speeds differ from OMI speed %d", i_omi_freq);
+#endif
+ break;
+ }
+
+ default:
+ // Switches on an enum class
+ // The only valid speed_equality values are NOT_EQUAL and EQUAL.
+ // If it's something else ,I think it's a code error and really shouldn't be possible, thus fapi2::Assert below
+ FAPI_ERR("Invalid speed_equality parameter!");
+ fapi2::Assert(false);
+ break;
+ }// end switch
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+#ifndef __HOSTBOOT_MODULE
+fapi_try_exit:
+ return fapi2::current_err;
+#endif
+}
+
+}// mss
diff --git a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
index 7b8cb4fe9..06345713c 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/lib/freq/axone_sync.H
@@ -22,3 +22,183 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file axone_sync.H
+/// @brief Synchronous function implementations for Axone
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_SYNC_H_
+#define _MSS_SYNC_H_
+
+#include <map>
+#include <vector>
+
+#include <fapi2.H>
+#include <mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <lib/shared/axone_consts.H>
+#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/mss_math.H>
+
+namespace mss
+{
+
+// List of the OMI frequencies for Axone
+// Note: these need to be sorted so binary search works
+static const std::vector<uint64_t> AXONE_OMI_FREQS =
+{
+ 21330, // fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_21_33GBPS,
+ 23460, // fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_23_46GBPS,
+ 25600, // fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_25_60GBPS,
+};
+
+///
+/// @brief Converts an OMI frequency attribute enum to the corresponding OMI frequency
+/// @param[in] i_omi_enum a frequency enum value that is to be converted
+/// @return the corresponding OMI frequency
+///
+inline uint64_t convert_omi_freq_attr_to_freq(const fapi2::ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_Type
+ i_omi_enum)
+{
+ switch (i_omi_enum)
+ {
+ case fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_21_33GBPS:
+ return 21330;
+
+ case fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_23_46GBPS:
+ return 23460;
+
+ case fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_SERDES_FREQUENCY_SERDES_25_60GBPS:
+ return 25600;
+
+ default:
+ FAPI_ASSERT( false,
+ fapi2::P9A_MSS_UNSUPPORTED_OMI_FREQ()
+ .set_OMI_FREQ_ENUM(i_omi_enum),
+ "freq system saw an unsupported OMI frequency with enum value: %d",
+ i_omi_enum );
+ }
+
+fapi_try_exit:
+ return 0;
+}
+
+///
+/// @brief Converts a DDR frequency to the corresponding OMI frequency
+/// @param[in] i_target the port target
+/// @param[in] i_ddr_freq a frequency value that is to be converted
+/// @param[out] o_omi_freq the corresponding OMI frequency
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+inline fapi2::ReturnCode convert_ddr_freq_to_omi_freq(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_ddr_freq,
+ uint64_t& o_omi_freq)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+ constexpr uint64_t ROUND_UNITS = 10;
+
+ // Get the OMI to DDR freq ratio
+ uint8_t l_ratio[TT::MAX_DIMM_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_host_to_ddr_speed_ratio(i_target, l_ratio));
+
+ // Multiply by the ratio and round to the nearest 10GBPS
+ FAPI_TRY(mss::divide_and_round((i_ddr_freq * l_ratio[0]), ROUND_UNITS, o_omi_freq));
+ o_omi_freq *= ROUND_UNITS;
+ FAPI_DBG("For ratio %d and DDR freq %d, corresponding OMI freq is %d", l_ratio[0], i_ddr_freq, o_omi_freq);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Converts an OMI frequency to the corresponding DDR frequency
+/// @param[in] i_target the port target
+/// @param[in] i_omi_freq a frequency value that is to be converted
+/// @param[out] o_ddr_freq the corresponding DDR frequency
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+inline fapi2::ReturnCode convert_omi_freq_to_ddr_freq(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_omi_freq,
+ uint64_t& o_ddr_freq)
+{
+ using TT = mss::frequency_traits<mss::proc_type::AXONE>;
+
+ // Get the OMI to DDR freq ratio
+ uint8_t l_ratio[TT::MAX_DIMM_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_host_to_ddr_speed_ratio(i_target, l_ratio));
+
+ FAPI_TRY(mss::divide_and_round(i_omi_freq, static_cast<uint64_t>(l_ratio[0]), o_ddr_freq),
+ "%s freq system saw a zero Host (OMI) to DDR frequency ratio", mss::c_str(i_target));
+ FAPI_DBG( "For ratio %d and OMI freq %d, corresponding DDR freq is %d", l_ratio[0], i_omi_freq, o_ddr_freq);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Checks to see if a passed in value could be a valid OMI frequency
+/// @param[in] i_target the port target
+/// @param[in] i_proposed_freq a frequency value that is to be checked
+/// @param[out] o_valid boolean whether the value is a valid OMI frequency
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+inline fapi2::ReturnCode is_omi_freq_valid (const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_proposed_freq,
+ uint64_t& o_valid)
+{
+ uint64_t l_proposed_omi_freq = 0;
+ FAPI_TRY(convert_ddr_freq_to_omi_freq(i_target, i_proposed_freq, l_proposed_omi_freq));
+
+ o_valid = std::binary_search(AXONE_OMI_FREQS.begin(), AXONE_OMI_FREQS.end(), l_proposed_omi_freq);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Retrieves a mapping of MSS frequency values per port target
+/// @param[in] i_targets vector of port targets
+/// @param[out] o_freq_map dimm speed map <key, value> = (port target, frequency)
+/// @param[out] o_is_speed_equal holds whether map dimm speed is equal
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode dimm_speed_map(const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT> >& i_targets,
+ std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& o_freq_map,
+ speed_equality& o_is_speed_equal);
+
+///
+/// @brief Helper function to deconfigure MEM_PORT target
+/// @param[in] i_target the port target
+/// @param[in] i_dimm_speed dimm speed in MT/s
+/// @param[in] i_omi_freq OMI freq in MHz
+/// @return true if hardware was deconfigured
+///
+bool deconfigure(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ const uint64_t i_dimm_speed,
+ const uint32_t i_omi_freq);
+
+///
+/// @brief Selects synchronous mode and performs requirements enforced by selected port frequency
+/// @param[in] i_freq_map dimm speed mapping
+/// @param[in] i_equal_dimm_speed tracks whether map has equal dimm speeds
+/// @param[in] i_omi_freq OMI frequency
+/// @param[out] o_selected_sync_mode final synchronous mode
+/// @param[out] o_selected_omi_freq final freq selected, only valid if final sync mode is in-sync
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>, uint64_t >& i_freq_map,
+ const speed_equality i_equal_dimm_speed,
+ const uint32_t i_omi_freq,
+ uint8_t& o_selected_sync_mode,
+ uint64_t& o_selected_omi_freq);
+
+}// mss
+
+#endif
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C
index 4fc51a28e..75d23c6af 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_eff_config.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,6 +42,8 @@
#include <vpd_access.H>
#include <mss_generic_attribute_getters.H>
#include <lib/eff_config/explorer_attr_engine_traits.H>
+#include <lib/freq/axone_freq_traits.H>
+#include <lib/freq/axone_sync.H>
///
/// @brief Configure the attributes for each controller
@@ -53,21 +55,15 @@ fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MEM
// Workaround until DIMM level attrs work
uint8_t l_ranks[mss::exp::MAX_DIMM_PER_PORT] = {};
- // Get EFD size - should only need to do it once
- const auto l_ocmb = mss::find_target<fapi2::TARGET_TYPE_OCMB_CHIP>(i_target);
- fapi2::MemVpdData_t l_vpd_type(fapi2::EFD);
- fapi2::VPDInfo<fapi2::TARGET_TYPE_OCMB_CHIP> l_vpd_info(l_vpd_type);
- FAPI_TRY( fapi2::getVPD(l_ocmb, l_vpd_info, nullptr) );
-
FAPI_TRY( mss::attr::get_num_master_ranks_per_dimm(i_target, l_ranks) );
for(const auto& dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target))
{
uint8_t l_dimm_index = 0;
uint64_t l_freq = 0;
+ uint64_t l_omi_freq = 0;
FAPI_TRY( mss::attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(dimm), l_freq) );
-
- FAPI_TRY( mss::attr_derived_engine<mss::generic_metadata_fields>::set(dimm) );
+ FAPI_TRY( mss::convert_ddr_freq_to_omi_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(dimm), l_freq, l_omi_freq));
// Quick hack to get the index until DIMM level attrs work
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_REL_POS, dimm, l_dimm_index) );
@@ -76,9 +72,15 @@ fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MEM
{
std::shared_ptr<mss::efd::base_decoder> l_efd_data;
- // Get EFD data
+ // Get EFD size
+ const auto l_ocmb = mss::find_target<fapi2::TARGET_TYPE_OCMB_CHIP>(i_target);
+ fapi2::MemVpdData_t l_vpd_type(fapi2::MemVpdData::EFD);
+ fapi2::VPDInfo<fapi2::TARGET_TYPE_OCMB_CHIP> l_vpd_info(l_vpd_type);
l_vpd_info.iv_rank = rank;
- l_vpd_info.iv_omi_freq_mhz = l_freq;
+ l_vpd_info.iv_omi_freq_mhz = l_omi_freq;
+ FAPI_TRY( fapi2::getVPD(l_ocmb, l_vpd_info, nullptr), "failed getting VPD size from getVPD" );
+
+ // Get EFD data
std::vector<uint8_t> l_vpd_raw (l_vpd_info.iv_size, 0);
FAPI_TRY( fapi2::getVPD(l_ocmb, l_vpd_info, l_vpd_raw.data()) );
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C
index 7591689e2..342523d5a 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -30,14 +30,23 @@
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
+// fapi2
+#include <fapi2.H>
+
+// mss lib
#include <p9a_mss_freq.H>
+
+#include <lib/freq/axone_freq_traits.H>
#include <generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H>
+#include <lib/eff_config/explorer_attr_engine_traits.H>
#include <generic/memory/lib/data_engine/data_engine.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/freq/gen_mss_freq.H>
///
/// @brief Calculate and save off DIMM frequencies
@@ -46,6 +55,13 @@
///
fapi2::ReturnCode p9a_mss_freq( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target )
{
+ // If there are no DIMM, we can just get out.
+ if (mss::count_dimm(i_target) == 0)
+ {
+ FAPI_INF("Seeing no DIMM on %s, no freq to set", mss::c_str(i_target));
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
// We will first set pre-eff_config attribes
for(const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target))
{
@@ -60,12 +76,12 @@ fapi2::ReturnCode p9a_mss_freq( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>
FAPI_TRY( l_rc, "Failed to initialize SPD facade for %s", mss::spd::c_str(d) );
FAPI_TRY( mss::attr_eff_engine<mss::pre_data_init_fields>::set(l_spd_decoder) );
+ FAPI_TRY( mss::attr_derived_engine<mss::generic_metadata_fields>::set(d) );
}
- // TK - Remove hard-code FREQ -- Should we have enums? Louis problem now
- uint64_t HARDCODE_FREQ_LOUIS_REMOVE = 25600;
- FAPI_TRY( mss::attr::set_freq(i_target, HARDCODE_FREQ_LOUIS_REMOVE) );
- }// dimm
+ }
+
+ FAPI_TRY(mss::generate_freq<mss::proc_type::AXONE>(i_target));
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H
index 179292a80..e4e20b050 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,7 +37,6 @@
#define P9A_MSS_FREQ_H_
#include <fapi2.H>
-#include <vector>
typedef fapi2::ReturnCode (*p9a_mss_freq_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>&);
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.mk b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.mk
index bd2a3e083..47d2c11ea 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.mk
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_freq.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2018
+# Contributors Listed Below - COPYRIGHT 2018,2019
# [+] International Business Machines Corp.
#
#
@@ -27,5 +27,5 @@
-include 00p9a_common.mk
PROCEDURE=p9a_mss_freq
-$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+$(eval $(call ADD_P9A_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml b/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml
index c83af56bf..37909deb2 100644
--- a/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml
+++ b/src/import/chips/p9a/procedures/xml/error_info/p9a_freq_errors.xml
@@ -24,5 +24,117 @@
<!-- IBM_PROLOG_END_TAG -->
<hwpErrors>
+ <hwpError>
+ <rc>RC_P9A_MSS_BAD_FREQ_CALCULATED</rc>
+ <description>
+ No frequency found for MC Either bad mrw attribute or no DIMMS installed?
+ Should be a code bug if we get here
+ </description>
+ <ffdc>MSS_FREQ</ffdc>
+ <ffdc>SUPPORTED_FREQ_0</ffdc>
+ <ffdc>SUPPORTED_FREQ_1</ffdc>
+ <ffdc>SUPPORTED_FREQ_2</ffdc>
+ <ffdc>TARGET</ffdc>
+ <ffdc>PROC_TYPE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <!-- Cronus only error when we can't match DIMM speeds to sync mode -->
+ <hwpError>
+ <rc>RC_P9A_MSS_FAILED_SYNC_MODE</rc>
+ <description>
+ DIMM speeds are different and sync mode is required
+ </description>
+ <ffdc>OMI_FREQ</ffdc>
+ <ffdc>MEM_FREQ</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_P9A_MSS_MRW_FREQ_MAX_FREQ_EMPTY_SET</rc>
+ <description>
+ When considering the frequencies in the MRW, the OMI frequency, and the max supported
+ frequencies based on DIMM config (MAX_ALLOWED_DIMM_FREQ), there are no applicable frequencies
+ remaining
+ </description>
+ <ffdc>MSS_VPD_FREQ_0</ffdc>
+ <ffdc>MSS_VPD_FREQ_1</ffdc>
+ <ffdc>MSS_VPD_FREQ_2</ffdc>
+ <ffdc>MSS_MAX_FREQ_0</ffdc>
+ <ffdc>MSS_MAX_FREQ_1</ffdc>
+ <ffdc>MSS_MAX_FREQ_2</ffdc>
+ <ffdc>MSS_MAX_FREQ_3</ffdc>
+ <ffdc>MSS_MAX_FREQ_4</ffdc>
+ <ffdc>OMI_FREQ_0</ffdc>
+ <ffdc>OMI_FREQ_1</ffdc>
+ <ffdc>OMI_FREQ_2</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>PORT_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_P9A_MSS_NO_SUPPORTED_FREQ</rc>
+ <description>
+ When considering the frequencies in the MRW and the max supported
+ frequencies based on DIMM config, there are no applicable frequencies
+ remaining
+ </description>
+ <ffdc>MEM_PORT_TARGET</ffdc>
+ <ffdc>MRW_MAX_FREQ_0</ffdc>
+ <ffdc>MRW_MAX_FREQ_1</ffdc>
+ <ffdc>MRW_MAX_FREQ_2</ffdc>
+ <ffdc>MRW_MAX_FREQ_3</ffdc>
+ <ffdc>MRW_MAX_FREQ_4</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <childTargets>
+ <parent>MEM_PORT_TARGET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ </childTargets>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_P9A_MSS_UNSUPPORTED_OMI_FREQ</rc>
+ <description>
+ Unsupported OMI frequency encountered in mss_freq_system
+ </description>
+ <ffdc>OMI_FREQ_ENUM</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_P9A_MSS_ZERO_HOST_TO_DDR_FREQ_RATIO</rc>
+ <description>
+ Zero OMI to DDR frequency ratio encountered in mss_freq_system
+ </description>
+ <ffdc>PORT_TARGET</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
</hwpErrors>
diff --git a/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H b/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H
index 57ae5355b..be55890ea 100644
--- a/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H
+++ b/src/import/generic/memory/lib/data_engine/data_engine_traits_def.H
@@ -74,9 +74,10 @@ enum pre_data_init_fields
HYBRID_MEDIA = 4,
MRANKS = 5,
DIMM_RANKS_CNFG = 6,
+ HOST_TO_DDR_SPEED_RATIO = 7,
// Dispatcher set to last enum value
- ATTR_PRE_DATA_ENG_DISPATCHER = DIMM_RANKS_CNFG,
+ ATTR_PRE_DATA_ENG_DISPATCHER = HOST_TO_DDR_SPEED_RATIO,
};
///
diff --git a/src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H b/src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H
index 0fd4a0056..d0f00d6f0 100644
--- a/src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H
+++ b/src/import/generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H
@@ -208,6 +208,84 @@ struct attrEngineTraits<pre_data_init_fields, DRAM_GEN>
///
/// @brief Traits for pre_data_engine
/// @class attrEngineTraits
+/// @note pre_data_init_fields, HOST_TO_DDR_SPEED_RATIO specialization
+///
+template<>
+struct attrEngineTraits<pre_data_init_fields, HOST_TO_DDR_SPEED_RATIO>
+{
+ using attr_type = fapi2::ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_Type;
+ using attr_integral_type = std::remove_all_extents<attr_type>::type;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_TargetType;
+ static constexpr generic_ffdc_codes FFDC_CODE = SET_HOST_TO_DDR_SPEED_RATIO;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the attr target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ return mss::attr::get_host_to_ddr_speed_ratio(i_target, o_setting);
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the attr target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& i_setting)
+ {
+ return mss::attr::set_host_to_ddr_speed_ratio(i_target, i_setting);
+ }
+
+ ///
+ /// @brief Computes setting for attribute
+ /// @param[in] i_spd_data SPD data
+ /// @param[in] i_setting value we want to set attr with
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_value_to_set(const spd::facade& i_spd_data,
+ attr_integral_type& o_setting)
+ {
+ // =========================================================
+ // DDR4 SPD Document Release 4
+ // Byte 220 (0x0DC): Host Interface Speed to DDR Interface Speed Ratio
+ // =========================================================
+ static const std::vector< std::pair<uint8_t, uint8_t> > HOST_TO_DDR_SPEED_RATIO_MAP =
+ {
+ // {key byte, speed ratio}
+ {0, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_1_TO_1},
+ {1, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_2_TO_1},
+ {2, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_4_TO_1},
+ {3, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_8_TO_1},
+ {4, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_16_TO_1},
+ {5, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_32_TO_1},
+ {6, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_64_TO_1},
+ {7, fapi2::ENUM_ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_128_TO_1},
+ // All others reserved or not supported
+ };
+
+ const auto l_dimm = i_spd_data.get_dimm_target();
+
+ attr_integral_type l_value = 0;
+ FAPI_TRY( i_spd_data.host_to_ddr_speed_ratio(l_value),
+ "%s failed to get host to DDR speed ratio from SPD", spd::c_str(l_dimm) );
+
+ FAPI_TRY( lookup_table_check(l_dimm, HOST_TO_DDR_SPEED_RATIO_MAP, FFDC_CODE, l_value, o_setting),
+ "%s failed HOST_TO_DDR_SPEED_RATIO lookup check", spd::c_str(l_dimm) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class attrEngineTraits
/// @note pre_data_init_fields, HYBRID specialization
///
template<>
diff --git a/src/import/generic/memory/lib/data_engine/pre_data_init.H b/src/import/generic/memory/lib/data_engine/pre_data_init.H
index b8311f83e..df19a86ef 100644
--- a/src/import/generic/memory/lib/data_engine/pre_data_init.H
+++ b/src/import/generic/memory/lib/data_engine/pre_data_init.H
@@ -145,7 +145,6 @@ class pre_data_engine
return fapi2::current_err;
}
-
///
/// @brief Set ATTR_EFF_HYBRID
/// @return FAPI2_RC_SUCCESS iff ok
diff --git a/src/import/generic/memory/lib/mss_generic_attribute_getters.H b/src/import/generic/memory/lib/mss_generic_attribute_getters.H
new file mode 100644
index 000000000..f16829f3b
--- /dev/null
+++ b/src/import/generic/memory/lib/mss_generic_attribute_getters.H
@@ -0,0 +1,4199 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/mss_generic_attribute_getters.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
+/* [+] 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 */
+// mss_generic_attribute_getters.H
+#ifndef MSS_GENERIC_ATTR_GETTERS_H_
+#define MSS_GENERIC_ATTR_GETTERS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/index.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+
+
+namespace mss
+{
+namespace attr
+{
+///
+/// @brief ATTR_MEM_DIMM_POS_METADATA getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint32_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_other_attr_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note To get the FAPI_POS to the equivilent of ATTR_POS, we need to normalize the fapi_pos
+/// value to the processor (stride across which ever processor we're on) and then add
+/// in the delta per processor as ATTR_POS isn't processor relative (delta is the total
+/// dimm on a processor)
+///
+inline fapi2::ReturnCode get_dimm_pos_metadata(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint32_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_POS_METADATA, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_POS_METADATA: 0x%lx",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DRAM_GEN_METADATA getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_other_attr_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note DRAM Device Type. Decodes SPD byte 2. Created for use by attributes that need this
+/// data earlier than eff_config, such as c_str and the hypervisor. Not meant for direct
+/// HWP use. This is just an abstraction of any chip specific EFF_DRAM_GEN attribute.
+///
+inline fapi2::ReturnCode get_dram_gen_metadata(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DRAM_GEN_METADATA, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DRAM_GEN_METADATA: 0x%lx",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_TYPE_METADATA getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_other_attr_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Base Module Type. Decodes SPD Byte 3 (bits 3~0). Created for use by attributes that
+/// need this data earlier than eff_config, such as c_str and the hypervisor. Not meant
+/// for direct HWP use. This is just an abstraction of any chip specific EFF_DIMM_TYPE
+/// attribute.
+///
+inline fapi2::ReturnCode get_dimm_type_metadata(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_TYPE_METADATA, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_TYPE_METADATA: 0x%lx",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MEM_DRAM_CWL getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note CAS Write Latency.
+///
+inline fapi2::ReturnCode get_dram_cwl(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DRAM_CWL, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DRAM_CWL: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_RDIMM_BUFFER_DELAY getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Delay due to the presence of a buffer, in number of clocks
+///
+inline fapi2::ReturnCode get_dimm_buffer_delay(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_RDIMM_BUFFER_DELAY, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_RDIMM_BUFFER_DELAY: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_VPD_DQ_MAP getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[Dimm DQ PIN] The map from the Dual Inline Memory Module (DIMM) Data (DQ) Pin
+/// to the Module Package Data (DQ) Pinout
+///
+inline fapi2::ReturnCode get_mem_vpd_dq_map(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[72])
+{
+ uint8_t l_value[72] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_VPD_DQ_MAP, i_target, l_value) );
+ memcpy(o_array, &l_value, 72);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_VPD_DQ_MAP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC0F getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC0F - Command Latency Adder Control Word; Default value - 04. Values
+/// Range from 00 to 04. No need to calculate; User can override with desired experimental
+/// value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc0f(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC0F, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC0F: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC0F getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC0F - Command Latency Adder Control Word; Default value - 04. Values
+/// Range from 00 to 04. No need to calculate; User can override with desired experimental
+/// value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc0f(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC0F, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC0F: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_CS_CMD_LATENCY getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] CS to CMD/ADDR Latency. This is for DDR4 MRS4. Computed in mss_eff_cnfg.
+/// Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_cs_cmd_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_CS_CMD_LATENCY, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_CS_CMD_LATENCY: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_CS_CMD_LATENCY getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] CS to CMD/ADDR Latency. This is for DDR4 MRS4. Computed in mss_eff_cnfg.
+/// Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_cs_cmd_latency(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_CS_CMD_LATENCY, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_CS_CMD_LATENCY: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_CA_PARITY_LATENCY getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] C/A Parity Latency Mode. This is for DDR4 MRS5. Computed in mss_eff_cnfg.
+/// Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_ca_parity_latency(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_CA_PARITY_LATENCY, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_CA_PARITY_LATENCY: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_CA_PARITY_LATENCY getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] C/A Parity Latency Mode. This is for DDR4 MRS5. Computed in mss_eff_cnfg.
+/// Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_ca_parity_latency(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_CA_PARITY_LATENCY, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_CA_PARITY_LATENCY: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC02 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC02: Timing and IBT Control Word; Default value - 0x00. Values Range
+/// from 0-8. No need to calculate; User can override with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC02, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC02: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC02 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC02: Timing and IBT Control Word; Default value - 0x00. Values Range
+/// from 0-8. No need to calculate; User can override with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc02(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC02, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC02: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC03 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC03 - CA and CS Signals Driver Characteristics Control Word; Default
+/// value - 0x05 (Moderate Drive). Values Range from 00 to 0F. Has to be picked up from
+/// SPD byte 137, 1st Nibble for CS and CA.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC03, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC03: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC03 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC03 - CA and CS Signals Driver Characteristics Control Word; Default
+/// value - 0x05 (Moderate Drive). Values Range from 00 to 0F. Has to be picked up from
+/// SPD byte 137, 1st Nibble for CS and CA.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc03(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC03, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC03: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC04 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC04 - ODT and CKE Signals Driver Characteristics Control Word; Default
+/// value - 0x05 (Moderate Drive). Values Range from 00 to 0F. Has to be picked up from
+/// SPD byte 137, 2nd Nibble for ODT and CKE.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC04, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC04: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC04 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC04 - ODT and CKE Signals Driver Characteristics Control Word; Default
+/// value - 0x05 (Moderate Drive). Values Range from 00 to 0F. Has to be picked up from
+/// SPD byte 137, 2nd Nibble for ODT and CKE.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc04(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC04, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC04: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC05 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC05 - Clock Driver Characteristics Control Word; Default value -
+/// 0x05 (Moderate Drive). Values Range from 00 to 0F. Has to be picked up from SPD
+/// byte 138, 2nd Nibble for CK.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC05, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC05: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC05 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC05 - Clock Driver Characteristics Control Word; Default value -
+/// 0x05 (Moderate Drive). Values Range from 00 to 0F. Has to be picked up from SPD
+/// byte 138, 2nd Nibble for CK.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc05(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC05, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC05: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC0B getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Operating Voltage VDD and VrefCA Source Control Word; Read from ATTR_MSS_VOLT_VDDR.
+/// Default value - 14. Values Range from 00 to 15 decimal. No need to calculate; User
+/// can override with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc0b(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC0B, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC0B: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC0B getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Operating Voltage VDD and VrefCA Source Control Word; Read from ATTR_MSS_VOLT_VDDR.
+/// Default value - 14. Values Range from 00 to 15 decimal. No need to calculate; User
+/// can override with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc0b(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC0B, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC0B: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC1X getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC1x - Internal VrefCA Control Word; Default value - 00. Values Range
+/// from 00 to 3F. No need to calculate; User can override with desired experimental
+/// value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc1x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC1X, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC1X: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC1X getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC1x - Internal VrefCA Control Word; Default value - 00. Values Range
+/// from 00 to 3F. No need to calculate; User can override with desired experimental
+/// value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc1x(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC1X, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC1X: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC7X getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC7x: IBT Control Word; Default value - 00. Values Range from 00 to
+/// FF.No need to calculate. User can override with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc7x(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC7X, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC7X: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F0RC7X getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F0RC7x: IBT Control Word; Default value - 00. Values Range from 00 to
+/// FF.No need to calculate. User can override with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f0rc7x(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F0RC7X, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F0RC7X: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC00 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word; Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC00, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC00: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC00 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word; Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc00(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC00, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC00: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC02 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word; Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate; User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC02, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC02: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC02 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word; Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate; User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc02(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC02, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC02: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC03 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word. Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC03, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC03: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC03 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word. Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc03(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC03, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC03: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC04 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word; Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC04, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC04: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC04 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word; Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc04(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC04, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC04: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC05 getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word. Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC05, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC05: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_DIMM_DDR4_F1RC05 getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] F1RC00: Data Buffer Interface Driver Characteristics Control Word. Default
+/// value - 00. Values Range from 00 to 0F. No need to calculate. User can override
+/// with desired experimental value.
+///
+inline fapi2::ReturnCode get_dimm_ddr4_f1rc05(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_DIMM_DDR4_F1RC05, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_DIMM_DDR4_F1RC05: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MEM_REORDER_QUEUE_SETTING getter
+/// @param[in] const ref to the TARGET_TYPE_OCMB_CHIP
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Contains the settings for write/read reorder queue
+///
+inline fapi2::ReturnCode get_reorder_queue_setting(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_REORDER_QUEUE_SETTING, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_REORDER_QUEUE_SETTING: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_2N_MODE getter
+/// @param[in] const ref to the TARGET_TYPE_OCMB_CHIP
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Default value for 2N Mode from Signal Integrity. 0x0 = Invalid Mode, 0x01 = 1N Mode
+/// , 0x02 = 2N Mode If value is set to 0x0 this indicate value was never initialized
+/// correctly.
+///
+inline fapi2::ReturnCode get_mem_2n_mode(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_2N_MODE, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_2N_MODE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_BAD_DQ_BITMAP getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_other_attr_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Bad DQ bitmap from a controller point of view. The data is a 10 byte bitmap for
+/// each of 4 possible ranks. The bad DQ data is stored in NVRAM, and it is stored in
+/// a special format translated to a DIMM Connector point of view. All of these details
+/// are hidden from the user of this attribute.
+///
+inline fapi2::ReturnCode get_bad_dq_bitmap(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4][10])
+{
+ uint8_t l_value[4][10] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_BAD_DQ_BITMAP, i_target, l_value) );
+ memcpy(o_array, &l_value, 40);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_BAD_DQ_BITMAP: 0x%lx",
+ uint64_t(fapi2::current_err));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_GEN getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Device Type. Decodes SPD byte 2. Generation of memory: DDR3, DDR4.
+///
+inline fapi2::ReturnCode get_dram_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_GEN, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_GEN: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_GEN getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Device Type. Decodes SPD byte 2. Generation of memory: DDR3, DDR4.
+///
+inline fapi2::ReturnCode get_dram_gen(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_GEN, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_GEN: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Base Module Type. Decodes SPD Byte 3 (bits 3~0). Type of DIMM: RDIMM,
+/// UDIMM, LRDIMM as specified by the JEDEC standard.
+///
+inline fapi2::ReturnCode get_dimm_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_TYPE, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Base Module Type. Decodes SPD Byte 3 (bits 3~0). Type of DIMM: RDIMM,
+/// UDIMM, LRDIMM as specified by the JEDEC standard.
+///
+inline fapi2::ReturnCode get_dimm_type(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_TYPE, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_HYBRID_MEMORY_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Hybrid Media. Decodes SPD Byte 3 (bits 6~4)
+///
+inline fapi2::ReturnCode get_hybrid_memory_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_HYBRID_MEMORY_TYPE, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_HYBRID_MEMORY_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_HYBRID_MEMORY_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Hybrid Media. Decodes SPD Byte 3 (bits 6~4)
+///
+inline fapi2::ReturnCode get_hybrid_memory_type(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_HYBRID_MEMORY_TYPE, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_HYBRID_MEMORY_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_HYBRID getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Hybrid. Decodes SPD Byte 3 (bit 7)
+///
+inline fapi2::ReturnCode get_hybrid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_HYBRID, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_HYBRID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_HYBRID getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Hybrid. Decodes SPD Byte 3 (bit 7)
+///
+inline fapi2::ReturnCode get_hybrid(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_HYBRID, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_HYBRID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] OMI to DDR frequency ratio
+///
+inline fapi2::ReturnCode get_host_to_ddr_speed_ratio(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] OMI to DDR frequency ratio
+///
+inline fapi2::ReturnCode get_host_to_ddr_speed_ratio(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_DENSITY getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Density. Decodes SPD Byte 4 (bits 3~0). Total SDRAM capacity per
+/// die. For multi-die stacks (DDP, QDP, or 3DS), this represents the capacity of each
+/// DRAM die in the stack.
+///
+inline fapi2::ReturnCode get_dram_density(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_DENSITY, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_DENSITY: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_DENSITY getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Density. Decodes SPD Byte 4 (bits 3~0). Total SDRAM capacity per
+/// die. For multi-die stacks (DDP, QDP, or 3DS), this represents the capacity of each
+/// DRAM die in the stack.
+///
+inline fapi2::ReturnCode get_dram_density(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_DENSITY, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_DENSITY: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_BANK_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Number of DRAM bank address bits. Actual number of banks is 2^N, where
+/// N is the number of bank address bits. Decodes SPD Byte 4 (bits 5~4).
+///
+inline fapi2::ReturnCode get_dram_bank_bits(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_BANK_BITS, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_BANK_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_BANK_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Number of DRAM bank address bits. Actual number of banks is 2^N, where
+/// N is the number of bank address bits. Decodes SPD Byte 4 (bits 5~4).
+///
+inline fapi2::ReturnCode get_dram_bank_bits(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_BANK_BITS, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_BANK_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_BANK_GROUP_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Bank Groups Bits. Decoded SPD Byte 4 (bits 7~6). Actual number of bank
+/// groups is 2^N, where N is the number of bank address bits. This value represents
+/// the number of bank groups into which the memory array is divided.
+///
+inline fapi2::ReturnCode get_dram_bank_group_bits(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_BANK_GROUP_BITS, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_BANK_GROUP_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_BANK_GROUP_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Bank Groups Bits. Decoded SPD Byte 4 (bits 7~6). Actual number of bank
+/// groups is 2^N, where N is the number of bank address bits. This value represents
+/// the number of bank groups into which the memory array is divided.
+///
+inline fapi2::ReturnCode get_dram_bank_group_bits(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_BANK_GROUP_BITS, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_BANK_GROUP_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_COLUMN_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Column Address Bits. Decoded SPD Byte 5 (bits 2~0). Actual number of
+/// DRAM columns is 2^N, where N is the number of column address bits
+///
+inline fapi2::ReturnCode get_dram_column_bits(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_COLUMN_BITS, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_COLUMN_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_COLUMN_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Column Address Bits. Decoded SPD Byte 5 (bits 2~0). Actual number of
+/// DRAM columns is 2^N, where N is the number of column address bits
+///
+inline fapi2::ReturnCode get_dram_column_bits(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_COLUMN_BITS, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_COLUMN_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_ROW_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Row Address Bits. Decodes Byte 5 (bits 5~3). Number of DRAM column address
+/// bits. Actual number of DRAM rows is 2^N, where N is the number of row address bits
+///
+inline fapi2::ReturnCode get_dram_row_bits(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_ROW_BITS, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_ROW_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_ROW_BITS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Row Address Bits. Decodes Byte 5 (bits 5~3). Number of DRAM column address
+/// bits. Actual number of DRAM rows is 2^N, where N is the number of row address bits
+///
+inline fapi2::ReturnCode get_dram_row_bits(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_ROW_BITS, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_ROW_BITS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_PRIM_STACK_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Primary SDRAM Package Type. Decodes Byte 6. This byte defines the primary
+/// set of SDRAMs. Monolithic = SPD, Multi-load stack = DDP/QDP, Single-load stack =
+/// 3DS
+///
+inline fapi2::ReturnCode get_prim_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PRIM_STACK_TYPE, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PRIM_STACK_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_PRIM_STACK_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Primary SDRAM Package Type. Decodes Byte 6. This byte defines the primary
+/// set of SDRAMs. Monolithic = SPD, Multi-load stack = DDP/QDP, Single-load stack =
+/// 3DS
+///
+inline fapi2::ReturnCode get_prim_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PRIM_STACK_TYPE, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PRIM_STACK_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_PPR getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Post Package Repair. Used in various locations and is evaluated in mss_eff_cnfg.
+///
+inline fapi2::ReturnCode get_dram_ppr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_PPR, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_PPR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_PPR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Post Package Repair. Used in various locations and is evaluated in mss_eff_cnfg.
+///
+inline fapi2::ReturnCode get_dram_ppr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_PPR, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_PPR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_SOFT_PPR getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Soft Post Package Repair. Used in various locations and is evaluated
+/// in mss_eff_cnfg.
+///
+inline fapi2::ReturnCode get_dram_soft_ppr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_SOFT_PPR, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_SOFT_PPR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_SOFT_PPR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Soft Post Package Repair. Used in various locations and is evaluated
+/// in mss_eff_cnfg.
+///
+inline fapi2::ReturnCode get_dram_soft_ppr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_SOFT_PPR, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_SOFT_PPR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRCD getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum RAS to CAS Delay Time in nck (number of clock cyles). Decodes SPD byte 25
+/// (7~0) and byte 112 (7~0). Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_trcd(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRCD, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRCD: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRP getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note SDRAM Row Precharge Delay Time in nck (number of clock cycles). Decodes SPD byte
+/// 26 (bits 7~0) and byte 121 (bits 7~0). Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_trp(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRP, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRAS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Active to Precharge Delay Time in nck (number of clock cycles). Decodes
+/// SPD byte 27 (bits 3~0) and byte 28 (7~0). Each memory channel will have a value.
+/// creator: mss_eff_cnfg_timing
+///
+inline fapi2::ReturnCode get_dram_tras(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRAS, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRAS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRC getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Active to Active/Refresh Delay in nck (number of clock cyles). Decodes SPD
+/// byte 27 (bits 7~4), byte 29 (bits 7~0), and byte 120. Each memory channel will have
+/// a value.
+///
+inline fapi2::ReturnCode get_dram_trc(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRC, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRC: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRFC getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint16_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note DDR4 Spec defined as Refresh Cycle Time (tRFC). SPD Spec refers it to the Minimum
+/// Refresh Recovery Delay Time. In nck (number of clock cyles). Decodes SPD byte 31
+/// (bits 15~8) and byte 30 (bits 7~0) for tRFC1. Decodes SPD byte 33 (bits 15~8) and
+/// byte 32 (bits 7~0) for tRFC2. Decodes SPD byte 35 (bits 15~8) and byte 34 (bits
+/// 7~0) for tRFC4. Selected tRFC value depends on MRW attribute that selects refresh
+/// mode. For 3DS, The tRFC time to the same logical rank is defined as tRFC_slr and
+/// is specificed as the value as for a monolithic DDR4 SDRAM of equivalent density.
+///
+inline fapi2::ReturnCode get_dram_trfc(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint16_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRFC, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRFC: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TFAW getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Four Activate Window Delay Time in nck (number of clock cycles). Decodes
+/// SPD byte 36 (bits 3~0) and byte 37 (bits 7~0). For 3DS, tFAW time to the same logical
+/// rank is defined as tFAW_slr_x4 or tFAW_slr_x8 (for x4 and x8 devices only) and specificed
+/// as the value as for a monolithic DDR4 SDRAM equivalent density. Each memory channel
+/// will have a value.
+///
+inline fapi2::ReturnCode get_dram_tfaw(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TFAW, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TFAW: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRRD_S getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Activate to Activate Delay Time, different bank group in nck (number of
+/// clock cycles). Decodes SPD byte 38 (bits 7~0). For 3DS, The tRRD_S time to a different
+/// bank group in the same logical rank is defined as tRRD_slr and is specificed as
+/// the value as for a monolithic DDR4 SDRAM of equivalent density. Each memory channel
+/// will have a value.
+///
+inline fapi2::ReturnCode get_dram_trrd_s(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRRD_S, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRRD_S: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRRD_L getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Activate to Activate Delay Time, same bank group in nck (number of clock
+/// cycles). Decodes SPD byte 39 (bits 7~0). For 3DS, The tRRD_L time to the same bank
+/// group in the same logical rank is defined as tRRD_L_slr and is specificed as the
+/// value as for a monolithic DDR4 SDRAM of equivalent density. Each memory channel
+/// will have a value.
+///
+inline fapi2::ReturnCode get_dram_trrd_l(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRRD_L, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRRD_L: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRRD_DLR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Activate to Activate Delay Time (different logical ranks) in nck (number
+/// of clock cycles). For 3DS, The tRRD_S time to a different logical rank is defined
+/// as tRRD_dlr. Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_trrd_dlr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRRD_DLR, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRRD_DLR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TCCD_L getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum CAS to CAS Delay Time, same bank group in nck (number of clock cycles).
+/// Decodes SPD byte 40 (bits 7~0) and byte 117 (bits 7~0). This is for DDR4 MRS6. Each
+/// memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_tccd_l(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TCCD_L, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TCCD_L: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TWR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Write Recovery Time. Decodes SPD byte 41 (bits 3~0) and byte 42 (bits 7~0).
+/// Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_twr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TWR, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TWR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TWTR_S getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Write to Read Time, different bank group in nck (number of clock cycles).
+/// Decodes SPD byte 43 (3~0) and byte 44 (bits 7~0). Each memory channel will have
+/// a value.
+///
+inline fapi2::ReturnCode get_dram_twtr_s(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TWTR_S, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TWTR_S: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TWTR_L getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Write to Read Time, same bank group in nck (number of clock cycles). Decodes
+/// byte 43 (7~4) and byte 45 (bits 7~0). Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_twtr_l(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TWTR_L, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TWTR_L: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TMAW getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint16_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Maximum Activate Window in nck (number of clock cycles). Decodes SPD byte 7 (bits
+/// 5~4). Depends on tREFI multiplier. Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_tmaw(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint16_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TMAW, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TMAW: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_WIDTH getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] SDRAM Device Width Decodes SPD Byte 12 (bits 2~0). Options: X4 (4 bits),
+/// X8 (8 bits), X16 (16 bits), X32 (32 bits).
+///
+inline fapi2::ReturnCode get_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_WIDTH, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_WIDTH: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_WIDTH getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] SDRAM Device Width Decodes SPD Byte 12 (bits 2~0). Options: X4 (4 bits),
+/// X8 (8 bits), X16 (16 bits), X32 (32 bits).
+///
+inline fapi2::ReturnCode get_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_WIDTH, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_WIDTH: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_NUM_RANKS_PER_DIMM getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Total number of ranks in each DIMM. For monolithic and multi-load stack
+/// modules (SDP/DDP) this is the same as the number of package ranks per DIMM (SPD
+/// Byte 12 bits 5~3). For single load stack (3DS) modules this value represents the
+/// number of logical ranks per DIMM. Logical rank refers the individually addressable
+/// die in a 3DS stack and has no meaning for monolithic or multi-load stacked SDRAMs.
+///
+inline fapi2::ReturnCode get_num_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NUM_RANKS_PER_DIMM, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_NUM_RANKS_PER_DIMM: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_NUM_RANKS_PER_DIMM getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Total number of ranks in each DIMM. For monolithic and multi-load stack
+/// modules (SDP/DDP) this is the same as the number of package ranks per DIMM (SPD
+/// Byte 12 bits 5~3). For single load stack (3DS) modules this value represents the
+/// number of logical ranks per DIMM. Logical rank refers the individually addressable
+/// die in a 3DS stack and has no meaning for monolithic or multi-load stacked SDRAMs.
+///
+inline fapi2::ReturnCode get_num_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NUM_RANKS_PER_DIMM, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_NUM_RANKS_PER_DIMM: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_REGISTER_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Register Type Decodes SPD Byte 131
+///
+inline fapi2::ReturnCode get_register_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_REGISTER_TYPE, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_REGISTER_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_REGISTER_TYPE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Register Type Decodes SPD Byte 131
+///
+inline fapi2::ReturnCode get_register_type(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_REGISTER_TYPE, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_REGISTER_TYPE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_MFG_ID getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint16_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Manufacturer ID Code Decodes SPD Byte 350 and 351
+///
+inline fapi2::ReturnCode get_dram_mfg_id(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value)
+{
+ uint16_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_MFG_ID, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_MFG_ID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_MFG_ID getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint16_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DRAM Manufacturer ID Code Decodes SPD Byte 350 and 351
+///
+inline fapi2::ReturnCode get_dram_mfg_id(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint16_t (&o_array)[2])
+{
+ uint16_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_MFG_ID, i_target, l_value) );
+ memcpy(o_array, &l_value, 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_MFG_ID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_RCD_MFG_ID getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint16_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Register Manufacturer ID Code Decodes SPD Byte 133 and 134
+///
+inline fapi2::ReturnCode get_rcd_mfg_id(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value)
+{
+ uint16_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_RCD_MFG_ID, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_RCD_MFG_ID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_RCD_MFG_ID getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint16_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Register Manufacturer ID Code Decodes SPD Byte 133 and 134
+///
+inline fapi2::ReturnCode get_rcd_mfg_id(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint16_t (&o_array)[2])
+{
+ uint16_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_RCD_MFG_ID, i_target, l_value) );
+ memcpy(o_array, &l_value, 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_RCD_MFG_ID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_REGISTER_REV getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Register Revision Number Decodes SPD Byte 135
+///
+inline fapi2::ReturnCode get_register_rev(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_REGISTER_REV, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_REGISTER_REV: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_REGISTER_REV getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Register Revision Number Decodes SPD Byte 135
+///
+inline fapi2::ReturnCode get_register_rev(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_REGISTER_REV, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_REGISTER_REV: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_PACKAGE_RANK_MAP getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][DQ_NIBBLES] Package Rank Map Decodes SPD Byte 60 - 77 (Bits 7~6)
+///
+inline fapi2::ReturnCode get_package_rank_map(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[20])
+{
+ uint8_t l_value[2][20] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PACKAGE_RANK_MAP, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 20);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PACKAGE_RANK_MAP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_PACKAGE_RANK_MAP getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][DQ_NIBBLES] Package Rank Map Decodes SPD Byte 60 - 77 (Bits 7~6)
+///
+inline fapi2::ReturnCode get_package_rank_map(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][20])
+{
+ uint8_t l_value[2][20] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_PACKAGE_RANK_MAP, i_target, l_value) );
+ memcpy(o_array, &l_value, 40);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_PACKAGE_RANK_MAP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_NIBBLE_MAP getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][DQ_NIBBLES] Nibble Map Decodes SPD Byte 60 - 77 (Bits 5~0) for DDR4
+///
+inline fapi2::ReturnCode get_nibble_map(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t (&o_array)[20])
+{
+ uint8_t l_value[2][20] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NIBBLE_MAP, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 20);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_NIBBLE_MAP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_NIBBLE_MAP getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][DQ_NIBBLES] Nibble Map Decodes SPD Byte 60 - 77 (Bits 5~0) for DDR4
+///
+inline fapi2::ReturnCode get_nibble_map(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][20])
+{
+ uint8_t l_value[2][20] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NIBBLE_MAP, i_target, l_value) );
+ memcpy(o_array, &l_value, 40);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_NIBBLE_MAP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_SIZE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint32_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DIMM Size, in GB Used in various locations
+///
+inline fapi2::ReturnCode get_dimm_size(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
+{
+ uint32_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_SIZE, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_SIZE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_SIZE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint32_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] DIMM Size, in GB Used in various locations
+///
+inline fapi2::ReturnCode get_dimm_size(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint32_t (&o_array)[2])
+{
+ uint32_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_SIZE, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_SIZE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_SPARE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Spare DRAM availability. Used in various locations and is computed in mss_eff_cnfg.
+/// Array indexes are [DIMM][RANK]
+///
+inline fapi2::ReturnCode get_dimm_spare(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_SPARE, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_SPARE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_SPARE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Spare DRAM availability. Used in various locations and is computed in mss_eff_cnfg.
+/// Array indexes are [DIMM][RANK]
+///
+inline fapi2::ReturnCode get_dimm_spare(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_SPARE, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_SPARE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_CL getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note CAS Latency. Each memory channel will have a value.
+///
+inline fapi2::ReturnCode get_dram_cl(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_CL, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_CL: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Specifies the number of master ranks per DIMM. Represents the number
+/// of physical ranks on a DIMM. From SPD spec JEDEC Standard No. 21-C: Page 4.1.2.L-4.
+/// Byte 12 (Bits 5~3) Number of package ranks per DIMM. Package ranks per DIMM refers
+/// to the collections of devices on the module sharing common chip select signals.
+///
+inline fapi2::ReturnCode get_num_master_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM] Specifies the number of master ranks per DIMM. Represents the number
+/// of physical ranks on a DIMM. From SPD spec JEDEC Standard No. 21-C: Page 4.1.2.L-4.
+/// Byte 12 (Bits 5~3) Number of package ranks per DIMM. Package ranks per DIMM refers
+/// to the collections of devices on the module sharing common chip select signals.
+///
+inline fapi2::ReturnCode get_num_master_ranks_per_dimm(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_NUM_MASTER_RANKS_PER_DIMM: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_RANKS_CONFIGED getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Bit wise representation of master ranks in each DIMM that are used for reads and
+/// writes. Used by PRD.
+///
+inline fapi2::ReturnCode get_dimm_ranks_configed(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_RANKS_CONFIGED, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_RANKS_CONFIGED: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DIMM_RANKS_CONFIGED getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Bit wise representation of master ranks in each DIMM that are used for reads and
+/// writes. Used by PRD.
+///
+inline fapi2::ReturnCode get_dimm_ranks_configed(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DIMM_RANKS_CONFIGED, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DIMM_RANKS_CONFIGED: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TREFI getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint16_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Average Refresh Interval (tREFI) in nck (number of clock cycles). This depends on
+/// MRW attribute that selects fine refresh mode (x1, x2, x4). From DDR4 spec (79-4A).
+/// For 3DS, the tREFI time to the same logical rank is defined as tRFC_slr1, tRFC_slr2,
+/// or tRFC_slr4.
+///
+inline fapi2::ReturnCode get_dram_trefi(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint16_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TREFI, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TREFI: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRTP getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Internal Read to Precharge Delay. From the DDR4 spec (79-4A). Each memory channel
+/// will have a value.
+///
+inline fapi2::ReturnCode get_dram_trtp(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRTP, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRTP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_DRAM_TRFC_DLR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Minimum Refresh Recovery Delay Time (different logical ranks) in nck (number of
+/// clock cyles). Selected tRFC value (tRFC_dlr1, tRFC_dlr2, or tRFC_dlr4) depends on
+/// MRW attribute that selects fine refresh mode (x1, x2, x4). For 3DS, The tRFC time
+/// to different logical ranks are defined as tRFC_dlr
+///
+inline fapi2::ReturnCode get_dram_trfc_dlr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_DRAM_TRFC_DLR, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_DRAM_TRFC_DLR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_FREQ getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint64_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Frequency of this memory channel in MT/s (Mega Transfers per second)
+///
+inline fapi2::ReturnCode get_freq(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target, uint64_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_FREQ, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_FREQ: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MEM_EFF_VOLT_VDDR getter
+/// @param[in] const ref to the TARGET_TYPE_OCMB_CHIP
+/// @param[out] uint32_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note DRAM Voltage, each voltage rail would need to have a value.
+///
+inline fapi2::ReturnCode get_volt_vddr(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, uint32_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_VOLT_VDDR, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_VOLT_VDDR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_EFF_VOLT_VPP getter
+/// @param[in] const ref to the TARGET_TYPE_OCMB_CHIP
+/// @param[out] uint32_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note DRAM VPP Voltage, each voltage rail would need to have a value.
+///
+inline fapi2::ReturnCode get_volt_vpp(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, uint32_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_EFF_VOLT_VPP, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_EFF_VOLT_VPP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief ATTR_MEM_SI_SIGNATURE_HASH getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint32_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Hash Signature for SI settings from SPD. The hash signature is 32bits for 256 bytes
+/// of data.
+///
+inline fapi2::ReturnCode get_si_signature_hash(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint32_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_SIGNATURE_HASH, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_SIGNATURE_HASH: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_CA getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for Command/Address in
+/// tens of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_ca(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_CA, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_CA: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_CA getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for Command/Address in
+/// tens of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_ca(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_CA, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_CA: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_CKE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for Clock Enable in tens
+/// of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_cke(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_CKE, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_CKE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_CKE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for Clock Enable in tens
+/// of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_cke(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_CKE, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_CKE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_CS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for Chip Select in tens
+/// of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_cs(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_CS, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_CS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_CS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for Chip Select in tens
+/// of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_cs(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_CS, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_CS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_ODT getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for On Die Termination
+/// in tens of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_odt(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t& o_value)
+{
+ uint8_t l_value[2] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_ODT, l_port, l_value) );
+ o_value = l_value[mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_ODT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DIMM_RCD_IBT_ODT getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM] Register Clock Driver, Input Bus Termination for On Die Termination
+/// in tens of Ohms.
+///
+inline fapi2::ReturnCode get_si_dimm_rcd_ibt_odt(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2])
+{
+ uint8_t l_value[2] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DIMM_RCD_IBT_ODT, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DIMM_RCD_IBT_ODT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DQ and DQS Drive Impedance.
+///
+inline fapi2::ReturnCode get_si_dram_drv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DQ and DQS Drive Impedance.
+///
+inline fapi2::ReturnCode get_si_dram_drv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_DRV_IMP_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_PREAMBLE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Number of clocks used for read/write preamble. Calibration only
+/// uses 1 nCK preamble (DEFAULT). Mainline has both 1 nCK and 2 nCK preamble option.
+/// The value of "0" means 1 nCK preamble, the value of "1" means 2 nCK preamble. Bit
+/// 3 for READ preamble, and Bit 7 for WRITE preamble. E.g. 0b00010001 means 2 nCK preamble
+/// for both READ and WRITE
+///
+inline fapi2::ReturnCode get_si_dram_preamble(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_PREAMBLE, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_PREAMBLE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_PREAMBLE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Number of clocks used for read/write preamble. Calibration only
+/// uses 1 nCK preamble (DEFAULT). Mainline has both 1 nCK and 2 nCK preamble option.
+/// The value of "0" means 1 nCK preamble, the value of "1" means 2 nCK preamble. Bit
+/// 3 for READ preamble, and Bit 7 for WRITE preamble. E.g. 0b00010001 means 2 nCK preamble
+/// for both READ and WRITE
+///
+inline fapi2::ReturnCode get_si_dram_preamble(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_PREAMBLE, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_PREAMBLE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_RTT_NOM getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DRAM side Nominal Termination Resistance in Ohms.
+///
+inline fapi2::ReturnCode get_si_dram_rtt_nom(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_RTT_NOM, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_RTT_NOM: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_RTT_NOM getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DRAM side Nominal Termination Resistance in Ohms.
+///
+inline fapi2::ReturnCode get_si_dram_rtt_nom(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_RTT_NOM, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_RTT_NOM: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_RTT_PARK getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DRAM side Park Termination Resistance in Ohms.
+///
+inline fapi2::ReturnCode get_si_dram_rtt_park(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_RTT_PARK, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_RTT_PARK: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_RTT_PARK getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DRAM side Park Termination Resistance in Ohms.
+///
+inline fapi2::ReturnCode get_si_dram_rtt_park(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_RTT_PARK, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_RTT_PARK: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_RTT_WR getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DRAM side Write Termination Resistance in Ohms.
+///
+inline fapi2::ReturnCode get_si_dram_rtt_wr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_RTT_WR, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_RTT_WR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_DRAM_RTT_WR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] DRAM side Write Termination Resistance in Ohms.
+///
+inline fapi2::ReturnCode get_si_dram_rtt_wr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_DRAM_RTT_WR, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_DRAM_RTT_WR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][RANK] vrefdq_train value. This is for DDR4 MRS6.
+///
+inline fapi2::ReturnCode get_si_vref_dq_train_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][RANK] vrefdq_train value. This is for DDR4 MRS6.
+///
+inline fapi2::ReturnCode get_si_vref_dq_train_value(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_VALUE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][RANK] vrefdq_train range. This is for DDR4 MRS6.
+///
+inline fapi2::ReturnCode get_si_vref_dq_train_range(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][RANK] vrefdq_train range. This is for DDR4 MRS6.
+///
+inline fapi2::ReturnCode get_si_vref_dq_train_range(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DQ_TRAIN_RANGE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_GEARDOWN_MODE getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][RANK] Gear Down Mode. This is for DDR4 MRS3. Each memory channel will
+/// have a value.
+///
+inline fapi2::ReturnCode get_si_geardown_mode(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_GEARDOWN_MODE, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_GEARDOWN_MODE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_GEARDOWN_MODE getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note ARRAY[DIMM][RANK] Gear Down Mode. This is for DDR4 MRS3. Each memory channel will
+/// have a value.
+///
+inline fapi2::ReturnCode get_si_geardown_mode(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_GEARDOWN_MODE, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_GEARDOWN_MODE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Tx drive impedance for DQ/DQS of all ranks in ohms
+///
+inline fapi2::ReturnCode get_si_mc_drv_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_DQ_DQS, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Tx drive impedance for DQ/DQS of all ranks in ohms
+///
+inline fapi2::ReturnCode get_si_mc_drv_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_DQ_DQS, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_RCV_EQ_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Receiver Equalization for Data and Data
+/// Strobe Lines.
+///
+inline fapi2::ReturnCode get_si_mc_rcv_eq_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_RCV_EQ_DQ_DQS, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_RCV_EQ_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_RCV_EQ_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Receiver Equalization for Data and Data
+/// Strobe Lines.
+///
+inline fapi2::ReturnCode get_si_mc_rcv_eq_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_RCV_EQ_DQ_DQS, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_RCV_EQ_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_EQ_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Equalization for Data and Data Strobe
+/// Lines.
+///
+inline fapi2::ReturnCode get_si_mc_drv_eq_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_EQ_DQ_DQS, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_EQ_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_EQ_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Equalization for Data and Data Strobe
+/// Lines.
+///
+inline fapi2::ReturnCode get_si_mc_drv_eq_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_EQ_DQ_DQS, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_EQ_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CLK getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Clock in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_clk(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CLK, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CLK: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CLK getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Clock in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_clk(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CLK, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CLK: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Address, Bank Address,
+/// Bank Group and Activate Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_cmd_addr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Address, Bank Address,
+/// Bank Group and Activate Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_cmd_addr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CMD_ADDR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CNTL getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Clock Enable, ODT,
+/// Parity, and Reset Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_cntl(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CNTL, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CNTL: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CNTL getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Clock Enable, ODT,
+/// Parity, and Reset Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_cntl(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CNTL, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CNTL: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CSCID getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Chip Select and Chip
+/// ID Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_cscid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CSCID, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CSCID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_CSCID getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance for Chip Select and Chip
+/// ID Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_cscid(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_CSCID, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_CSCID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Down for Data and
+/// Data Strobe Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_down(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Down for Data and
+/// Data Strobe Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_down(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_DOWN: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Up for Data and Data
+/// Strobe Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_up(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Impedance Pull Up for Data and Data
+/// Strobe Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_imp_dq_dqs_pull_up(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_IMP_DQ_DQS_PULL_UP: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CLK getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Clock in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_clk(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CLK, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CLK: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CLK getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Clock in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_clk(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CLK, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CLK: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CMD_ADDR getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Address, Bank Address,
+/// Bank Group and Activate Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_cmd_addr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CMD_ADDR, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CMD_ADDR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CMD_ADDR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Address, Bank Address,
+/// Bank Group and Activate Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_cmd_addr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CMD_ADDR, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CMD_ADDR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CNTL getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Clock Enable, ODT,
+/// Parity, and Reset Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_cntl(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CNTL, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CNTL: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CNTL getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Clock Enable, ODT,
+/// Parity, and Reset Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_cntl(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CNTL, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CNTL: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CSCID getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Chip Select and Chip
+/// ID Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_cscid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CSCID, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CSCID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_CSCID getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Chip Select and Chip
+/// ID Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_cscid(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_CSCID, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_CSCID: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Data and Data Strobe
+/// Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_DQ_DQS, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_DRV_SLEW_RATE_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Drive Slew Rate for Data and Data Strobe
+/// Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_drv_slew_rate_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_DRV_SLEW_RATE_DQ_DQS, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_DRV_SLEW_RATE_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_RCV_IMP_ALERT_N getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Memory Controller side Receiver Impedance. Alert_N line in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_rcv_imp_alert_n(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_RCV_IMP_ALERT_N, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_RCV_IMP_ALERT_N: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_RCV_IMP_ALERT_N getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Memory Controller side Receiver Impedance. Alert_N line in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_rcv_imp_alert_n(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_RCV_IMP_ALERT_N, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_RCV_IMP_ALERT_N: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Receiver Impedance. Data and Data Strobe
+/// Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_rcv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] Memory Controller side Receiver Impedance. Data and Data Strobe
+/// Lines in Ohms.
+///
+inline fapi2::ReturnCode get_si_mc_rcv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_MC_RCV_IMP_DQ_DQS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_ODT_RD getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] READ, On Die Termination triggering bitmap. Use bitmap to determine
+/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+///
+inline fapi2::ReturnCode get_si_odt_rd(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_ODT_RD, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_ODT_RD: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_ODT_RD getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] READ, On Die Termination triggering bitmap. Use bitmap to determine
+/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+///
+inline fapi2::ReturnCode get_si_odt_rd(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_ODT_RD, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_ODT_RD: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_ODT_WR getter
+/// @param[in] const ref to the TARGET_TYPE_DIMM
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] WRITE, On Die Termination triggering bitmap. Use bitmap to determine
+/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+///
+inline fapi2::ReturnCode get_si_odt_wr(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t (&o_array)[4])
+{
+ uint8_t l_value[2][4] = {};
+ const auto l_port = i_target.getParent<fapi2::TARGET_TYPE_MEM_PORT>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_ODT_WR, l_port, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_ODT_WR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_ODT_WR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t&[] array reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Array[DIMM][RANK] WRITE, On Die Termination triggering bitmap. Use bitmap to determine
+/// which ODT to fire for the designated rank. The bits in 8 bit field are [DIMM0 ODT0][DIMM0
+/// ODT1][DIMM0 ODT2][DIMM0 ODT3][DIMM1 ODT0][DIMM1 ODT1][DIMM1 ODT2][DIMM1 ODT3]
+///
+inline fapi2::ReturnCode get_si_odt_wr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t (&o_array)[2][4])
+{
+ uint8_t l_value[2][4] = {};
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_ODT_WR, i_target, l_value) );
+ memcpy(o_array, &l_value, 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_ODT_WR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_VREF_DRAM_WR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint8_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note DRAM side Write Vref setting for DDR4. Bit encode is 01234567. Bit 0 is unused.
+/// Bit 1 is the Range. Bits 2-7 is the Value. Refer to the VrefDQ Training Table in
+/// JEDEC.
+///
+inline fapi2::ReturnCode get_si_vref_dram_wr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint8_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_DRAM_WR, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_VREF_DRAM_WR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_VREF_MC_RD getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] uint32_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Memory Controller side Read Vref setting. Dividing by 1000 gives you percentage
+/// of Vdd. Disable = 0, defined as no HW adjustment or Vdd/2 if possible.
+///
+inline fapi2::ReturnCode get_si_vref_mc_rd(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ uint32_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_VREF_MC_RD, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_VREF_MC_RD: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MEM_SI_WINDAGE_RD_CTR getter
+/// @param[in] const ref to the TARGET_TYPE_MEM_PORT
+/// @param[out] int16_t& reference to store the value
+/// @note Generated by gen_accessors.pl generate_mc_port_params
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Derived from calibration/characterization of read centering. Number of windage offset
+/// in units of pico-seconds[ps]. Default is 0 for no windage adjustment. Specification
+/// of the value in this file is 2's compliment hex
+///
+inline fapi2::ReturnCode get_si_windage_rd_ctr(const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
+ int16_t& o_value)
+{
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MEM_SI_WINDAGE_RD_CTR, i_target, o_value) );
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed getting ATTR_MEM_SI_WINDAGE_RD_CTR: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+
+} // attr
+} // mss
+
+#endif
diff --git a/src/import/generic/memory/lib/utils/assert_noexit.H b/src/import/generic/memory/lib/utils/assert_noexit.H
index 5836511de..e8192e784 100644
--- a/src/import/generic/memory/lib/utils/assert_noexit.H
+++ b/src/import/generic/memory/lib/utils/assert_noexit.H
@@ -22,3 +22,40 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file assert_noexit.H
+/// @brief MSS specific assert, but don't exit macro
+///
+// *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: HB:FSP
+
+#ifndef _MSS_ASSERT_NOEXIT_H_
+#define _MSS_ASSERT_NOEXIT_H_
+
+#include <fapi2.H>
+
+///
+/// @brief Create an error log based on __conditional__,
+/// the FFDC gathering function is called and the
+/// trace is output as a FAPI error trace. An error log
+/// is created. fapi2::current_err is set to indicate there was
+/// an error so the caller can ripple thru accordingly
+/// The caller is responsible for handling the error object.
+///
+/// @param[in] __conditional__ the condition to assert
+/// @param[in] __ffdc__ the FFDC gathering function
+/// @param[in] ... varargs, as input to FAPI_ERR
+///
+#define MSS_ASSERT_NOEXIT( __conditional__, __ffdc__, ... ) \
+ if (! (__conditional__)) \
+ { \
+ __ffdc__.execute(fapi2::FAPI2_ERRL_SEV_UNDEFINED, true); \
+ FAPI_ERR(__VA_ARGS__); \
+ fapi2::current_err = fapi2::FAPI2_RC_FALSE; \
+ }
+
+#endif
diff --git a/src/import/generic/memory/lib/utils/freq/cas_latency.H b/src/import/generic/memory/lib/utils/freq/cas_latency.H
index 83ae824c9..1b71481e2 100644
--- a/src/import/generic/memory/lib/utils/freq/cas_latency.H
+++ b/src/import/generic/memory/lib/utils/freq/cas_latency.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -135,7 +135,7 @@ template <>
class CasLatencyTraits<mc_type::EXPLORER>
{
public:
- static constexpr fapi2::TargetType TARGET_TYPE = fapi2::TARGET_TYPE_OCMB_CHIP;
+ static constexpr fapi2::TargetType TARGET_TYPE = fapi2::TARGET_TYPE_MEM_PORT;
static const std::vector<uint32_t> SUPPORTED_FREQS;
static constexpr const char* MC_STR = "EXPLORER";
};
diff --git a/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H b/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H
index a70dcebb5..4df0eeb06 100644
--- a/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H
+++ b/src/import/generic/memory/lib/utils/freq/gen_mss_freq.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -43,7 +43,6 @@
#include <generic/memory/lib/spd/spd_utils.H>
#include <generic/memory/lib/utils/freq/cas_latency.H>
#include <generic/memory/lib/utils/freq/mss_freq_scoreboard.H>
-#include <generic/memory/lib/data_engine/pre_data_init.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <vpd_access.H>
@@ -81,7 +80,7 @@ fapi2::ReturnCode set_freq(const fapi2::Target<T>& i_target,
/// @param[out] o_master_ranks number of master ranks per DIMM
/// @return FAPI2_RC_SUCCESS iff ok
///
-template<mss::proc_type P, fapi2::TargetType T>
+template<mss::proc_type P, typename TT = mss::frequency_traits<P>, fapi2::TargetType T>
fapi2::ReturnCode get_master_rank_per_dimm(const fapi2::Target<T>& i_target,
uint8_t* o_master_ranks);
@@ -93,56 +92,114 @@ fapi2::ReturnCode get_master_rank_per_dimm(const fapi2::Target<T>& i_target,
/// @param[out] o_dimm_type DIMM types
/// @return FAPI2_RC_SUCCESS iff ok
///
-template<mss::proc_type P, fapi2::TargetType T>
+template<mss::proc_type P, typename TT = mss::frequency_traits<P>, fapi2::TargetType T>
fapi2::ReturnCode get_dimm_type(const fapi2::Target<T>& i_target,
uint8_t* o_dimm_type);
///
-/// @brief Configures the number of ranks in the VPD accessor dependent upon DIMM type
+/// @brief Calls out the code if we calculated a bad frequency for the domain
/// @tparam P mss::proc_type on which to operate
/// @tparam TT Traits associated with the processor type
-/// @param[in] i_target the target on which to set the frequency values
-/// @param[in,out] io_vpd_info VPD information that needs to be configured
-/// @return FAPI2_RC_SUCCESS iff ok
+/// @param[in] i_target target on which to operate
+/// @param[in] i_final_freq frequency calculated for domain
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
+fapi2::ReturnCode callout_bad_freq_calculated(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
+ const uint64_t i_final_freq);
+
+///
+/// @brief Configures the number of ranks in the VPD accessor dependent upon DIMM type
+/// @tparam P mss::proc_type on which to operate
+/// @tparam TT Traits associated with the processor type
+/// @param[in] i_target the target on which to set the frequency values
+/// @param[in,out] io_vpd_info VPD information that needs to be configured
+/// @return FAPI2_RC_SUCCESS iff ok
///
template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
fapi2::ReturnCode configure_vpd_ranks(const fapi2::Target<TT::PORT_TARGET_TYPE>& i_target,
- fapi2::VPDInfo<TT::VPD_TARGET_TYPE>& io_vpd_info)
+ fapi2::VPDInfo<TT::VPD_TARGET_TYPE>& io_vpd_info);
+
+///
+/// @brief Checks to see if a specific VPD configuration is valid
+/// @tparam P mss::proc_type on which to operate
+/// @tparam TT Traits associated with the processor type
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_proposed_freq frequency to check for support
+/// @param[in,out] io_vpd_info VPDInfo instance to use
+/// @param[out] o_supported true if VPD supports the proposed frequency
+///
+template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
+fapi2::ReturnCode is_vpd_config_supported( const fapi2::Target<TT::VPD_TARGET_TYPE>& i_target,
+ const uint64_t i_proposed_freq,
+ fapi2::VPDInfo<TT::VPD_TARGET_TYPE>& io_vpd_info,
+ bool& o_supported)
{
- uint8_t l_rank_count_dimm[TT::MAX_DIMM_PER_PORT] = {};
- uint8_t l_dimm_type[TT::MAX_DIMM_PER_PORT] = {};
-
- // ATTR to update
- // Note: this flat out assumes that we have two DIMM per port max. This goes against the directive to have arrays be dynamic in length and derived from ATTR's
- FAPI_TRY( get_master_rank_per_dimm<P>(i_target, &(l_rank_count_dimm[0])) );
- FAPI_TRY( get_dimm_type<P>(i_target, &(l_dimm_type[0])) );
-
- // So for LRDIMM, our SI works a bit differently than for non-LRDIMM
- // LRDIMM's have buffers that operate on a per-DIMM basis across multiple ranks
- // As such, they act as a single load, similar to a 1R DIMM would
- // per the IBM signal integrity team, the 1R DIMM settings should be used for LRDIMM's
- // So, if we are LRDIMM's and have ranks, we want to only note it as a 1R DIMM for purposes of querying the VPD
- FAPI_DBG("%s for DIMM 0 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
- FAPI_DBG("%s for DIMM 1 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
-
- l_rank_count_dimm[0] = ((l_dimm_type[0] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[0] > 0)) ? 1 : l_rank_count_dimm[0];
- l_rank_count_dimm[1] = ((l_dimm_type[1] == TT::LRDIMM_TYPE) && (l_rank_count_dimm[1] > 0)) ? 1 : l_rank_count_dimm[1];
-
- FAPI_DBG("after LR modification %s for DIMM 0 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[0], l_dimm_type[0], l_dimm_type[0] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
- FAPI_DBG("after LR modification %s for DIMM 1 rank count %u dimm type %u %s",
- mss::c_str(i_target), l_rank_count_dimm[1], l_dimm_type[1], l_dimm_type[1] == TT::LRDIMM_TYPE ? "LRDIMM" : "RDIMM");
-
- io_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0];
- io_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1];
+ uint8_t l_vpd_blob[TT::VPD_KEYWORD_MAX] = {};
+
+ // We are unsupported by default
+ o_supported = false;
+
+ // In order to retrieve the VPD contents we first need the keyword size.
+ // If we are unable to retrieve the keyword size then this speed isn't
+ // supported in the VPD in Cronus (but not FW) and we skip to the next
+ // possible speed bin.
+
+ // So, we'll use VPD access for the IBM specific product data (assuming the vendor of the OCMB's side as well)
+ if( fapi2::getVPD(i_target, io_vpd_info, nullptr) != fapi2::FAPI2_RC_SUCCESS )
+ {
+ FAPI_INF("Couldn't retrieve MR size from VPD for this config %s -- skipping freq %d MT/s",
+ mss::c_str(i_target), i_proposed_freq );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Need temporary variables to avoid issues with FAPI_ASSERT and templated variables
+ {
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ const auto VPD_KW_MAX = TT::VPD_KEYWORD_MAX;
+ const auto VPD_BLOB = TT::VPD_BLOB;
+ FAPI_ASSERT( io_vpd_info.iv_size <= TT::VPD_KEYWORD_MAX,
+ fapi2::MSS_INVALID_VPD_KEYWORD_MAX().
+ set_MAX(VPD_KW_MAX).
+ set_ACTUAL(io_vpd_info.iv_size).
+ set_KEYWORD(VPD_BLOB).
+ set_MCS_TARGET(i_target),
+ "VPD MR keyword size retrieved: %d, is larger than max: %d for %s",
+ io_vpd_info.iv_size, TT::VPD_KEYWORD_MAX, mss::c_str(i_target));
+ }
+
+ // Firmware doesn't do the VPD lookup in the size check so repeat the logic here
+ if( fapi2::getVPD(i_target, io_vpd_info, &(l_vpd_blob[0])) != fapi2::FAPI2_RC_SUCCESS )
+ {
+ FAPI_INF("Couldn't retrieve %s data from VPD for this config %s -- skipping freq %d MT/s", TT::VPD_BLOB_NAME,
+ mss::c_str(i_target), i_proposed_freq );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // If we made it here, it means the frequency was supported for this config
+ o_supported = true;
fapi_try_exit:
return fapi2::current_err;
}
///
+/// @brief Check VPD config for support of a given freq
+/// @tparam P mss::proc_type on which to operate
+/// @tparam TT Traits associated with the processor type
+/// @param[in] i_target the target on which to operate
+/// @param[in] i_proposed_freq frequency to check for support
+/// @param[out] o_supported true if VPD supports the proposed frequency
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
+fapi2::ReturnCode check_freq_support_vpd( const fapi2::Target<TT::PORT_TARGET_TYPE>& i_target,
+ const uint64_t i_proposed_freq,
+ bool& o_supported);
+
+///
/// @brief Sets frequency attributes
/// @tparam P mss::proc_type on which to operate
/// @tparam TT Traits associated with the processor type
@@ -169,28 +226,7 @@ inline fapi2::ReturnCode set_freq_attrs(const fapi2::Target<TT::FREQ_TARGET_TYPE
// If we saw all 0's, write a 0.
l_final_freq = (l_final_freq == UINT64_MAX) ? 0 : l_final_freq;
- {
- // Declaring temporary variables to avoid linker errors associated with FAPI_ASSERT
- const auto FREQ0 = TT::SUPPORTED_FREQ0;
- const auto FREQ1 = TT::SUPPORTED_FREQ1;
- const auto FREQ2 = TT::SUPPORTED_FREQ2;
- const auto FREQ3 = TT::SUPPORTED_FREQ3;
-
- // If we don't find a valid frequency OR don't get a 0 (nothing configured on this clock domain), then error out
- FAPI_ASSERT( std::binary_search(TT::SUPPORTED_FREQS.begin(), TT::SUPPORTED_FREQS.end(), l_final_freq) ||
- l_final_freq == 0,
- fapi2::MSS_BAD_FREQ_CALCULATED()
- .set_MSS_FREQ(l_final_freq)
- .set_TARGET(i_target)
- .set_PROC_TYPE(P)
- .set_SUPPORTED_FREQ_0(FREQ0)
- .set_SUPPORTED_FREQ_1(FREQ1)
- .set_SUPPORTED_FREQ_2(FREQ2)
- .set_SUPPORTED_FREQ_3(FREQ3),
- "%s: Calculated FREQ (%d) isn't supported",
- mss::c_str(i_target),
- l_final_freq);
- }
+ FAPI_TRY(callout_bad_freq_calculated<P>(i_target, l_final_freq));
FAPI_INF( "Final Chosen Frequency: %d (%s)", l_final_freq, mss::c_str(i_target) );
@@ -258,7 +294,6 @@ fapi_try_exit:
/// @tparam P mss::proc_type on which to operate
/// @tparam TT Traits associated with the processor type
/// @param[in] i_target the target on which to operate
-/// @param[in] i_target target on which to operate for which to get the DIMM configs
/// @param[out] o_vpd_supported_freqs reference to a 2 dimensional vector of supported VPD frequencies for each MCA
/// @return FAPI2_RC_SUCCESS iff ok
///
@@ -267,8 +302,6 @@ template<mss::proc_type P, typename TT = mss::frequency_traits<P>>
fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_target,
std::vector<std::vector<uint32_t>>& o_vpd_supported_freqs)
{
- uint8_t l_vpd_blob[TT::VPD_KEYWORD_MAX] = {};
-
// This bitmap will keep track of the ports we visit.
// Any we don't are not configured, so will support all frequencies in the scoreboard
fapi2::buffer<uint8_t> configured_ports;
@@ -281,12 +314,9 @@ fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE>
o_vpd_supported_freqs.push_back(std::vector<uint32_t>());
}
- fapi2::VPDInfo<TT::VPD_TARGET_TYPE> l_vpd_info(TT::VPD_BLOB);
-
// Just go to find target for the port level
for( const auto& p : mss::find_targets<TT::PORT_TARGET_TYPE>(i_target) )
{
- const auto& l_vpd_target = mss::find_target<TT::VPD_TARGET_TYPE>(p);
const auto l_port_pos = mss::relative_pos<TT::FREQ_TARGET_TYPE>(p);
FAPI_TRY( configured_ports.setBit(l_port_pos) );
@@ -302,61 +332,21 @@ fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target<TT::FREQ_TARGET_TYPE>
continue;
}
- // Configures the number of ranks for the VPD configuration
- FAPI_TRY( configure_vpd_ranks<P>(p, l_vpd_info), "%s failed to configure VPD ranks", mss::c_str(p));
- l_vpd_info.iv_is_config_ffdc_enabled = false;
-
// Iterate through all supported memory freqs
for( const auto& freq : TT::SUPPORTED_FREQS )
{
- l_vpd_info.iv_freq_mhz = freq;
+ bool l_supported = false;
- FAPI_INF("%s. VPD info - frequency: %d MT/s, rank count for dimm_0: %d, dimm_1: %d",
- mss::c_str(p), l_vpd_info.iv_freq_mhz, l_vpd_info.iv_rank_count_dimm_0, l_vpd_info.iv_rank_count_dimm_1);
+ FAPI_TRY(check_freq_support_vpd<P>(p, freq, l_supported));
- // In order to retrieve the VPD contents we first need the keyword size.
- // If we are unable to retrieve the keyword size then this speed isn't
- // supported in the VPD in Cronus (but not FW) and we skip to the next
- // possible speed bin.
-
- // So, we'll use VPD access for the IBM specific product data (assuming the vendor of the OCMB's side as well)
- if( fapi2::getVPD(l_vpd_target, l_vpd_info, nullptr) != fapi2::FAPI2_RC_SUCCESS )
- {
- FAPI_INF("Couldn't retrieve MR size from VPD for this config %s -- skipping freq %d MT/s", mss::c_str(p), freq );
-
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- continue;
- }
-
- // Need temporary variables to avoid issues with FAPI_ASSERT and templated variables
- {
- const auto VPD_KW_MAX = TT::VPD_KEYWORD_MAX;
- const auto VPD_BLOB = TT::VPD_BLOB;
- FAPI_ASSERT( l_vpd_info.iv_size <= TT::VPD_KEYWORD_MAX,
- fapi2::MSS_INVALID_VPD_KEYWORD_MAX().
- set_MAX(VPD_KW_MAX).
- set_ACTUAL(l_vpd_info.iv_size).
- set_KEYWORD(VPD_BLOB).
- set_MCS_TARGET(i_target),
- "VPD MR keyword size retrieved: %d, is larger than max: %d for %s",
- l_vpd_info.iv_size, TT::VPD_KEYWORD_MAX, mss::c_str(i_target));
- }
-
- // Firmware doesn't do the VPD lookup in the size check so repeat the logic here
- if( fapi2::getVPD(l_vpd_target, l_vpd_info, &(l_vpd_blob[0])) != fapi2::FAPI2_RC_SUCCESS )
+ // Add supported freqs to our output
+ if (l_supported)
{
- FAPI_INF("Couldn't retrieve %s data from VPD for this config %s -- skipping freq %d MT/s", TT::VPD_BLOB_NAME,
- mss::c_str(p), freq );
-
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- continue;
+ FAPI_INF("VPD supported freq added: %d for %s", freq, mss::c_str(p) );
+ o_vpd_supported_freqs[l_port_pos].push_back(freq);
}
-
- // Add supported freqs to our output
- FAPI_INF("VPD supported freq added: %d for %s", freq, mss::c_str(p) );
- o_vpd_supported_freqs[l_port_pos].push_back(freq);
- }// freqs
- }// mca
+ }
+ }
// Mark any ports we didn't visit as supporting all frequencies
for ( uint64_t l_port_pos = 0; l_port_pos < TT::PORTS_PER_FREQ_DOMAIN; ++l_port_pos )
@@ -468,13 +458,13 @@ inline fapi2::ReturnCode supported_freqs(const fapi2::Target<TT::FREQ_TARGET_TYP
o_freqs.clear();
freq_scoreboard l_scoreboard(TT::PORTS_PER_FREQ_DOMAIN, TT::SUPPORTED_FREQS);
- std::vector<uint32_t> l_max_freqs(NUM_MAX_FREQS, 0);
+ std::vector<uint32_t> l_max_mrw_freqs(NUM_MAX_FREQS, 0);
std::vector<std::vector<uint32_t>> l_vpd_supported_freqs;
std::vector<uint32_t> l_spd_supported_freq;
std::vector<uint8_t> l_deconfigured = {0};
// Retrieve system MRW, SPD, and VPD constraints
- FAPI_TRY( max_allowed_dimm_freq<P>(l_max_freqs.data()), "%s max_allowed_dimm_freq", mss::c_str(i_target) );
+ FAPI_TRY( max_allowed_dimm_freq<P>(l_max_mrw_freqs.data()), "%s max_allowed_dimm_freq", mss::c_str(i_target) );
FAPI_TRY( spd_supported_freq<P>(i_target, l_spd_supported_freq),
"%s spd supported freqs", mss::c_str(i_target) );
FAPI_TRY( vpd_supported_freqs<P>(i_target, l_vpd_supported_freqs),
@@ -484,7 +474,7 @@ inline fapi2::ReturnCode supported_freqs(const fapi2::Target<TT::FREQ_TARGET_TYP
FAPI_TRY( limit_freq_by_processor<P>(i_target, l_scoreboard) );
// Limit frequency scoreboard according to MRW constraints
- FAPI_TRY( limit_freq_by_mrw<P>(i_target, l_max_freqs, l_scoreboard) );
+ FAPI_TRY( limit_freq_by_mrw<P>(i_target, l_max_mrw_freqs, l_scoreboard) );
// Limit frequency scoreboard according to VPD constraints
FAPI_TRY( limit_freq_by_vpd<P>(i_target, l_vpd_supported_freqs, l_scoreboard) );
@@ -537,9 +527,6 @@ fapi2::ReturnCode generate_freq(const fapi2::Target<TT::FREQ_TARGET_TYPE>& i_tar
std::vector<uint64_t> l_min_dimm_freq;
std::vector<uint32_t> l_supported_freqs;
- // We will first set pre-eff_config attributes
- FAPI_TRY( mss::set_pre_init_attrs<P>(i_target));
-
// Get supported freqs for this MCBIST
FAPI_TRY( mss::supported_freqs<P>(i_target, l_supported_freqs), "%s failed to get supported frequencies",
mss::c_str(i_target) );
diff --git a/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H b/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H
index 791fa5b97..5c6e31ab3 100644
--- a/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H
+++ b/src/import/generic/memory/lib/utils/freq/gen_mss_freq_traits.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,9 +36,7 @@
#ifndef _GEN_MSS_FREQ_TRAITS_H_
#define _GEN_MSS_FREQ_TRAITS_H_
-#include <fapi2.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <vpd_access.H>
namespace mss
{
@@ -50,52 +48,5 @@ namespace mss
template< mss::proc_type P >
class frequency_traits;
-///
-/// @class Traits and policy class for frequency and synchronous code - specialization for the NIMBUS processor type
-///
-template<>
-class frequency_traits<mss::proc_type::NIMBUS>
-{
- public:
- //////////////////////////////////////////////////////////////
- // Target types
- //////////////////////////////////////////////////////////////
- static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
- static constexpr fapi2::TargetType FREQ_TARGET_TYPE = fapi2::TARGET_TYPE_MCBIST;
- static constexpr fapi2::TargetType VPD_TARGET_TYPE = fapi2::TARGET_TYPE_MCS;
-
- //////////////////////////////////////////////////////////////
- // Traits values
- //////////////////////////////////////////////////////////////
- static const std::vector<uint64_t> SUPPORTED_FREQS;
- // MCBIST is our frequency domain. So 4 ports per MCBIST
- static constexpr uint64_t PORTS_PER_FREQ_DOMAIN = 4;
- // Max DIMM's per port
- static constexpr uint64_t MAX_DIMM_PER_PORT = 2;
- // Maxium number of primary ranks on a DIMM
- static constexpr uint64_t MAX_PRIMARY_RANK_PER_DIMM = 4;
- // MC type for Nimbus is constant - NIMBUS
- static constexpr mss::mc_type MC = mss::mc_type::NIMBUS;
- static constexpr const char* PROC_STR = "NIMBUS";
-
- // VPD traits values
- // VPD keyword max is slightly repeated (it's in NIMBUS consts too)
- static constexpr uint64_t VPD_KEYWORD_MAX = 255;
- static constexpr const char* VPD_BLOB_NAME = "MR";
- static constexpr auto VPD_BLOB = fapi2::MemVpdData::MR;
- static constexpr auto LRDIMM_TYPE = fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM;
-
- // Coding minion, why have these explicitly defined frequency values?
- // Isn't the supported frequency vector used for this purpose?
- // Well, we need to callout the specific frequency values that are allowed on a given system
- // As we can't callout a vector in error callouts and each traits might have a different number of allowable traits,
- // the below values are hardcoded specifically for the error callouts
- static constexpr uint64_t SUPPORTED_FREQ0 = DIMM_SPEED_1866;
- static constexpr uint64_t SUPPORTED_FREQ1 = DIMM_SPEED_2133;
- static constexpr uint64_t SUPPORTED_FREQ2 = DIMM_SPEED_2400;
- static constexpr uint64_t SUPPORTED_FREQ3 = DIMM_SPEED_2666;
-};
-
-
} // ns mss
#endif
diff --git a/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H b/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H
index 104bf38ca..cf96a1f5d 100644
--- a/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H
+++ b/src/import/generic/memory/lib/utils/freq/mss_freq_scoreboard.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -574,7 +574,7 @@ inline fapi2::ReturnCode limit_freq_by_mrw(const fapi2::Target<TT::FREQ_TARGET_T
FAPI_ASSERT( (l_dimms_on_port <= TT::MAX_DIMM_PER_PORT),
fapi2::MSS_TOO_MANY_DIMMS_ON_PORT()
.set_DIMM_COUNT(l_dimms_on_port)
- .set_MCA_TARGET(p),
+ .set_PORT_TARGET(p),
"Seeing %d DIMM on port %s",
l_dimms_on_port,
mss::c_str(p));
diff --git a/src/import/generic/memory/lib/utils/mss_math.H b/src/import/generic/memory/lib/utils/mss_math.H
index b60cbc2ae..ebb3da8e3 100644
--- a/src/import/generic/memory/lib/utils/mss_math.H
+++ b/src/import/generic/memory/lib/utils/mss_math.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -71,6 +71,42 @@ inline int64_t round_half_away_from_zero( const double i_input )
return ( i_input < 0.0 ? static_cast<int64_t>(i_input - 0.5) : static_cast<int64_t>(i_input + 0.5) );
}
+///
+/// @brief Divide and round unsigned values
+/// @tparam T input and output types
+/// @param[in] i_divisor the divisor (number to be divided)
+/// @param[in] i_dividend the dividend (number to divide by)
+/// @param[out] o_quotient the quotient
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+template<typename T>
+inline fapi2::ReturnCode divide_and_round( const T i_divisor,
+ const T i_dividend,
+ T& o_quotient )
+{
+ o_quotient = 0;
+
+ // Zero dividend would cause a divide-by-zero, so prevent that
+ FAPI_ASSERT( (i_dividend != 0),
+ fapi2::MSS_DIVIDE_BY_ZERO()
+ .set_DIVISOR(i_divisor)
+ .set_DIVIDEND(i_dividend),
+ "Caught an attempt to divide by zero (%d / %d)",
+ i_divisor, i_dividend );
+
+ {
+ const auto l_quotient_unrounded = i_divisor / i_dividend;
+ const auto l_remainder = i_divisor % i_dividend;
+
+ // Round the quotient up or down depending on the remainder
+ o_quotient = l_quotient_unrounded + ((l_remainder >= i_dividend / 2) ? 1 : 0);
+ }
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
}// mss
diff --git a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
index f7f2338fb..7a15bdfe0 100644
--- a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
+++ b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] Evan Lojewski */
/* [+] International Business Machines Corp. */
/* */
@@ -136,9 +136,11 @@ enum generic_ffdc_codes
LIMIT_FREQ_BY_VPD = 0x1025,
SET_DIMM_TYPE = 0x1026,
SET_DRAM_GEN = 0x1027,
- SET_HYBRID = 0x1027,
- SET_HYBRID_MEDIA = 0x1028,
- SET_MRANKS = 0x1029,
+ SET_HYBRID = 0x1028,
+ SET_HYBRID_MEDIA = 0x1029,
+ SET_MRANKS = 0x102A,
+ SET_HOST_TO_DDR_SPEED_RATIO = 0x102B,
+ SET_ATTR_HOST_TO_DDR_SPEED_RATIO = 0x102C,
SET_DIMM_RANKS_CNFG = 0x1039,
DDIMM_RAWCARD_DECODE = 0x103a,
SET_DRAM_WIDTH = 0x1040,
@@ -240,6 +242,14 @@ enum states
NO_CHIP_SELECT_ACTIVE = 0xFF,
};
+///
+/// @brief Supported DIMM speed equality deliberations
+///
+enum class speed_equality : uint8_t
+{
+ NOT_EQUAL_DIMM_SPEEDS = 0, ///< denotes all DIMMs don't have the same speed
+ EQUAL_DIMM_SPEEDS = 1, ///< denotes all DIMMs have the same speed
+};
namespace spd
{
diff --git a/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml b/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml
index 864d871f4..8890a447b 100644
--- a/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml
+++ b/src/import/generic/procedures/xml/attribute_info/generic_memory_eff_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -103,6 +103,23 @@
</attribute>
<attribute>
+ <id>ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO</id>
+ <targetType>TARGET_TYPE_MEM_PORT</targetType>
+ <description>
+ ARRAY[DIMM]
+ OMI to DDR frequency ratio
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint8</valueType>
+ <enum> 1_TO_1 = 1, 2_TO_1 = 2, 4_TO_1 = 4, 8_TO_1 = 8, 16_TO_1 = 16, 32_TO_1 = 32, 64_TO_1 = 64, 128_TO_1 = 128</enum>
+ <default>8</default>
+ <writeable/>
+ <array>2</array>
+ <mssUnit>ratio</mssUnit>
+ <mssAccessorName>host_to_ddr_speed_ratio</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MEM_EFF_DRAM_DENSITY</id>
<targetType>TARGET_TYPE_MEM_PORT</targetType>
<description>
diff --git a/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml b/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml
index faf8a75fb..e55a14ce2 100644
--- a/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml
+++ b/src/import/generic/procedures/xml/attribute_info/generic_memory_mrw_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2018 -->
+<!-- Contributors Listed Below - COPYRIGHT 2018,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -24,6 +24,28 @@
<!-- IBM_PROLOG_END_TAG -->
<attributes>
<attribute>
+ <id>ATTR_MSS_MRW_SUPPORTED_FREQ</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ List of memory frequencies supported by the current system.
+ </description>
+ <valueType>uint32</valueType>
+ <array>4</array>
+ <platInit/>
+ <!-- Note, mirrors ATTR_MSS_FREQ -->
+ <enum>
+ MT1866 = 1866,
+ MT2133 = 2133,
+ MT2400 = 2400,
+ MT2666 = 2666,
+ MT2933 = 2933,
+ MT3200 = 3200
+ </enum>
+ <default> 1866, 2133, 2400, 2666, 2933, 3200 </default>
+ <mssUnit>MT/s</mssUnit>
+ </attribute>
+
+ <attribute>
<id>ATTR_MEM_MRW_IS_PLANAR</id>
<targetType>TARGET_TYPE_OCMB_CHIP</targetType>
<description>
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 aaa8edd2b..7b3f1e894 100644
--- a/src/import/generic/procedures/xml/error_info/generic_error.xml
+++ b/src/import/generic/procedures/xml/error_info/generic_error.xml
@@ -38,21 +38,15 @@
<hwpErrors>
<hwpError>
- <rc>RC_MSS_BAD_FREQ_CALCULATED</rc>
+ <rc>RC_MSS_DIVIDE_BY_ZERO</rc>
<description>
- No frequency found for MC Either bad mrw attribute or no DIMMS installed?
- Should be a code bug if we get here
+ Attempt to divide by zero
</description>
- <ffdc>MSS_FREQ</ffdc>
- <ffdc>SUPPORTED_FREQ_0</ffdc>
- <ffdc>SUPPORTED_FREQ_1</ffdc>
- <ffdc>SUPPORTED_FREQ_2</ffdc>
- <ffdc>SUPPORTED_FREQ_3</ffdc>
- <ffdc>TARGET</ffdc>
- <ffdc>PROC_TYPE</ffdc>
+ <ffdc>DIVISOR</ffdc>
+ <ffdc>DIVIDEND</ffdc>
<callout>
<procedure>CODE</procedure>
- <priority>HIGH</priority>
+ <priority>LOW</priority>
</callout>
</hwpError>
OpenPOWER on IntegriCloud