diff options
Diffstat (limited to 'src/import/generic/memory/lib/data_engine/data_engine.H')
-rw-r--r-- | src/import/generic/memory/lib/data_engine/data_engine.H | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/src/import/generic/memory/lib/data_engine/data_engine.H b/src/import/generic/memory/lib/data_engine/data_engine.H index 471390306..6a7cbb437 100644 --- a/src/import/generic/memory/lib/data_engine/data_engine.H +++ b/src/import/generic/memory/lib/data_engine/data_engine.H @@ -22,3 +22,220 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +/// +/// @file pre_data_init.H +/// @brief Class to set preliminary eff_config attributes +/// +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: HB:CI + +#ifndef _MSS_GEN_DATA_ENGINE_H_ +#define _MSS_GEN_DATA_ENGINE_H_ + +#include <cstring> +#include <fapi2.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> +#include <generic/memory/lib/data_engine/attr_engine_traits.H> +#include <generic/memory/lib/data_engine/data_engine_utils.H> +#include <generic/memory/lib/spd/spd_utils.H> +#include <generic/memory/lib/utils/conversions.H> +#include <generic/memory/lib/mss_generic_attribute_getters.H> + +namespace mss +{ + +/// +/// @brief Alias for function pointer to spd_facade timing methods +/// +using spd_facade_fptr = fapi2::ReturnCode (spd::facade::*)(int64_t& o_timing_in_mtb) const; + +/// +/// @brief Algorithm to calculate SPD timings in nCK +/// @tparam ET SPD fields enumeration (e.g. attr_eff_engine_fields) +/// @tparam F SPD field +/// @tparam OT output type +/// @tparam TT defaulted to setTimingTraits<ET, F> +/// @param[in] i_spd the SPD data +/// @param[out] o_timing_in_ps SPD timing value in picoseconds +/// @return FAPI2_RC_SUCCESS iff okay +/// +template < typename ET, + ET F, + typename OT, + typename TT = setTimingTraits<ET, F> > +inline fapi2::ReturnCode calc_spd_time_in_ps(const spd::facade& i_spd, + OT& o_timing_in_ps) +{ + const auto l_dimm = i_spd.get_dimm_target(); + int64_t l_timing_mtb = 0; + int64_t l_timing_ftb = 0; + int64_t l_mtb = 0; + int64_t l_ftb = 0; + + FAPI_TRY( spd::get_timebases(i_spd, l_mtb, l_ftb) ); + + FAPI_TRY( (i_spd.*TT::get_timing_in_mtb)(l_timing_mtb), + "Failed to get % (in MTB) for %s", TT::TIMING_NAME, spd::c_str(l_dimm) ); + FAPI_TRY( (i_spd.*TT::get_timing_in_ftb)(l_timing_ftb), + "Failed to get %s (in FTB) for %s", TT::TIMING_NAME, spd::c_str(l_dimm) ); + + FAPI_DBG("%s medium timebase (ps): %ld, fine timebase (ps): %ld, %s (MTB): %ld, (FTB): %ld", + spd::c_str(l_dimm), l_mtb, l_ftb, TT::TIMING_NAME, l_timing_mtb, l_timing_ftb ); + + o_timing_in_ps = spd::calc_timing_from_timebase(l_timing_mtb, l_mtb, l_timing_ftb, l_ftb); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Algorithm to calculate SPD timings in nCK +/// @tparam ET SPD fields enumeration (e.g. attr_eff_engine_fields) +/// @tparam F SPD field +/// @tparam OT output type +/// @tparam TT defaulted to setTimingTraits<ET, F> +/// @param[in] i_spd the SPD data +/// @param[out] o_timing_in_ps SPD timing value in number of clocks (nCK) +/// @return FAPI2_RC_SUCCESS iff okay +/// +template < typename ET, + ET F, + typename OT, + typename TT = setTimingTraits<ET, F> > +inline fapi2::ReturnCode calc_spd_time_in_nck(const spd::facade& i_spd, + OT& o_timing_in_nck) +{ + const auto l_dimm = i_spd.get_dimm_target(); + + // Calculate the DIMM speed in picoseconds (a.k.a tCK == clock period) + int64_t l_tck_in_ps = 0; + uint64_t l_freq = 0; + FAPI_TRY( attr::get_freq(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(l_dimm), l_freq) ); + FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps), + "Failed to calculate clock period (tCK) for %s", spd::c_str(l_dimm) ); + + { + // Calculate the desired timing in ps + int64_t l_timing_in_ps = 0; + FAPI_TRY( (calc_spd_time_in_ps<ET, F>(i_spd, l_tck_in_ps)) ); + + // Calculate nck + FAPI_TRY( spd::calc_nck(l_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, o_timing_in_nck), + "Error in calculating %s (nCK) for target %s, with value of %d", + TT::TIMING_NAME, spd::c_str(l_dimm), l_timing_in_ps ); + + FAPI_INF("tCK (ps): %d, %s (ps): %d, %s (nck): %d", + l_tck_in_ps, TT::TIMING_NAME, l_timing_in_ps, TT::TIMING_NAME, o_timing_in_nck); + } + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Sets preliminary data fields +/// @tparam F pre_data_init_fields +/// @tparam T FAPI2 target type +/// @tparam IT Input data type +/// @tparam TT defaulted to preDataInitTraits<T> +/// @param[in] i_setting value we want to set attr with +/// @return FAPI2_RC_SUCCESS iff okay +/// +template< attr_eff_engine_fields F, + fapi2::TargetType T, + typename IT, + typename TT = mss::attrEngineTraits<decltype(F), F> + > +inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target, + const IT i_setting) +{ + FAPI_TRY( (gen::set_field<TT>(i_target, i_setting)), + "Failed set_field() for %s", spd::c_str(i_target) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Value traits for attrEnumTraits +/// @class attrEnumTraits - attr_si_engine_fields specialization +/// +template < > +struct attrEnumTraits<attr_si_engine_fields> +{ + static constexpr size_t DISPATCHER = ATTR_SI_DISPATCHER; +}; + +/// +/// @brief Value traits for attrEnumTraits +/// @class attrEnumTraits - attr_eff_engine_fields specialization +/// +template < > +struct attrEnumTraits<attr_eff_engine_fields> +{ + static constexpr size_t DISPATCHER = ATTR_EFF_DISPATCHER; +}; + +/// +/// @brief Value traits for attrEnumTraits +/// @class attrEnumTraits - attr_eff_engine_fields specialization +/// +template < > +struct attrEnumTraits<pre_data_init_fields> +{ + static constexpr size_t DISPATCHER = ATTR_PRE_DATA_ENG_DISPATCHER; +}; + +/// +/// @brief attribute signal integrity engine +/// @class attr_si_engine +/// @tparam ET field enumeration type +/// @tparam TT defaulted to attrEnumTraits<ET> +/// +template < typename ET, typename TT = attrEnumTraits<ET> > +struct attr_si_engine +{ + using attr_eng_t = gen::attr_engine<ET, static_cast<ET>(TT::DISPATCHER)>; + + /// + /// @brief Sets attr_si_engine_fields + /// @tparam[in] IT rank input type + /// @param[in] i_target the DIMM target + /// @param[in] i_efd_data EFD data + /// @param[in] i_rank current rank + /// @return FAPI2_RC_SUCCESS iff ok + /// + static fapi2::ReturnCode set(const std::shared_ptr<efd::base_decoder>& i_efd_data) + { + return attr_eng_t::set(i_efd_data); + } +}; + +/// +/// @brief Data structure to set effective config EFF data +/// @class pre_attr_eff_engine +/// @tparam F attr_eff_engine_fields enum +/// +template < typename ET, typename TT = attrEnumTraits<ET> > +struct attr_eff_engine +{ + using attr_eng_t = gen::attr_engine<ET, static_cast<ET>(TT::DISPATCHER)>; + + /// + /// @brief Sets attr_si_engine_fields + /// @param[in] i_target the DIMM target + /// @param[in] i_spd_data EFD data + /// @return FAPI2_RC_SUCCESS iff ok + /// + static fapi2::ReturnCode set(const mss::spd::facade& i_spd_data) + { + return attr_eng_t::set(i_spd_data); + } +}; + +}// mss + +#endif |