From 2b26420e72477835ffeacb2dab9970266ef07566 Mon Sep 17 00:00:00 2001 From: Louis Stermole Date: Thu, 24 Jan 2019 13:36:56 -0500 Subject: Add p9a_mss_freq procedure Change-Id: I764e1ade2f63cabb7f6e5cf2b39e89811ea432c4 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70989 Tested-by: FSP CI Jenkins Tested-by: HWSV CI Tested-by: Jenkins Server Reviewed-by: STEPHEN GLANCY Reviewed-by: ANDRE A. MARIN Tested-by: Hostboot CI Reviewed-by: Jennifer A. Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/75567 Reviewed-by: Christian R. Geddes Tested-by: Christian R. Geddes --- .../lib/eff_config/explorer_attr_engine_traits.H | 16 +- .../procedures/hwp/memory/lib/utils/explorer_pos.C | 14 +- .../p9/procedures/hwp/memory/lib/dimm/eff_dimm.C | 1 + .../hwp/memory/lib/eff_config/plug_rules.C | 2 +- .../chips/p9/procedures/hwp/memory/lib/fir/check.C | 12 +- .../hwp/memory/lib/freq/nimbus_freq_traits.H | 71 + .../hwp/memory/lib/freq/nimbus_mss_freq.C | 143 +- .../chips/p9/procedures/hwp/memory/lib/freq/sync.C | 16 +- .../chips/p9/procedures/hwp/memory/lib/freq/sync.H | 9 +- .../hwp/memory/lib/utils/assert_noexit.H | 61 - .../hwp/memory/lib/workarounds/freq_workarounds.C | 4 +- .../chips/p9/procedures/hwp/memory/p9_mss_freq.C | 7 +- .../xml/attribute_info/memory_mrw_attributes.xml | 19 - .../xml/error_info/p9_memory_mss_freq.xml | 44 +- .../hwp/memory/lib/freq/axone_freq_traits.H | 70 + .../hwp/memory/lib/freq/axone_mss_freq.C | 427 ++ .../procedures/hwp/memory/lib/freq/axone_sync.C | 250 ++ .../procedures/hwp/memory/lib/freq/axone_sync.H | 180 + .../p9a/procedures/hwp/memory/p9a_mss_eff_config.C | 24 +- .../chips/p9a/procedures/hwp/memory/p9a_mss_freq.C | 28 +- .../chips/p9a/procedures/hwp/memory/p9a_mss_freq.H | 3 +- .../p9a/procedures/hwp/memory/p9a_mss_freq.mk | 4 +- .../procedures/xml/error_info/p9a_freq_errors.xml | 112 + .../lib/data_engine/data_engine_traits_def.H | 3 +- .../lib/data_engine/p9a/p9a_data_init_traits.H | 78 + .../generic/memory/lib/data_engine/pre_data_init.H | 1 - .../memory/lib/mss_generic_attribute_getters.H | 4199 ++++++++++++++++++++ .../generic/memory/lib/utils/assert_noexit.H | 37 + .../generic/memory/lib/utils/freq/cas_latency.H | 4 +- .../generic/memory/lib/utils/freq/gen_mss_freq.H | 225 +- .../memory/lib/utils/freq/gen_mss_freq_traits.H | 51 +- .../memory/lib/utils/freq/mss_freq_scoreboard.H | 4 +- src/import/generic/memory/lib/utils/mss_math.H | 38 +- .../memory/lib/utils/shared/mss_generic_consts.H | 18 +- .../generic_memory_eff_attributes.xml | 19 +- .../generic_memory_mrw_attributes.xml | 24 +- .../procedures/xml/error_info/generic_error.xml | 16 +- 37 files changed, 5879 insertions(+), 355 deletions(-) delete mode 100644 src/import/chips/p9/procedures/hwp/memory/lib/utils/assert_noexit.H create mode 100644 src/import/generic/memory/lib/mss_generic_attribute_getters.H 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,22 +58,10 @@ 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::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::get_timing_in_ftb = &spd::facade::fine_offset_min_taa; - /// /// @brief Traits for attr_engine /// @class attrEngineTraits 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(const fapi2::Target(const fapi2::Target(const fapi2::Target +posTraits::pos_type +relative_pos(const fapi2::Target& 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 // mss lib +#include #include #include #include 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 #include -#include +#include #include 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 #include #include -#include +#include #include using fapi2::TARGET_TYPE_MCBIST; @@ -231,7 +231,7 @@ fapi2::ReturnCode during_draminit_training( const fapi2::Target( 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( const fapi2::Target(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( const fapi2::Target(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( const fapi2::Target(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( const fapi2::Target(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 +// *HWP FW Owner: Andre Marin +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: CI + +#ifndef _NIMBUS_FREQ_TRAITS_H_ +#define _NIMBUS_FREQ_TRAITS_H_ + +#include +#include +#include +#include +#include + +namespace mss +{ + +/// +/// @class Traits and policy class for frequency and synchronous code - specialization for the NIMBUS processor type +/// +template<> +class frequency_traits +{ + 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 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 -#include #include +#include #include #include // Generic libraries +#include #include -#include #include #include @@ -94,7 +94,7 @@ fapi2::ReturnCode set_CL_attr( 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, @@ -168,6 +168,133 @@ fapi2::ReturnCode get_dimm_type( return mss::eff_dimm_type(i_target, o_dimm_type); } +/// +/// @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( + const fapi2::Target& i_target, + const uint64_t i_final_freq) +{ + using TT = mss::frequency_traits; + + // 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( + const fapi2::Target& i_target, + fapi2::VPDInfo& io_vpd_info) +{ + using TT = mss::frequency_traits; + + 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(i_target, &(l_rank_count_dimm[0])) ); + FAPI_TRY( get_dimm_type(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( + const fapi2::Target& i_target, + const uint64_t i_proposed_freq, + bool& o_supported) +{ + using TT = mss::frequency_traits; + + o_supported = false; + + fapi2::VPDInfo l_vpd_info(TT::VPD_BLOB); + + const auto& l_vpd_target = mss::find_target(i_target); + + // Configures the number of ranks for the VPD configuration + FAPI_TRY( configure_vpd_ranks(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(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 @@ -211,10 +338,10 @@ fapi2::ReturnCode num_master_ranks_per_dimm(const fapi2: /// @return FAPI2_RC_SUCCESS iff ok /// template<> -fapi2::ReturnCode callout_no_common_freq(const fapi2::Target& - i_target, - const bool l_supported_freq, - const uint64_t i_num_ports) +fapi2::ReturnCode callout_no_common_freq( + const fapi2::Target& i_target, + const bool l_supported_freq, + const uint64_t i_num_ports) { std::vector 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 // Memory libraries +#include #include #include -#include // Generic libraries +#include #include #include #include #include #include -#include #include #include @@ -97,7 +97,7 @@ fapi2::ReturnCode dimm_speed_map(const std::vector< fapi2::Target& 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 #include +#include #include #include #include @@ -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 -// *HWP HWP Backup: Andre Marin -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -#ifndef _MSS_ASSERT_NOEXIT_H_ -#define _MSS_ASSERT_NOEXIT_H_ - -#include - -/// -/// @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 #include -#include +#include 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 // mss lib +#include #include #include +#include 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(l_mcbist)); + FAPI_TRY(mss::generate_freq(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 @@ -529,25 +529,6 @@ mrw_dram_2n_mode - - ATTR_MSS_MRW_SUPPORTED_FREQ - TARGET_TYPE_SYSTEM - - List of memory frequencies supported by the current system. - - uint32 - 4 - - - - MT1866 = 1866, - MT2133 = 2133, - MT2400 = 2400, - MT2666 = 2666 - - 1866, 2133, 2400, 2666 - - ATTR_MSS_MRW_UNSUPPORTED_RANK_CONFIG TARGET_TYPE_MCS 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 @@ - + @@ -47,7 +47,7 @@ - MCA_TARGET + PORT_TARGET TARGET_TYPE_DIMM MEDIUM @@ -55,27 +55,47 @@ - RC_MSS_FREQ_NOT_EQUAL_NEST_FREQ + RC_MSS_BAD_FREQ_CALCULATED + + No frequency found for MC Either bad mrw attribute or no DIMMS installed? + Should be a code bug if we get here + + MSS_FREQ + SUPPORTED_FREQ_0 + SUPPORTED_FREQ_1 + SUPPORTED_FREQ_2 + SUPPORTED_FREQ_3 + TARGET + PROC_TYPE + + CODE + HIGH + + + + + RC_MSS_FREQ_NOT_EQUAL_MAX_DOMAIN_FREQ 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. MSS_FREQ - NEST_FREQ + DOMAIN_FREQ + DOMAIN_TARGET CODE MEDIUM - MCS_TARGET + DOMAIN_TARGET TARGET_TYPE_DIMM HIGH - MCS_TARGET + DOMAIN_TARGET TARGET_TYPE_DIMM @@ -96,9 +116,9 @@ - RC_MSS_EMPTY_MCBIST_VECTOR_PASSED + RC_MSS_EMPTY_FREQ_TARGET_VECTOR_PASSED - Empty MCBIST target vector found when constructing dimm speed mapping + Empty freq target vector found when constructing dimm speed mapping CODE @@ -144,9 +164,9 @@ - RC_MSS_ALL_MCBIST_HAVE_0_FREQ + RC_MSS_ALL_TARGETS_HAVE_0_FREQ - 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? VECTOR_SIZE @@ -275,7 +295,7 @@ - MCA_TARGET + PORT_TARGET TARGET_TYPE_DIMM MEDIUM 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 +// *HWP FW Owner: Andre Marin +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: CI + +#ifndef _AXONE_FREQ_TRAITS_H_ +#define _AXONE_FREQ_TRAITS_H_ + +#include +#include +#include +#include + +namespace mss +{ + +/// +/// @class Traits and policy class for frequency and synchronous code - specialization for the AXONE processor type +/// +template<> +class frequency_traits +{ + 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 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 +// *HWP HWP Backup: Louis Stermole +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#include +#include +#include + +// Memory libraries +#include +#include +#include + +// Generic libraries +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +const std::vector< uint64_t > frequency_traits::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( + const fapi2::Target& i_target, + const uint64_t i_cas_latency) +{ + const auto l_temp = static_cast(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( + const fapi2::Target& 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( + const fapi2::Target& i_target, + uint8_t* o_master_ranks) +{ + using TT = mss::frequency_traits; + + 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(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( + const fapi2::Target& i_target, + uint8_t* o_dimm_type) +{ + using TT = mss::frequency_traits; + + 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( + const fapi2::Target& i_target, + const uint64_t i_final_freq) +{ + using TT = mss::frequency_traits; + + // 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& i_target, + std::vector& o_ranks) +{ + using TT = mss::frequency_traits; + + 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(i_target, &(l_rank_count_dimm[0])) ); + FAPI_TRY( get_dimm_type(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( const fapi2::Target& + i_target, + const uint64_t i_proposed_freq, + bool& o_supported) +{ + using TT = mss::frequency_traits; + o_supported = false; + + std::vector l_ranks; + fapi2::VPDInfo l_vpd_info(TT::VPD_BLOB); + + const auto& l_vpd_target = mss::find_target(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(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( + const fapi2::Target& i_target, + freq_scoreboard& io_scoreboard) +{ + std::vector 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( + const fapi2::Target& 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( + const fapi2::Target& 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( + const fapi2::Target& i_target, + const std::vector>& i_vpd_supported_freqs) +{ + + std::vector 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(const fapi2::Target& 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 +// *HWP HWP Backup: Louis Stermole +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#include +#include +#include +#include +#include + +// Memory libraries +#include +#include +#include + +// Generic libraries +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 = (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 >& i_targets, + std::map< fapi2::Target, 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& 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& 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, 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 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, 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, 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 +// *HWP HWP Backup: Louis Stermole +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _MSS_SYNC_H_ +#define _MSS_SYNC_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +// List of the OMI frequencies for Axone +// Note: these need to be sorted so binary search works +static const std::vector 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& i_target, + const uint64_t i_ddr_freq, + uint64_t& o_omi_freq) +{ + using TT = mss::frequency_traits; + 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& i_target, + const uint64_t i_omi_freq, + uint64_t& o_ddr_freq) +{ + using TT = mss::frequency_traits; + + // 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(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& 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 = (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 >& i_targets, + std::map< fapi2::Target, 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& 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, 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 #include #include +#include +#include /// /// @brief Configure the attributes for each controller @@ -53,21 +55,15 @@ fapi2::ReturnCode p9a_mss_eff_config( const fapi2::Target(i_target); - fapi2::MemVpdData_t l_vpd_type(fapi2::EFD); - fapi2::VPDInfo 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(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(dimm), l_freq) ); - - FAPI_TRY( mss::attr_derived_engine::set(dimm) ); + FAPI_TRY( mss::convert_ddr_freq_to_omi_freq(mss::find_target(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 l_efd_data; - // Get EFD data + // Get EFD size + const auto l_ocmb = mss::find_target(i_target); + fapi2::MemVpdData_t l_vpd_type(fapi2::MemVpdData::EFD); + fapi2::VPDInfo 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 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 // *HWP HWP Backup: Louis Stermole // *HWP Team: Memory -// *HWP Level: 1 +// *HWP Level: 2 // *HWP Consumed by: FSP:HB +// fapi2 +#include + +// mss lib #include + +#include #include +#include #include #include #include +#include +#include /// /// @brief Calculate and save off DIMM frequencies @@ -46,6 +55,13 @@ /// fapi2::ReturnCode p9a_mss_freq( const fapi2::Target& 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(i_target)) { @@ -60,12 +76,12 @@ fapi2::ReturnCode p9a_mss_freq( const fapi2::Target FAPI_TRY( l_rc, "Failed to initialize SPD facade for %s", mss::spd::c_str(d) ); FAPI_TRY( mss::attr_eff_engine::set(l_spd_decoder) ); + FAPI_TRY( mss::attr_derived_engine::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(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 -#include typedef fapi2::ReturnCode (*p9a_mss_freq_FP_t) (const fapi2::Target&); 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 @@ + + RC_P9A_MSS_BAD_FREQ_CALCULATED + + No frequency found for MC Either bad mrw attribute or no DIMMS installed? + Should be a code bug if we get here + + MSS_FREQ + SUPPORTED_FREQ_0 + SUPPORTED_FREQ_1 + SUPPORTED_FREQ_2 + TARGET + PROC_TYPE + + CODE + HIGH + + + + + + RC_P9A_MSS_FAILED_SYNC_MODE + + DIMM speeds are different and sync mode is required + + OMI_FREQ + MEM_FREQ + + CODE + HIGH + + + + + RC_P9A_MSS_MRW_FREQ_MAX_FREQ_EMPTY_SET + + 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 + + MSS_VPD_FREQ_0 + MSS_VPD_FREQ_1 + MSS_VPD_FREQ_2 + MSS_MAX_FREQ_0 + MSS_MAX_FREQ_1 + MSS_MAX_FREQ_2 + MSS_MAX_FREQ_3 + MSS_MAX_FREQ_4 + OMI_FREQ_0 + OMI_FREQ_1 + OMI_FREQ_2 + + CODE + HIGH + + + + PORT_TARGET + TARGET_TYPE_DIMM + + MEDIUM + + + + + RC_P9A_MSS_NO_SUPPORTED_FREQ + + When considering the frequencies in the MRW and the max supported + frequencies based on DIMM config, there are no applicable frequencies + remaining + + MEM_PORT_TARGET + MRW_MAX_FREQ_0 + MRW_MAX_FREQ_1 + MRW_MAX_FREQ_2 + MRW_MAX_FREQ_3 + MRW_MAX_FREQ_4 + + CODE + HIGH + + + + MEM_PORT_TARGET + TARGET_TYPE_DIMM + + MEDIUM + + + + + RC_P9A_MSS_UNSUPPORTED_OMI_FREQ + + Unsupported OMI frequency encountered in mss_freq_system + + OMI_FREQ_ENUM + + CODE + HIGH + + + + + RC_P9A_MSS_ZERO_HOST_TO_DDR_FREQ_RATIO + + Zero OMI to DDR frequency ratio encountered in mss_freq_system + + PORT_TARGET + + CODE + HIGH + + 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 @@ -205,6 +205,84 @@ struct attrEngineTraits } }; +/// +/// @brief Traits for pre_data_engine +/// @class attrEngineTraits +/// @note pre_data_init_fields, HOST_TO_DDR_SPEED_RATIO specialization +/// +template<> +struct attrEngineTraits +{ + using attr_type = fapi2::ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO_Type; + using attr_integral_type = std::remove_all_extents::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& 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& 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 > 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 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 +#include +#include + + + +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& 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& 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& 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& 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& 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& 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& 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint16_t& o_value) +{ + uint16_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint16_t& o_value) +{ + uint16_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[20]) +{ + uint8_t l_value[2][20] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t (&o_array)[20]) +{ + uint8_t l_value[2][20] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint32_t& o_value) +{ + uint32_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& 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& 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& 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& 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& 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& 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t& o_value) +{ + uint8_t l_value[2] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, + uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& i_target, uint8_t (&o_array)[4]) +{ + uint8_t l_value[2][4] = {}; + const auto l_port = i_target.getParent(); + + 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& 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& 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& 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& 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 +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _MSS_ASSERT_NOEXIT_H_ +#define _MSS_ASSERT_NOEXIT_H_ + +#include + +/// +/// @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 { 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 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 #include #include -#include #include #include @@ -81,7 +80,7 @@ fapi2::ReturnCode set_freq(const fapi2::Target& i_target, /// @param[out] o_master_ranks number of master ranks per DIMM /// @return FAPI2_RC_SUCCESS iff ok /// -template +template, fapi2::TargetType T> fapi2::ReturnCode get_master_rank_per_dimm(const fapi2::Target& i_target, uint8_t* o_master_ranks); @@ -93,55 +92,113 @@ fapi2::ReturnCode get_master_rank_per_dimm(const fapi2::Target& i_target, /// @param[out] o_dimm_type DIMM types /// @return FAPI2_RC_SUCCESS iff ok /// -template +template, fapi2::TargetType T> fapi2::ReturnCode get_dimm_type(const fapi2::Target& 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> +fapi2::ReturnCode callout_bad_freq_calculated(const fapi2::Target& 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> fapi2::ReturnCode configure_vpd_ranks(const fapi2::Target& i_target, - fapi2::VPDInfo& io_vpd_info) + fapi2::VPDInfo& 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> +fapi2::ReturnCode is_vpd_config_supported( const fapi2::Target& i_target, + const uint64_t i_proposed_freq, + fapi2::VPDInfo& 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

(i_target, &(l_rank_count_dimm[0])) ); - FAPI_TRY( get_dimm_type

(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> +fapi2::ReturnCode check_freq_support_vpd( const fapi2::Target& i_target, + const uint64_t i_proposed_freq, + bool& o_supported); + /// /// @brief Sets frequency attributes /// @tparam P mss::proc_type on which to operate @@ -169,28 +226,7 @@ inline fapi2::ReturnCode set_freq_attrs(const fapi2::Target(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> fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target& i_target, std::vector>& 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 configured_ports; @@ -281,12 +314,9 @@ fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target o_vpd_supported_freqs.push_back(std::vector()); } - fapi2::VPDInfo l_vpd_info(TT::VPD_BLOB); - // Just go to find target for the port level for( const auto& p : mss::find_targets(i_target) ) { - const auto& l_vpd_target = mss::find_target(p); const auto l_port_pos = mss::relative_pos(p); FAPI_TRY( configured_ports.setBit(l_port_pos) ); @@ -302,61 +332,21 @@ fapi2::ReturnCode vpd_supported_freqs( const fapi2::Target continue; } - // Configures the number of ranks for the VPD configuration - FAPI_TRY( configure_vpd_ranks

(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, 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 l_max_freqs(NUM_MAX_FREQS, 0); + std::vector l_max_mrw_freqs(NUM_MAX_FREQS, 0); std::vector> l_vpd_supported_freqs; std::vector l_spd_supported_freq; std::vector l_deconfigured = {0}; // Retrieve system MRW, SPD, and VPD constraints - FAPI_TRY( max_allowed_dimm_freq

(l_max_freqs.data()), "%s max_allowed_dimm_freq", mss::c_str(i_target) ); + FAPI_TRY( max_allowed_dimm_freq

(l_max_mrw_freqs.data()), "%s max_allowed_dimm_freq", mss::c_str(i_target) ); FAPI_TRY( spd_supported_freq

(i_target, l_spd_supported_freq), "%s spd supported freqs", mss::c_str(i_target) ); FAPI_TRY( vpd_supported_freqs

(i_target, l_vpd_supported_freqs), @@ -484,7 +474,7 @@ inline fapi2::ReturnCode supported_freqs(const fapi2::Target(i_target, l_scoreboard) ); // Limit frequency scoreboard according to MRW constraints - FAPI_TRY( limit_freq_by_mrw

(i_target, l_max_freqs, l_scoreboard) ); + FAPI_TRY( limit_freq_by_mrw

(i_target, l_max_mrw_freqs, l_scoreboard) ); // Limit frequency scoreboard according to VPD constraints FAPI_TRY( limit_freq_by_vpd

(i_target, l_vpd_supported_freqs, l_scoreboard) ); @@ -537,9 +527,6 @@ fapi2::ReturnCode generate_freq(const fapi2::Target& i_tar std::vector l_min_dimm_freq; std::vector l_supported_freqs; - // We will first set pre-eff_config attributes - FAPI_TRY( mss::set_pre_init_attrs

(i_target)); - // Get supported freqs for this MCBIST FAPI_TRY( mss::supported_freqs

(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 #include -#include 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 -{ - 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 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(i_input - 0.5) : static_cast(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 +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 @@ - + @@ -102,6 +102,23 @@ hybrid + + ATTR_MEM_EFF_HOST_TO_DDR_SPEED_RATIO + TARGET_TYPE_MEM_PORT + + ARRAY[DIMM] + OMI to DDR frequency ratio + + + uint8 + 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 + 8 + + 2 + ratio + host_to_ddr_speed_ratio + + ATTR_MEM_EFF_DRAM_DENSITY TARGET_TYPE_MEM_PORT 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 @@ - + @@ -23,6 +23,28 @@ + + ATTR_MSS_MRW_SUPPORTED_FREQ + TARGET_TYPE_SYSTEM + + List of memory frequencies supported by the current system. + + uint32 + 4 + + + + MT1866 = 1866, + MT2133 = 2133, + MT2400 = 2400, + MT2666 = 2666, + MT2933 = 2933, + MT3200 = 3200 + + 1866, 2133, 2400, 2666, 2933, 3200 + MT/s + + ATTR_MEM_MRW_IS_PLANAR TARGET_TYPE_OCMB_CHIP 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 @@ - RC_MSS_BAD_FREQ_CALCULATED + RC_MSS_DIVIDE_BY_ZERO - 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 - MSS_FREQ - SUPPORTED_FREQ_0 - SUPPORTED_FREQ_1 - SUPPORTED_FREQ_2 - SUPPORTED_FREQ_3 - TARGET - PROC_TYPE + DIVISOR + DIVIDEND CODE - HIGH + LOW -- cgit v1.2.1