diff options
Diffstat (limited to 'src/import/generic/memory')
25 files changed, 6226 insertions, 8872 deletions
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 1f20e6b75..aa061a530 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 @@ -22,3 +22,499 @@ /* 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: CI + +#ifndef _MSS_PRE_DATA_INIT_H_ +#define _MSS_PRE_DATA_INIT_H_ + +#include <cstring> +#include <fapi2.H> +#include <generic/memory/lib/spd/spd_facade.H> +#include <generic/memory/lib/utils/find.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> + +namespace mss +{ + +/// +/// @brief enum list of preliminary data fields +/// +enum pre_data_init_fields +{ + DIMM_TYPE, + DRAM_GEN, + HYBRID, + HYBRID_MEDIA, + MRANKS, + DIMM_RANKS_CNFG, +}; + +/// +/// @brief Traits for pre_data_engine +/// @class preDataInitTraits +/// @tparam T proc_type (e.g. Nimbus, Axone, etc.) +/// @tparam TT pre_data_init_fields (e.g. DIMM_TYPE, MRANK, etc.) +/// +template< proc_type T, pre_data_init_fields TT > +class preDataInitTraits; + +/// +/// @brief Traits for pre_data_engine +/// @class preDataInitTraits +/// @note NIMBUS, DIMM_TYPE specialization +/// +template<> +class preDataInitTraits<NIMBUS, DIMM_TYPE> +{ + public: + using attr_type = fapi2::ATTR_EFF_DIMM_TYPE_Type; + static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_DIMM_TYPE_TargetType; + + /// + /// @brief attribute getter + /// @param[in] i_target the MCS target + /// @param[out] o_setting array to populate + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target, + attr_type& o_setting) + { + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_DIMM_TYPE, i_target, o_setting) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief attribute setter + /// @param[in] i_target the MCS target + /// @param[in] i_setting array to set + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target, + const attr_type& i_setting) + { + attr_type l_data = {}; + memcpy(l_data, i_setting, sizeof(l_data)); + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_TYPE, i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @brief Traits for pre_data_engine +/// @class preDataInitTraits +/// @note NIMBUS, DRAM_GEN specialization +/// +template<> +class preDataInitTraits<NIMBUS, DRAM_GEN> +{ + public: + using attr_type = fapi2::ATTR_EFF_DRAM_GEN_Type; + static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_DRAM_GEN_TargetType; + + /// + /// @brief attribute getter + /// @param[in] i_target the MCS target + /// @param[out] o_setting array to populate + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target, + attr_type& o_setting) + { + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_DRAM_GEN, i_target, o_setting) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief attribute setter + /// @param[in] i_target the MCS target + /// @param[in] i_setting array to set + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target, + const attr_type& i_setting) + { + attr_type l_data = {}; + memcpy(l_data, i_setting, sizeof(l_data)); + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_GEN, i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @brief Traits for pre_data_engine +/// @class preDataInitTraits +/// @note NIMBUS, HYBRID specialization +/// +template<> +class preDataInitTraits<NIMBUS, HYBRID> +{ + public: + using attr_type = fapi2::ATTR_EFF_HYBRID_Type; + static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_HYBRID_TargetType; + + /// + /// @brief attribute getter + /// @param[in] i_target the MCS target + /// @param[out] o_setting array to populate + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target, + attr_type& o_setting) + { + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_HYBRID, i_target, o_setting) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief attribute setter + /// @param[in] i_target the MCS target + /// @param[in] i_setting array to set + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target, + const attr_type& i_setting) + { + attr_type l_data = {}; + memcpy(l_data, i_setting, sizeof(l_data)); + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID, i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @brief Traits for pre_data_engine +/// @class preDataInitTraits +/// @note NIMBUS, HYBRID_MEDIA specialization +/// +template<> +class preDataInitTraits<NIMBUS, HYBRID_MEDIA> +{ + public: + using attr_type = fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE_Type; + static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE_TargetType; + + /// + /// @brief attribute getter + /// @param[in] i_target the MCS target + /// @param[out] o_setting array to populate + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target, + attr_type& o_setting) + { + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, i_target, o_setting) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief attribute setter + /// @param[in] i_target the MCS target + /// @param[in] i_setting array to set + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target, + const attr_type& i_setting) + { + attr_type l_data = {}; + memcpy(l_data, i_setting, sizeof(l_data)); + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @brief Traits for pre_data_engine +/// @class preDataInitTraits +/// @note NIMBUS, MRANKS specialization +/// +template<> +class preDataInitTraits<NIMBUS, MRANKS> +{ + public: + using attr_type = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_Type; + static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_TargetType; + + /// + /// @brief attribute getter + /// @param[in] i_target the MCS target + /// @param[out] o_setting array to populate + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target, + attr_type& o_setting) + { + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, i_target, o_setting) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief attribute setter + /// @param[in] i_target the MCS target + /// @param[in] i_setting array to set + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target, + const attr_type& i_setting) + { + attr_type l_data = {}; + memcpy(l_data, i_setting, sizeof(l_data)); + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @brief Traits for pre_data_engine +/// @class preDataInitTraits +/// @note NIMBUS, DIMM_RANKS_CNFG specialization +/// +template<> +class preDataInitTraits<NIMBUS, DIMM_RANKS_CNFG> +{ + public: + using attr_type = fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED_Type; + static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_TargetType; + + /// + /// @brief attribute getter + /// @param[in] i_target the MCS target + /// @param[out] o_setting array to populate + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target, + attr_type& o_setting) + { + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, o_setting) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief attribute setter + /// @param[in] i_target the MCS target + /// @param[in] i_setting array to set + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target, + const attr_type& i_setting) + { + attr_type l_data = {}; + memcpy(l_data, i_setting, sizeof(l_data)); + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @brief Helper function for attribute setting +/// @tparam T processor type (e.g. NIMBUS, AXONE, etc.) +/// defaulted to NIMBUS +/// @tparam X size of 1st array index +/// @tparam Y size of 2nd array index +/// @tparam TT FAPI2 target type +/// @tparam IT Input/outpu data type +/// @param[in] i_target the MCS target +/// @param[in] i_setting array to set +/// @param[out] o_data attribute data structure to set +/// @warning This is Nimbus specific +/// +template < size_t X, size_t Y, typename IT > +void data_setter( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const IT i_setting, + IT (&o_data)[X][Y]) +{ + const size_t l_port_index = mss::index( find_target<fapi2::TARGET_TYPE_MCA>(i_target) ); + const size_t l_dimm_index = mss::index(i_target); + + o_data[l_port_index][l_dimm_index] = i_setting; +} + +/// +/// @brief Mapping boilerplate check +/// @tparam T FAPI2 target type +/// @tparam IT map key type +/// @tparam OT map value type +/// @param[in] i_map SPD to attribute data mapping +/// @param[in] i_ffdc_code FFDC function code +/// @param[in] i_key Key to query map +/// @param[out] o_output value from key +/// +template< fapi2::TargetType T, typename IT, typename OT > +fapi2::ReturnCode lookup_table_check(const fapi2::Target<T>& i_target, + const std::vector<std::pair<IT, OT>>& i_map, + const generic_ffdc_codes i_ffdc_code, + const IT i_key, + OT& o_output) +{ + const bool l_is_val_found = mss::find_value_from_key(i_map, i_key, o_output); + + FAPI_ASSERT( l_is_val_found, + fapi2::MSS_LOOKUP_FAILED() + .set_KEY(i_key) + .set_DATA(o_output) + .set_FUNCTION(i_ffdc_code) + .set_TARGET(i_target), + "Failed to find a mapped value for %d on %s", + i_key, + spd::c_str(i_target) ); +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Sets preliminary data fields +/// @tparam P processor type (e.g. NIMBUS, AXONE, etc.) +/// @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< proc_type P, + pre_data_init_fields F, + fapi2::TargetType T, + typename IT, + typename TT = preDataInitTraits<P, F> + > +fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target, const IT i_setting) +{ + const auto l_target = mss::find_target<TT::TARGET_TYPE>(i_target); + typename TT::attr_type l_attr_list = {}; + IT l_mapping_value = i_setting; + + FAPI_TRY( TT::get_attr(l_target, l_attr_list) ); + + // Indexing isn't very general + data_setter(i_target, l_mapping_value, l_attr_list); + + FAPI_TRY( TT::set_attr(l_target, l_attr_list) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Data structure to set pre-effective config data +/// @class pre_data_engine +/// @tparam T supported processor type (e.g. Nimbus, Axone, etc.) +/// +template< proc_type T > +class pre_data_engine; + +/// +/// @brief Data structure to set pre-effective config data +/// @class pre_data_engine +/// @note NIMBUS specialization +/// +template< > +class pre_data_engine< NIMBUS > +{ + private: + + fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_dimm; + uint8_t iv_master_ranks; + spd::facade iv_spd_data; + size_t iv_port_index; + size_t iv_dimm_index; + + public: + + static const std::vector<std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP; + static const std::vector<std::pair<uint8_t, uint8_t> > BASE_MODULE_TYPE_MAP; + static const std::vector<std::pair<uint8_t, uint8_t> > DRAM_GEN_MAP; + static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_MAP; + static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_MEMORY_TYPE_MAP; + + /// + /// @brief ctor + /// @param[in] i_target the DIMM target + /// @param[in] i_spd_data SPD decoder + /// @param[out] o_rc ReturnCode for failure to init object + /// + pre_data_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const spd::facade& i_spd_data, + fapi2::ReturnCode& o_rc); + + /// + /// @brief default dtor + /// + ~pre_data_engine() = default; + + /// + /// @brief Set ATTR_EFF_DIMM_TYPE + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode set_dimm_type(); + + /// + /// @brief Set ATTR_EFF_DRAM_GEN + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode set_dram_gen(); + + /// + /// @brief Set ATTR_EFF_HYBRID + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode set_hybrid(); + + /// + /// @brief Set ATTR_EFF_HYBRID_MEMORY_TYPE + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode set_hybrid_media(); + + /// + /// @brief Set ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode set_master_ranks(); + + /// + /// @brief Sets ATTR_EFF_DIMM_RANKS_CONFIGED + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode set_dimm_ranks_configured(); +}; + +}//mss + +#endif diff --git a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H index e7fee6e6d..422d95443 100644 --- a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H +++ b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H @@ -45,17 +45,55 @@ #include <fapi2.H> // mss lib +#include <generic/memory/lib/spd/spd_decoder_def.H> #include <generic/memory/lib/spd/common/dimm_module_decoder.H> #include <generic/memory/lib/spd/common/rcw_settings.H> -#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H> -#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H> -#include <generic/memory/lib/utils/c_str.H> #include <generic/memory/lib/spd/common/spd_decoder_base.H> #include <generic/memory/lib/spd/spd_checker.H> namespace mss { +namespace spd +{ + +/// +/// @brief sdram package types. Follows encodings in SPD +/// +enum sdram_package_type : uint8_t +{ + // Package Type + MONOLITHIC = 0, ///< Monolithic DRAM device + NON_MONOLITHIC = 1, ///< NonMonolithic DRAM device (3DS, Dual/Quad Die, etc) + + // Signal loading + UNSPECIFIED = MONOLITHIC, ///< Not specified + MULTI_LOAD_STACK = 1, ///< Multi laod stack + SINGLE_LOAD_STACK = 2, ///< Single load stack (3DS) +}; + +/// +/// @brief module type DDR4 encoding +/// +enum module_type +{ + NOT_HYBRID = 0, + HYBRID = 1, + NVDIMM_HYBRID = 1 +}; + +/// +/// @brief enum for voltage information. Encoding comes from SPD +/// +enum nominal_voltage : uint8_t +{ + NOT_OPERABLE = 0, ///< Not operable at 1.2V + OPERABLE = 1, ///< Operable at 1.2V + + NOT_ENDURANT = 0, ///< Not endurant at 1.2V + ENDURANT = 1 ///< Endurant at 1.2 V +}; + /// /// @brief Connector to SDRAM Bit Mapping field positions /// @note Bytes 60 - 77 . Mapping to Package rank map and @@ -117,11 +155,11 @@ static fapi2::ReturnCode nibble_map_helper( const fapi2::Target<fapi2::TARGET_TY const bool VALID_LOWER_NIBBLE = (i_bit_order >= LOW_BIT_ORDER_MIN) && (i_bit_order <= LOW_BIT_ORDER_MAX); const bool VALID_UPPER_NIBBLE = (i_bit_order >= UP_BIT_ORDER_MIN) && (i_bit_order <= UP_BIT_ORDER_MAX); - FAPI_TRY(mss::check::spd::fail_for_invalid_value(i_target, - (VALID_LOWER_NIBBLE || VALID_UPPER_NIBBLE), - i_byte, - i_bit_order, - "Failed check on the NIBBLE_MAP field") ); + FAPI_TRY(check::fail_for_invalid_value(i_target, + (VALID_LOWER_NIBBLE || VALID_UPPER_NIBBLE), + i_byte, + i_bit_order, + "Failed check on the NIBBLE_MAP field") ); fapi_try_exit: return fapi2::current_err; } @@ -139,11 +177,11 @@ static fapi2::ReturnCode package_rank_map_helper( const fapi2::Target<fapi2::TAR { // Taken from the SPD JEDEC spec, only valid encoding, the rest are reserved constexpr uint64_t VALID_VALUE = 0; - FAPI_TRY(mss::check::spd::fail_for_invalid_value(i_target, - (i_pkg_rank_map == VALID_VALUE), - i_byte, - i_pkg_rank_map, - "Failed check on Package Rank Map") ); + FAPI_TRY(check::fail_for_invalid_value(i_target, + (i_pkg_rank_map == VALID_VALUE), + i_byte, + i_pkg_rank_map, + "Failed check on Package Rank Map") ); fapi_try_exit: return fapi2::current_err; } @@ -374,1353 +412,1453 @@ class connectorTraits<CB0_7, PKG_RANK_MAP> } }; -namespace spd -{ - -/// -/// @brief sdram package types. Follows encodings in SPD -/// -enum sdram_package_type : uint8_t -{ - // Package Type - MONOLITHIC = 0, ///< Monolithic DRAM device - NON_MONOLITHIC = 1, ///< Non-Monolithic DRAM device (3DS, Dual/Quad Die, etc) - - // Signal loading - UNSPECIFIED = MONOLITHIC, ///< Not specified - MULTI_LOAD_STACK = 1, ///< Multi laod stack - SINGLE_LOAD_STACK = 2, ///< Single load stack (3DS) -}; - -/// -/// @brief enum for voltage information. Encoding comes from SPD -/// -enum nominal_voltage : uint8_t -{ - NOT_OPERABLE = 0, ///< Not operable at 1.2V - OPERABLE = 1, ///< Operable at 1.2V - - NOT_ENDURANT = 0, ///< Not endurant at 1.2V - ENDURANT = 1 ///< Endurant at 1.2 V -}; - -namespace ddr4 -{ - /// /// @class decoder +/// @tparam R SPD revision - partial specialization /// @brief Base SPD DRAM decoder /// -class decoder_v1_0 : public decoder +template < rev R > +class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder { - protected: - enum - { - // Byte 0 - BYTES_USED_START = 4, - BYTES_USED_LEN = 4, - - BYTES_TOTAL_START = 1, - BYTES_TOTAL_LEN = 3, - - // Byte 1 - see factory byte enum - // Byte 2 - Entire byte used - // Byte 3 - used in the SPD factory - - // Byte 4 - SDRAM_CAPACITY_START = 4, - SDRAM_CAPACITY_LEN = 4, - - SDRAM_BANKS_START = 2, - SDRAM_BANKS_LEN = 2, - - BANK_GROUP_START = 0, - BANK_GROUP_LEN = 2, - - // Byte 5 - COL_ADDRESS_START = 5, - COL_ADDRESS_LEN = 3, - - ROW_ADDRESS_START = 2, - ROW_ADDRESS_LEN = 3, - - // Byte 6 - PRIM_SIGNAL_LOAD_START = 6, - PRIM_SIGNAL_LOAD_LEN = 2, - - PRIM_DIE_COUNT_START = 1, - PRIM_DIE_COUNT_LEN = 3, - - PRIM_PACKAGE_TYPE_START = 0, - PRIM_PACKAGE_TYPE_LEN = 1, - - // Byte 7 - MAC_START = 4, - MAC_LEN = 4, - - TMAW_START = 2, - TMAW_LEN = 2, - - // Byte 8 reserved - - // Byte 9 - SOFT_PPR_START = 2, - SOFT_PPR_LEN = 1, - - PPR_START = 0, - PPR_LEN = 2, - - // Byte 10 - SEC_SIGNAL_LOAD_START = 5, - SEC_SIGNAL_LOAD_LEN = 2, - - DENSITY_RATIO_START = 4, - DENSITY_RATIO_LEN = 2, - - SEC_DIE_COUNT_START = 1, - SEC_DIE_COUNT_LEN = 3, - - SEC_PACKAGE_TYPE_START = 0, - SEC_PACKAGE_TYPE_LEN = 1, - - // Byte 11 - OPERABLE_START = 7, - OPERABLE_LEN = 1, - - ENDURANT_START = 6, - ENDURANT_LEN = 1, - - NOM_VOLT_START = 0, - NOM_VOLT_LEN = 6, - - // Byte 12 - SDRAM_WIDTH_START = 5, - SDRAM_WIDTH_LEN = 3, - - PACKAGE_RANKS_START = 2, - PACKAGE_RANKS_LEN = 3, - - RANK_MIX_START = 1, - RANK_MIX_LEN = 1, - - // Byte 13 - BUS_WIDTH_START = 5, - BUS_WIDTH_LEN = 3, + private: - BUS_EXT_WIDTH_START = 3, - BUS_EXT_WIDTH_LEN = 2, + using fields_t = fields<DDR4, BASE_CNFG>; + fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + std::vector<uint8_t> iv_data; - // Byte 14 - THERM_SENSOR_RESERV_START = 1, - THERM_SENSOR_RESERV_LEN = 7, + /// + /// @brief SPD byte field threshold check + /// @param[out] o_value list of connector_field values from SPD + /// @return FAPI2_RC_SUCCESS iff okay + /// + template< connector_bits T, connector_field OT, typename TT = connectorTraits<T, OT> > + fapi2::ReturnCode sdram_connector_helper( std::vector<uint8_t>& o_value ) const + { + for( size_t byte = TT::START; byte <= TT::END; ++byte ) + { + uint8_t l_field = 0; - THERM_SENSOR_START = 0, - THERM_SENSOR_LEN = 1, + fapi2::buffer<uint8_t> l_buffer(iv_data[byte]); + l_buffer.extractToRight<TT::EXTRACT_START, TT::EXTRACT_LEN>(l_field); - // Byte 15 - EXT_MOD_TYPE_START = 5, - EXT_MOD_TYPE_LEN = 3, + FAPI_DBG("%s SPD byte %d, data: %d, field value: %d, starting bit: %d, bit length: %d", + spd::c_str(iv_target), byte, iv_data[byte], l_field, TT::EXTRACT_START, TT::EXTRACT_LEN); - // Byte 16 - reserved + FAPI_TRY( TT::fail_check(iv_target, byte, l_field) ); - // Byte 17 - FINE_TIMEBASE_START = 6, - FINE_TIMEBASE_LEN = 2, + o_value.push_back(l_field); + } - MED_TIMEBASE_START = 4, - MED_TIMEBASE_LEN = 2, + fapi_try_exit: + return fapi2::current_err; + } - // Byte 18 - Entire byte used - // Byte 19 - Entire byte used + /// + /// @class proxy + /// @brief Nested class to help specialize certain decoder methods + /// @tparam U SPD revision + /// @tparam B dummy var to faciliate partial specialization - defaulted to true + /// @note explicit specialization of a class isn't allowed on the HB compiler. + /// This is a helper class to workaround specialization for just a few methods + /// instead of having the explicitly specialize the entire class itself. + /// Since nested classes also can't be explicitly specialized...we use a bool + /// template param to facilitate partial specialzation of the nested helper class. + /// + template< rev U, bool B = true > + struct proxy + { + /// + /// @brief Decodes Minimum Write Recovery Time + /// @param[in] i_target dimm target + /// @param[in] i_data SPD data vector + /// @param[out] o_value tWRmin in MTB units + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode min_twr( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_data, + int64_t& o_value ) + { + uint8_t l_twrmin_msn = 0; + uint8_t l_twrmin_lsb = 0; + + FAPI_TRY( (mss::spd::reader<fields_t::TWRMIN_MSN, U>(i_target, i_data, l_twrmin_msn)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TWRMIN_LSB, U>(i_target, i_data, l_twrmin_lsb)) ); + + { + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_twrmin_msn, l_twrmin_lsb); + + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWRMIN)); + o_value = l_buffer; + + FAPI_INF("%s. Minimum Write Recovery Time (tWRmin) in MTB units: %d", + spd::c_str(i_target), + o_value); + } + fapi_try_exit: + return fapi2::current_err; + } - // Byte 20-23 - CAS_BYTE_1_START = 56, - CAS_BYTE_1_LEN = 8, - CAS_BYTE_2_START = 48, - CAS_BYTE_2_LEN = 8, - CAS_BYTE_3_START = 40, - CAS_BYTE_3_LEN = 8, - CAS_BYTE_4_START = 32, - CAS_BYTE_4_LEN = 8, + /// + /// @brief Decodes Minimum Write to Read Time - Same Bank Group + /// @param[in] i_target dimm target + /// @param[in] i_data SPD data vector + /// @param[out] o_value tWRT_Lmin in MTB units + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode min_twtr_l( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_data, + int64_t& o_value ) + { + uint8_t l_twtr_lmin_msn = 0; + uint8_t l_twtr_lmin_lsb = 0; - // Byte 24 - Entire byte used - // Byte 25 - Entire byte used - // Byte 26 - Entire byte used + FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_L_MSN, U>(i_target, i_data, l_twtr_lmin_msn)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_L_LSB, U>(i_target, i_data, l_twtr_lmin_lsb)) ); - // Byte 27 - TRASMIN_MSN_START = 4, // MSN = most significant nibble - TRASMIN_MSN_LEN = 4, + { + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_twtr_lmin_msn, l_twtr_lmin_lsb); - TRCMIN_MSN_START = 0, // MSN = most significant nibble - TRCMIN_MSN_LEN = 4, + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWTR_L_MIN)); + o_value = l_buffer; - // Byte 28 - TRASMIN_LSB_START = 0, // LSB = least significant byte - TRASMIN_LSB_LEN = 8, + FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Lmin) in MTB units: %d", + spd::c_str(i_target), + o_value); + } - // Byte 29 - TRCMIN_LSB_START = 0, // LSB = least significant byte - TRCMIN_LSB_LEN = 8, + fapi_try_exit: + return fapi2::current_err; + } - // Byte 30 - TRFC1MIN_LSB_START = 0, - TRFC1MIN_LSB_LEN = 8, + /// + /// @brief Decodes Minimum Write to Read Time - Different Bank Group + /// @param[in] i_target dimm target + /// @param[in] i_data SPD data vector + /// @param[out] o_value tWRT_Smin in MTB units + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode min_twtr_s( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_data, + int64_t& o_value ) + { + uint8_t l_twtr_smin_msn = 0; + uint8_t l_twtr_smin_lsb = 0; - // Byte 31 - TRFC1MIN_MSB_START = 0, - TRFC1MIN_MSB_LEN = 8, + FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_S_MSN, U>(i_target, i_data, l_twtr_smin_msn)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_S_LSB, U>(i_target, i_data, l_twtr_smin_lsb)) ); - // Byte 32 - TRFC2MIN_LSB_START = 0, - TRFC2MIN_LSB_LEN = 8, + { + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_twtr_smin_msn, l_twtr_smin_lsb); - // Byte 33 - TRFC2MIN_MSB_START = 0, - TRFC2MIN_MSB_LEN = 8, + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWTR_S_MIN)); + o_value = l_buffer; - // Byte 34 & Byte 35 - TRFC4MIN_LSB_START = 0, - TRFC4MIN_LSB_LEN = 8, + FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Smin) in MTB units: %d", + spd::c_str(i_target), + o_value); + } - TRFC4MIN_MSB_START = 0, - TRFC4MIN_MSB_LEN = 8, + fapi_try_exit: + return fapi2::current_err; + } + }; - // Byte 36 - TFAWMIN_MSN_START = 4, - TFAWMIN_MSN_LEN = 4, + /// + /// @class proxy - rev::V1_0 specialization + /// @brief Nested class to help specialize certain decoder methods + /// @tparam B dummy var to faciliatate partial specialization + /// @note If the decoder methods are rev::v1_0 hardcode them to these values + /// + template< bool B > + struct proxy<rev::V1_0, B> + { - // Byte 37 - TFAWMIN_LSB_START = 0, - TFAWMIN_LSB_LEN = 8, + /// + /// @brief Decodes Minimum Write Recovery Time + /// @param[in] i_target dimm target + /// @param[in] i_data SPD data vector + /// @param[out] o_value tWRmin in MTB units + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode min_twr( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_data, + int64_t& o_value ) + { + // For General Section rev 1.0 of the SPD, + // SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) were reserved + // and coded as zeros. + // Default as 0x78 for all DDR4 bins for rev 1.0 + o_value = 0x78; + return fapi2::FAPI2_RC_SUCCESS; + } - // Byte 38 - Entire byte used - // Byte 39 - Entire byte used - // Byte 40 - Entire byte used + /// + /// @brief Decodes Minimum Write to Read Time - Same Bank Group + /// @param[in] i_target dimm target + /// @param[in] i_data SPD data vector + /// @param[out] o_value tWRT_Lmin in MTB units + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode min_twtr_l( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_data, + int64_t& o_value ) + { + // For General Section rev 1.0 of the SPD, + // SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) were reserved + // and coded as zeros. + // Default as 0x3C for all DDR4 bins for rev 1.0 + o_value = 0x3C; + return fapi2::FAPI2_RC_SUCCESS; + } - // Byte 41 - TWRMIN_MSN_START = 4, // MSN = most significant nibble - TWRMIN_MSN_LEN = 4, + /// + /// @brief Decodes Minimum Write to Read Time - Different Bank Group + /// @param[in] i_target dimm target + /// @param[in] i_data SPD data vector + /// @param[out] o_value tWRT_Smin in MTB units + /// @return FAPI2_RC_SUCCESS iff okay + /// + static fapi2::ReturnCode min_twtr_s( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_data, + int64_t& o_value ) + { + // For General Section rev 1.0 of the SPD, + // SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) were reserved + // and coded as zeros. + // Default as 0x14 for all DDR4 bins for rev 1.0 + o_value = 0x14; + return fapi2::FAPI2_RC_SUCCESS; + } - // Byte 42 - TWRMIN_LSB_START = 0, // LSB = least significant nibble - TWRMIN_LSB_LEN = 8, + }; - // Byte 43 - TWTRMIN_L_MSN_START = 0, // MSN = most significant nibble - TWTRMIN_L_MSN_LEN = 4, + public: - TWTRMIN_S_MSN_START = 4, // MSN = most significant nibble - TWTRMIN_S_MSN_LEN = 4, + /// + /// @brief default ctor + /// + decoder() = default; - // Byte 44 - TWTRMIN_S_LSB_START = 0, // LSB = least significant byte - TWTRMIN_S_LSB_LEN = 8, + /// + /// @brief ctor + /// @param[in] i_target dimm target + /// @param[in] i_spd_data SPD data vector + /// + decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data): + base_cnfg_decoder(i_target, i_spd_data), + iv_target(i_target), + iv_data(i_spd_data) + { + static_assert( R <= rev::GEN_SEC_MAX, " R > rev::GEN_SEC_MAX"); + } - // Byte 45 - TWTRMIN_L_LSB_START = 0, - TWTRMIN_L_LSB_LEN = 8, + /// + /// @brief Default dtor + /// + virtual ~decoder() = default; - // Bytes 46 - 59 - reserved + ///////////////////////// + // Member Methods + ///////////////////////// - // Bytes 78 - 116 - reserved + /// + /// @brief Gets decoder target + /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM> + /// + virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const + { + return iv_target; + } - // Bytes 117 - 125 : Entire byte used + /// + /// @brief Gets decoder SPD data + /// @return std::vector<uint8_t> + /// + virtual std::vector<uint8_t> get_data() const + { + return iv_data; + } - // Byte 126 - CRC_LSB_START = 0, - CRC_LSB_LEN = 8, + /// + /// @brief Sets decoder SPD data + /// @param[in] i_spd_data SPD data in a vector reference + /// + virtual void set_data(const std::vector<uint8_t>& i_spd_data) + { + iv_data = i_spd_data; + } - // Byte 127 - CRC_MSB_START = 0, - CRC_MSB_LEN = 8, + /// + /// @brief Decodes number of used SPD bytes + /// @param[out] o_value number of SPD bytes used + /// @return FAPI2_RC_SUCCESS iff okay + /// + virtual fapi2::ReturnCode number_of_used_bytes( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BYTES_USED, R>(iv_target, iv_data, o_value)) ); - // Byte 320 - // Skip SPD most signigicant bit, so our 0 - MOD_MFG_LSB_START = 0, - MOD_MFG_LSB_LEN = 8, + fapi_try_exit: + return fapi2::current_err; + } - // Byte 321 - MOD_MFG_MSB_START = 0, - MOD_MFG_MSB_LEN = 8, + /// + /// @brief Decodes total number of SPD bytes + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay + /// + virtual fapi2::ReturnCode number_of_total_bytes( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TOTAL_BYTES, R>(iv_target, iv_data, o_value)) ); - }; + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Helper function that turns Logical ranks in Primary SDRAM type - /// @param[out] o_logical_ranks number of logical ranks - /// @return fapi2::FAPI2_RC_SUCCESS iff okay + /// @brief Decodes SDP revision + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const; - - public: + virtual fapi2::ReturnCode revision( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::REVISION, R>(iv_target, iv_data, o_value)) ); - // First field is byte index - // Second field is the decoding start bit - // Third field is the decoding bit length - static constexpr field_t BYTES_USED{0, BYTES_USED_START, BYTES_USED_LEN}; - static constexpr field_t TOTAL_BYTES_USED{0, BYTES_TOTAL_START, BYTES_TOTAL_LEN}; - static constexpr field_t SDRAM_CAPACITY{4, SDRAM_CAPACITY_START, SDRAM_CAPACITY_LEN}; - static constexpr field_t SDRAM_BANKS{4, SDRAM_BANKS_START, SDRAM_BANKS_LEN}; - static constexpr field_t BANK_GROUP{4, BANK_GROUP_START, BANK_GROUP_LEN}; - static constexpr field_t COL_ADDRESS{5, COL_ADDRESS_START, COL_ADDRESS_LEN}; - static constexpr field_t ROW_ADDRESS{5, ROW_ADDRESS_START, ROW_ADDRESS_LEN}; - static constexpr field_t PRIM_SIGNAL_LOADING{6, PRIM_SIGNAL_LOAD_START, PRIM_SIGNAL_LOAD_LEN}; - static constexpr field_t PRIM_DIE_COUNT{6, PRIM_DIE_COUNT_START, PRIM_DIE_COUNT_LEN}; - static constexpr field_t PRIM_PACKAGE_TYPE{6, PRIM_PACKAGE_TYPE_START, PRIM_PACKAGE_TYPE_LEN}; - static constexpr field_t MAC{7, MAC_START, MAC_LEN}; - static constexpr field_t TMAW{7, TMAW_START, TMAW_LEN}; - static constexpr field_t PPR{9, PPR_START, PPR_LEN}; - static constexpr field_t SOFT_PPR{9, SOFT_PPR_START, SOFT_PPR_LEN}; - static constexpr field_t SEC_SIGNAL_LOADING{10, SEC_SIGNAL_LOAD_START, SEC_SIGNAL_LOAD_LEN}; - static constexpr field_t SEC_DENSITY_RATIO{10, DENSITY_RATIO_START, DENSITY_RATIO_LEN}; - static constexpr field_t SEC_DIE_COUNT{10, SEC_DIE_COUNT_START, SEC_DIE_COUNT_LEN}; - static constexpr field_t SEC_PACKAGE_TYPE{10, SEC_PACKAGE_TYPE_START, SEC_PACKAGE_TYPE_LEN}; - static constexpr field_t OPERABLE_FLD{11, OPERABLE_START, OPERABLE_LEN}; - static constexpr field_t ENDURANT_FLD{11, ENDURANT_START, ENDURANT_LEN}; - static constexpr field_t SDRAM_WIDTH{12, SDRAM_WIDTH_START, SDRAM_WIDTH_LEN}; - static constexpr field_t RANK_MIX{12, RANK_MIX_START, RANK_MIX_LEN}; - static constexpr field_t PACKAGE_RANKS{12, PACKAGE_RANKS_START, PACKAGE_RANKS_LEN}; - static constexpr field_t BUS_WIDTH{13, BUS_WIDTH_START, BUS_WIDTH_LEN}; - static constexpr field_t BUS_EXT_WIDTH{13, BUS_EXT_WIDTH_START, BUS_EXT_WIDTH_LEN}; - static constexpr field_t THERM_SENSOR{14, THERM_SENSOR_START, THERM_SENSOR_LEN}; - static constexpr field_t EXTENDED_MODULE_TYPE{15, EXT_MOD_TYPE_START, EXT_MOD_TYPE_LEN}; - static constexpr field_t FINE_TIMEBASE{17, FINE_TIMEBASE_START, FINE_TIMEBASE_LEN}; - static constexpr field_t MEDIUM_TIMEBASE{17, MED_TIMEBASE_START, MED_TIMEBASE_LEN}; - static constexpr field_t TRASMIN_MSN{27, TRASMIN_MSN_START, TRASMIN_MSN_LEN}; - static constexpr field_t TRASMIN_LSB{28, TRASMIN_LSB_START, TRASMIN_LSB_LEN}; - static constexpr field_t TRCMIN_MSN{27, TRCMIN_MSN_START, TRCMIN_MSN_LEN}; - static constexpr field_t TRCMIN_LSB{29, TRCMIN_LSB_START, TRCMIN_LSB_LEN}; - static constexpr field_t TRFC1MIN_MSB{31, TRFC1MIN_MSB_START, TRFC1MIN_MSB_LEN}; - static constexpr field_t TRFC1MIN_LSB{30, TRFC1MIN_LSB_START, TRFC1MIN_LSB_LEN}; - static constexpr field_t TRFC2MIN_MSB{33, TRFC2MIN_MSB_START, TRFC2MIN_MSB_LEN}; - static constexpr field_t TRFC2MIN_LSB{32, TRFC2MIN_LSB_START, TRFC2MIN_LSB_LEN}; - static constexpr field_t TRFC4MIN_MSB{35, TRFC4MIN_MSB_START, TRFC4MIN_MSB_LEN}; - static constexpr field_t TRFC4MIN_LSB{34, TRFC4MIN_LSB_START, TRFC4MIN_LSB_LEN}; - static constexpr field_t TFAWMIN_MSN{36, TFAWMIN_MSN_START, TFAWMIN_MSN_LEN}; - static constexpr field_t TFAWMIN_LSB{37, TFAWMIN_LSB_START, TFAWMIN_LSB_LEN}; - static constexpr field_t TWRMIN_MSN{41, TWRMIN_MSN_START, TWRMIN_MSN_LEN}; - static constexpr field_t TWRMIN_LSB{42, TWRMIN_LSB_START, TWRMIN_LSB_LEN}; - static constexpr field_t TWTRMIN_S_MSN{43, TWTRMIN_S_MSN_START, TWTRMIN_S_MSN_LEN}; - static constexpr field_t TWTRMIN_S_LSB{44, TWTRMIN_S_LSB_START, TWTRMIN_S_LSB_LEN}; - static constexpr field_t TWTRMIN_L_MSN{43, TWTRMIN_L_MSN_START, TWTRMIN_L_MSN_LEN}; - static constexpr field_t TWTRMIN_L_LSB{45, TWTRMIN_L_LSB_START, TWTRMIN_L_LSB_LEN}; - static constexpr field_t CRC_MSB{127, CRC_MSB_START, CRC_MSB_LEN}; - static constexpr field_t CRC_LSB{126, CRC_LSB_START, CRC_LSB_LEN}; - - // Default constructor deleted - decoder_v1_0() = delete; + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief ctor - /// @param[in] i_target dimm target - /// @param[in] i_spd_data SPD data vector - /// @param[in] i_module_decoder shared_ptr to dimm module decoder - /// @param[in] i_raw_card raw pointer to rcd data + /// @brief Decodes DRAM device type + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data, - const std::shared_ptr<dimm_module_decoder>& i_module_decoder, - const rcw_settings& i_raw_card); + virtual fapi2::ReturnCode device_type( uint8_t& o_value ) const override + { + // Sparsed reserved bits within valid SPD field range + static const std::vector<uint8_t> l_reserved_bits{0x00, 0x0D}; + FAPI_TRY( (mss::spd::reader<fields_t::DEVICE_TYPE, R>(iv_target, iv_data, o_value)) ); + FAPI_TRY( check::reserved_values(iv_target, l_reserved_bits, DEVICE_TYPE, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Default dtor + /// @brief Decodes base module type + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual ~decoder_v1_0() = default; + virtual fapi2::ReturnCode base_module( uint8_t& o_value ) const override + { + // Sparsed reserved bits within valid SPD field range + static const std::vector<uint8_t> l_reserved_bits{0b0111, 0b1010, 0b1011, 0b1110, 0b1111}; + FAPI_TRY( (mss::spd::reader<fields_t::BASE_MODULE, R>(iv_target, iv_data, o_value)) ); + FAPI_TRY( check::reserved_values(iv_target, l_reserved_bits, BASE_MODULE_TYPE, o_value) ); - ///////////////////////// - // Member Methods - ///////////////////////// + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Decodes number of used SPD bytes - /// @param[out] o_value number of SPD bytes used + /// @brief Decodes hybrid media + /// @param[out] o_value number of total SPD bytes /// @return FAPI2_RC_SUCCESS iff okay - /// @note Decodes SPD Byte 0 (3~0) - /// @note Item JC-45-2220.01x - /// @note Page 14 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode number_of_used_bytes( uint16_t& o_value ) const override; + virtual fapi2::ReturnCode hybrid_media( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::HYBRID_MEDIA, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Decodes total number of SPD bytes + /// @brief Decodes hybrid /// @param[out] o_value number of total SPD bytes /// @return FAPI2_RC_SUCCESS iff okay - /// @note Decodes SPD Byte 0 (bits 6~4) - /// @note Item JC-45-2220.01x - /// @note Page 14 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode number_of_total_bytes( uint16_t& o_value ) const override; + virtual fapi2::ReturnCode hybrid( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::HYBRID, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM density from SPD /// @param[out] o_value SDRAM density in GBs /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 4 (bits 3~0) - /// @note Item JC-45-2220.01x - /// @note Page 18 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::SDRAM_CAPACITY, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of SDRAM banks bits from SPD /// @param[out] o_value Number of SDRAM bank bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 4 (bits 5~4) - /// @note Item JC-45-2220.01x - /// @note Page 18 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode bank_bits( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode bank_bits( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BANKS_ADDR_BITS, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of SDRAM bank groups bits from SPD /// @param[out] o_value Number of SDRAM bank groups bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 4 (bits 7~6) - /// @note Item JC-45-2220.01x - /// @note Page 18 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BANK_GROUP_BITS, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of SDRAM column address bits + /// @param[out] o_value Number of SDRAM bank bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 5 (bits 2~0) - /// @note Item JC-45-2220.01x - /// @note Page 18 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::COL_ADDR_BITS, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of SDRAM row address bits + /// @param[out] o_value Number of SDRAM bank bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 5 (bits 5~3) - /// @note Item JC-45-2220.01x - /// @note Page 18 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ROW_ADDR_BITS, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Primary SDRAM signal loading + /// @param[out] o_value Number of SDRAM bank bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 6 (bits 1~0) - /// @note Item JC-45-2220.01x - /// @note Page 19 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::PRIM_SIGNAL_LOADING, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Primary SDRAM die count + /// @param[out] o_value Number of SDRAM bank bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 6 (bits 6~4) - /// @note Item JC-45-2220.01x - /// @note Page 19 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::PRIM_DIE_COUNT, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Primary SDRAM package type /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 6 (bit 7) - /// @note Item JC-45-2220.01x - /// @note Page 19 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::PRIM_PACKAGE_TYPE, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode SDRAM Maximum activate count /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 7 (bits 3~0) - /// @note Item JC-45-2220.01x - /// @note Page 20 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode maximum_activate_count( uint32_t& o_value ) const override; + virtual fapi2::ReturnCode maximum_activate_count( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::MAC, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 7 (bits 3~0) - /// @note Item JC-45-2220.01x - /// @note Page 20 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint32_t& o_value ) const override; + virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TMAW, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Post package repair (PPR) /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 9 (bits 7~6) - /// @note Item JC-45-2220.01x - /// @note Page 21 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::PPR, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Soft post package repair (soft PPR) /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 9 (bit 5) - /// @note Item JC-45-2220.01x - /// @note Page 21 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::SOFT_PPR, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Secondary SDRAM signal loading /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bits 1~0) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::SEC_SIGNAL_LOADING, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Secondary DRAM Density Ratio /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bits 3~2) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::SEC_DENSITY_RATIO, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Secondary SDRAM die count /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bits 6~4) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::SEC_DIE_COUNT, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Secondary SDRAM package type /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bit 7) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::SEC_PACKAGE_TYPE, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Module Nominal Voltage, VDD /// @param[out] o_value enum representing if 1.2V is operable /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 11 (bit 0) - /// @note Item JC-45-2220.01x - /// @note Page 23 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OPERABLE_FLD, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Module Nominal Voltage, VDD /// @param[out] o_value enum representing if 1.2V is endurant /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 11 (bit 1) - /// @note Item JC-45-2220.01x - /// @note Page 23 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ENDURANT_FLD, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes SDRAM device width /// @param[out] o_value device width in bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 12 (bits 2~0) - /// @note Item JC-45-2220.01x - /// @note Page 23 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode device_width( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode device_width( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::SDRAM_WIDTH, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of package ranks per DIMM /// @param[out] o_value number of package ranks per DIMM /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 12 (bits 5~3) - /// @note Item JC-45-2220.01x - /// @note Page 23 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::PACKAGE_RANKS, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Rank Mix /// @param[out] o_value rank mix value from SPD /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 12 (bit 6) - /// @note Item JC-45-2220.01x - /// @note Page 23 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::RANK_MIX, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes primary bus width /// @param[out] o_value primary bus width in bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 13 (bits 2~0) - /// @note Item JC-45-2220.01x - /// @note Page 27 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BUS_WIDTH, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes bus width extension /// @param[out] o_value bus width extension in bits /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 13 (bits 4~3) - /// @note Item JC-45-2220.01x - /// @note Page 27 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BUS_EXT_WIDTH, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Module Thermal Sensor /// @param[out] o_value thermal sensor value from SPD /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 14 (bit 7) - /// @note Item JC-45-2220.01x - /// @note Page 28 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::THERM_SENSOR, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Extended Base Module Type /// @param[out] o_value extended base module type value from SPD /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 15 (bits 3~0) - /// @note Item JC-45-2220.01x - /// @note Page 28 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::EXTENDED_MODULE_TYPE, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Fine Timebase /// @param[out] o_value fine_timebase from SPD in picoseconds /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 17 (bits 1~0) - /// @note Item JC-45-2220.01x - /// @note Page 29 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_timebase( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_timebase( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::FINE_TIMEBASE, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode Medium Timebase /// @param[out] o_value fine_timebase from SPD in picoseconds /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 17 (bits 3~2) - /// @note Item JC-45-2220.01x - /// @note Page 29 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode medium_timebase( int64_t& o_value ) const override; + virtual fapi2::ReturnCode medium_timebase( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::MEDIUM_TIMEBASE, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// /// @brief Decodes SDRAM Minimum Cycle Time in MTB /// @param[out] o_value tCKmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 18 - /// @note Item JC-45-2220.01x - /// @note Page 31-32 - /// @note DDR4 SPD Document Release 3 - /// @warning If tCKmin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tCKmin (SPD byte 125) - /// used for correction to get the actual value. /// - virtual fapi2::ReturnCode min_tck( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_tck( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TCK_MIN, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Maximum Cycle Time in MTB /// @param[out] o_value tCKmax in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 19 - /// @note Item JC-45-2220.01x - /// @note Page 32 - /// @note DDR4 SPD Document Release 3 - /// @warning If tCKmax cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tCKmax (SPD byte 124) - /// used for correction to get the actual value. /// - virtual fapi2::ReturnCode max_tck( int64_t& o_value ) const override; + virtual fapi2::ReturnCode max_tck( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TCK_MAX, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decode CAS Latencies Supported /// @param[out] o_value bitmap of supported CAS latencies /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Bytes 20-23 - /// @note Item JC-45-2220.01x - /// @note Page 33-34 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const override; + virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const override + { + uint8_t l_first_raw_byte = 0; + uint8_t l_sec_raw_byte = 0; + uint8_t l_third_raw_byte = 0; + uint8_t l_fourth_raw_byte = 0; + + FAPI_TRY( (mss::spd::reader<fields_t::CL_FIRST_BYTE, R>(iv_target, iv_data, l_first_raw_byte)) ); + FAPI_TRY( (mss::spd::reader<fields_t::CL_SECOND_BYTE, R>(iv_target, iv_data, l_sec_raw_byte)) ); + FAPI_TRY( (mss::spd::reader<fields_t::CL_THIRD_BYTE, R>(iv_target, iv_data, l_third_raw_byte)) ); + FAPI_TRY( (mss::spd::reader<fields_t::CL_FOURTH_BYTE, R>(iv_target, iv_data, l_fourth_raw_byte)) ); + + { + // Buffers used for bit manipulation + // Combine Bytes to create bitmap - right aligned + fapi2::buffer<uint64_t> l_buffer; + rightAlignedInsert(l_buffer, l_fourth_raw_byte, l_third_raw_byte, l_sec_raw_byte, l_first_raw_byte); + + // According to the JEDEC spec: + // Byte 22 (Bits 7~0) and Byte 23 are reserved and thus not supported + // Check for a valid value + constexpr size_t MAX_VALID_VAL = 0x3FFFF; + FAPI_TRY( check::fail_for_invalid_value(iv_target, + l_buffer <= MAX_VALID_VAL, + 23, + l_buffer, + "Failed check on CAS latencies supported") ); + + // Update output value only if range check passes + o_value = int64_t(l_buffer); + + FAPI_INF("%s. CAS latencies supported (bitmap): 0x%llX", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum CAS Latency Time in MTB /// @param[out] o_value tAAmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 24 - /// @note Item JC-45-2220.01x - /// @note Page 34 - /// @note DDR4 SPD Document Release 3 - /// @warning If tAAmin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tAAmin (SPD byte 123) - /// used for correction to get the actual value. /// - virtual fapi2::ReturnCode min_taa( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_taa( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TAA_MIN, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB /// @param[out] o_value tRCDmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 25 - /// @note Item JC-45-2220.01x - /// @note Page 35 - /// @note DDR4 SPD Document Release 3 - /// @warning If tRCDmin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tRCDmin (SPD byte 122) - /// used for correction to get the actual value /// - virtual fapi2::ReturnCode min_trcd( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trcd( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TRCD_MIN, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB /// @param[out] o_value tRPmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 26 - /// @note Item JC-45-2220.01x - /// @note Page 36-37 - /// @note DDR4 SPD Document Release 3 - /// @warning If tRPmin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tRPmin (SPD byte 121) - /// used for correction to get the actual value /// - virtual fapi2::ReturnCode min_trp( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trp( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TRP_MIN, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB /// @param[out] o_value tRASmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 28 (bits 7~4) & SPD Byte 27 (bits 3~0) - /// @note Item JC-45-2220.01x - /// @note Page 38 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_tras( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_tras( int64_t& o_value ) const override + { + uint8_t l_tRASmin_msn = 0; + uint8_t l_tRASmin_lsb = 0; + FAPI_TRY( (mss::spd::reader<fields_t::TRASMIN_MSN, R>(iv_target, iv_data, l_tRASmin_msn)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TRASMIN_LSB, R>(iv_target, iv_data, l_tRASmin_lsb)) ); + + { + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_tRASmin_msn, l_tRASmin_lsb); + + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TRASMIN)); + o_value = l_buffer; + + FAPI_INF("%s. Minimum Active to Precharge Delay Time (tRASmin) in MTB units: %d", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB /// @param[out] o_value tRCmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 27 (bits 7~4) & SPD Byte 29 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 38 - /// @note DDR4 SPD Document Release 3 - /// @warning If tRCmin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tRCmin (SPD byte 120) - /// used for correction to get the actual value. /// - virtual fapi2::ReturnCode min_trc( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trc( int64_t& o_value ) const override + { + uint8_t l_trcmin_msn = 0; + uint8_t l_trcmin_lsb = 0; + FAPI_TRY( (mss::spd::reader<fields_t::TRCMIN_MSN, R>(iv_target, iv_data, l_trcmin_msn)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TRCMIN_LSB, R>(iv_target, iv_data, l_trcmin_lsb)) ); + + { + // Combining bits to create timing value (in a buffer) + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_trcmin_msn, l_trcmin_lsb); + + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TRCMIN)); + o_value = l_buffer; + + FAPI_INF("%s. Minimum Active to Active/Refresh Delay Time (tRCmin) in MTB units: %d", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1 /// @param[out] o_value tRFC1min in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 30 & Byte 31 - /// @note Item JC-45-2220.01x - /// @note Page 39-40 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_trfc1( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trfc1( int64_t& o_value ) const override + { + uint8_t l_trfc1min_msb = 0; + uint8_t l_trfc1min_lsb = 0; + + FAPI_TRY( (mss::spd::reader<fields_t::TRFC1MIN_MSB, R>(iv_target, iv_data, l_trfc1min_msb)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TRFC1MIN_LSB, R>(iv_target, iv_data, l_trfc1min_lsb)) ); + + { + // Combining bits to create timing value (in a buffer) + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_trfc1min_msb, l_trfc1min_lsb); + + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC1MIN)); + o_value = l_buffer; + + FAPI_INF("%s. Minimum Refresh Recovery Delay Time 1 (tRFC1min) in MTB units: %d", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2 /// @param[out] o_value tRFC2min in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 32 & Byte 33 - /// @note Item JC-45-2220.01x - /// @note Page 40 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_trfc2( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trfc2( int64_t& o_value ) const override + { + uint8_t l_trfc2min_msb = 0; + uint8_t l_trfc2min_lsb = 0; + FAPI_TRY( (mss::spd::reader<fields_t::TRFC2MIN_MSB, R>(iv_target, iv_data, l_trfc2min_msb)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TRFC2MIN_LSB, R>(iv_target, iv_data, l_trfc2min_lsb)) ); + + { + // Combining bits to create timing value (in a buffer) + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_trfc2min_msb, l_trfc2min_lsb); + + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC2MIN)); + o_value = l_buffer; + + FAPI_INF("%s. Minimum Refresh Recovery Delay Time 2 (tRFC2min) in MTB units: %d", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4 /// @param[out] o_value tRFC4min in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 34 & Byte 35 - /// @note Item JC-45-2220.01x - /// @note Page 40 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_trfc4( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trfc4( int64_t& o_value ) const override + { + uint8_t l_trfc4min_msb = 0; + uint8_t l_trfc4min_lsb = 0; + FAPI_TRY( (mss::spd::reader<fields_t::TRFC4MIN_MSB, R>(iv_target, iv_data, l_trfc4min_msb)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TRFC4MIN_LSB, R>(iv_target, iv_data, l_trfc4min_lsb)) ); + + { + // Combining bits to create timing value (in a buffer) + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_trfc4min_msb, l_trfc4min_lsb); + + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC4MIN)); + o_value = l_buffer; + + FAPI_INF("%s. Minimum Refresh Recovery Delay Time 4 (tRFC4min) in MTB units: %d", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes SDRAM Minimum Four Activate Window Delay Time /// @param[out] o_value tFAWmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 36 (bits 3~0) & Byte 37 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 42 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_tfaw( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_tfaw( int64_t& o_value ) const override + { + uint8_t l_tfawmin_msn = 0; + uint8_t l_tfawmin_lsb = 0; + FAPI_TRY( (mss::spd::reader<fields_t::TFAWMIN_MSN, R>(iv_target, iv_data, l_tfawmin_msn)) ); + FAPI_TRY( (mss::spd::reader<fields_t::TFAWMIN_LSB, R>(iv_target, iv_data, l_tfawmin_lsb)) ); + + { + // Combining bits to create timing value (in a buffer) + fapi2::buffer<int64_t> l_buffer; + rightAlignedInsert(l_buffer, l_tfawmin_msn, l_tfawmin_lsb); + + // Update output only after check passes + FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TFAWMIN)); + o_value = l_buffer; + + FAPI_INF("%s. Minimum Four Activate Window Delay Time (tFAWmin) in MTB units: %d", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group /// @param[out] o_value tRRD_Smin MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 38 - /// @note Item JC-45-2220.01x - /// @note Page 43 - /// @note DDR4 SPD Document Release 3 - /// @warning If tRRD_Smin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tRRD_Smin (SPD byte 119) - /// used for correction to get the actual value. /// - virtual fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TRRD_S_MIN, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group /// @param[out] o_value tRRD_Lmin MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 39 - /// @note Item JC-45-2220.01x - /// @note Page 43-44 - /// @note DDR4 SPD Document Release 3 - /// @warning If tRRD_Lmin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tRRD_Lmin (SPD byte 118) - /// used for correction to get the actual value. /// - virtual fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TRRD_L_MIN, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group /// @param[out] o_value tCCD_Lmin MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 40 - /// @note Item JC-45-2220.01x - /// @note Page 44-45 - /// @note DDR4 SPD Document Release 3 - /// @warning If tCCD_Lmin cannot be divided evenly by the MTB, - /// this byte must be rounded up to the next larger - /// integer and the Fine Offset for tCCD_Lmin (SPD byte 117) - /// used for correction to get the actual value. /// - virtual fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::TCCD_L_MIN, R>(iv_target, iv_data, o_value)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Minimum Write Recovery Time /// @param[out] o_value tWRmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 40 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const override + { + FAPI_TRY( proxy<R>::min_twr(iv_target, iv_data, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Minimum Write to Read Time - Different Bank Group /// @param[out] o_value tWRT_Smin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 40 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const override + { + FAPI_TRY( proxy<R>::min_twtr_s(iv_target, iv_data, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes Minimum Write to Read Time - Same Bank Group /// @param[out] o_value tWRT_Lmin in MTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 46 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const override; + virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const override + { + FAPI_TRY( proxy<R>::min_twtr_l(iv_target, iv_data, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Package Rank Map /// @param[out] o_value vector of package rank maps for SPD bytes 60 - 77 /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 60 - 77 - /// @note JEDEC Standard No. 21-C - /// @note Page 45 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode package_rank_map( std::vector<uint8_t>& o_value ) const override; + virtual fapi2::ReturnCode package_rank_map( std::vector<uint8_t>& o_value ) const override + { + o_value.clear(); + + FAPI_TRY( (sdram_connector_helper<DQ0_31, PKG_RANK_MAP>(o_value)), + "%s Failed to sdram_connector_helper for DQ0_31, PKG_RANK_MAP", spd::c_str(iv_target) ); + + FAPI_TRY( (sdram_connector_helper<DQ32_63, PKG_RANK_MAP>(o_value)), + "%s Failed to sdram_connector_helper for DQ32_63, PKG_RANK_MAP", spd::c_str(iv_target) ); + + FAPI_TRY( (sdram_connector_helper<CB0_7, PKG_RANK_MAP>(o_value)), + "%s Failed to sdram_connector_helper for CB0_7, PKG_RANK_MAP", spd::c_str(iv_target) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Nibble Map /// @param[out] o_value vector of nibble map encoding for SPD bytes 60 - 77 /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 60 - 77 - /// @note JEDEC Standard No. 21-C - /// @note Page 45 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode nibble_map( std::vector<uint8_t>& o_value ) const override; + virtual fapi2::ReturnCode nibble_map( std::vector<uint8_t>& o_value ) const override + { + o_value.clear(); + + FAPI_TRY( (sdram_connector_helper<DQ0_31, NIBBLE_MAP>(o_value)), + "%s Failed to sdram_connector_helper for DQ0_31, NIBBLE_MAP", spd::c_str(iv_target) ); + + FAPI_TRY( (sdram_connector_helper<DQ32_63, NIBBLE_MAP>(o_value)), + "%s Failed to sdram_connector_helper for DQ32_63, NIBBLE_MAP", spd::c_str(iv_target) ); + + FAPI_TRY( (sdram_connector_helper<CB0_7, NIBBLE_MAP>(o_value)), + "%s Failed to sdram_connector_helper for CB0_7, NIBBLE_MAP", spd::c_str(iv_target) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for Minimum CAS to CAS Delay Time - Same Bank Group /// @param[out] o_value tCCD_Lmin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 117 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TCCD_L_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group /// @param[out] o_value tRRD_Lmin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 118 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRRD_L_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group /// @param[out] o_value tRRD_Smin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 119 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRRD_S_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time /// @param[out] o_value tRCmin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 120 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRC_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time /// @param[out] o_value tRPmin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 121 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRP_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time /// @param[out] o_value tRCDmin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 122 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRCD_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time /// @param[out] o_value tAAmin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 123 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TAA_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time /// @param[out] o_value tCKmax offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 124 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TCK_MAX, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time /// @param[out] o_value tCKmin offset in FTB units /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 125 - /// @note Item JC-45-2220.01x - /// @note Page 52 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const override; + virtual fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TCK_MIN, R>(iv_target, iv_data, o_value)) ); + o_value = static_cast<int8_t>(o_value); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section /// @param[out] o_value crc value from SPD /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 127 & Byte 126 - /// @note Item JC-45-2220.01x - /// @note Page 53 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const override; + virtual fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const override + { + uint8_t l_crc_msb = 0; + uint8_t l_crc_lsb = 0; + FAPI_TRY( (mss::spd::reader<fields_t::CRC_MSB, R>(iv_target, iv_data, l_crc_msb)) ); + FAPI_TRY( (mss::spd::reader<fields_t::CRC_LSB, R>(iv_target, iv_data, l_crc_lsb)) ); + + { + // Combining bits to create timing value (in a buffer) + fapi2::buffer<uint16_t> l_buffer; + rightAlignedInsert(l_buffer, l_crc_msb, l_crc_lsb); + + // This value isn't bounded in the SPD document + o_value = l_buffer; + + FAPI_INF("%s. Cyclical Redundancy Code (CRC): %d", + spd::c_str(iv_target), + o_value); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes module manufacturer ID code /// @param[out] o_output module manufacturing id code /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 320 (bit 7~0), 321 (6~0) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12 - 54 - /// - virtual fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const override; - /// - /// @brief Decodes Module Manufacturing Location - /// @param[out] o_value uint8_t identifier for manufacturing location of memory module - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 322 - /// @note Item JC-45-2220.01x - /// @note Page 55 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const override; - /// - /// @brief Decodesmodule manufacturing date - /// @param[out] o_output the 2 byte date of manufacturing in BCD format - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 323 & 324 - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12 - 54 - /// @note in Binary Coded Decimal (BCD) - /// @note MSB = year, LSB = week - /// - virtual fapi2::ReturnCode module_manufacturing_date( uint16_t& o_output ) const override; + virtual fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const override + { + uint8_t l_cont_codes = 0; + uint8_t l_last_nonzero_byte = 0; - /// - /// @brief Decodes module's unique serial number - /// @param[out] o_output - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 325-328 - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12 - 54 - /// - virtual fapi2::ReturnCode module_serial_number( uint32_t& o_output ) const override; + FAPI_TRY( (mss::spd::reader<fields_t::CONTINUATION_CODES, R>(iv_target, iv_data, l_cont_codes)) ); + FAPI_TRY( (mss::spd::reader<fields_t::LAST_NON_ZERO_BYTE, R>(iv_target, iv_data, l_last_nonzero_byte)) ); - /// - /// @brief Decodes Module Revision Code - /// @param[out] o_value uint8_t identifier for revision code - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 349 - /// @note Item JC-45-2220.01x - /// @note Page 55 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const override; + { + fapi2::buffer<uint16_t> l_buffer; + rightAlignedInsert(l_buffer, l_last_nonzero_byte, l_cont_codes); - /// - /// @brief Decodes DRAM Manufacturer ID code - /// @param[out] o_output dram manufacturing id code - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 350 - 351 - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12 - 54 - /// - virtual fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_output ) const override; + o_value = l_buffer; - /// - /// @brief Decodes RCD Manufacturer ID code - /// @param[out] o_value rcd manufacturing id code - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 133 134 - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12 - 54 - /// - virtual fapi2::ReturnCode reg_manufacturer_id_code( uint16_t& o_value ) const override; + FAPI_INF("%s.Module Manufacturer ID Code: %x", + spd::c_str(iv_target), + o_value); + } - /// - /// @brief Decodes Register Revision Number - /// @param[out] o_value register revision number - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 135 - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12 - 54 - /// - virtual fapi2::ReturnCode register_rev_num( uint8_t& o_value ) const override; + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Decodes DRAM Stepping - /// @param[out] o_value uint8_t DRAM Stepping val + /// @brief Decodes Module Manufacturing Location + /// @param[out] o_value uint8_t identifier for manufacturing location of memory module /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 352 - /// @note Item JC-45-2220.01x - /// @note Page 56 - /// @note DDR4 SPD Document Release 3 - /// @note also called die revision level - /// - virtual fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const override; - - /// - /// @brief Returns Logical ranks per DIMM - /// @param[out] o_logical_ranks number of logical ranks - /// @return fapi2::FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const override; + virtual fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_MFG_LOCATION, R>(iv_target, iv_data, o_value)) ); - private: + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief SPD byte field threshold check - /// @param[out] o_value list of connector_field values from SPD + /// @brief Decodesmodule manufacturing date + /// @param[out] o_value the 2 byte date of manufacturing in BCD format /// @return FAPI2_RC_SUCCESS iff okay - /// - template< mss::connector_bits T, mss::connector_field OT, typename TT = mss::connectorTraits<T, OT> > - fapi2::ReturnCode sdram_connector_helper( std::vector<uint8_t>& o_value ) const + virtual fapi2::ReturnCode module_manufacturing_date( uint16_t& o_value ) const override { - for( size_t byte = TT::START; byte <= TT::END; ++byte ) - { - uint8_t l_field = 0; + uint8_t l_date_msb = 0; + uint8_t l_date_lsb = 0; - fapi2::buffer<uint8_t> l_buffer(iv_spd_data[byte]); - l_buffer.extractToRight<TT::EXTRACT_START, TT::EXTRACT_LEN>(l_field); + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_MFG_DATE_MSB, R>(iv_target, iv_data, l_date_msb)) ); + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_MFG_DATE_LSB, R>(iv_target, iv_data, l_date_lsb)) ); - FAPI_DBG("%s SPD byte %d, data: %d, field value: %d, starting bit: %d, bit length: %d", - iv_target_str_storage, byte, iv_spd_data[byte], l_field, TT::EXTRACT_START, TT::EXTRACT_LEN); + { + fapi2::buffer<uint16_t> l_buffer; + rightAlignedInsert(l_buffer, l_date_msb, l_date_lsb); - FAPI_TRY( TT::fail_check(iv_target, byte, l_field) ); + o_value = l_buffer; - o_value.push_back(l_field); + FAPI_INF("%s.Module Manufacturer ID date: %x", + spd::c_str(iv_target), + o_value); } fapi_try_exit: return fapi2::current_err; } -};// decoder - -/// -/// @class decoder_v1_1 -/// @brief Base SPD DRAM decoder, 1st addition to general section -/// -class decoder_v1_1 : public decoder_v1_0 -{ - protected: - - /// - /// @brief Helper functions that returns Logical ranks in Secondary SDRAM type - /// @param[out] o_logical_ranks number of logical ranks - /// @return fapi2::FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const; - - public: - /// - /// @brief Default constructor + /// @brief Decodes module's unique serial number + /// @param[out] o_value module's serial number + /// @return FAPI2_RC_SUCCESS iff okay /// - decoder_v1_1() = default; + virtual fapi2::ReturnCode module_serial_number( uint32_t& o_value ) const override + { + uint8_t l_sn_byte_0 = 0; + uint8_t l_sn_byte_1 = 0; + uint8_t l_sn_byte_2 = 0; + uint8_t l_sn_byte_3 = 0; - /// - /// @brief ctor - /// @param[in] i_target dimm target - /// @param[in] i_spd_data SPD data vector - /// @param[in] i_module_decoder shared_ptr to dimm module decoder - /// @param[in] i_raw_card raw pointer to rcd data - /// - decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data, - const std::shared_ptr<dimm_module_decoder>& i_module_decoder, - const rcw_settings& i_raw_card); + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE1, R>(iv_target, iv_data, l_sn_byte_0)) ); + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE2, R>(iv_target, iv_data, l_sn_byte_1)) ); + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE3, R>(iv_target, iv_data, l_sn_byte_2)) ); + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE4, R>(iv_target, iv_data, l_sn_byte_3)) ); - /// - /// @brief Default dtor - /// - virtual ~decoder_v1_1() = default; + { + fapi2::buffer<uint32_t> l_buffer; + rightAlignedInsert(l_buffer, l_sn_byte_3, l_sn_byte_2, l_sn_byte_1, l_sn_byte_0); - ///////////////////////// - // Member Methods - ///////////////////////// + o_value = l_buffer; - /// - /// @brief Decodes SDRAM density from SPD - /// @param[out] o_value SDRAM density in GBs - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 4 (bits 3~0) - /// @note Item JC-45-2220.01x - /// @note Page 18 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const override; - - /// - /// @brief Decode Soft post package repair (soft PPR) - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 9 (bit 5) - /// @note Item JC-45-2220.01x - /// @note Page 21 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const override; + FAPI_INF("%s.Module Serial Number : 0x%08x", + spd::c_str(iv_target), + o_value); + } - /// - /// @brief Decodes Secondary SDRAM signal loading - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bits 1~0) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const override; + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Decodes Secondary DRAM Density Ratio + /// @brief Decodes Module Revision Code + /// @param[out] o_value uint8_t identifier for revision code /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bits 3~2) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_REV_CODE, R>(iv_target, iv_data, o_value)) ); - /// - /// @brief Decodes Secondary SDRAM die count - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bits 6~4) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const override; + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Decodes Secondary SDRAM package type + /// @brief Decodes DRAM Manufacturer ID code + /// @param[out] o_value dram manufacturing id code /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 10 (bit 7) - /// @note Item JC-45-2220.01x - /// @note Page 22 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const override; + virtual fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const override + { + uint8_t l_mfgid_msb = 0; + uint8_t l_mfgid_lsb = 0; - /// - /// @brief Decodes number of package ranks per DIMM - /// @param[out] o_value number of package ranks per DIMM - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 12 (bits 5~3) - /// @note Item JC-45-2220.01x - /// @note Page 23 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const override; + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_MFR_ID_CODE_LSB, R>(iv_target, iv_data, l_mfgid_lsb)) ); + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_MFR_ID_CODE_MSB, R>(iv_target, iv_data, l_mfgid_msb)) ); - /// - /// @brief Decodes Rank Mix - /// @param[out] o_value rank mix value from SPD - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 12 (bit 6) - /// @note Item JC-45-2220.01x - /// @note Page 23 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const override; + { + fapi2::buffer<uint16_t> l_buffer; + rightAlignedInsert(l_buffer, l_mfgid_msb, l_mfgid_lsb); - /// - /// @brief Decode CAS Latencies Supported - /// @param[out] o_value bitmap of supported CAS latencies - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Bytes 20-23 - /// @note Item JC-45-2220.01x - /// @note Page 33-34 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value) const override; + o_value = l_buffer; - /// - /// @brief Decodes Minimum Write Recovery Time - /// @param[out] o_value tWRmin in MTB units - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 40 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const override; + FAPI_INF("%s.DRAM Manufacturer ID Code: %x", + spd::c_str(iv_target), + o_value); + } - /// - /// @brief Decodes Minimum Write to Read Time - Different Bank Group - /// @param[out] o_value tWRT_Smin in MTB units - /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 40 - /// @note DDR4 SPD Document Release 3 - /// - virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const override; + fapi_try_exit: + return fapi2::current_err; + } /// - /// @brief Decodes Minimum Write to Read Time - Same Bank Group - /// @param[out] o_value tWRT_Lmin in MTB units + /// @brief Decodes DRAM Stepping + /// @param[out] o_value uint8_t DRAM Stepping val /// @return FAPI2_RC_SUCCESS iff okay - /// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) - /// @note Item JC-45-2220.01x - /// @note Page 46 - /// @note DDR4 SPD Document Release 3 /// - virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const override; + virtual fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_STEPPING, R>(iv_target, iv_data, o_value)) ); - /// - /// @brief Returns Logical ranks per DIMM - /// @param[out] o_logical_ranks number of logical ranks - /// @return fapi2::FAPI2_RC_SUCCESS iff okay - /// - virtual fapi2::ReturnCode logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const override; + fapi_try_exit: + return fapi2::current_err; + } -};// spd_decoder_v1_1 +};// decoder -}// ddr4 }// spd }// mss diff --git a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C deleted file mode 100644 index fa47e5384..000000000 --- a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C +++ /dev/null @@ -1,3021 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -/// -/// @file spd_decoder.C -/// @brief SPD decoder definitions -/// -// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -// std lib -#include <map> -#include <vector> - -// fapi2 -#include <fapi2.H> - -// mss lib -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> -#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H> -#include <generic/memory/lib/spd/common/rcw_settings.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/find.H> -#include <generic/memory/lib/utils/mss_math.H> - -using fapi2::TARGET_TYPE_MCA; -using fapi2::TARGET_TYPE_MCS; -using fapi2::TARGET_TYPE_DIMM; - -namespace mss -{ -namespace spd -{ -namespace ddr4 -{ - -///////////////////////// -// Member Method implementation -///////////////////////// - -/// -/// @brief ctor -/// @param[in] i_target dimm target -/// @param[in] i_spd_data SPD data vector -/// @param[in] i_module_decoder shared_ptr to dimm module decoder -/// @param[in] i_raw_card raw card data structure -/// -decoder_v1_0::decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data, - const std::shared_ptr<dimm_module_decoder>& i_module_decoder, - const rcw_settings& i_raw_card) - : decoder(i_target, i_spd_data, i_module_decoder, i_raw_card) -{} - -/// -/// @brief Decodes number of used SPD bytes -/// @param[out] o_value number of SPD bytes used -/// @return FAPI2_RC_SUCCESS iff okay -/// @note Decodes SPD Byte 0 bits(0~3) -/// @note Item JC-45-2220.01x -/// @note Page 14 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::number_of_used_bytes( uint16_t& o_value ) const -{ - // ========================================================= - // Byte 0 maps - // Item JC-45-2220.01x - // Page 14 - // DDR4 SPD Document Release 3 - // Byte 0 (0x000): Number of Bytes Used / Number of Bytes in SPD Device - // ========================================================= - static const std::vector<std::pair<uint8_t, uint16_t> > BYTES_USED_MAP = - { - //{key byte, number of used bytes} - {1, 128}, - {2, 256}, - {3, 384}, - {4, 512} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< BYTES_USED >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(BYTES_USED_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - BYTES_USED.iv_byte, - l_field_bits, - "Failed check on SPD used bytes") ); - - FAPI_INF("%s. Bytes Used: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes total number of SPD bytes -/// @param[out] o_value number of total SPD bytes -/// @return FAPI2_RC_SUCCESS iff okay -/// @note Decodes SPD Byte 0 (bits 4~6) -/// @note Item JC-45-2220.01x -/// @note Page 14 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::number_of_total_bytes( uint16_t& o_value ) const -{ - - // ========================================================= - // Byte 0 maps - // Item JC-45-2220.01x - // Page 14 - // DDR4 SPD Document Release 3 - // Byte 0 (0x000): Number of Bytes Used / Number of Bytes in SPD Device - // ========================================================= - static const std::vector<std::pair<uint8_t, uint16_t> > BYTES_TOTAL_MAP = - { - //{key byte, number of total bytes} - {1, 256}, - {2, 512} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< TOTAL_BYTES_USED >(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(BYTES_TOTAL_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - TOTAL_BYTES_USED.iv_byte, - l_field_bits, - "Failed check on SPD total bytes") ); - - FAPI_INF("%s. Total Bytes: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM density from SPD -/// @param[out] o_value SDRAM density in GBs -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 4 (bits 0~3) -/// @note Item JC-45-2220.01x -/// @note Page 18 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::sdram_density( uint8_t& o_value) const -{ - // ========================================================= - // Byte 4 maps - // Item JC-45-2220.01x - // Page 18 - // DDR4 SPD Document Release 3 - // Byte 4 (0x004): SDRAM Density and Banks - // ========================================================= - static const std::vector< std::pair<uint8_t, uint8_t> > SDRAM_DENSITY_MAP = - { - // {key byte, capacity in GBs} - {2, 1}, - {3, 2}, - {4, 4}, - {5, 8}, - {6, 16}, - {7, 32}, - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SDRAM_CAPACITY >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check to assure SPD DRAM capacity (map) wont be at invalid values - const bool l_is_val_found = mss::find_value_from_key(SDRAM_DENSITY_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - SDRAM_CAPACITY.iv_byte, - l_field_bits, - "Failed check for SPD DRAM capacity") ); - - FAPI_INF("%s. SDRAM density: %d Gb", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes number of SDRAM bank_bits from SPD -/// @param[out] o_value Number of SDRAM bank bits -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 4 (bits 5~4) -/// @note Item JC-45-2220.01x -/// @note Page 18 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::bank_bits( uint8_t& o_value) const - -{ - // ========================================================= - // Byte 4 maps - // Item JC-45-2220.01x - // Page 18 - // DDR4 SPD Document Release 3 - // Byte 4 (0x004): SDRAM Density and Banks - // ========================================================= - static const std::vector< std::pair<uint8_t, uint8_t> > BANK_ADDR_BITS_MAP = - { - // {key byte, number of bank address bits} - {0, 2}, - {1, 3} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SDRAM_BANKS >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check to assure SPD DRAM capacity (map) wont be at invalid values - const bool l_is_val_found = mss::find_value_from_key(BANK_ADDR_BITS_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - SDRAM_BANKS.iv_byte, - l_field_bits, - "Failed check for SPD DRAM banks") ); - - FAPI_INF("%s. Number of banks address bits: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes number of SDRAM bank group bits from SPD -/// @param[out] o_value Number of SDRAM bank group bits -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 4 (bits 6~7) -/// @note Item JC-45-2220.01x -/// @note Page 18 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::bank_group_bits( uint8_t& o_value) const -{ - // ========================================================= - // Byte 4 maps - // Item JC-45-2220.01x - // Page 18 - // DDR4 SPD Document Release 3 - // Byte 4 (0x004): SDRAM Density and Banks - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > BANK_GROUP_BITS_MAP = - { - // {key byte, number of bank groups bits} - {0, 0}, - {1, 1}, - {2, 2} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< BANK_GROUP >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check to assure SPD DRAM capacity (map) wont be at invalid values - const bool l_is_val_found = mss::find_value_from_key(BANK_GROUP_BITS_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - BANK_GROUP.iv_byte, - l_field_bits, - "Failed check for SPD DRAM bank groups") ); - - FAPI_INF("%s. Number of bank group bits: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes number of SDRAM column address bits -/// @param[out] o_value number of column address bits -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 5 (bits 2~0) -/// @note Item JC-45-2220.01x -/// @note Page 18 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::column_address_bits( uint8_t& o_value) const -{ - // ========================================================= - // Byte 5 maps - // Item JC-45-2220.01x - // Page 18 - // DDR4 SPD Document Release 3 - // Byte 5 (0x005): SDRAM Addressing - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > COLUMN_ADDRESS_BITS_MAP = - { - //{key byte,col address bits} - {0, 9}, - {1, 10}, - {2, 11}, - {3, 12} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< COL_ADDRESS >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check to assure SPD DRAM capacity (map) wont be at invalid values - const bool l_is_val_found = mss::find_value_from_key(COLUMN_ADDRESS_BITS_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - COL_ADDRESS.iv_byte, - l_field_bits, - "Failed check for SDRAM Column Address Bits") ); - - FAPI_INF("%s. Number of Column Address Bits: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes number of SDRAM row address bits -/// @param[out] o_value number of row address bits -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 5 (bits 5~3) -/// @note Item JC-45-2220.01x -/// @note Page 18 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::row_address_bits( uint8_t& o_value) const -{ - // ========================================================= - // Byte 5 maps - // Item JC-45-2220.01x - // Page 18 - // DDR4 SPD Document Release 3 - // Byte 5 (0x005): SDRAM Addressing - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > ROW_ADDRESS_BITS_MAP = - { - //{key byte,row address bits} - {0, 12}, - {1, 13}, - {2, 14}, - {3, 15}, - {4, 16}, - {5, 17}, - {6, 18} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< ROW_ADDRESS >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check to assure SPD DRAM capacity (map) wont be at invalid values - const bool l_is_val_found = mss::find_value_from_key(ROW_ADDRESS_BITS_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target, - l_is_val_found, - ROW_ADDRESS.iv_byte, - l_field_bits, - "Failed check for SDRAM Row Address Bits") ); - - FAPI_INF("%s. Number of Row Address Bits: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes Primary SDRAM signal loading -/// @param[out] o_value enum representing signal loading type -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 6 (bits 1~0) -/// @note Item JC-45-2220.01x -/// @note Page 19 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::prim_sdram_signal_loading( uint8_t& o_value) const -{ - // ========================================================= - // Byte 6 maps - // Item JC-45-2220.01x - // Page 19 - // DDR4 SPD Document Release 3 - // Byte 6 (0x006): Primary SDRAM Package Type - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_SIGNAL_LOADING_MAP = - { - // {key byte, signal loading} - {0, fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP}, - {1, fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_DDP_QDP}, - {2, fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< PRIM_SIGNAL_LOADING >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(PRIM_SIGNAL_LOADING_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target, - l_is_val_found, - PRIM_SIGNAL_LOADING.iv_byte, - l_field_bits, - "Failed check for Primary SDRAM Signal Loading") ); - - FAPI_INF("%s. Primary SDRAM Signal Loading: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Primary SDRAM die count -/// @param[out] o_value die count -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 6 (bits 6~4) -/// @note Item JC-45-2220.01x -/// @note Page 19 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::prim_sdram_die_count( uint8_t& o_value) const -{ - // ========================================================= - // Byte 6 maps - // Item JC-45-2220.01x - // Page 19 - // DDR4 SPD Document Release 3 - // Byte 6 (0x006): Primary SDRAM Package Type - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_DIE_COUNT_MAP = - { - // {key byte, number of die} - {0, 1}, - {1, 2}, - {2, 3}, - {3, 4}, - {4, 5}, - {5, 6}, - {6, 7}, - {7, 8} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< PRIM_DIE_COUNT >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(PRIM_DIE_COUNT_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target, - l_is_val_found, - PRIM_DIE_COUNT.iv_byte, - l_field_bits, - "Failed check for SDRAM Row Address Bits") ); - - FAPI_INF("%s. Number of Row Address Bits: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Primary SDRAM package type -/// @param[out] o_value enum representing package type -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 6 (bit 7) -/// @note Item JC-45-2220.01x -/// @note Page 19 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::prim_sdram_package_type( uint8_t& o_value) const -{ - // ========================================================= - // Byte 6 maps - // Item JC-45-2220.01x - // Page 19 - // DDR4 SPD Document Release 3 - // Byte 6 (0x006): Primary SDRAM Package Type - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_PACKAGE_TYPE_MAP = - { - // {key byte, value} - {0, MONOLITHIC}, - {1, NON_MONOLITHIC} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< PRIM_PACKAGE_TYPE >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(PRIM_PACKAGE_TYPE_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - PRIM_PACKAGE_TYPE.iv_byte, - l_field_bits, - "Failed check for Primary SDRAM package type") ); - - FAPI_INF("%s. Primary SDRAM package type: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decode SDRAM Maximum activate count -/// @param[out] o_value enum representing max activate count -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 7 (bits 3~0) -/// @note Item JC-45-2220.01x -/// @note Page 20 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::maximum_activate_count( uint32_t& o_value ) const -{ - // ========================================================= - // Byte 7 maps - // Item JC-45-2220.01x - // Page 20 - // DDR4 SPD Document Release 3 - // Byte 7 (0x007): SDRAM Optional Features - // ========================================================= - static const std::vector<std::pair<uint8_t, uint32_t> > MAC_MAP = - { - // {key byte, maximum activate count} - {0, fapi2::ENUM_ATTR_EFF_DRAM_MAC_UNTESTED}, - {1, fapi2::ENUM_ATTR_EFF_DRAM_MAC_700K}, - {2, fapi2::ENUM_ATTR_EFF_DRAM_MAC_600K}, - {3, fapi2::ENUM_ATTR_EFF_DRAM_MAC_500K}, - {4, fapi2::ENUM_ATTR_EFF_DRAM_MAC_400K}, - {5, fapi2::ENUM_ATTR_EFF_DRAM_MAC_300K}, - {6, fapi2::ENUM_ATTR_EFF_DRAM_MAC_200K}, - {8, fapi2::ENUM_ATTR_EFF_DRAM_MAC_UNLIMITED} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< MAC >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(MAC_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - MAC.iv_byte, - l_field_bits, - "Failed check for SDRAM Maximum Active Count (MAC)") ); - - FAPI_INF("%s. Maximum Active Count (MAC): %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point -/// @param[out] o_value max activate window multiplier -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 7 (bits 3~0) -/// @note Item JC-45-2220.01x -/// @note Page 20 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::maximum_activate_window_multiplier( uint32_t& o_value ) const -{ - // ========================================================= - // Byte 7 maps - // Item JC-45-2220.01x - // Page 20 - // DDR4 SPD Document Release 3 - // Byte 7 (0x007): SDRAM Optional Features - // ========================================================= - // Multiplier with tREFI is not taken into account here - static const std::vector<std::pair<uint8_t, uint32_t> > TMAW_MAP = - { - // {key byte, tMAW multiplier} - {0, 8192}, - {1, 4096}, - {2, 2048} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< TMAW >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(TMAW_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - TMAW.iv_byte, - l_field_bits, - "Failed check for Maximum Active Window (tMAW)") ); - - FAPI_INF("%s. Maximum Active Window multiplier: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decode Post package repair (PPR) -/// @param[out] o_value enum representing if (hard) PPR is supported -/// @return fapi2::ReturnCode -/// @note SPD Byte 9 (bits 7~6) -/// @note Item JC-45-2220.01x -/// @note Page 21 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::post_package_repair( uint8_t& o_value) const -{ - // ========================================================= - // Byte 9 maps - // Item JC-45-2220.01x - // Page 21 - // DDR4 SPD Document Release 3 - // Byte 9 (0x009): Other SDRAM Optional Features - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > PPR_MAP = - { - // {key byte, value } - {0, fapi2::ENUM_ATTR_EFF_DRAM_PPR_NOT_SUPPORTED}, - {1, fapi2::ENUM_ATTR_EFF_DRAM_PPR_SUPPORTED} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< PPR >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(PPR_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - PPR.iv_byte, - l_field_bits, - "Failed check for PPR") ); - - FAPI_INF("%s. Post Package Repair (PPR): %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Secondary SDRAM signal loading -/// @param[out] o_value enum representing signal loading type -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 10 (bits 1~0) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::sec_sdram_signal_loading( uint8_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 10 (bits 1~0) were reserved - // and coded as zeros. There was no concept of - // secondary SDRAM signal loading so this - // is thus hard-wired to zero. - o_value = 0x00; - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decode Soft post package repair (soft PPR) -/// @param[out] o_value enum representing if soft PPR is supported -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 9 (bit 5) -/// @note Item JC-45-2220.01x -/// @note Page 21 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::soft_post_package_repair( uint8_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 9 (bit 5) was reserved - // and coded as zeros. There was no concept of soft PPR so this - // is thus hard-wired to zero. - o_value = 0x00; - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes Secondary DRAM Density Ratio -/// @param[out] o_value raw bits from SPD -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 10 (bits 3~2) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::sec_dram_density_ratio( uint8_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 10 (bits 3~2) were reserved - // and coded as zeros. There was no concept of - // secondary SDRAM density ratio so this - // is thus hard-wired to zero. - o_value = 0x00; - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes Secondary SDRAM die count -/// @param[out] o_value die count -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 10 (bits 6~4) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::sec_sdram_die_count( uint8_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 10 (bits 6~4) were reserved - // and coded as zeros. There was no concept of - // secondary SDRAM hybrid media so this - // is thus hard-wired to zero. - o_value = 0x00; - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes Secondary SDRAM package type -/// @param[out] o_value enum representing package type -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 10 (bit 7) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::sec_sdram_package_type( uint8_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 10 (bit 7) was reserved - // and coded as zeros. There was no concept of - // secondary SDRAM package type so this - // is thus hard-wired to zero. - o_value = 0x00; - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decode Module Nominal Voltage, VDD -/// @param[out] o_value enum representing if 1.2V is operable -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 11 (bit 0) -/// @note Item JC-45-2220.01x -/// @note Page 23 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::operable_nominal_voltage( uint8_t& o_value) const -{ - // ========================================================= - // Byte 11 maps - // Item JC-45-2220.01x - // Page 22-23 - // DDR4 SPD Document Release 3 - // Byte 11 (0x00B): Modle Nominal Voltage - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > OPERABLE_MAP = - { - // {key byte, value } - {0, NOT_OPERABLE }, - {1, OPERABLE} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< OPERABLE_FLD >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(OPERABLE_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - OPERABLE_FLD.iv_byte, - l_field_bits, - "Failed check for Operable nominal voltage") ); - - FAPI_INF("%s. Operable: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decode Module Nominal Voltage, VDD -/// @param[out] o_value enum representing if 1.2V is endurant -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 11 (bit 1) -/// @note Item JC-45-2220.01x -/// @note Page 23 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::endurant_nominal_voltage( uint8_t& o_value) const -{ - // ========================================================= - // Byte 11 maps - // Item JC-45-2220.01x - // Page 22-23 - // DDR4 SPD Document Release 3 - // Byte 11 (0x00B): Modle Nominal Voltage - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > ENDURANT_MAP = - { - // {key byte, value } - {0, NOT_ENDURANT}, - {1, ENDURANT} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< ENDURANT_FLD >(iv_target, iv_spd_data); - - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(ENDURANT_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - ENDURANT_FLD.iv_byte, - l_field_bits, - "Failed check for Endurant nominal voltage") ); - - FAPI_INF("%s. Endurant: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM device width -/// @param[out] o_value device width in bits -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 12 (bits 2~0) -/// @note Item JC-45-2220.01x -/// @note Page 23 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::device_width( uint8_t& o_value) const -{ - // ========================================================= - // Byte 12 maps - // Item JC-45-2220.01x - // Page 23 - // DDR4 SPD Document Release 3 - // Byte 12 (0x00C): Module Organization - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > DEVICE_WIDTH_MAP = - { - // {key byte, device width (bits)} - {0, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4}, - {1, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8}, - {2, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16}, - {3, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X32}, - // All others reserved - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SDRAM_WIDTH >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(DEVICE_WIDTH_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - SDRAM_WIDTH.iv_byte, - l_field_bits, - "Failed check for Device Width") ); - - FAPI_INF("%s. Device Width: %d bits", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes number of package ranks per DIMM -/// @param[out] o_value number of package ranks per DIMM -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 12 (bits 5~3) -/// @note Item JC-45-2220.01x -/// @note Page 23 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::num_package_ranks_per_dimm( uint8_t& o_value) const -{ - // ========================================================= - // Byte 12 maps - // Item JC-45-2220.01x - // Page 23 - // DDR4 SPD Document Release 3 - // Byte 12 (0x00C): Module Organization - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP = - { - // {key byte, num of package ranks per DIMM (package ranks)} - {0, 1}, - {1, 2}, - {2, 3}, - {3, 4}, - {4, 5}, - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< PACKAGE_RANKS >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(NUM_PACKAGE_RANKS_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - PACKAGE_RANKS.iv_byte, - l_field_bits, - "Failed check for Num Package Ranks Per DIMM") ); - - FAPI_INF("%s. Num Package Ranks per DIMM: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Rank Mix -/// @param[out] o_value rank mix value from SPD -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 12 (bit 6) -/// @note Item JC-45-2220.01x -/// @note Page 23 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::rank_mix( uint8_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // Decodes SPD Byte 3 (bits 4~6) were reserved - // and coded as zeros. There was no concept of rank_mix so this - // is thus hard-wired to zero. - o_value = 0x00; - return fapi2::FAPI2_RC_SUCCESS; - -} - -/// -/// @brief Decodes primary bus width -/// @param[out] o_value primary bus width in bits -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 13 (bits 2~0) -/// @note Item JC-45-2220.01x -/// @note Page 27 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::prim_bus_width( uint8_t& o_value) const -{ - // ========================================================= - // Byte 13 maps - // Item JC-45-2220.01x - // Page 27 - // DDR4 SPD Document Release 3 - // Byte 13 (0x00D): Module Memory Bus Width - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > BUS_WIDTH_MAP = - { - // {key byte, bus width (in bits) - {0, 8}, - {1, 16}, - {2, 32}, - {3, 64} - // All others reserved - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< BUS_WIDTH >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(BUS_WIDTH_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - BUS_WIDTH.iv_byte, - l_field_bits, - "Failed check for Primary Bus Width") ); - - FAPI_INF("%s. Primary Bus Width: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes bus width extension -/// @param[out] o_value bus width extension in bits -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 13 (bits 2~0) -/// @note Item JC-45-2220.01x -/// @note Page 28 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::bus_width_extension( uint8_t& o_value) const -{ - // ========================================================= - // Byte 13 maps - // Item JC-45-2220.01x - // Page 27 - // DDR4 SPD Document Release 3 - // Byte 13 (0x00D): Module Memory Bus Width - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > BUS_WIDTH_EXT_MAP = - { - {0, 0}, - {1, 8} - // All others reserved - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< BUS_EXT_WIDTH >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(BUS_WIDTH_EXT_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - BUS_EXT_WIDTH.iv_byte, - l_field_bits, - "Failed check for Bus Width Extension") ); - - FAPI_INF("%s. Bus Width Extension (bits): %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decode Module Thermal Sensor -/// @param[out] o_value thermal sensor value from SPD -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 14 (bit 7) -/// @note Item JC-45-2220.01x -/// @note Page 28 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::thermal_sensor( uint8_t& o_value) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< THERM_SENSOR >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check for valid value - constexpr size_t INVALID_VALUE = 2; // single bit value 0 or 1 - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < INVALID_VALUE, - THERM_SENSOR.iv_byte, - l_field_bits, - "Failed check for Thermal Sensor") ); - - // Update output after check passes - o_value = l_field_bits; - - FAPI_INF("%s. Thermal Sensor: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decode Extended Base Module Type -/// @param[out] o_value raw data from SPD -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 15 (bits 3~0) -/// @note Item JC-45-2220.01x -/// @note Page 28 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::extended_base_module_type( uint8_t& o_value) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< EXTENDED_MODULE_TYPE >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check for valid value - // Currently reserved to 0b000 - constexpr size_t RESERVED = 0; - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits == RESERVED, - EXTENDED_MODULE_TYPE.iv_byte, - l_field_bits, - "Failed check for Extended Base Module Type") ); - - // Update output for check passes - o_value = l_field_bits; - - FAPI_INF("%s. Extended Base Module Type: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decode Fine Timebase -/// @param[out] o_value fine_timebase from SPD in picoseconds -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 17 (bits 1~0) -/// @note Item JC-45-2220.01x -/// @note Page 29 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_timebase( int64_t& o_value) const -{ - // ========================================================= - // Byte 17 maps - // Item JC-45-2220.01x - // Page 29 - // DDR4 SPD Document Release 3 - // Byte 17 (0x011): Timebases - // ========================================================= - // Created a maps of a single value in case mapping expands to more values - static const std::vector<std::pair<uint8_t, int64_t> > FINE_TIMEBASE_MAP = - { - // {key byte, fine timebase (in picoseconds) - {0, 1} - // All others reserved - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< FINE_TIMEBASE >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(FINE_TIMEBASE_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - FINE_TIMEBASE.iv_byte, - l_field_bits, - "Failed check for Fine Timebase") ); - - FAPI_INF("%s. Fine Timebase: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decode Medium Timebase -/// @param[out] o_value medium timebase from SPD in picoseconds -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 17 (bits 3~2) -/// @note Item JC-45-2220.01x -/// @note Page 29 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::medium_timebase( int64_t& o_value) const -{ - // ========================================================= - // Byte 17 maps - // Item JC-45-2220.01x - // Page 29 - // DDR4 SPD Document Release 3 - // Byte 17 (0x011): Timebases - // ========================================================= - // Created a maps of a single value in case mapping expands to more values - static const std::vector<std::pair<uint8_t, int64_t> > MEDIUM_TIMEBASE_MAP = - { - // {key byte, medium timebase (in picoseconds) - {0, 125} - // All others reserved - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< MEDIUM_TIMEBASE >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - const bool l_is_val_found = mss::find_value_from_key(MEDIUM_TIMEBASE_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - MEDIUM_TIMEBASE.iv_byte, - l_field_bits, - "Failed check for Medium Timebase") ); - - FAPI_INF("%s. Medium Timebase: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes SDRAM Minimum Cycle Time in MTB -/// @param[out] o_value tCKmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 18 -/// @note Item JC-45-2220.01x -/// @note Page 31-32 -/// @note DDR4 SPD Document Release 3 -/// @warning If tCKmin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tCKmin (SPD byte 125) -/// used for correction to get the actual value. -/// -fapi2::ReturnCode decoder_v1_0::min_tck( int64_t& o_value ) const -{ - // Explicit conversion - constexpr size_t BYTE_INDEX = 18; - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: %d.", - iv_target_str_storage, - BYTE_INDEX, - l_timing_val); - - // Check if value is valid - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the min cycle time (tckmin) in MTB") ); - - // Update output after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Cycle Time (tCKmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM Maximum Cycle Time in MTB -/// @param[out] o_value tCKmax in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 19 -/// @note Item JC-45-2220.01x -/// @note Page 32 -/// @note DDR4 SPD Document Release 3 -/// @warning If tCKmax cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tCKmax (SPD byte 124) -/// used for correction to get the actual value. -/// -fapi2::ReturnCode decoder_v1_0::max_tck( int64_t& o_value ) const -{ - // Explicit conversion - constexpr size_t BYTE_INDEX = 19; - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: %d.", - iv_target_str_storage, - BYTE_INDEX, - l_timing_val); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the max cycle time (tckmax) in MTB") ); - - // Update output after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Maximum Cycle Time (tCKmax) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decode CAS Latencies Supported -/// @param[out] o_value bitmap of supported CAS latencies -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Bytes 20-23 -/// @note Item JC-45-2220.01x -/// @note Page 33-34 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::supported_cas_latencies( uint64_t& o_value ) const -{ - // Trace print in the front assists w/ debug - constexpr size_t FIRST_BYTE = 20; - uint8_t first_raw_byte = iv_spd_data[FIRST_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - FIRST_BYTE, - first_raw_byte); - - constexpr size_t SEC_BYTE = 21; - uint8_t sec_raw_byte = iv_spd_data[SEC_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - SEC_BYTE, - sec_raw_byte); - - constexpr size_t THIRD_BYTE = 22; - uint8_t third_raw_byte = iv_spd_data[THIRD_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - THIRD_BYTE, - third_raw_byte); - - constexpr size_t FOURTH_BYTE = 23; - uint8_t fourth_raw_byte = iv_spd_data[FOURTH_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - FOURTH_BYTE, - fourth_raw_byte); - - // Buffers used for bit manipulation - // Combine Bytes to create bitmap - right aligned - fapi2::buffer<uint64_t> l_buffer; - - l_buffer.insertFromRight<CAS_BYTE_1_START, CAS_BYTE_1_LEN>(first_raw_byte) - .insertFromRight<CAS_BYTE_2_START, CAS_BYTE_2_LEN>(sec_raw_byte) - .insertFromRight<CAS_BYTE_3_START, CAS_BYTE_3_LEN>(third_raw_byte) - .insertFromRight<CAS_BYTE_4_START, CAS_BYTE_4_LEN>(fourth_raw_byte); - - // According to the JEDEC spec: - // Byte 22 (Bits 7~0) and Byte 23 are reserved and thus not supported - constexpr size_t MAX_VALID_VAL = 0x3FFFF; - - // Check for a valid value - uint64_t l_supported_cl = l_buffer; - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_supported_cl <= MAX_VALID_VAL, - FOURTH_BYTE, - fourth_raw_byte, - "Failed check on CAS latencies supported") ); - - // Update output value only if range check passes - o_value = l_supported_cl; - - FAPI_INF("%s. CAS latencies supported (bitmap): 0x%llX", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes SDRAM Minimum CAS Latency Time in MTB -/// @param[out] o_value tAAmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 24 -/// @note Item JC-45-2220.01x -/// @note Page 34 -/// @note DDR4 SPD Document Release 3 -/// @warning If tAAmin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tAAmin (SPD byte 123) -/// used for correction to get the actual value. -/// -fapi2::ReturnCode decoder_v1_0::min_taa( int64_t& o_value ) const -{ - // Explicit conversion - constexpr size_t BYTE_INDEX = 24; - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_timing_val); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum CAS Latency Time (tAAmin) in MTB") ); - - // Only update output if it passes check - o_value = l_timing_val; - - FAPI_INF("%s. Minimum CAS Latency Time (tAAmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB -/// @param[out] o_value tRCDmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 25 -/// @note Item JC-45-2220.01x -/// @note Page 35 -/// @note DDR4 SPD Document Release 3 -/// @warning If tRCDmin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tRCDmin (SPD byte 122) -/// used for correction to get the actual value -/// -fapi2::ReturnCode decoder_v1_0::min_trcd( int64_t& o_value ) const -{ - // Explicit conversion - constexpr size_t BYTE_INDEX = 25; - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_timing_val); - - // Find valid value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum RAS to CAS Delay Time (tRCDmin) in MTB") ); - - // Only update output if it passes check - o_value = l_timing_val; - - FAPI_INF("%s. Minimum RAS to CAS Delay Time (tRCDmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB -/// @param[out] o_value tRPmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 26 -/// @note Item JC-45-2220.01x -/// @note Page 36-37 -/// @note DDR4 SPD Document Release 3 -/// @warning If tRPmin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tRPmin (SPD byte 121) -/// used for correction to get the actual value -/// -fapi2::ReturnCode decoder_v1_0::min_trp( int64_t& o_value ) const -{ - // Explicit conversion - constexpr size_t BYTE_INDEX = 26; - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_timing_val); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Row Precharge Delay Time (tRPmin) in MTB") ); - - // Only update output if it passes check - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Row Precharge Delay Time (tRPmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB -/// @param[out] o_value tRASmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 27 (bits 3~0) & Byte 28 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 38 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_tras( int64_t& o_value) const -{ - uint8_t tRASmin_MSN = extract_spd_field< TRASMIN_MSN >(iv_target, iv_spd_data); - FAPI_INF("MSN Field Bits value: %lu", tRASmin_MSN); - - uint8_t tRASmin_LSB = extract_spd_field< TRASMIN_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tRASmin_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSN_START = 52; - constexpr size_t MSN_LEN = 4; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - - l_buffer.insertFromRight<MSN_START, MSN_LEN>( tRASmin_MSN ) - .insertFromRight<LSB_START, LSB_LEN>( tRASmin_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // But byte 28 of the JEDEC spec explains how to piece this together - AAM - constexpr size_t ERROR_BYTE_INDEX = 28; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Active to Precharge Delay Time (tRASmin) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Active to Precharge Delay Time (tRASmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB -/// @param[out] o_value tRCmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 27 (bits 7~4) & SPD Byte 29 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 38 -/// @note DDR4 SPD Document Release 3 -/// @warning If tRCmin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tRCmin (SPD byte 120) -/// used for correction to get the actual value. -/// -fapi2::ReturnCode decoder_v1_0::min_trc( int64_t& o_value) const -{ - uint8_t tRCmin_MSN = extract_spd_field< TRCMIN_MSN >(iv_target, iv_spd_data); - FAPI_INF("MSN Field Bits value: %lu", tRCmin_MSN); - - uint8_t tRCmin_LSB = extract_spd_field< TRCMIN_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tRCmin_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSN_START = 52; - constexpr size_t MSN_LEN = 4; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - l_buffer.insertFromRight<MSN_START, MSN_LEN>( tRCmin_MSN ) - .insertFromRight<LSB_START, LSB_LEN>( tRCmin_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // But byte 29 of the JEDEC spec explains how to piece this together - AAM - constexpr size_t ERROR_BYTE_INDEX = 29; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Active to Active/Refresh Delay Time (tRCmin) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Active to Active/Refresh Delay Time (tRCmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1 -/// @param[out] o_value tRFC1min in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 30 & Byte 31 -/// @note Item JC-45-2220.01x -/// @note Page 39-40 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_trfc1( int64_t& o_value) const -{ - uint8_t tRFC1min_MSB = extract_spd_field< TRFC1MIN_MSB >(iv_target, iv_spd_data); - FAPI_INF("MSB Field Bits value: %lu", tRFC1min_MSB); - - uint8_t tRFC1min_LSB = extract_spd_field< TRFC1MIN_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tRFC1min_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSB_START = 48; - constexpr size_t MSB_LEN = 8; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - - l_buffer.insertFromRight<MSB_START, MSB_LEN>( tRFC1min_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( tRFC1min_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // Chose one of them (byte 30) to for error printout of this decode - constexpr size_t ERROR_BYTE_INDEX = 30; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Refresh Recovery Delay Time 1 (tRFC1min) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Refresh Recovery Delay Time 1 (tRFC1min) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2 -/// @param[out] o_value tRFC2min in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 32 & Byte 33 -/// @note Item JC-45-2220.01x -/// @note Page 40 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_trfc2( int64_t& o_value) const -{ - uint8_t tRFC2min_MSB = extract_spd_field< TRFC2MIN_MSB >(iv_target, iv_spd_data); - FAPI_INF("MSB Field Bits value: %lu", tRFC2min_MSB); - - uint8_t tRFC2min_LSB = extract_spd_field< TRFC2MIN_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tRFC2min_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSB_START = 48; - constexpr size_t MSB_LEN = 8; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - - l_buffer.insertFromRight<MSB_START, MSB_LEN>( tRFC2min_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( tRFC2min_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // Chose one of them (byte 33) to for error printout of this decode - constexpr size_t ERROR_BYTE_INDEX = 33; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Refresh Recovery Delay Time 2 (tRFC2min) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Refresh Recovery Delay Time 2 (tRFC2min) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4 -/// @param[out] o_value tRFC4min in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 34 & Byte 35 -/// @note Item JC-45-2220.01x -/// @note Page 40 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_trfc4( int64_t& o_value) const -{ - uint8_t tRFC4min_MSB = extract_spd_field< TRFC4MIN_MSB >(iv_target, iv_spd_data); - FAPI_INF("MSB Field Bits value: %lu", tRFC4min_MSB); - - uint8_t tRFC4min_LSB = extract_spd_field< TRFC4MIN_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tRFC4min_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSB_START = 48; - constexpr size_t MSB_LEN = 8; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - - l_buffer.insertFromRight<MSB_START, MSB_LEN>( tRFC4min_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( tRFC4min_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // Chose one of them (byte 34) for error printout of this decode - constexpr size_t ERROR_BYTE_INDEX = 34; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Refresh Recovery Delay Time 4 (tRFC4min) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Refresh Recovery Delay Time 4 (tRFC4min) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes SDRAM Minimum Four Activate Window Delay Time -/// @param[out] o_value tFAWmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 36 (bits 3~0) & Byte 37 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 42 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_tfaw( int64_t& o_value) const -{ - uint8_t tFAWmin_MSN = extract_spd_field< TFAWMIN_MSN >(iv_target, iv_spd_data); - FAPI_INF("MSN Field Bits value: %lu", tFAWmin_MSN); - - uint8_t tFAWmin_LSB = extract_spd_field< TFAWMIN_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tFAWmin_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSN_START = 52; - constexpr size_t MSN_LEN = 4; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - - l_buffer.insertFromRight<MSN_START, MSN_LEN>( tFAWmin_MSN ). - insertFromRight<LSB_START, LSB_LEN>( tFAWmin_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // Chose one of them (byte 37) to for error printout of this decode - constexpr size_t ERROR_BYTE_INDEX = 37; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Four Activate Window Delay Time (tFAWmin) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Four Activate Window Delay Time (tFAWmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group -/// @param[out] o_value tRRD_Smin MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 38 -/// @note Item JC-45-2220.01x -/// @note Page 43 -/// @note DDR4 SPD Document Release 3 -/// @warning If tRRD_Smin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tRRD_Smin (SPD byte 119) -/// used for correction to get the actual value. -/// -fapi2::ReturnCode decoder_v1_0::min_trrd_s( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 38; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Minimum Activate to Activate Delay Time - Different Bank Group - // explicit conversion to int64_t - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Find valid value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin) in MTB") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group -/// @param[out] o_value tRRD_Lmin MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 39 -/// @note Item JC-45-2220.01x -/// @note Page 43-44 -/// @note DDR4 SPD Document Release 3 -/// @warning If tRRD_Lmin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tRRD_Lmin (SPD byte 118) -/// used for correction to get the actual value. -/// -fapi2::ReturnCode decoder_v1_0::min_trrd_l( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 39; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Minimum Activate to Activate Delay Time - Same Bank Group - // explicit conversion to int64_t - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Find valid value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on Minimum Activate to Activate Delay Time - Same Bank Group (tRRD_Lmin) in MTB") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Activate to Activate Delay Time - Same Bank Group (tRRD_Lmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group -/// @param[out] o_value tCCD_Lmin MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 40 -/// @note Item JC-45-2220.01x -/// @note Page 44-45 -/// @note DDR4 SPD Document Release 3 -/// @warning If tCCD_Lmin cannot be divided evenly by the MTB, -/// this byte must be rounded up to the next larger -/// integer and the Fine Offset for tCCD_Lmin (SPD byte 117) -/// used for correction to get the actual value. -/// -fapi2::ReturnCode decoder_v1_0::min_tccd_l( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 40; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Minimum CAS to CAS Delay Time - Same Bank Group - // explicit conversion to int64_t - int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on Minimum CAS to CAS Delay Time - Same Bank Group (tCCD_Lmin) in MTB") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum CAS to CAS Delay Time - Same Bank Group (tCCD_Lmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Minimum Write Recovery Time -/// @param[out] o_value tWRmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 40 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_twr( int64_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) were reserved - // and coded as zeros. - // Default as 0x78 for all DDR4 bins for rev 1.0 - // No value given in 1.0 JEDEC spec and no value in SPD - JLH - // 1.1 Has valid values defined and in SPD, this is taken from there - o_value = 0x78; - return fapi2::FAPI2_RC_SUCCESS; - -} - -/// -/// @brief Decodes Minimum Write to Read Time - Different Bank Group -/// @param[out] o_value tWRT_Smin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 40 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_twtr_s( int64_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) were reserved - // and coded as zeros. - // Default as 0x14 for all DDR4 bins for rev 1.0 - // No value given in 1.0 JEDEC spec and no value in SPD - JLH - // 1.1 Has valid values defined and in SPD, this is taken from there - o_value = 0x14; - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes Minimum Write to Read Time - Same Bank Group -/// @param[out] o_value tWRT_Lmin in MTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 46 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::min_twtr_l( int64_t& o_value) const -{ - // For General Section rev 1.0 of the SPD, - // SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) were reserved - // and coded as zeros. - // Default as 0x3C for all DDR4 bins for rev 1.0 - // No value given in 1.0 JEDEC spec and no value in SPD - JLH - // 1.1 Has valid values defined and in SPD, this is taken from there - o_value = 0x3C; - return fapi2::FAPI2_RC_SUCCESS; - -} - -/// -/// @brief Decodes Package Rank Map -/// @param[out] o_value vector of package rank maps for SPD bytes 60 - 77 -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 60 - 77 -/// @note JEDEC Standard No. 21-C -/// @note Page 45 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::package_rank_map( std::vector<uint8_t>& o_value ) const -{ - o_value.clear(); - - FAPI_TRY( (sdram_connector_helper<DQ0_31, PKG_RANK_MAP>(o_value)), - "%s Failed to sdram_connector_helper for DQ0_31, PKG_RANK_MAP", iv_target_str_storage ); - - FAPI_TRY( (sdram_connector_helper<DQ32_63, PKG_RANK_MAP>(o_value)), - "%s Failed to sdram_connector_helper for DQ32_63, PKG_RANK_MAP", iv_target_str_storage ); - - FAPI_TRY( (sdram_connector_helper<CB0_7, PKG_RANK_MAP>(o_value)), - "%s Failed to sdram_connector_helper for CB0_7, PKG_RANK_MAP", iv_target_str_storage ); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Nibble map -/// @param[out] o_value vector of bit order encoding for SPD bytes 60 - 77 -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 60 - 77 -/// @note JEDEC Standard No. 21-C -/// @note Page 45 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::nibble_map( std::vector<uint8_t>& o_value ) const -{ - o_value.clear(); - - FAPI_TRY( (sdram_connector_helper<DQ0_31, NIBBLE_MAP>(o_value)), - "%s Failed to sdram_connector_helper for DQ0_31, NIBBLE_MAP", iv_target_str_storage ); - - FAPI_TRY( (sdram_connector_helper<DQ32_63, NIBBLE_MAP>(o_value)), - "%s Failed to sdram_connector_helper for DQ32_63, NIBBLE_MAP", iv_target_str_storage ); - - FAPI_TRY( (sdram_connector_helper<CB0_7, NIBBLE_MAP>(o_value)), - "%s Failed to sdram_connector_helper for CB0_7, NIBBLE_MAP", iv_target_str_storage ); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Fine Offset for Minimum CAS to CAS Delay Time - Same Bank Group -/// @param[out] o_value tCCD_Lmin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 117 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_tccd_l( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 117; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for Minimum CAS to CAS Delay Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the fine offset for min RAS to CAS Delay Time (tCCD_Lmin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum RAS to CAS Delay Time (tCCD_Lmin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group -/// @param[out] o_value tRRD_Lmin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 118 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_trrd_l( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 118; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for Minimum Activate to Activate Delay Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the fine offset for Minimum Activate to Activate Delay Time (tRRD_Lmin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum Activate to Activate Delay Time (tRRD_Lmin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group -/// @param[out] o_value tRRD_Smin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 119 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_trrd_s( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 119; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the fine offset for Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time -/// @param[out] o_value tRCmin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 120 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_trc( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 120; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for Minimum Active to Active/Refresh Delay Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for vali value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the fine offset for Minimum Active to Active/Refresh Delay Time (tRCmin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum Active to Active/Refresh Delay Time (tRCmin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time -/// @param[out] o_value tRPmin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 121 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_trp( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 121; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for Minimum Row Precharge Delay Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the fine offset for Minimum Row Precharge Delay Time (tRPmin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum Row Precharge Delay Time (tRPmin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} -/// -/// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time -/// @param[out] o_value tRCDmin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 122 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_trcd( int64_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 122; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for SDRAM Minimum RAS to CAS Delay Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the fine offset for min RAS to CAS Delay Time (tRCDmin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum RAS to CAS Delay Time (tRCDmin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time -/// @param[out] o_value tAAmin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 123 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_taa( int64_t& o_value ) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 123; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for SDRAM Minimum CAS Latency Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the Fine offset for Minimum CAS Latency Time (tAAmin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum CAS Latency Time (tAAmin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time -/// @param[out] o_value tCKmax offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 124 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_max_tck( int64_t& o_value ) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 124; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for SDRAM Maximum Cycle Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the fine offset for max cycle time (tckmax)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Maximum Cycle Time (tCKmax) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time -/// @param[out] o_value tCKmin offset in FTB units -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 125 -/// @note Item JC-45-2220.01x -/// @note Page 52 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::fine_offset_min_tck( int64_t& o_value ) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 125; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - // Retrieve Fine Offset for SDRAM Minimum Cycle Time - // int8_t conversion - allows me to get a negative offset - // then implicit conversion to int64_t - int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]); - - // Check for valid value - constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC - constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - BYTE_INDEX, - l_timing_val, - "Failed check on the Fine offset for Minimum Cycle Time (tCKmin)") ); - - // Update output value only if range check passes - o_value = l_timing_val; - - FAPI_INF("%s. Fine offset for Minimum Cycle Time (tCKmin) in FTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section -/// @param[out] o_value crc value from SPD -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 127 & Byte 126 -/// @note Item JC-45-2220.01x -/// @note Page 53 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::cyclical_redundancy_code( uint16_t& o_value ) const -{ - uint8_t crc_MSB = extract_spd_field< CRC_MSB >(iv_target, iv_spd_data); - FAPI_INF("MSB Field Bits value: %lu", crc_MSB); - - uint8_t crc_LSB = extract_spd_field< CRC_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", crc_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSN_START = 0; - constexpr size_t MSN_LEN = 8; - constexpr size_t LSB_START = 8; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<uint16_t> l_buffer; - l_buffer.insertFromRight<MSN_START, MSN_LEN>( crc_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( crc_LSB ); - - // This value isn't bounded in the SPD document - o_value = l_buffer; - - FAPI_INF("%s. Cyclical Redundancy Code (CRC): %d", - iv_target_str_storage, - o_value); - - // Returns "happy" until we can figure out a way to test this - AAM - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes module manufacturer ID code -/// @param[out] o_value module manufacturing id code -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 320 (bit 7~0), 321 (6~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12 - 54 -/// -fapi2::ReturnCode decoder_v1_0::module_manufacturer_id_code( uint16_t& o_value ) const -{ - - constexpr size_t BYTE_INDEX_MSB = 320; - uint8_t mfgid_MSB = iv_spd_data[BYTE_INDEX_MSB]; - - constexpr size_t BYTE_INDEX_LSB = 321; - uint8_t mfgid_LSB = iv_spd_data[BYTE_INDEX_LSB]; - - constexpr size_t MSB_START = 0; - constexpr size_t MSB_LEN = 8; - constexpr size_t LSB_START = 8; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<uint16_t> l_buffer; - l_buffer.insertFromRight<MSB_START, MSB_LEN>( mfgid_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( mfgid_LSB ); - - o_value = l_buffer; - - FAPI_INF("%s.Module Manufacturer ID Code: %x", - iv_target_str_storage, - o_value); - - // Returns "happy" until we can figure out a way to test this - AAM - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes Module Manufacturing Location -/// @param[out] o_value uint8_t identifier for manufacturing location of memory module -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 322 -/// @note Item JC-45-2220.01x -/// @note Page 55 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::module_manufacturing_location( uint8_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 322; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - o_value = iv_spd_data[BYTE_INDEX]; - - FAPI_INF("%s. Module Manufacturing Location: %x", - iv_target_str_storage, - o_value); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodesmodule manufacturing date -/// @param[out] o_value the 2 byte date of manufacturing in BCD format -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 323-324 -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 54 -/// @note in Binary Coded Decimal (BCD) -/// @note MSB = year, LSB = week -/// -fapi2::ReturnCode decoder_v1_0::module_manufacturing_date( uint16_t& o_value ) const -{ - - constexpr size_t BYTE_INDEX_MSB = 323; - uint8_t date_MSB = iv_spd_data[BYTE_INDEX_MSB]; - - constexpr size_t BYTE_INDEX_LSB = 324; - uint8_t date_LSB = iv_spd_data[BYTE_INDEX_LSB]; - - constexpr size_t MSB_START = 0; - constexpr size_t MSB_LEN = 8; - constexpr size_t LSB_START = 8; - constexpr size_t LSB_LEN = 8; - - //Using insertFromRight because IBM is backwards - fapi2::buffer<uint16_t> l_buffer; - l_buffer.insertFromRight<MSB_START, MSB_LEN>( date_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( date_LSB ); - - o_value = l_buffer; - - FAPI_INF("%s.Module Manufacturer ID date: %x", - iv_target_str_storage, - o_value); - - // Returns "happy" until we can figure out a way to test this - AAM - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes module's unique serial number -/// @param[out] o_value -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 325-328 -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 54 -/// @note in Binary Coded Decimal (BCD) -/// -fapi2::ReturnCode decoder_v1_0::module_serial_number( uint32_t& o_value ) const -{ - constexpr size_t BYTE_INDEX_0 = 325; - uint8_t sn_byte_0 = iv_spd_data[BYTE_INDEX_0]; - - constexpr size_t BYTE_INDEX_1 = 326; - uint8_t sn_byte_1 = iv_spd_data[BYTE_INDEX_1]; - - constexpr size_t BYTE_INDEX_2 = 327; - uint8_t sn_byte_2 = iv_spd_data[BYTE_INDEX_2]; - - constexpr size_t BYTE_INDEX_3 = 328; - uint8_t sn_byte_3 = iv_spd_data[BYTE_INDEX_3]; - - constexpr size_t START_BYTE_0 = 0; - constexpr size_t LEN_BYTE_0 = 8; - constexpr size_t START_BYTE_1 = 8; - constexpr size_t LEN_BYTE_1 = 8; - constexpr size_t START_BYTE_2 = 16; - constexpr size_t LEN_BYTE_2 = 8; - constexpr size_t START_BYTE_3 = 24; - constexpr size_t LEN_BYTE_3 = 8; - - //Goes down the batting order, Inserts from left side because IBM - fapi2::buffer<uint32_t> l_buffer; - l_buffer.insertFromRight<START_BYTE_0, LEN_BYTE_0>( sn_byte_0 ) - .insertFromRight<START_BYTE_1, LEN_BYTE_1>( sn_byte_1 ) - .insertFromRight<START_BYTE_2, LEN_BYTE_2>( sn_byte_2 ) - .insertFromRight<START_BYTE_3, LEN_BYTE_3>( sn_byte_3 ); - - o_value = l_buffer; - - FAPI_INF("%s.Module Serial Number : %x", - iv_target_str_storage, - o_value); - - // Returns "happy" until we can figure out a way to test this - AAM - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes Module Revision Code -/// @param[out] o_value uint8_t identifier for revision code -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 349 -/// @note Item JC-45-2220.01x -/// @note Page 55 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_0::module_revision_code( uint8_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 349; - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - o_value = iv_spd_data[BYTE_INDEX]; - - FAPI_INF("%s. Module Revision Code: %x", - iv_target_str_storage, - o_value); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes DRAM Manufacturer ID code -/// @param[out] o_value dram manufacturing id code -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 350 351 -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 54 -/// -fapi2::ReturnCode decoder_v1_0::dram_manufacturer_id_code( uint16_t& o_value ) const -{ - constexpr size_t BYTE_INDEX_MSB = 350; - uint8_t mfgid_MSB = iv_spd_data[BYTE_INDEX_MSB]; - - constexpr size_t BYTE_INDEX_LSB = 351; - uint8_t mfgid_LSB = iv_spd_data[BYTE_INDEX_LSB]; - - constexpr size_t MSB_START = 0; - constexpr size_t MSB_LEN = 8; - constexpr size_t LSB_START = 8; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<uint16_t> l_buffer; - l_buffer.insertFromRight<MSB_START, MSB_LEN>( mfgid_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( mfgid_LSB ); - - o_value = l_buffer; - - FAPI_INF("%s.DRAM Manufacturer ID Code (dram_mfg_id): %x", - iv_target_str_storage, - o_value); - - // Returns "happy" until we can figure out a way to test this - AAM - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes REGISTER Manufacturer ID code -/// @param[out] o_value rcd manufacturing id code -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 133-134 -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 54 -/// -fapi2::ReturnCode decoder_v1_0::reg_manufacturer_id_code( uint16_t& o_value ) const -{ - constexpr size_t BYTE_INDEX_LSB = 133; - uint8_t mfgid_LSB = iv_spd_data[BYTE_INDEX_LSB]; - - constexpr size_t BYTE_INDEX_MSB = 134; - uint8_t mfgid_MSB = iv_spd_data[BYTE_INDEX_MSB]; - - constexpr size_t MSB_START = 0; - constexpr size_t MSB_LEN = 8; - constexpr size_t LSB_START = 8; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<uint16_t> l_buffer; - l_buffer.insertFromRight<MSB_START, MSB_LEN>( mfgid_MSB ) - .insertFromRight<LSB_START, LSB_LEN>( mfgid_LSB ); - - o_value = l_buffer; - - FAPI_INF("%s.RCD Manufacturer ID Code (rcd_mfg_id): %x", - iv_target_str_storage, - o_value); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes Register Revision Number -/// @param[out] o_value register revision number -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 135 -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 54 -/// -fapi2::ReturnCode decoder_v1_0::register_rev_num( uint8_t& o_value ) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 135; - - FAPI_INF("%s SPD data at Byte %d: 0x%01X.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - o_value = iv_spd_data[BYTE_INDEX]; - - FAPI_INF("%s. Register Revision Number: %x", - iv_target_str_storage, - o_value); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes DRAM Stepping -/// @param[out] o_value uint8_t DRAM Stepping val -/// @return FAPI2_RC_SUCCESS iff okay -/// @note SPD Byte 353 -/// @note Item JC-45-2220.01x -/// @note Page 56 -/// @note DDR4 SPD Document Release 3 -/// @note also called die revision level -/// -fapi2::ReturnCode decoder_v1_0::dram_stepping( uint8_t& o_value) const -{ - // Trace in the front assists w/ debug - constexpr size_t BYTE_INDEX = 352; - - FAPI_INF("%s SPD data at Byte %d: 0x%01X.", - iv_target_str_storage, - BYTE_INDEX, - iv_spd_data[BYTE_INDEX]); - - o_value = iv_spd_data[BYTE_INDEX]; - - FAPI_INF("%s. DRAM stepping: %x", - iv_target_str_storage, - o_value); - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Returns Logicalranks in Primary SDRAM type -/// @param[out] o_logical_ranks number of logical ranks -/// @return fapi2::FAPI2_RC_SUCCESS iff okay -/// -fapi2::ReturnCode decoder_v1_0::prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const -{ - uint8_t l_signal_loading = 0; - uint8_t l_ranks_per_dimm = 0; - - FAPI_TRY( prim_sdram_signal_loading(l_signal_loading) ); - FAPI_TRY( num_package_ranks_per_dimm(l_ranks_per_dimm) ); - - if(l_signal_loading == spd::SINGLE_LOAD_STACK) - { - // For single-load-stack(3DS) the logical ranks per package ends up being the same as the die count. - uint8_t l_die_count = 0; - FAPI_TRY( prim_sdram_die_count(l_die_count) ); - - o_logical_ranks = l_ranks_per_dimm * l_die_count; - } - else - { - // Covers case for MONOLITHIC & MULTI_LOAD_STACK - // The die count isn't guaranteed to be 1 (e.g. SDP - 1 die package, DDP - 2 die package). - // Value of 1 is used for calculation purposes as defined by the SPD spec. - o_logical_ranks = l_ranks_per_dimm; - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Returns Logical ranks per DIMM -/// @param[in] i_pDecoder shared pointer to the SPD decoder -/// @param[out] o_logical_ranks number of logical ranks -/// @return fapi2::FAPI2_RC_SUCCESS iff okay -/// -fapi2::ReturnCode decoder_v1_0::logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const -{ - FAPI_TRY( prim_sdram_logical_ranks(o_logical_rank_per_dimm) ); - -fapi_try_exit: - return fapi2::current_err; -} - -}// ddr4 -}//spd -}// mss diff --git a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C deleted file mode 100644 index ca08de944..000000000 --- a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C +++ /dev/null @@ -1,760 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -/// -/// @file spd_decoder_v1_1.C -/// @brief SPD decoder definitions -/// -// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -// fapi2 -#include <fapi2.H> - -// mss lib -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> -#include <generic/memory/lib/spd/spd_checker.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/find.H> - -using fapi2::TARGET_TYPE_MCA; -using fapi2::TARGET_TYPE_MCS; -using fapi2::TARGET_TYPE_DIMM; - -namespace mss -{ -namespace spd -{ -namespace ddr4 -{ - -///////////////////////// -// Member method definitions -///////////////////////// - -/// -/// @brief ctor -/// @param[in] i_target dimm target -/// @param[in] i_spd_data SPD data vector -/// @param[in] i_module_decoder shared_ptr to dimm module decoder -/// @param[in] i_raw_card raw card data structure -/// -decoder_v1_1::decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data, - const std::shared_ptr<dimm_module_decoder>& i_module_decoder, - const rcw_settings& i_raw_card) - : decoder_v1_0(i_target, i_spd_data, i_module_decoder, i_raw_card) -{} - -/// -/// @brief Decodes SDRAM density from SPD -/// @param[out] o_value SDRAM density in GBs -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 4 (bits 0~3) -/// @note Item JC-45-2220.01x -/// @note Page 18 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::sdram_density( uint8_t& o_value ) const -{ - // ========================================================= - // Byte 4 maps - // Item JC-45-2220.01x - // Page 18 - // DDR4 SPD Document Release 3 - // Byte 4 (0x004): SDRAM Density and Banks - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > SDRAM_DENSITY_MAP = - { - // {key byte, capacity in GBs} - {2, 1}, - {3, 2}, - {4, 4}, - {5, 8}, - {6, 16}, - {7, 32}, - {8, 12}, - {12, 24} - }; - - // Extracting desired biits - const uint8_t l_field_bits = extract_spd_field< SDRAM_CAPACITY >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Check to assure SPD DRAM capacity (map) wont be at invalid values - bool l_is_val_found = mss::find_value_from_key(SDRAM_DENSITY_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - SDRAM_CAPACITY.iv_byte, - l_field_bits, - "Failed check for SPD DRAM capacity") ); - - FAPI_INF("%s. SDRAM density: %d Gb", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Secondary SDRAM signal loading -/// @param[out] o_value enum representing signal loading type -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 10 (bits 1~0) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::sec_sdram_signal_loading( uint8_t& o_value ) const -{ - // ========================================================= - // Byte 10 maps - // Item JC-45-2220.01x - // Page 21-22 - // DDR4 SPD Document Release 3 - // Byte 10 (0x00A): Secondary SDRAM Package Type - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > SEC_SIGNAL_LOADING_MAP = - { - // {key byte, signal loading} - {0, UNSPECIFIED}, - {1, MULTI_LOAD_STACK}, - {2, SINGLE_LOAD_STACK} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SEC_SIGNAL_LOADING >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - bool l_is_val_found = mss::find_value_from_key(SEC_SIGNAL_LOADING_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - SEC_SIGNAL_LOADING.iv_byte, - l_field_bits, - "Failed check for Secondary SDRAM Signal Loading") ); - - FAPI_INF("%s. Secondary SDRAM Signal Loading: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decode Soft post package repair (soft PPR) -/// @param[out] o_value enum representing if soft PPR is supported -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 9 (bit 5) -/// @note Item JC-45-2220.01x -/// @note Page 21 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::soft_post_package_repair( uint8_t& o_value ) const -{ - // ========================================================= - // Byte 9 maps - // Item JC-45-2220.01x - // Page 21 - // DDR4 SPD Document Release 3 - // Byte 9 (0x009): Other SDRAM Optional Features - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > SOFT_PPR_MAP = - { - // {key byte, value } - {0, fapi2::ENUM_ATTR_EFF_DRAM_SOFT_PPR_NOT_SUPPORTED}, - {1, fapi2::ENUM_ATTR_EFF_DRAM_SOFT_PPR_SUPPORTED} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SOFT_PPR >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - bool l_is_val_found = mss::find_value_from_key(SOFT_PPR_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target, - l_is_val_found, - SOFT_PPR.iv_byte, - l_field_bits, - "Failed check for Soft PPR") ); - - FAPI_INF("%s. Soft Post Package Repair (Soft PPR): %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Secondary DRAM Density Ratio -/// @param[out] o_value raw bits from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 10 (bits 3~2) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::sec_dram_density_ratio( uint8_t& o_value ) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SEC_DENSITY_RATIO >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - constexpr size_t UNDEFINED = 3; // JEDEC map doesn't go beyond 3 - - FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target, - l_field_bits < UNDEFINED, - SEC_DENSITY_RATIO.iv_byte, - l_field_bits, - "Failed check for DRAM Density Ratio") ); - - FAPI_INF("%s. DRAM Density Ratio: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes Secondary SDRAM die count -/// @param[out] o_value die count -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 10 (bits 6~4) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::sec_sdram_die_count( uint8_t& o_value ) const -{ - // ========================================================= - // Byte 10 maps - // Item JC-45-2220.01x - // Page 21-22 - // DDR4 SPD Document Release 3 - // Byte 10 (0x00A): Secondary SDRAM Package Type - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > SEC_DIE_COUNT_MAP = - { - // {key byte, number of die} - {0, 1}, - {1, 2}, - {2, 3}, - {3, 4}, - {4, 5}, - {5, 6}, - {6, 7}, - {7, 8} - - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SEC_DIE_COUNT >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - bool l_is_val_found = mss::find_value_from_key(SEC_DIE_COUNT_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - SEC_DIE_COUNT.iv_byte, - l_field_bits, - "Failed check for Secondary Die Count") ); - - FAPI_INF("%s. Secondary Die Count: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Secondary SDRAM package type -/// @param[out] o_value enum representing package type -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 10 (bit 7) -/// @note Item JC-45-2220.01x -/// @note Page 22 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::sec_sdram_package_type( uint8_t& o_value ) const -{ - // ========================================================= - // Byte 10 maps - // Item JC-45-2220.01x - // Page 21-22 - // DDR4 SPD Document Release 3 - // Byte 10 (0x00A): Secondary SDRAM Package Type - // ========================================================= - - static const std::vector<std::pair<uint8_t, uint8_t> > SEC_PACKAGE_TYPE_MAP = - { - // {key byte, value } - {0, MONOLITHIC}, - {1, NON_MONOLITHIC} - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< SEC_PACKAGE_TYPE >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - bool l_is_val_found = mss::find_value_from_key(SEC_PACKAGE_TYPE_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - SEC_PACKAGE_TYPE.iv_byte, - l_field_bits, - "Failed check for Secondary Package Type") ); - - FAPI_INF("%s. Secondary Package Type: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes number of package ranks per DIMM -/// @param[out] o_value number of package ranks per DIMM -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 12 (bits 5~3) -/// @note Item JC-45-2220.01x -/// @note Page 23 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::num_package_ranks_per_dimm( uint8_t& o_value ) const -{ - // ========================================================= - // Byte 12 maps - // Item JC-45-2220.01x - // Page 23 - // DDR4 SPD Document Release 3 - // Byte 12 (0x00C): Module Organization - // ========================================================= - static const std::vector<std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP = - { - // {key byte, num of package ranks per DIMM (package ranks)} - {0, 1}, - {1, 2}, - {2, 3}, - {3, 4}, - {4, 5}, - {5, 6}, - {6, 7}, - {7, 8}, - }; - - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< PACKAGE_RANKS >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - bool l_is_val_found = mss::find_value_from_key(NUM_PACKAGE_RANKS_MAP, l_field_bits, o_value); - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_is_val_found, - PACKAGE_RANKS.iv_byte, - l_field_bits, - "Failed check for Num Package Ranks Per DIMM") ); - - FAPI_INF("%s. Num Package Ranks per DIMM: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Rank Mix -/// @param[out] o_value rank mix value from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 12 (bit 6) -/// @note Item JC-45-2220.01x -/// @note Page 23 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::rank_mix( uint8_t& o_value ) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< RANK_MIX >(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // Find map value - constexpr size_t INVALID_VALUE = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits < INVALID_VALUE), - RANK_MIX.iv_byte, - l_field_bits, - "Failed check for Rank Mix") ); - - // Update output after check passes - o_value = l_field_bits; - - FAPI_INF("%s. Rank Mix: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decode CAS Latencies Supported -/// @param[out] o_value bitmap of supported CAS latencies -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Bytes 20-23 -/// @note Item JC-45-2220.01x -/// @note Page 33-34 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::supported_cas_latencies( uint64_t& o_value ) const -{ - // Trace print in the front assists w/ debug - constexpr size_t FIRST_BYTE = 20; - uint8_t first_raw_byte = iv_spd_data[FIRST_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - FIRST_BYTE, - first_raw_byte); - - constexpr size_t SEC_BYTE = 21; - uint8_t sec_raw_byte = iv_spd_data[SEC_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - SEC_BYTE, - sec_raw_byte); - - constexpr size_t THIRD_BYTE = 22; - uint8_t third_raw_byte = iv_spd_data[THIRD_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - THIRD_BYTE, - third_raw_byte); - - constexpr size_t FOURTH_BYTE = 23; - uint8_t fourth_raw_byte = iv_spd_data[FOURTH_BYTE]; - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - FOURTH_BYTE, - fourth_raw_byte); - - // Buffers used for bit manipulation - // Combine Bytes to create bitmap - right aligned - fapi2::buffer<uint64_t> l_buffer; - - l_buffer.insertFromRight<CAS_BYTE_1_START, CAS_BYTE_1_LEN>(first_raw_byte) - .insertFromRight<CAS_BYTE_2_START, CAS_BYTE_2_LEN>(sec_raw_byte) - .insertFromRight<CAS_BYTE_3_START, CAS_BYTE_3_LEN>(third_raw_byte) - .insertFromRight<CAS_BYTE_4_START, CAS_BYTE_4_LEN>(fourth_raw_byte); - - // According to the JEDEC spec: - // Byte 23 bit 6 is reserved and must be coded as 0. - // Should we warn instead of fail because in last revision this was a reserved byte coded as 0x00 - constexpr size_t BIT_START = 33; // relative position of bit 6 in byte 23 relative to uint64_t - constexpr size_t BIT_LEN = 1; - - // Check for a valid value - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - !(l_buffer.getBit<BIT_START, BIT_LEN>()), - FOURTH_BYTE, - fourth_raw_byte, - "Failed check on CAS latencies supported") ); - - // Update output value only if range check passes - o_value = l_buffer; - - FAPI_INF("%s. CAS latencies supported (bitmap): 0x%llX", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Minimum Write Recovery Time -/// @param[out] o_value tWRmin in MTB units -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 40 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::min_twr( int64_t& o_value ) const -{ - uint8_t tWRmin_MSN = extract_spd_field< TWRMIN_MSN >(iv_target, iv_spd_data); - FAPI_INF("MSN Field Bits value: %lu", tWRmin_MSN); - - uint8_t tWRmin_LSB = extract_spd_field< TWRMIN_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tWRmin_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSN_START = 52; - constexpr size_t MSN_LEN = 4; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - l_buffer.insertFromRight<MSN_START, MSN_LEN>( tWRmin_MSN ). - insertFromRight<LSB_START, LSB_LEN>( tWRmin_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - // This value used to be reserved to 0 - before spec update - // constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - - constexpr int64_t TIMING_LOWER_BOUND = 0; - constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // Chose one of them (byte 42) to for error printout of this decode - constexpr size_t ERROR_BYTE_INDEX = 42; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Write Recovery Time (tWRmin) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Write Recovery Time (tWRmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes Minimum Write to Read Time - Different Bank Group -/// @param[out] o_value tWTR_Smin in MTB units -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 40 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::min_twtr_s( int64_t& o_value ) const -{ - uint8_t tWTR_Smin_MSN = extract_spd_field< TWTRMIN_S_MSN >(iv_target, iv_spd_data); - FAPI_INF("MSN Field Bits value: %lu", tWTR_Smin_MSN); - - uint8_t tWTR_Smin_LSB = extract_spd_field< TWTRMIN_S_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tWTR_Smin_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSN_START = 52; - constexpr size_t MSN_LEN = 4; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - - l_buffer.insertFromRight<MSN_START, MSN_LEN>( tWTR_Smin_MSN ) - .insertFromRight<LSB_START, LSB_LEN>( tWTR_Smin_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - - // This value used to be reserved to 0 - before spec update - AAM - // constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC - constexpr int64_t TIMING_LOWER_BOUND = 0; - constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // Chose one of them (byte 44) to for error printout of this decode - constexpr size_t ERROR_BYTE_INDEX = 44; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Write to Read Time - Different Bank Group (tWTR_Smin) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Smin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes Minimum Write to Read Time - Same Bank Group -/// @param[out] o_value tWTR_Lmin in MTB units -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) -/// @note Item JC-45-2220.01x -/// @note Page 46 -/// @note DDR4 SPD Document Release 3 -/// -fapi2::ReturnCode decoder_v1_1::min_twtr_l( int64_t& o_value ) const -{ - // Extracting desired bits - uint8_t tWTR_Lmin_MSN = extract_spd_field< TWTRMIN_L_MSN >(iv_target, iv_spd_data); - FAPI_INF("MSN Field Bits value: %lu", tWTR_Lmin_MSN); - - uint8_t tWTR_Lmin_LSB = extract_spd_field< TWTRMIN_L_LSB >(iv_target, iv_spd_data); - FAPI_INF("LSB Field Bits value: %lu", tWTR_Lmin_LSB); - - // Combining bits to create timing value (in a buffer) - constexpr size_t MSN_START = 52; - constexpr size_t MSN_LEN = 4; - constexpr size_t LSB_START = 56; - constexpr size_t LSB_LEN = 8; - - fapi2::buffer<int64_t> l_buffer; - - l_buffer.insertFromRight<MSN_START, MSN_LEN>( tWTR_Lmin_MSN ) - .insertFromRight<LSB_START, LSB_LEN>( tWTR_Lmin_LSB ); - - // Extract timing value from the buffer into an integral type - int64_t l_timing_val = l_buffer; - - // JEDEC spec limits for this timing value - // This value used to be reserved to 0 - before spec update - //constexpr int64_t TIMING_LOWER_BOUND = 1 // from JEDEC - constexpr int64_t TIMING_LOWER_BOUND = 0; - constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC - - // best we can do? - // I had to combine parts from two different bytes. - // Chose one of them (byte 45) to for error printout of this decode - constexpr size_t ERROR_BYTE_INDEX = 45; - - FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target, - (l_timing_val <= TIMING_UPPER_BOUND) && - (l_timing_val >= TIMING_LOWER_BOUND), - ERROR_BYTE_INDEX, - l_timing_val, - "Failed check on the Minimum Write to Read Time - Same Bank Group (tWTR_Lmin) in MTB") ); - - // Update output only after check passes - o_value = l_timing_val; - - FAPI_INF("%s. Minimum Write to Read Time - Same Bank Group (tWTR_Lmin) in MTB units: %d", - iv_target_str_storage, - o_value); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Helper function that returns Logical ranks in SDRAM type -/// @param[out] o_logical_ranks number of logical ranks -/// @return fapi2::FAPI2_RC_SUCCESS if okay -/// -fapi2::ReturnCode decoder_v1_1::sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const -{ - uint8_t l_signal_loading = 0; - uint8_t l_ranks_per_dimm = 0; - - FAPI_TRY( sec_sdram_signal_loading(l_signal_loading) ); - FAPI_TRY( num_package_ranks_per_dimm(l_ranks_per_dimm) ); - - if(l_signal_loading == spd::SINGLE_LOAD_STACK) - { - // For single-load-stack(3DS) the logical ranks per package ends up being the same as the die count. - uint8_t l_die_count = 0; - FAPI_TRY( sec_sdram_die_count(l_die_count) ); - - o_logical_ranks = l_ranks_per_dimm * l_die_count; - } - else - { - // Covers case for MONOLITHIC & MULTI_LOAD_STACK - // The die count isn't guaranteed to be 1 (e.g. SDP - 1 die package, DDP - 2 die package). - // Value of 1 is used for calculation purposes as defined by the SPD spec. - o_logical_ranks = l_ranks_per_dimm; - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Returns Logical ranks per DIMM -/// @param[out] o_logical_ranks number of logical ranks -/// @return fapi2::FAPI2_RC_SUCCESS if okay -/// -fapi2::ReturnCode decoder_v1_1::logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const -{ - uint8_t l_rank_mix = 0; - - FAPI_TRY( rank_mix(l_rank_mix) ); - - if(l_rank_mix == fapi2::ENUM_ATTR_EFF_DRAM_RANK_MIX_SYMMETRICAL) - { - FAPI_TRY( prim_sdram_logical_ranks(o_logical_rank_per_dimm) ); - } - else - { - // Rank mix is ASYMMETRICAL - uint8_t l_prim_logical_rank_per_dimm = 0; - uint8_t l_sec_logical_rank_per_dimm = 0; - - FAPI_TRY( prim_sdram_logical_ranks(l_prim_logical_rank_per_dimm) ); - FAPI_TRY( sec_sdram_logical_ranks(l_sec_logical_rank_per_dimm) ); - - o_logical_rank_per_dimm = l_prim_logical_rank_per_dimm + l_sec_logical_rank_per_dimm; - } - -fapi_try_exit: - return fapi2::current_err; -} - -}// ddr4 -}// spd -}// mss diff --git a/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H b/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H index da24f3155..ec7916df4 100644 --- a/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H +++ b/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H @@ -52,11 +52,12 @@ namespace spd /// class dimm_module_decoder { - public: + private: + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + std::vector<uint8_t> iv_data; - // - std::vector<uint8_t> iv_spd_data; + public: /// /// @brief default ctor @@ -67,9 +68,10 @@ class dimm_module_decoder /// @brief ctor /// dimm_module_decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data): iv_target(i_target), iv_spd_data(i_spd_data) + const std::vector<uint8_t>& i_spd_data): + iv_target(i_target), + iv_data(i_spd_data) { - fapi2::toString(iv_target, iv_target_str_storage, fapi2::MAX_ECMD_STRING_LEN); } /// @@ -78,6 +80,33 @@ class dimm_module_decoder virtual ~dimm_module_decoder() = default; /// + /// @brief Gets decoder target + /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM> + /// + virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const + { + return iv_target; + } + + /// + /// @brief Gets decoder SPD data + /// @return std::vector<uint8_t> + /// + virtual std::vector<uint8_t> get_data() const + { + return iv_data; + } + + /// + /// @brief Sets decoder SPD data + /// @param[in] i_spd_data SPD data in a vector reference + /// + virtual void set_data(const std::vector<uint8_t>& i_spd_data) + { + iv_data = i_spd_data; + } + + /// /// @brief Decodes module nominal height max /// @param[out] o_output height range encoding from SPD /// @return FAPI2_RC_SUCCESS if okay @@ -122,8 +151,23 @@ class dimm_module_decoder } /// + /// @brief Decodes reference raw card used + /// @param[out] o_output encoding from SPD + /// @return FAPI2_RC_SUCCESS if okay + /// @note SPD Byte 130 (Bits 7~0) + /// @note Item JEDEC Standard No. 21-C + /// @note DDR4 SPD Document Release 2 + /// @note Page 4.1.2.12 - 48 + /// + virtual fapi2::ReturnCode reference_raw_card(uint8_t& o_output) const + { + o_output = 0; + return fapi2::FAPI2_RC_SUCCESS; + } + + /// /// @brief Decodes number of registers used on RDIMM - /// @param[out] o_output encoding from SPD + /// @param[out] o_output encoding from SPD /// @return FAPI2_RC_SUCCESS if okay /// virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const @@ -145,7 +189,7 @@ class dimm_module_decoder /// /// @brief Decodes register and buffer type for LRDIMMs - /// @param[out] o_output encoding from SPD + /// @param[out] o_output encoding from SPD /// @return FAPI2_RC_SUCCESS if okay /// virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const @@ -178,22 +222,11 @@ class dimm_module_decoder } /// - /// @brief Decodes number of continuation codes - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// - virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output) const - { - o_output = 0; - return fapi2::FAPI2_RC_SUCCESS; - } - - /// /// @brief Decodes register manufacturer ID code /// @param[out] o_output drive strength encoding from SPD /// @return FAPI2_RC_SUCCESS if okay /// - virtual fapi2::ReturnCode reg_manufacturer_id_code(uint8_t& o_output) const + virtual fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_output) const { o_output = 0; return fapi2::FAPI2_RC_SUCCESS; @@ -312,7 +345,7 @@ class dimm_module_decoder /// /// @brief Decodes RCD output slew rate control - /// @param[out] o_output encoded drive strength + /// @param[out] o_output encoded slew rate /// @return FAPI2_RC_SUCCESS if okay /// virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output) const @@ -521,45 +554,8 @@ class dimm_module_decoder o_output = 0; return fapi2::FAPI2_RC_SUCCESS; } - - protected: - - char iv_target_str_storage[fapi2::MAX_ECMD_STRING_LEN]; - }; -/// -/// @brief data structure for byte fields -/// @note holds byte index, start bit and length of decoded field -/// -struct field_t -{ - const uint64_t iv_byte; - const uint64_t iv_start; - const uint64_t iv_length; - - // default ctor deleted - constexpr field_t() = delete; - - /// - /// @brief ctor - /// @param[in] i_byte_index - /// @param[in] i_start_bit - /// @param[in] i_bit_length - /// - constexpr field_t(const uint64_t i_byte_index, - const uint64_t i_start_bit, - const uint64_t i_bit_length) - : iv_byte(i_byte_index), iv_start(i_start_bit), iv_length(i_bit_length) - {} - - /// - /// @brief default dtor - /// - ~field_t() = default; - -};// field_t - }// spd }// mss diff --git a/src/import/generic/memory/lib/spd/common/spd_decoder_base.H b/src/import/generic/memory/lib/spd/common/spd_decoder_base.H index 53b931b40..878d2f27e 100644 --- a/src/import/generic/memory/lib/spd/common/spd_decoder_base.H +++ b/src/import/generic/memory/lib/spd/common/spd_decoder_base.H @@ -40,157 +40,140 @@ #include <memory> #include <fapi2.H> -#include <generic/memory/lib/spd/common/dimm_module_decoder.H> -#include <generic/memory/lib/spd/common/rcw_settings.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> +#include <generic/memory/lib/spd/spd_reader.H> namespace mss { + namespace spd { -/// -/// @brief Helper function to extract byte information -/// @tparam F the SPD field to extract -/// @param[in] i_target the dimm target -/// @param[in] i_spd_data the SPD data -/// @return extracted byte (right aligned) -/// -template< const field_t& F > -inline uint8_t extract_spd_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data) +class base_cnfg_decoder { - char l_target_str_storage[fapi2::MAX_ECMD_STRING_LEN]; - fapi2::toString(i_target, l_target_str_storage, fapi2::MAX_ECMD_STRING_LEN); - - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - l_target_str_storage, - F.iv_byte, - i_spd_data[F.iv_byte]); - - fapi2::buffer<uint8_t> l_buffer(i_spd_data[F.iv_byte]); + private: - // Extracting desired bits - uint8_t l_field_bits = 0; - l_buffer.extractToRight<F.iv_start, F.iv_length>(l_field_bits); - - return l_field_bits; -} + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + std::vector<uint8_t> iv_data; -/// -/// @brief Helper function to extract byte information -/// @param[in] i_target the dimm target -/// @param[in] i_field the SPD field -/// @param[in] i_spd_data the SPD data -/// @return extracted byte (right aligned) -/// -inline uint8_t extract_spd_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const field_t& i_field, - const std::vector<uint8_t>& i_spd_data) -{ - char l_target_str_storage[fapi2::MAX_ECMD_STRING_LEN]; - fapi2::toString(i_target, l_target_str_storage, fapi2::MAX_ECMD_STRING_LEN); + public: - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - l_target_str_storage, - i_field.iv_byte, - i_spd_data[i_field.iv_byte]); + /// + /// @brief ctor + /// @param[in] i_target dimm target + /// @param[in] i_spd_data SPD data vector + /// + base_cnfg_decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data) + : iv_target(i_target), + iv_data(i_spd_data) + { + } - fapi2::buffer<uint8_t> l_buffer(i_spd_data[i_field.iv_byte]); + /// + /// @brief dtor + /// + virtual ~base_cnfg_decoder() = default; - // Extracting desired bits - uint8_t l_field_bits = 0; - l_buffer.extractToRight( l_field_bits, i_field.iv_start, i_field.iv_length ); + /// + /// @brief Gets decoder target + /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM> + /// + virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const + { + return iv_target; + } - return l_field_bits; -} + /// + /// @brief Gets decoder SPD data + /// @return std::vector<uint8_t> + /// + virtual std::vector<uint8_t> get_data() const + { + return iv_data; + } -/// -/// @class decoder -/// @brief Base SPD DRAM decoder -/// -class decoder -{ - protected: - char iv_target_str_storage[fapi2::MAX_ECMD_STRING_LEN]; + /// + /// @brief Sets decoder SPD data + /// @param[in] i_spd_data SPD data in a vector reference + /// + virtual void set_data(const std::vector<uint8_t>& i_spd_data) + { + iv_data = i_spd_data; + } /// - /// @brief Helper function that turns Logical ranks in Primary SDRAM type - /// @param[out] o_logical_ranks number of logical ranks - /// @return fapi2::FAPI2_RC_SUCCESS if okay + /// @brief Decodes number of used SPD bytes + /// @param[out] o_value number of SPD bytes used + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const + virtual fapi2::ReturnCode number_of_used_bytes( uint8_t& o_value ) const { - o_logical_ranks = 0; + o_value = 0; return fapi2::FAPI2_RC_SUCCESS; } /// - /// @brief Helper functions that returns Logical ranks in Secondary SDRAM type - /// @param[out] o_logical_ranks number of logical ranks - /// @return fapi2::FAPI2_RC_SUCCESS if okay + /// @brief Decodes SDP revision + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const + virtual fapi2::ReturnCode revision( uint8_t& o_value ) const { - o_logical_ranks = 0; + o_value = 0; return fapi2::FAPI2_RC_SUCCESS; } - public: - const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; - std::shared_ptr<dimm_module_decoder> iv_module_decoder; - std::vector<uint8_t> iv_spd_data; - rcw_settings iv_raw_card; - /// - /// @brief default ctor + /// @brief Decodes total number of SPD bytes + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - decoder() = default; + virtual fapi2::ReturnCode number_of_total_bytes( uint8_t& o_value ) const + { + o_value = 0; + return fapi2::FAPI2_RC_SUCCESS; + } /// - /// @brief ctor - /// @param[in] i_target dimm target - /// @param[in] i_spd_data SPD data vector - /// @param[in] i_module_decoder shared_ptr to dimm module decoder - /// @param[in] i_raw_card raw pointer to rcd data + /// @brief Decodes DRAM device type + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data, - const std::shared_ptr<dimm_module_decoder>& i_module_decoder, - const rcw_settings& i_raw_card) - : iv_target(i_target), - iv_module_decoder(i_module_decoder), - iv_spd_data(i_spd_data), - iv_raw_card(i_raw_card) + virtual fapi2::ReturnCode device_type( uint8_t& o_value ) const { - fapi2::toString(iv_target, iv_target_str_storage, fapi2::MAX_ECMD_STRING_LEN); + o_value = 0; + return fapi2::FAPI2_RC_SUCCESS; } /// - /// @brief Default dtor + /// @brief Decodes base module type + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual ~decoder() = default; - - ///////////////////////// - // Member Methods - ///////////////////////// + virtual fapi2::ReturnCode base_module( uint8_t& o_value ) const + { + o_value = 0; + return fapi2::FAPI2_RC_SUCCESS; + } /// - /// @brief Decodes number of used SPD bytes - /// @param[out] o_value number of SPD bytes used - /// @return FAPI2_RC_SUCCESS if okay + /// @brief Decodes hybrid media + /// @param[out] o_value number of total SPD bytes + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode number_of_used_bytes( uint16_t& o_value ) const + virtual fapi2::ReturnCode hybrid_media( uint8_t& o_value ) const { o_value = 0; return fapi2::FAPI2_RC_SUCCESS; } /// - /// @brief Decodes total number of SPD bytes + /// @brief Decodes hybrid /// @param[out] o_value number of total SPD bytes - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode number_of_total_bytes( uint16_t& o_value ) const + virtual fapi2::ReturnCode hybrid( uint8_t& o_value ) const { o_value = 0; return fapi2::FAPI2_RC_SUCCESS; @@ -199,7 +182,7 @@ class decoder /// /// @brief Decodes SDRAM density from SPD /// @param[out] o_value SDRAM density in GBs - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const { @@ -210,7 +193,7 @@ class decoder /// /// @brief Decodes number of SDRAM banks bits from SPD /// @param[out] o_value Number of SDRAM bank bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode bank_bits( uint8_t& o_value ) const { @@ -221,7 +204,7 @@ class decoder /// /// @brief Decodes number of SDRAM bank groups bits from SPD /// @param[out] o_value Number of SDRAM bank groups bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const { @@ -232,7 +215,7 @@ class decoder /// /// @brief Decodes number of SDRAM column address bits /// @param[out] o_value Number of SDRAM bank bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const { @@ -243,7 +226,7 @@ class decoder /// /// @brief Decodes number of SDRAM row address bits /// @param[out] o_value Number of SDRAM bank bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const { @@ -254,7 +237,7 @@ class decoder /// /// @brief Decodes Primary SDRAM signal loading /// @param[out] o_value Number of SDRAM bank bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const { @@ -265,7 +248,7 @@ class decoder /// /// @brief Decodes Primary SDRAM die count /// @param[out] o_value Number of SDRAM bank bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const { @@ -275,7 +258,7 @@ class decoder /// /// @brief Decodes Primary SDRAM package type - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const { @@ -285,9 +268,9 @@ class decoder /// /// @brief Decode SDRAM Maximum activate count - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode maximum_activate_count( uint32_t& o_value ) const + virtual fapi2::ReturnCode maximum_activate_count( uint8_t& o_value ) const { o_value = 0; return fapi2::FAPI2_RC_SUCCESS; @@ -295,9 +278,9 @@ class decoder /// /// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// - virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint32_t& o_value ) const + virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint8_t& o_value ) const { o_value = 0; return fapi2::FAPI2_RC_SUCCESS; @@ -305,7 +288,7 @@ class decoder /// /// @brief Decode Post package repair (PPR) - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const { @@ -315,7 +298,7 @@ class decoder /// /// @brief Decode Soft post package repair (soft PPR) - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const { @@ -325,7 +308,7 @@ class decoder /// /// @brief Decodes Secondary SDRAM signal loading - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const { @@ -335,7 +318,7 @@ class decoder /// /// @brief Decodes Secondary DRAM Density Ratio - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const { @@ -345,7 +328,7 @@ class decoder /// /// @brief Decodes Secondary SDRAM die count - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const { @@ -355,7 +338,7 @@ class decoder /// /// @brief Decodes Secondary SDRAM package type - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const { @@ -366,7 +349,7 @@ class decoder /// /// @brief Decode Module Nominal Voltage, VDD /// @param[out] o_value enum representing if 1.2V is operable - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const { @@ -377,17 +360,18 @@ class decoder /// /// @brief Decode Module Nominal Voltage, VDD /// @param[out] o_value enum representing if 1.2V is endurant - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const { o_value = 0; return fapi2::FAPI2_RC_SUCCESS; } + /// /// @brief Decodes SDRAM device width /// @param[out] o_value device width in bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode device_width( uint8_t& o_value ) const { @@ -398,7 +382,7 @@ class decoder /// /// @brief Decodes number of package ranks per DIMM /// @param[out] o_value number of package ranks per DIMM - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const { @@ -409,7 +393,7 @@ class decoder /// /// @brief Decodes Rank Mix /// @param[out] o_value rank mix value from SPD - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const { @@ -420,7 +404,7 @@ class decoder /// /// @brief Decodes primary bus width /// @param[out] o_value primary bus width in bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const { @@ -431,7 +415,7 @@ class decoder /// /// @brief Decodes bus width extension /// @param[out] o_value bus width extension in bits - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const { @@ -442,7 +426,7 @@ class decoder /// /// @brief Decode Module Thermal Sensor /// @param[out] o_value thermal sensor value from SPD - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const { @@ -453,7 +437,7 @@ class decoder /// /// @brief Decode Extended Base Module Type /// @param[out] o_value extended base module type value from SPD - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const { @@ -464,7 +448,7 @@ class decoder /// /// @brief Decode Fine Timebase /// @param[out] o_value fine_timebase from SPD in picoseconds - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_timebase( int64_t& o_value ) const { @@ -475,7 +459,7 @@ class decoder /// /// @brief Decode Medium Timebase /// @param[out] o_value fine_timebase from SPD in picoseconds - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode medium_timebase( int64_t& o_value ) const { @@ -487,7 +471,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Cycle Time in MTB /// @param[out] o_value tCKmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_tck( int64_t& o_value ) const { @@ -498,7 +482,7 @@ class decoder /// /// @brief Decodes SDRAM Maximum Cycle Time in MTB /// @param[out] o_value tCKmax in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode max_tck( int64_t& o_value ) const { @@ -509,7 +493,7 @@ class decoder /// /// @brief Decode CAS Latencies Supported /// @param[out] o_value bitmap of supported CAS latencies - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const { @@ -520,7 +504,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum CAS Latency Time in MTB /// @param[out] o_value tAAmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_taa( int64_t& o_value ) const { @@ -531,7 +515,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB /// @param[out] o_value tRCDmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trcd( int64_t& o_value ) const { @@ -542,7 +526,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB /// @param[out] o_value tRPmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trp( int64_t& o_value ) const { @@ -553,7 +537,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB /// @param[out] o_value tRASmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_tras( int64_t& o_value ) const { @@ -564,7 +548,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB /// @param[out] o_value tRCmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trc( int64_t& o_value ) const { @@ -575,7 +559,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1 /// @param[out] o_value tRFC1min in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trfc1( int64_t& o_value ) const { @@ -586,7 +570,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2 /// @param[out] o_value tRFC2min in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trfc2( int64_t& o_value ) const { @@ -597,7 +581,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4 /// @param[out] o_value tRFC4min in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trfc4( int64_t& o_value ) const { @@ -608,7 +592,7 @@ class decoder /// /// @brief Decodes SDRAM Minimum Four Activate Window Delay Time /// @param[out] o_value tFAWmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_tfaw( int64_t& o_value ) const { @@ -619,7 +603,7 @@ class decoder /// /// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group /// @param[out] o_value tRRD_Smin MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const { @@ -630,7 +614,7 @@ class decoder /// /// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group /// @param[out] o_value tRRD_Lmin MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const { @@ -641,7 +625,7 @@ class decoder /// /// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group /// @param[out] o_value tCCD_Lmin MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const { @@ -652,7 +636,7 @@ class decoder /// /// @brief Decodes Minimum Write Recovery Time /// @param[out] o_value tWRmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const { @@ -663,7 +647,7 @@ class decoder /// /// @brief Decodes Minimum Write to Read Time - Different Bank Group /// @param[out] o_value tWRT_Smin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const { @@ -674,7 +658,7 @@ class decoder /// /// @brief Decodes Minimum Write to Read Time - Same Bank Group /// @param[out] o_value tWRT_Lmin in MTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const { @@ -707,7 +691,7 @@ class decoder /// /// @brief Decodes Fine Offset for Minimum CAS to CAS Delay Time - Same Bank Group /// @param[out] o_value tCCD_Lmin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const { @@ -718,7 +702,7 @@ class decoder /// /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group /// @param[out] o_value tRRD_Lmin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const { @@ -729,7 +713,7 @@ class decoder /// /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group /// @param[out] o_value tRRD_Smin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const { @@ -740,7 +724,7 @@ class decoder /// /// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time /// @param[out] o_value tRCmin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const { @@ -751,7 +735,7 @@ class decoder /// /// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time /// @param[out] o_value tRPmin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const { @@ -762,7 +746,7 @@ class decoder /// /// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time /// @param[out] o_value tRCDmin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const { @@ -773,7 +757,7 @@ class decoder /// /// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time /// @param[out] o_value tAAmin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const { @@ -784,7 +768,7 @@ class decoder /// /// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time /// @param[out] o_value tCKmax offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const { @@ -795,7 +779,7 @@ class decoder /// /// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time /// @param[out] o_value tCKmin offset in FTB units - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const { @@ -806,7 +790,7 @@ class decoder /// /// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section /// @param[out] o_value crc value from SPD - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const { @@ -817,7 +801,7 @@ class decoder /// /// @brief Decodes module manufacturer ID code /// @param[out] o_output module manufacturing id code - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const { @@ -828,7 +812,7 @@ class decoder /// /// @brief Decodes Module Manufacturing Location /// @param[out] o_value uint8_t identifier for manufacturing location of memory module - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const { @@ -839,7 +823,7 @@ class decoder /// /// @brief Decodesmodule manufacturing date /// @param[out] o_value the 2 byte date of manufacturing in BCD format - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay virtual fapi2::ReturnCode module_manufacturing_date( uint16_t& o_value ) const { o_value = 0; @@ -849,7 +833,7 @@ class decoder /// /// @brief Decodes module's unique serial number /// @param[out] o_value module's serial number - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode module_serial_number( uint32_t& o_value ) const { @@ -860,7 +844,7 @@ class decoder /// /// @brief Decodes Module Revision Code /// @param[out] o_value uint8_t identifier for revision code - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const { @@ -871,7 +855,7 @@ class decoder /// /// @brief Decodes DRAM Manufacturer ID code /// @param[out] o_value dram manufacturing id code - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const { @@ -880,50 +864,16 @@ class decoder } /// - /// @brief Decodes RCD Manufacturer ID code - /// @param[out] o_value rcd manufacturing id code - /// @return FAPI2_RC_SUCCESS if okay - /// - virtual fapi2::ReturnCode reg_manufacturer_id_code( uint16_t& o_value ) const - { - o_value = 0; - return fapi2::FAPI2_RC_SUCCESS; - } - - /// - /// @brief Decodes Register Revision Number - /// @param[out] o_value register revision number - /// @return FAPI2_RC_SUCCESS if okay - /// - virtual fapi2::ReturnCode register_rev_num( uint8_t& o_value ) const - { - o_value = 0; - return fapi2::FAPI2_RC_SUCCESS; - } - - /// /// @brief Decodes DRAM Stepping /// @param[out] o_value uint8_t DRAM Stepping val - /// @return FAPI2_RC_SUCCESS if okay + /// @return FAPI2_RC_SUCCESS iff okay /// virtual fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const { o_value = 0; return fapi2::FAPI2_RC_SUCCESS; } - - /// - /// @brief Returns Logical ranks per DIMM - /// @param[out] o_logical_ranks number of logical ranks - /// @return FAPI2_RC_SUCCESS if okay - /// - virtual fapi2::ReturnCode logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const - { - o_logical_rank_per_dimm = 0; - return fapi2::FAPI2_RC_SUCCESS; - } - -};// decoder +}; }// spd }// mss diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H index f8031274e..49220680c 100644 --- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H +++ b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H @@ -39,84 +39,107 @@ #include <fapi2.H> #include <vector> +#include <generic/memory/lib/spd/spd_decoder_def.H> #include <generic/memory/lib/spd/common/dimm_module_decoder.H> +#include <generic/memory/lib/spd/spd_reader.H> namespace mss { namespace spd { -namespace ddr4 -{ -namespace lrdimm -{ /// -/// @brief LRDIMM module decoder for revision 1.0 +/// @brief LRDIMM module decoder +/// @tparam R SPD revision - partial specialization /// -class decoder_v1_0 : public dimm_module_decoder +template < rev R > +class decoder<DDR4, LRDIMM_MODULE, R > : public dimm_module_decoder { - public: - - // First field - SPD byte - // Second field - start bit - // Third field - bit length - constexpr static field_t MODULE_NOMINAL_HEIGHT{128, 3, 5}; - constexpr static field_t RAW_CARD_EXTENSION{128, 0, 3}; - - constexpr static field_t FRONT_MODULE_THICKNESS{129, 4, 4}; - constexpr static field_t BACK_MODULE_THICKNESS{129, 0, 4}; - - constexpr static field_t NUM_REGISTERS_USED{131, 6, 2}; - constexpr static field_t NUM_ROWS_OF_DRAMS{131, 4, 2}; - constexpr static field_t REGISTER_TYPE{131, 0, 4}; - - constexpr static field_t HEAT_SPREADER_THERM_CHAR{132, 1, 7}; - constexpr static field_t HEAT_SPREADER_SOLUTION{132, 0, 1}; - - constexpr static field_t CONTINUATION_CODES{133, 1, 7}; - constexpr static field_t ADDR_MAPPING{136, 7, 1}; - - constexpr static field_t CKE_DRIVE_STRENGTH{137, 6, 2}; - constexpr static field_t ODT_DRIVE_STRENGTH{137, 4, 2}; - constexpr static field_t CA_DRIVE_STRENGTH{137, 2, 2}; - constexpr static field_t CS_DRIVE_STRENGTH{137, 0, 2}; + private: - constexpr static field_t B_SIDE_DRIVE_STRENGTH{138, 6, 2}; - constexpr static field_t A_SIDE_DRIVE_STRENGTH{138, 4, 2}; - constexpr static field_t BCOM_BODT_BCKE_DRIVE_STRENGTH{138, 3, 1}; - constexpr static field_t BCK_DRIVE_STRENGTH{138, 2, 1}; - constexpr static field_t RCD_SLEW_CNTRL{138, 1, 1 }; + using fields_t = fields<DDR4, LRDIMM_MODULE>; + fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + std::vector<uint8_t> iv_data; - constexpr static field_t VREF_DQ_RANK0{140, 2, 6}; - constexpr static field_t VREF_DQ_RANK1{141, 2, 6}; - constexpr static field_t VREF_DQ_RANK2{142, 2, 6}; - constexpr static field_t VREF_DQ_RANK3{143, 2, 6}; - - constexpr static field_t DATA_BUFFER_MDQ{145, 1, 3}; - - constexpr static field_t DRAM_VREF_DQ_RANGE{155, 4, 4}; - constexpr static field_t DATA_BUFFER_VREF_DQ{155, 3, 1}; + /// + /// @brief Helper function to check for reserved values for DRAM interface MDQ Drive Strenth + /// @tparam T SPD revision + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[in] i_input value to check reserved bits against + /// @return FAPI2_RC_SUCCESS iff okay + /// + template < rev T > + fapi2::ReturnCode check_for_reserved_values(const uint64_t i_dimm_speed, + const uint8_t i_input) const + { + static_assert(T <= LRDIMM_MAX, "Invalid SPD revision"); + const std::vector<size_t> l_reserved_bits{0b011, 0b100, 0b110, 0b111}; + + // Lets make an additinal check that we aren't being set to a reserved field + FAPI_ASSERT( !std::binary_search(l_reserved_bits.begin(), l_reserved_bits.end(), i_input), + fapi2::MSS_INVALID_DB_MDQ_DRIVE_STRENGTH() + .set_DATA_RATE(i_dimm_speed) + .set_TARGET(iv_target), + "Reserved settings for data buffer MDQ drive strength received for dimm speed %d on %s", + i_dimm_speed, + spd::c_str(iv_target) ); + + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + return fapi2::current_err; + } - constexpr static field_t DATA_BUFFER_GAIN_ADJUST{156, 7, 1}; - constexpr static field_t DATA_BUFFER_DFE{156, 6, 1}; + public: // deleted default ctor - decoder_v1_0() = delete; + decoder() = delete; /// /// @brief ctor /// @param[in] i_target dimm target /// @param[in] i_spd_data vector DIMM SPD data /// - decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data) - : dimm_module_decoder(i_target, i_spd_data) - {} + decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data): + dimm_module_decoder(i_target, i_spd_data), + iv_target(i_target), + iv_data(i_spd_data) + { + static_assert( R <= rev::LRDIMM_MAX, " R > rev::LRDIMM_MAX"); + } /// /// @brief default dtor /// - virtual ~decoder_v1_0() = default; + virtual ~decoder() = default; + + /// + /// @brief Gets decoder target + /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM> + /// + virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const + { + return iv_target; + } + + /// + /// @brief Gets decoder SPD data + /// @return std::vector<uint8_t> + /// + virtual std::vector<uint8_t> get_data() const + { + return iv_data; + } + + /// + /// @brief Sets decoder SPD data + /// @param[in] i_spd_data SPD data in a vector reference + /// + virtual void set_data(const std::vector<uint8_t>& i_spd_data) + { + iv_data = i_spd_data; + } /// /// @brief Decodes module nominal height max @@ -127,7 +150,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 55 /// - virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override; + virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_NOMINAL_HEIGHT, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes raw card extension @@ -138,7 +167,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 55 /// - virtual fapi2::ReturnCode raw_card_extension(uint8_t& o_output) const override; + virtual fapi2::ReturnCode raw_card_extension(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::RAW_CARD_EXT, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes front module maximum thickness max @@ -149,7 +184,14 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 55 /// - virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override; + virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::FRONT_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + + } /// /// @brief Decodes back module maximum thickness max @@ -160,7 +202,31 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 55 /// - virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override; + virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BACK_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + + } + + /// + /// @brief Decodes reference raw card used + /// @param[out] o_output encoding from SPD + /// @return FAPI2_RC_SUCCESS if okay + /// @note SPD Byte 130 (Bits 7~0) + /// @note Item JEDEC Standard No. 21-C + /// @note DDR4 SPD Document Release 2 + /// @note Page 4.1.2.12 - 48 + /// + virtual fapi2::ReturnCode reference_raw_card(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::REF_RAW_CARD, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of registers used on LRDIMM @@ -171,7 +237,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 57 /// - virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override; + virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::NUM_REGS_USED, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of rows of DRAMs on LRDIMM @@ -182,29 +254,49 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 57 /// - virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override; + virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ROWS_OF_DRAMS, rev::V1_0>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + + } /// - /// @brief Decodes heat spreader solution - /// @param[out] o_output drive strength encoding from SPD + /// @brief Decodes register and data buffer types + /// @param[out] o_output encoding from SPD /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 132 (Bit 7) + /// @note SPD Byte 131 (Bits 7~4) /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12.2 - 58 + /// @note DDR4 SPD Document Release 3 + /// @note Page 4.1.2.12.3 - 63 /// - virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override; + virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_TYPE, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + + } /// - /// @brief Decodes number of continuation codes + /// @brief Decodes heat spreader solution /// @param[out] o_output drive strength encoding from SPD /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 133 (Bits 6~0) + /// @note SPD Byte 132 (Bit 7) /// @note Item JEDEC Standard No. 21-C /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 58 /// - virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output) const override; + virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::HEAT_SPREADER_SOL, rev::V1_0>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register manufacturer ID code @@ -215,7 +307,28 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 58 /// - virtual fapi2::ReturnCode reg_manufacturer_id_code(uint8_t& o_output) const override; + virtual fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_output) const override + { + uint8_t l_cont_codes = 0; + uint8_t l_last_nonzero_byte = 0; + + FAPI_TRY( (mss::spd::reader<fields_t::CONTINUATION_CODES, R>(iv_target, iv_data, l_cont_codes)) ); + FAPI_TRY( (mss::spd::reader<fields_t::LAST_NON_ZERO_BYTE, R>(iv_target, iv_data, l_last_nonzero_byte)) ); + + { + fapi2::buffer<uint16_t> l_buffer; + rightAlignedInsert(l_buffer, l_last_nonzero_byte, l_cont_codes); + + o_output = l_buffer; + + FAPI_INF("%s.Module Manufacturer ID Code: 0x%04x", + spd::c_str(iv_target), + o_output); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register revision number @@ -226,7 +339,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 58 /// - virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override; + virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_REV, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes address mapping from register to dram @@ -237,7 +356,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 59 /// - virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override; + virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ADDR_MAP_REG_TO_DRAM, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for CKE signal @@ -247,7 +372,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 60 /// - virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::CKE_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for ODT signal @@ -258,7 +389,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 60 /// - virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ODT_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for command/address (CA) signal @@ -269,7 +406,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 60 /// - virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::CA_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for control signal (CS) signal @@ -280,7 +423,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 60 /// - virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::CS_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for clock (B side) @@ -291,7 +440,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 60 /// - virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::YO_Y2_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for clock (A side) @@ -302,7 +457,65 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 60 /// - virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::Y1_Y3_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE) + /// @param[out] o_output encoded drive strength + /// @return FAPI2_RC_SUCCESS if okay + /// @note SPD Byte 138 (Bit 4) + /// @note Item JEDEC Standard No. 21-C + /// @note DDR4 SPD Document Release 3 + /// @note Page 4.1.2.12.3 - 66 + /// + virtual fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BCOM_BODT_BCKE_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for data buffer control (BCK) + /// @param[out] o_output encoded drive strength + /// @return FAPI2_RC_SUCCESS if okay + /// @note SPD Byte 138 (Bit 5) + /// @note Item JEDEC Standard No. 21-C + /// @note DDR4 SPD Document Release 3 + /// @note Page 4.1.2.12.3 - 66 + /// + virtual fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BCK_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes RCD output slew rate control + /// @param[out] o_output encoded drive strength + /// @return FAPI2_RC_SUCCESS if okay + /// @note SPD Byte 138 (Bit 6) + /// @note Item JEDEC Standard No. 21-C + /// @note DDR4 SPD Document Release 4 + /// @note Page 4.1.2.L-4 - 70 + /// + virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::RCD_SLEW_CNTRL, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes data buffer revision number @@ -313,7 +526,14 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 60 /// - virtual fapi2::ReturnCode data_buffer_rev(uint8_t& o_output) const override; + virtual fapi2::ReturnCode data_buffer_rev(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_REV, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes DRAM VrefDQ for Package Rank 0 @@ -324,7 +544,14 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 61 /// - virtual fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK0, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes DRAM VrefDQ for Package Rank 1 @@ -335,7 +562,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 61 /// - virtual fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK1, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes DRAM VrefDQ for Package Rank 2 @@ -346,7 +579,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 61 /// - virtual fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK2, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes DRAM VrefDQ for Package Rank 3 @@ -357,7 +596,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 61 /// - virtual fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK3, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes data buffer VrefDQ for DRAM interface @@ -368,7 +613,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 61 /// - virtual fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_output) const override; + virtual fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_VREF_DQ, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes DRAM interface MDQ Drive Strenth @@ -382,7 +633,49 @@ class decoder_v1_0 : public dimm_module_decoder /// @note Page 4.1.2.12.2 - 62 /// virtual fapi2::ReturnCode data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed, - uint8_t& o_output) const override; + uint8_t& o_output) const override + { + switch(i_dimm_speed) + { + case mss::DIMM_SPEED_1600: + case mss::DIMM_SPEED_1866: + FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_LTE_1866, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2133: + case mss::DIMM_SPEED_2400: + FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_LTE_2400, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2666: + case mss::DIMM_SPEED_2933: + case mss::DIMM_SPEED_3200: + FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_LTE_3200, R>(iv_target, iv_data, o_output)) ); + break; + + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_SPEED() + .set_DIMM_SPEED(i_dimm_speed) + .set_TARGET(iv_target), + "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target)); + break; + } + + // Lets make an additinal check that we aren't being set to a reserved field + FAPI_TRY((check_for_reserved_values<R>(i_dimm_speed, o_output)), + "Failed reserved bit check for %s", spd::c_str(iv_target)); + + // If we are here we have a valid output, exit + // to avoid error path of fapi_try_exit + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + // A little output clean up if we fail out + o_output = 0; + return fapi2::current_err; + } + /// /// @brief Decodes DRAM interface MDQ read termination strength @@ -395,7 +688,41 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 62 /// - virtual fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output) const override; + virtual fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output) const override + { + switch(i_dimm_speed) + { + case mss::DIMM_SPEED_1600: + case mss::DIMM_SPEED_1866: + FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_RTT_LTE_1866, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2133: + case mss::DIMM_SPEED_2400: + FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_RTT_LTE_2400, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2666: + case mss::DIMM_SPEED_2933: + case mss::DIMM_SPEED_3200: + FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_RTT_LTE_3200, R>(iv_target, iv_data, o_output)) ); + break; + + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_SPEED() + .set_DIMM_SPEED(i_dimm_speed) + .set_TARGET(iv_target), + "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target)); + break; + } + + return fapi2::FAPI2_RC_SUCCESS; + + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes DRAM drive strenth @@ -408,7 +735,41 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 63 /// - virtual fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const override + { + switch(i_dimm_speed) + { + case mss::DIMM_SPEED_1600: + case mss::DIMM_SPEED_1866: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_DRIVE_STRENGTH_LTE_1866, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2133: + case mss::DIMM_SPEED_2400: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_DRIVE_STRENGTH_LTE_2400, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2666: + case mss::DIMM_SPEED_2933: + case mss::DIMM_SPEED_3200: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_DRIVE_STRENGTH_LTE_3200, R>(iv_target, iv_data, o_output)) ); + break; + + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_SPEED() + .set_DIMM_SPEED(i_dimm_speed) + .set_TARGET(iv_target), + "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target)); + break; + } + + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes DRAM ODT for RTT_NOM @@ -421,7 +782,42 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - (64 - 65) /// - virtual fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output) const override + { + switch(i_dimm_speed) + { + case mss::DIMM_SPEED_1600: + case mss::DIMM_SPEED_1866: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_NOM_LTE_1866, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2133: + case mss::DIMM_SPEED_2400: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_NOM_LTE_2400, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2666: + case mss::DIMM_SPEED_2933: + case mss::DIMM_SPEED_3200: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_NOM_LTE_3200, R>(iv_target, iv_data, o_output)) ); + break; + + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_SPEED() + .set_DIMM_SPEED(i_dimm_speed) + .set_TARGET(iv_target), + "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target)); + + break; + } + + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes DRAM ODT for RTT_WR @@ -434,7 +830,41 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - (64 - 65) /// - virtual fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output) const override + { + switch(i_dimm_speed) + { + case mss::DIMM_SPEED_1600: + case mss::DIMM_SPEED_1866: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_WR_LTE_1866, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2133: + case mss::DIMM_SPEED_2400: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_WR_LTE_2400, R>(iv_target, iv_data, o_output)) ); + break; + + case mss::DIMM_SPEED_2666: + case mss::DIMM_SPEED_2933: + case mss::DIMM_SPEED_3200: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_WR_LTE_3200, R>(iv_target, iv_data, o_output)) ); + break; + + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_SPEED() + .set_DIMM_SPEED(i_dimm_speed) + .set_TARGET(iv_target), + "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target)); + + break; + } + + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1 @@ -447,172 +877,95 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12.2 - 65 /// - virtual fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output) const override + { + switch(i_dimm_speed) + { + case mss::DIMM_SPEED_1600: + case mss::DIMM_SPEED_1866: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R01_LTE_1866, R>(iv_target, iv_data, + o_output)) ); + break; - /// - /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3 - /// for a particular dimm speed - /// @param[in] i_dimm_speed the dimm speed in MT/s - /// @param[out] o_output ODT termination strength (in ohms) - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 152 - 154 (Bits 5~3) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12.2 - 65 - /// - virtual fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output) const override; - -};//decoder - -/// -/// @brief LRDIMM module decoder for revision 1.1 -/// -class decoder_v1_1 : public decoder_v1_0 -{ - public: - - // deleted default ctor - decoder_v1_1() = delete; - - /// - /// @brief ctor - /// @param[in] i_target dimm target - /// @param[in] i_spd_data vector DIMM SPD data - /// - decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data) - : decoder_v1_0(i_target, i_spd_data) - {} - - /// - /// @brief default dtor - /// - virtual ~decoder_v1_1() = default; - - /// - /// @brief Decodes register and data buffer types - /// @param[out] o_output encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 131 (Bits 7~4) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 63 - /// - virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for CKE signal - /// @param[out] o_output encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 137 (Bits 1~0) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 65 - /// - virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for ODT signal - /// @param[out] o_output encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 137 (Bits 3~2) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 65 - /// - virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for control signal (CS) signal - /// @param[out] o_output encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 137 (Bits 6~7) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 65 - /// - virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for clock (B side) - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 138 (Bits 1~0) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 66 - /// - virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for clock (A side) - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 138 (Bits 3~2) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 66 - /// - virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override; -}; + case mss::DIMM_SPEED_2133: + case mss::DIMM_SPEED_2400: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R01_LTE_2400, R>(iv_target, iv_data, + o_output)) ); + break; -/// -/// @brief LRDIMM module decoder for revision 1.2 -/// -class decoder_v1_2 : public decoder_v1_1 -{ - public: + case mss::DIMM_SPEED_2666: + case mss::DIMM_SPEED_2933: + case mss::DIMM_SPEED_3200: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R01_LTE_3200, R>(iv_target, iv_data, + o_output)) ); + break; - // deleted default ctor - decoder_v1_2() = delete; + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_SPEED() + .set_DIMM_SPEED(i_dimm_speed) + .set_TARGET(iv_target), + "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target)); - /// - /// @brief ctor - /// @param[in] i_target dimm target - /// @param[in] i_spd_data vector DIMM SPD data - /// - decoder_v1_2(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data) - : decoder_v1_1(i_target, i_spd_data) - {} + break; + } - /// - /// @brief default dtor - /// - virtual ~decoder_v1_2() = default; + return fapi2::FAPI2_RC_SUCCESS; - /// - /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE) - /// @param[out] o_output encoded drive strength - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 138 (Bit 4) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 66 - /// - virtual fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_output) const override; + fapi_try_exit: + return fapi2::current_err; + } - /// - /// @brief Decodes register output drive strength for data buffer control (BCK) - /// @param[out] o_output encoded drive strength - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 138 (Bit 5) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 66 - /// - virtual fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_output) const override; /// - /// @brief Decodes RCD output slew rate control - /// @param[out] o_output encoded drive strength + /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3 + /// for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_output ODT termination strength (in ohms) /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 138 (Bit 6) + /// @note SPD Byte 152 - 154 (Bits 5~3) /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 4 - /// @note Page 4.1.2.L-4 - 70 + /// @note DDR4 SPD Document Release 2 + /// @note Page 4.1.2.12.2 - 65 /// - virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output) const override + { + switch(i_dimm_speed) + { + case mss::DIMM_SPEED_1600: + case mss::DIMM_SPEED_1866: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R23_LTE_1866, R>(iv_target, iv_data, + o_output)) ); + break; + + case mss::DIMM_SPEED_2133: + case mss::DIMM_SPEED_2400: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R23_LTE_2400, R>(iv_target, iv_data, + o_output)) ); + break; + + case mss::DIMM_SPEED_2666: + case mss::DIMM_SPEED_2933: + case mss::DIMM_SPEED_3200: + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R23_LTE_3200, R>(iv_target, iv_data, + o_output)) ); + break; + + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_SPEED() + .set_DIMM_SPEED(i_dimm_speed) + .set_TARGET(iv_target), + "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target)); + + break; + } + + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes VrefDQ range for DRAM interface range @@ -623,7 +976,14 @@ class decoder_v1_2 : public decoder_v1_1 /// @note DDR4 SPD Document Release 4 /// @note Page 4.1.2.L-4 - 76 /// - virtual fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_output) const override; + virtual fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::DRAM_VREF_DQ_RANGE, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + /// /// @brief Decodes data buffer VrefDQ range for DRAM interface range @@ -634,7 +994,13 @@ class decoder_v1_2 : public decoder_v1_1 /// @note DDR4 SPD Document Release 4 /// @note Page 4.1.2.L-4 - 76 /// - virtual fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_output) const override; + virtual fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_VREF_DQ_RANGE, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes data buffer gain adjustment @@ -645,7 +1011,13 @@ class decoder_v1_2 : public decoder_v1_1 /// @note DDR4 SPD Document Release 4 /// @note Page 4.1.2.L-4 - 77 /// - virtual fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_output) const override; + virtual fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_GAIN_ADJUST, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes data buffer Decision Feedback Equalization (DFE) @@ -656,11 +1028,16 @@ class decoder_v1_2 : public decoder_v1_1 /// @note DDR4 SPD Document Release 4 /// @note Page 4.1.2.L-4 - 77 /// - virtual fapi2::ReturnCode data_buffer_dfe(uint8_t& o_output) const override; -}; + virtual fapi2::ReturnCode data_buffer_dfe(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_DFE, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + +};//decoder -}// lrdimm -}// ddr4 }// spd }// mss diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C deleted file mode 100644 index dc3ef9cad..000000000 --- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C +++ /dev/null @@ -1,1368 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/// -/// @file lrdimm_decoder_v1_0.C -/// @brief LRDIMM module SPD decoder definitions for revision 1.0 -/// -// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -// std lib -#include <vector> - -// fapi2 -#include <fapi2.H> - -// mss lib -#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H> -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> -#include <generic/memory/lib/spd/spd_checker.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/find.H> - -using fapi2::TARGET_TYPE_MCA; -using fapi2::TARGET_TYPE_MCS; -using fapi2::TARGET_TYPE_DIMM; - - -namespace mss -{ -namespace spd -{ -namespace ddr4 -{ -namespace lrdimm -{ - -///////////////////////// -// Non-member helper functions -// For LRDIMM module rev 1.0 -///////////////////////// - -/// -/// @brief Helper function to find SPD byte based on freq -/// @param[in] i_dimm_speed DIMM speed in MT/s -/// @param[out] o_byte byte to extract spd from -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400, -/// -static fapi2::ReturnCode mdq_helper(const uint64_t i_dimm_speed, uint8_t& o_byte) -{ - switch(i_dimm_speed) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - o_byte = 145; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - o_byte = 146; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_byte = 147; - break; - - default: - FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed); - return fapi2::FAPI2_RC_INVALID_PARAMETER; - break; - } - - return fapi2::FAPI2_RC_SUCCESS; -}; - -/// -/// @brief Helper function to find start bit based on freq -/// @param[in] i_dimm_speed DIMM speed in MT/s -/// @param[out] o_start_bit start bit to extract SPD from -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400, -/// -static fapi2::ReturnCode drive_strength_start_bit_finder(const uint64_t i_dimm_speed, size_t& o_start_bit) -{ - switch(i_dimm_speed) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - o_start_bit = 6; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - o_start_bit = 4; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_start_bit = 2; - break; - - default: - FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed); - return fapi2::FAPI2_RC_INVALID_PARAMETER; - break; - } - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Helper function to find SPD byte based on freq -/// @param[in] i_dimm_speed DIMM speed in MT/s -/// @param[out] o_byte byte to extract spd from -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400, -/// -static fapi2::ReturnCode rtt_wr_and_nom_byte_finder(const uint64_t i_dimm_speed, size_t& o_byte) -{ - switch(i_dimm_speed) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - o_byte = 149; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - o_byte = 150; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_byte = 151; - break; - - default: - FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed); - return fapi2::FAPI2_RC_INVALID_PARAMETER; - break; - } - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Helper function to find SPD byte based on freq -/// @param[in] i_dimm_speed DIMM speed in MT/s -/// @param[out] o_byte byte to extract spd from -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400, -/// -static fapi2::ReturnCode rtt_park_byte_finder(const uint64_t i_dimm_speed, size_t& o_byte) -{ - switch(i_dimm_speed) - { - case fapi2::ENUM_ATTR_MSS_FREQ_MT1866: - o_byte = 152; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2133: - case fapi2::ENUM_ATTR_MSS_FREQ_MT2400: - o_byte = 153; - break; - - case fapi2::ENUM_ATTR_MSS_FREQ_MT2666: - o_byte = 154; - break; - - default: - FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed); - return fapi2::FAPI2_RC_INVALID_PARAMETER; - break; - } - - return fapi2::FAPI2_RC_SUCCESS; -} - -///////////////////////// -// Member Method implementation -// For LRDIMM module rev 1.0 -///////////////////////// - -/// -/// @brief Decodes module nominal height max -/// @param[out] o_output height range encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 128 (Bits 4~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 55 -/// -fapi2::ReturnCode decoder_v1_0::max_module_nominal_height(uint8_t& o_output) const -{ - const uint8_t l_field_bits = extract_spd_field< MODULE_NOMINAL_HEIGHT >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b11111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - MODULE_NOMINAL_HEIGHT.iv_byte, - l_field_bits, - "Failed bound check for module nominal height max") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Max module nominal height: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes raw card extension -/// @param[out] o_output raw card rev. encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 128 (Bits 7~5) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 55 -/// -fapi2::ReturnCode decoder_v1_0::raw_card_extension(uint8_t& o_output) const -{ - const uint8_t l_field_bits = extract_spd_field< RAW_CARD_EXTENSION >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - RAW_CARD_EXTENSION.iv_byte, - l_field_bits, - "Failed bound check for raw card extension") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Raw card extension: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes front module maximum thickness max -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 129 (Bits 3~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 55 -/// -fapi2::ReturnCode decoder_v1_0::front_module_max_thickness(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< FRONT_MODULE_THICKNESS >(iv_target, iv_spd_data); - - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b1111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - FRONT_MODULE_THICKNESS.iv_byte, - l_field_bits, - "Failed bound check for front module max thickness") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Front module max thickness: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes back module maximum thickness max -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 129 (Bits 7~4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 55 -/// -fapi2::ReturnCode decoder_v1_0::back_module_max_thickness(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< BACK_MODULE_THICKNESS >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b1111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - BACK_MODULE_THICKNESS.iv_byte, - l_field_bits, - "Failed bound check for back module max thickness") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Back module max thickness: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes number of registers used on LRDIMM -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 131 (Bits 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 57 -/// -fapi2::ReturnCode decoder_v1_0::num_registers_used(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< NUM_REGISTERS_USED >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 0b10; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - NUM_REGISTERS_USED.iv_byte, - l_field_bits, - "Failed bound check for number of registers used on RDIMM ") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Number of registers used on LRDIMM : %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes number of rows of DRAMs on LRDIMM -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 131 (Bits 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 57 -/// -fapi2::ReturnCode decoder_v1_0::num_rows_of_drams(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< NUM_ROWS_OF_DRAMS >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - NUM_REGISTERS_USED.iv_byte, - l_field_bits, - "Failed bound check for number of rows of DRAMs on LRDIMM ") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Number of rows of DRAMs on LRDIMM : %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes heat spreader solution -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 132 (Bit 7) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 58 -/// -fapi2::ReturnCode decoder_v1_0::heat_spreader_solution(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< HEAT_SPREADER_SOLUTION >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - HEAT_SPREADER_SOLUTION.iv_byte, - l_field_bits, - "Failed bound check for heat spreader solution") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Heat spreader solution: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes number of continuation codes -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 133 (bit 6~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 58 -/// -fapi2::ReturnCode decoder_v1_0::num_continuation_codes(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< CONTINUATION_CODES >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 10; // JEP106AS spec - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - CONTINUATION_CODES.iv_byte, - l_field_bits, - "Failed bound check for number of continuation codes") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Number of continuation codes: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register manufacturer ID code -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 134 (bit 7~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 58 -/// -fapi2::ReturnCode decoder_v1_0::reg_manufacturer_id_code(uint8_t& o_output) const -{ - constexpr size_t BYTE_INDEX = 134; - uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX]; - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_raw_byte); - - // All bits used for encoding, no bounds to check - o_output = l_raw_byte; - - FAPI_INF("%s. Register revision number: %d", - iv_target_str_storage, - o_output); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes register revision number -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 135 (bit 7~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 58 -/// -fapi2::ReturnCode decoder_v1_0::register_rev_num(uint8_t& o_output) const -{ - constexpr size_t BYTE_INDEX = 135; - uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX]; - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_raw_byte); - - // All bits used for encoding, no bounds to check - o_output = l_raw_byte; - - FAPI_INF("%s. Register revision number: %d", - iv_target_str_storage, - o_output); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes address mapping from register to dram -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 136 (bit 0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 59 -/// -fapi2::ReturnCode decoder_v1_0::register_to_dram_addr_mapping(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< ADDR_MAPPING >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - ADDR_MAPPING.iv_byte, - l_field_bits, - "Failed bound check for to register to dram addr mapping") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Address mapping from register to dram: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for CKE signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 60 -/// -fapi2::ReturnCode decoder_v1_0::cke_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< CKE_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - CKE_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CKE") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CKE: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for ODT signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 60 -/// -fapi2::ReturnCode decoder_v1_0::odt_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< ODT_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - ODT_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for ODT") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for ODT: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for command/address (CA) signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 5~4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 60 -/// -fapi2::ReturnCode decoder_v1_0::ca_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< CA_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t INVALID_VAL = 4; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < INVALID_VAL, // extract sanity check - CA_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CA") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CA: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for control signal (CS) signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 6~7) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 60 -/// -fapi2::ReturnCode decoder_v1_0::cs_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< CS_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - CS_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CS") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CS: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (B side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (bit 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 60 -/// -fapi2::ReturnCode decoder_v1_0::b_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< B_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - B_SIDE_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y0,Y2)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (A side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (bit 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 60 -/// -fapi2::ReturnCode decoder_v1_0::a_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< A_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - A_SIDE_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y1,Y3)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes data buffer revision number -/// @param[out] o_output revision number -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 139 (Bits 7~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 60 -/// -fapi2::ReturnCode decoder_v1_0::data_buffer_rev(uint8_t& o_output) const -{ - // Extracting desired bits - constexpr size_t BYTE_INDEX = 139; - const uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX]; - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_raw_byte); - - // This checks JEDEC range is met - constexpr size_t UNDEFINED = 0xFF; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_raw_byte != UNDEFINED, - BYTE_INDEX, - l_raw_byte, - "Failed bounds check for data buffer revision number") ); - - // Update output only if check passes - o_output = l_raw_byte; - - FAPI_INF("%s. Data buffer rev: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes DRAM VrefDQ for Package Rank 0 -/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 140 (Bits 5~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 61 -/// -fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank0(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK0 >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // JESD79-4 specification - constexpr size_t RESERVED = 0b110011; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - VREF_DQ_RANK0.iv_byte, - l_field_bits, - "Failed bounds check for DRAM VrefDQ for Package Rank 0") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM VrefDQ for Package Rank 0: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM VrefDQ for Package Rank 1 -/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 141 (Bits 5~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 61 -/// -fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank1(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK1 >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // JESD79-4 specification - constexpr size_t RESERVED = 0b110011; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - VREF_DQ_RANK1.iv_byte, - l_field_bits, - "Failed bounds check for DRAM VrefDQ for Package Rank 1") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM VrefDQ for Package Rank 1: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM VrefDQ for Package Rank 2 -/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 142 (Bits 5~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 61 -/// -fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank2(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK2 >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // JESD79-4 specification - constexpr size_t RESERVED = 0b110011; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - VREF_DQ_RANK2.iv_byte, - l_field_bits, - "Failed bounds check for DRAM VrefDQ for Package Rank 2") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM VrefDQ for Package Rank 2: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM VrefDQ for Package Rank 3 -/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 143 (Bits 5~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.12.2 - 61 -/// -fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank3(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK3 >(iv_target, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // JESD79-4 specification - constexpr size_t RESERVED = 0b110011; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - VREF_DQ_RANK3.iv_byte, - l_field_bits, - "Failed bounds check for DRAM VrefDQ for Package Rank 3") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM VrefDQ for Package Rank 3: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes data buffer VrefDQ for DRAM interface -/// @param[out] o_output encoding of F5BC6x in DDR4DB01 spec -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 144 (Bits 5~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 61 -/// -fapi2::ReturnCode decoder_v1_0::data_buffer_vref_dq(uint8_t& o_output) const -{ - constexpr size_t BYTE_INDEX = 144; - uint8_t l_raw_data = iv_spd_data[BYTE_INDEX]; - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_raw_data); - - // DDR4DB01 spec - constexpr size_t RESERVED = 0b00110011; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_raw_data < RESERVED, - BYTE_INDEX, - l_raw_data, - "Failed bounds check for data buffer VrefDQ for DRAM interface") ); - - // Update output only if check passes - o_output = l_raw_data; - - FAPI_INF("%s. Data buffer VrefDQ for DRAM interface: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM interface MDQ Drive Strenth -/// of the data buffer component for a particular dimm speed -/// @param[in] i_dimm_speed the dimm speed in MT/s -/// @param[out] o_output encoding of F5BC6x in -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 145 - 147 (Bits 6~4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 62 -/// -fapi2::ReturnCode decoder_v1_0::data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const -{ - uint8_t l_byte = 0; - - FAPI_TRY( mdq_helper(i_dimm_speed, l_byte) ); - - { - constexpr size_t START = 1; - constexpr size_t LEN = 3; - const field_t MDQ_DRIVE_STRENGTH(l_byte, START, LEN); - - const uint8_t l_field_bits = extract_spd_field( iv_target, MDQ_DRIVE_STRENGTH, iv_spd_data ); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // Lets make sure we aren't being set to a reserved field - bool is_reserved_bit = false; - - switch(l_field_bits) - { - case 0b011: - case 0b100: - case 0b110: - case 0b111: - is_reserved_bit = true; - break; - - default: - is_reserved_bit = false; - break; - } - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 7; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits <= MAX_VALID_VALUE) && - (is_reserved_bit != true), - l_byte, - l_field_bits, - "Failed bounds check for DRAM interface MDQ Drive Strenth") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM interface MDQ Drive Strenth: %d", - iv_target_str_storage, - o_output); - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM interface MDQ read termination strength -/// of the data buffer component for a particular dimm speed -/// @param[in] i_dimm_speed the dimm speed in MT/s -/// @param[out] o_output encoding of F5BC6x in -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 145 - 147 (Bits 2~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 62 -/// -fapi2::ReturnCode decoder_v1_0::data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output) const -{ - uint8_t l_byte = 0; - - FAPI_TRY( mdq_helper(i_dimm_speed, l_byte) ); - - { - constexpr size_t START = 1; - constexpr size_t LEN = 3; - const field_t DATA_BUFFER_MDQ_RTT(l_byte, START, LEN); - - const uint8_t l_field_bits = extract_spd_field( iv_target, DATA_BUFFER_MDQ_RTT, iv_spd_data ); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 7; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - l_byte, - l_field_bits, - "Failed bounds check for DRAM interface MDQ RTT:") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM interface MDQ RTT: %d", - iv_target_str_storage, - o_output); - } -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM drive strenth -/// for a particular dimm speed -/// @param[in] i_dimm_speed the dimm speed in MT/s -/// @param[out] o_output DRAM drive strength (encoding) -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 148 (Bits 5~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 63 -/// -fapi2::ReturnCode decoder_v1_0::dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const -{ - size_t l_start = 0; - FAPI_TRY( drive_strength_start_bit_finder(i_dimm_speed, l_start) ); - - { - constexpr size_t BYTE_INDEX = 148; - constexpr size_t LEN = 2; - const field_t DRAM_DRIVE_STRENGTH(BYTE_INDEX, l_start, LEN); - - const uint8_t l_field_bits = extract_spd_field( iv_target, DRAM_DRIVE_STRENGTH, iv_spd_data ); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // SPD JEDEC specification - constexpr size_t RESERVED = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - BYTE_INDEX, - l_field_bits, - "Failed bounds check for DRAM VrefDQ for Package Rank 3") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM drive strenth: %d", - iv_target_str_storage, - o_output); - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM ODT for RTT_NOM -/// for a particular dimm speed -/// @param[in] i_dimm_speed the dimm speed in MT/s -/// @param[out] o_output ODT termination strength (encoding) -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 149 - 151 (Bits 2~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - (64 - 65) -/// -fapi2::ReturnCode decoder_v1_0::dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output) const -{ - size_t l_byte = 0; - FAPI_TRY( rtt_wr_and_nom_byte_finder(i_dimm_speed, l_byte) ); - - { - constexpr size_t START = 5; - constexpr size_t LEN = 3; - const field_t DRAM_RTT_NOM(l_byte, START, LEN); - - const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_NOM, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 7; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - l_byte, - l_field_bits, - "Failed bounds check for DRAM RTT_NOM") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM RTT_NOM: %d", - iv_target_str_storage, - o_output); - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM ODT for RTT_WR -/// for a particular dimm speed -/// @param[in] i_dimm_speed the dimm speed in MT/s -/// @param[out] o_output ODT termination strength (encoding) -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 149 - 151 (Bits 5~3) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - (64 - 65) -/// -fapi2::ReturnCode decoder_v1_0::dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output) const -{ - size_t l_byte = 0; - FAPI_TRY( rtt_wr_and_nom_byte_finder(i_dimm_speed, l_byte) ); - - { - constexpr size_t START = 2; - constexpr size_t LEN = 3; - const field_t DRAM_RTT_WR(l_byte, START, LEN); - - const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_WR, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // Lets make sure we aren't being set to a reserved field - bool is_reserved_bit = false; - - switch(l_field_bits) - { - case 0b101: - case 0b110: - case 0b111: - is_reserved_bit = true; - break; - - default: - is_reserved_bit = false; - break; - } - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 7; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits <= MAX_VALID_VALUE) && - (is_reserved_bit != true), - l_byte, - l_field_bits, - "Failed bounds check for DRAM RTT_WR") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM_RTT_WR: %d", - iv_target_str_storage, - o_output); - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1 -/// for a particular dimm speed -/// @param[in] i_dimm_speed the dimm speed in MT/s -/// @param[out] o_output ODT termination strength (encoding) -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 152 - 154 (Bits 2~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 65 -/// -fapi2::ReturnCode decoder_v1_0::dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output) const -{ - size_t l_byte = 0; - FAPI_TRY( rtt_park_byte_finder(i_dimm_speed, l_byte) ); - - { - constexpr size_t START = 5; - constexpr size_t LEN = 3; - const field_t DRAM_RTT_PARK(l_byte, START, LEN); - - const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_PARK, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 7; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - l_byte, - l_field_bits, - "Failed bounds check for DRAM RTT_PARK (package ranks 0,1)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM RTT_PARK (package ranks 0,1): %d", - iv_target_str_storage, - o_output); - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3 -/// for a particular dimm speed -/// @param[in] i_dimm_speed the dimm speed in MT/s -/// @param[out] o_output ODT termination strength (encoding) -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 152 - 154 (Bits 5~3) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12.2 - 65 -/// -fapi2::ReturnCode decoder_v1_0::dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output) const -{ - size_t l_byte = 0; - FAPI_TRY( rtt_park_byte_finder(i_dimm_speed, l_byte) ); - - { - constexpr size_t START = 2; - constexpr size_t LEN = 3; - const field_t DRAM_RTT_PARK(l_byte, START, LEN); - - const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_PARK, iv_spd_data); - FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 7; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - l_byte, - l_field_bits, - "Failed bounds check for DRAM RTT_PARK (package ranks 2,3)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. DRAM RTT_PARK (package ranks 2,3): %d", - iv_target_str_storage, - o_output); - } - -fapi_try_exit: - return fapi2::current_err; -} - -}// lrdimm -}// ddr4 -}// spd -}// mss diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C deleted file mode 100644 index 3cccbb654..000000000 --- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C +++ /dev/null @@ -1,276 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/// -/// @file lrdimm_decoder_v1_1.C -/// @brief LRDIMM module SPD decoder definitions for revision 1.1 -/// -// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -// std lib -#include <vector> - -// fapi2 -#include <fapi2.H> - -// mss lib -#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H> -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> -#include <generic/memory/lib/spd/spd_checker.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/find.H> - -using fapi2::TARGET_TYPE_MCA; -using fapi2::TARGET_TYPE_MCS; -using fapi2::TARGET_TYPE_DIMM; - -namespace mss -{ -namespace spd -{ -namespace ddr4 -{ -namespace lrdimm -{ - -/// -/// @brief Decodes register and data buffer types -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 131 (Bits 7~4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12.3 - 63 -/// -fapi2::ReturnCode decoder_v1_1::register_and_buffer_type(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< REGISTER_TYPE >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - REGISTER_TYPE.iv_byte, - l_field_bits, - "Failed bounds check for Register and Data Buffer Types") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register and Data Buffer Types: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes register output drive strength for CKE signal -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (Bits 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12.3 - 65 -/// -fapi2::ReturnCode decoder_v1_1::cke_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< CKE_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - CKE_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CKE") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CKE: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for ODT signal -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (Bits 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12.3 - 65 -/// -fapi2::ReturnCode decoder_v1_1::odt_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< ODT_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - ODT_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for ODT") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for ODT: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for control signal (CS) signal -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (Bits 6~7) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12.3 - 65 -/// -fapi2::ReturnCode decoder_v1_1::cs_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< CS_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - CS_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CS") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CS: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (B side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (Bits 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12.3 - 66 -/// -fapi2::ReturnCode decoder_v1_1::b_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< B_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - B_SIDE_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y0,Y2)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (A side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (Bits 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12.3 - 66 -/// -fapi2::ReturnCode decoder_v1_1::a_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< A_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, - A_SIDE_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y1,Y3)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -}// lrdimm -}// ddr4 -}// spd -}// mss diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C deleted file mode 100644 index 029ad635e..000000000 --- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C +++ /dev/null @@ -1,310 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/// -/// @file lrdimm_decoder_v1_2.C -/// @brief LRDIMM module SPD decoder definitions for revision 1.2 -/// -// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -// std lib -#include <vector> - -// fapi2 -#include <fapi2.H> - -// mss lib -#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H> -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> -#include <generic/memory/lib/spd/spd_checker.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/find.H> - -using fapi2::TARGET_TYPE_MCA; -using fapi2::TARGET_TYPE_MCS; -using fapi2::TARGET_TYPE_DIMM; - -namespace mss -{ -namespace spd -{ -namespace ddr4 -{ -namespace lrdimm -{ - -/// -/// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE) -/// @param[out] o_output encoded drive strength -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (Bit 4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.12.3 - 76 -/// -fapi2::ReturnCode decoder_v1_2::bcom_bcke_bodt_drive_strength(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< BCOM_BODT_BCKE_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, - BCOM_BODT_BCKE_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for data buffer control (BCOM, BODT, BCKE)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for data buffer control (BCOM, BODT, BCKE): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for data buffer control (BCK) -/// @param[out] o_output encoded drive strength -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (Bit 5) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.12.3 - 76 -/// -fapi2::ReturnCode decoder_v1_2::bck_output_drive_strength(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< BCK_DRIVE_STRENGTH >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, - BCK_DRIVE_STRENGTH.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for data buffer control (BCK)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for data buffer control (BCK): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes RCD output slew rate control -/// @param[out] o_output encoded drive strength -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (Bit 6) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.L-4 - 76 -/// -fapi2::ReturnCode decoder_v1_2::slew_rate_control(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< RCD_SLEW_CNTRL >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 0b1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - RCD_SLEW_CNTRL.iv_byte, - l_field_bits, - "Failed bound check for RCD output slew rate control") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. RCD output slew rate control: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes VrefDQ range for DRAM interface range -/// @param[out] o_output spd encoding -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 155 (Bits 3~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.L-4 - 76 -/// -fapi2::ReturnCode decoder_v1_2::dram_vref_dq_range(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< DRAM_VREF_DQ_RANGE >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 0b1111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - DRAM_VREF_DQ_RANGE.iv_byte, - l_field_bits, - "Failed bound check for VrefDQ range for DRAM interface range ") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. VrefDQ range for DRAM interface range: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes data buffer VrefDQ range for DRAM interface range -/// @param[out] o_output spd encoding -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 155 (Bit 4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.L-4 - 76 -/// -fapi2::ReturnCode decoder_v1_2::data_buffer_vref_dq_range(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_VREF_DQ >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - DATA_BUFFER_VREF_DQ.iv_byte, - l_field_bits, - "Failed bound check for data buffer VrefDQ range for DRAM interface range") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Data buffer VrefDQ range for DRAM interface range: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes data buffer gain adjustment -/// @param[out] o_output spd encoding -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 156 (Bit 0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.L-4 - 77 -/// -fapi2::ReturnCode decoder_v1_2::data_buffer_gain_adjustment(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_GAIN_ADJUST >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - DATA_BUFFER_GAIN_ADJUST.iv_byte, - l_field_bits, - "Failed bound check for data buffer gain adjustment") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Data buffer gain adjustment: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes data buffer Decision Feedback Equalization (DFE) -/// @param[out] o_output spd encoding -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 156 (Bit 1) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 4 -/// @note Page 4.1.2.L-4 - 77 -/// -fapi2::ReturnCode decoder_v1_2::data_buffer_dfe(uint8_t& o_output) const -{ - // Extracting desired bits - uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_DFE >(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VAL = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VAL, // extract sanity check - DATA_BUFFER_DFE.iv_byte, - l_field_bits, - "Failed bound check for data buffer Decision Feedback Equalization (DFE)") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Data buffer Decision Feedback Equalization (DFE): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -}// lrdimm -}// ddr4 -}// spd -}// mss diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H index 0ec15c90e..96290460b 100644 --- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H +++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H @@ -38,137 +38,79 @@ #include <fapi2.H> #include <generic/memory/lib/spd/common/dimm_module_decoder.H> +#include <generic/memory/lib/spd/spd_decoder_def.H> +#include <generic/memory/lib/spd/spd_traits_ddr4.H> +#include <generic/memory/lib/spd/spd_reader.H> namespace mss { namespace spd { -namespace ddr4 -{ -namespace rdimm -{ /// /// @class decoder -/// @brief RDIMM module SPD DRAM decoder for rev 1.0 +/// @tparam R SPD revision - partial specialization +/// @brief RDIMM module SPD DRAM decoder /// -class decoder_v1_0 : public dimm_module_decoder +template < rev R > +class decoder<DDR4, RDIMM_MODULE, R > : public dimm_module_decoder { - protected: + private: - enum - { - // Byte 128 - MODULE_NOM_HEIGHT_START = 3, - MODULE_NOM_HEIGHT_LEN = 5, - RAW_CARD_EXT_START = 0, - RAW_CARD_EXT_LEN = 3, - - // Byte 129 - FRONT_MODULE_THICKNESS_START = 4, - FRONT_MODULE_THICKNESS_LEN = 4, - BACK_MODULE_THICKNESS_START = 0, - BACK_MODULE_THICKNESS_LEN = 4, - - // Byte 130 - REF_RAW_CARD_START = 3, - REF_RAW_CARD_LEN = 5, - REF_RAW_CARD_REV_START = 1, - REF_RAW_CARD_REV_LEN = 2, - REF_RAW_CARD_EXT_START = 0, - REF_RAW_CARD_EXT_LEN = 1, - - // Byte 131 - REGS_USED_START = 6, - REGS_USED_LEN = 2, - ROWS_OF_DRAMS_START = 4, - ROWS_OF_DRAMS_LEN = 2, - REGISTER_TYPE_START = 0, - REGISTER_TYPE_LEN = 4, - - // Byte 132 - HEAT_SPREADER_CHAR_START = 1, - HEAT_SPREADER_CHAR_LEN = 7, - HEAT_SPREADER_SOL_START = 0, - HEAT_SPREADER_SOL_LEN = 1, - - // Byte 133 - CONTINUATION_CODES_START = 1, - CONTINUATION_CODES_LEN = 7, - - // Byte 134 - whole byte taken - // Byte 135 - whole byte taken - - // Byte 136 - ADDR_MAPPING_START = 7, - ADDR_MAPPING_LEN = 1, - - // Byte 137 - CKE_DRIVER_START = 6, - CKE_DRIVER_LEN = 2, - ODT_DRIVER_START = 4, - ODT_DRIVER_LEN = 2, - CA_DRIVER_START = 2, - CA_DRIVER_LEN = 2, - CS_DRIVER_START = 0, - CS_DRIVER_LEN = 2, - - // Byte 138 - YO_Y2_DRIVER_START = 6, - YO_Y2_DRIVER_LEN = 2, - Y1_Y3_DRIVER_START = 4, - Y1_Y3_DRIVER_LEN = 2, - }; - - enum addr_mapping - { - STANDARD = 0, - MIRRORED = 1, - }; + using fields_t = fields<DDR4, RDIMM_MODULE>; + fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + std::vector<uint8_t> iv_data; public: - // First field - SPD byte - // Second field - start bit - // Third field - bit length - static constexpr field_t MODULE_NOMINAL_HEIGHT{128, MODULE_NOM_HEIGHT_START, MODULE_NOM_HEIGHT_LEN}; - static constexpr field_t RAW_CARD_EXTENSION{128, RAW_CARD_EXT_START, RAW_CARD_EXT_LEN}; - static constexpr field_t FRONT_MODULE_THICKNESS{129, FRONT_MODULE_THICKNESS_START, FRONT_MODULE_THICKNESS_LEN}; - static constexpr field_t BACK_MODULE_THICKNESS{129, BACK_MODULE_THICKNESS_START, BACK_MODULE_THICKNESS_LEN}; - static constexpr field_t REF_RAW_CARD{130, REF_RAW_CARD_START, REF_RAW_CARD_LEN}; - static constexpr field_t REF_RAW_CARD_REV{130, REF_RAW_CARD_REV_START, REF_RAW_CARD_REV_LEN}; - static constexpr field_t REF_RAW_CARD_EXT{130, REF_RAW_CARD_EXT_START, REF_RAW_CARD_EXT_LEN}; - static constexpr field_t NUM_REGS_USED{131, REGS_USED_START, REGS_USED_LEN}; - static constexpr field_t ROWS_OF_DRAMS{131, ROWS_OF_DRAMS_START, ROWS_OF_DRAMS_LEN}; - static constexpr field_t REGISTER_TYPE{131, REGISTER_TYPE_START, REGISTER_TYPE_LEN}; - static constexpr field_t HEAT_SPREADER_CHAR{132, HEAT_SPREADER_CHAR_START, HEAT_SPREADER_CHAR_LEN}; - static constexpr field_t HEAT_SPREADER_SOL{132, HEAT_SPREADER_SOL_START, HEAT_SPREADER_SOL_LEN}; - static constexpr field_t CONTINUATION_CODES{133, CONTINUATION_CODES_START, CONTINUATION_CODES_LEN}; - static constexpr field_t ADDR_MAPPING{136, ADDR_MAPPING_START, ADDR_MAPPING_LEN}; - static constexpr field_t CKE_DRIVER{137, CKE_DRIVER_START, CKE_DRIVER_LEN}; - static constexpr field_t ODT_DRIVER{137, ODT_DRIVER_START, ODT_DRIVER_LEN}; - static constexpr field_t CA_DRIVER{137, CA_DRIVER_START, CA_DRIVER_LEN}; - static constexpr field_t CS_DRIVER{137, CS_DRIVER_START, CS_DRIVER_LEN}; - static constexpr field_t YO_Y2_DRIVER{138, YO_Y2_DRIVER_START, YO_Y2_DRIVER_LEN}; - static constexpr field_t Y1_Y3_DRIVER{138, Y1_Y3_DRIVER_START, Y1_Y3_DRIVER_LEN}; - // deleted default ctor - decoder_v1_0() = delete; + decoder() = delete; /// /// @brief ctor /// @param[in] i_target dimm target /// @param[in] i_spd_data vector DIMM SPD data /// - decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data): - dimm_module_decoder(i_target, i_spd_data) - {} + decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data): + dimm_module_decoder(i_target, i_spd_data), + iv_target(i_target), + iv_data(i_spd_data) + { + static_assert( R <= rev::RDIMM_MAX, " R > rev::RDIMM_MAX"); + } /// /// @brief default dtor /// - virtual ~decoder_v1_0() = default; + virtual ~decoder() = default; + + /// + /// @brief Gets decoder target + /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM> + /// + virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const + { + return iv_target; + } + + /// + /// @brief Gets decoder SPD data + /// @return std::vector<uint8_t> + /// + virtual std::vector<uint8_t> get_data() const + { + return iv_data; + } + + /// + /// @brief Sets decoder SPD data + /// @param[in] i_spd_data SPD data in a vector reference + /// + virtual void set_data(const std::vector<uint8_t>& i_spd_data) + { + iv_data = i_spd_data; + } /// /// @brief Decodes module nominal height max, in mm @@ -179,7 +121,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 48 /// - virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override; + virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::MODULE_NOMINAL_HEIGHT, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes front module maximum thickness max, in mm @@ -190,7 +138,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 48 /// - virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override; + virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::FRONT_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes back module maximum thickness max, in mm @@ -201,7 +155,30 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 48 /// - virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override; + virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::BACK_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes reference raw card used + /// @param[out] o_output encoding from SPD + /// @return FAPI2_RC_SUCCESS if okay + /// @note SPD Byte 130 (Bits 7~0) + /// @note Item JEDEC Standard No. 21-C + /// @note DDR4 SPD Document Release 2 + /// @note Page 4.1.2.12 - 48 + /// + virtual fapi2::ReturnCode reference_raw_card(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::REF_RAW_CARD, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of registers used on RDIMM @@ -212,7 +189,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 50 /// - virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override; + virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::NUM_REGS_USED, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes number of rows of DRAMs on RDIMM @@ -223,7 +206,31 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 50 /// - virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override; + virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ROWS_OF_DRAMS, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + + } + + /// + /// @brief Decodes register types + /// @param[out] o_output encoding from SPD + /// @return FAPI2_RC_SUCCESS if okay + /// @note SPD Byte 131 (Bits 7~4) + /// @note Item JEDEC Standard No. 21-C + /// @note DDR4 SPD Document Release 3 + /// @note Page 4.1.2.12.3 - 63 + /// + virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_TYPE, R>(iv_target, iv_data, o_output)) ); + fapi_try_exit: + return fapi2::current_err; + + } /// /// @brief Decodes heat spreader thermal characteristics @@ -234,7 +241,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 51 /// - virtual fapi2::ReturnCode heat_spreader_thermal_char(uint8_t& o_output) const override; + virtual fapi2::ReturnCode heat_spreader_thermal_char(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::HEAT_SPREADER_CHAR, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes heat spreader solution @@ -245,18 +258,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 51 /// - virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override; + virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::HEAT_SPREADER_SOL, R>(iv_target, iv_data, o_output)) ); - /// - /// @brief Decodes number of continuation codes - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 133 (bit 6~0) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 2 - /// @note Page 4.1.2.12 - 51 - /// - virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output) const override; + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register manufacturer ID code @@ -267,7 +275,28 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 51 /// - virtual fapi2::ReturnCode reg_manufacturer_id_code(uint8_t& o_output) const override; + virtual fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_output) const override + { + uint8_t l_cont_codes = 0; + uint8_t l_last_nonzero_byte = 0; + + FAPI_TRY( (mss::spd::reader<fields_t::CONTINUATION_CODES, R>(iv_target, iv_data, l_cont_codes)) ); + FAPI_TRY( (mss::spd::reader<fields_t::LAST_NON_ZERO_BYTE, R>(iv_target, iv_data, l_last_nonzero_byte)) ); + + { + fapi2::buffer<uint16_t> l_buffer; + rightAlignedInsert(l_buffer, l_last_nonzero_byte, l_cont_codes); + + o_output = l_buffer; + + FAPI_INF("%s. Register Manufacturer ID Code: 0x%04x", + spd::c_str(iv_target), + o_output); + } + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register revision number @@ -278,7 +307,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 51 /// - virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override; + virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_REV, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes address mapping from register to dram @@ -289,7 +324,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 52 /// - virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override; + virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ADDR_MAP_REG_TO_DRAM, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for CKE signal @@ -300,7 +341,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 53 /// - virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::CKE_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for ODT signal @@ -311,7 +358,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 53 /// - virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::ODT_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for command/address (CA) signal @@ -322,7 +375,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 53 /// - virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::CA_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for control signal (CS) signal @@ -333,7 +392,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 53 /// - virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::CS_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for clock (B side) @@ -344,7 +409,13 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 53 /// - virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::YO_Y2_DRIVER, R>(iv_target, iv_data, o_output)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Decodes register output drive strength for clock (A side) @@ -355,106 +426,17 @@ class decoder_v1_0 : public dimm_module_decoder /// @note DDR4 SPD Document Release 2 /// @note Page 4.1.2.12 - 53 /// - virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override; - -};// decoder_v1_0 - -/// -/// @class decoder -/// @brief RDIMM module SPD DRAM decoder for rev 1.1 -/// -class decoder_v1_1 : public decoder_v1_0 -{ - public: - - // deleted default ctor - decoder_v1_1() = delete; - - /// - /// @brief ctor - /// @param[in] i_target dimm target - /// @param[in] i_spd_data vector DIMM SPD data - /// - decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const std::vector<uint8_t>& i_spd_data): - decoder_v1_0(i_target, i_spd_data) - {} - - /// - /// @brief default dtor - /// - virtual ~decoder_v1_1() = default; - - /// - /// @brief Decodes register types - /// @param[out] o_output encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 131 (Bits 7~4) - /// @note Item JEDEC Standard No. 21-C - /// @note DDR4 SPD Document Release 3 - /// @note Page 4.1.2.12.3 - 63 - /// - virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for CKE signal - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 137 (bit 1~0) - /// @note Item JC-45-2220.01x - /// @note Page 76 - /// @note DDR4 SPD Document Release 4 - /// - virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for ODT signal - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 137 (bit 3~2) - /// @note Item JC-45-2220.01x - /// @note Page 76 - /// @note DDR4 SPD Document Release 4 - /// - virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override; - - /// - /// @brief Decodes register output drive strength for control signal (CS) signal - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 137 (bit 6~7) - /// @note Item JC-45-2220.01x - /// @note Page 76 - /// @note DDR4 SPD Document Release 4 - /// - virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override; + virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override + { + FAPI_TRY( (mss::spd::reader<fields_t::Y1_Y3_DRIVER, R>(iv_target, iv_data, o_output)) ); - /// - /// @brief Decodes register output drive strength for clock (B side) - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 138 (bit 1~0) - /// @note Item JC-45-2220.01x - /// @note Page 76 - /// @note DDR4 SPD Document Release 4 - /// - virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override; + fapi_try_exit: + return fapi2::current_err; + } - /// - /// @brief Decodes register output drive strength for clock (A side) - /// @param[out] o_output drive strength encoding from SPD - /// @return FAPI2_RC_SUCCESS if okay - /// @note SPD Byte 138 (bit 3~2) - /// @note Item JC-45-2220.01x - /// @note Page 76 - /// @note DDR4 SPD Document Release 4 - /// - virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override; -};//decoder_v1_1 +};// decoder -}// rdimm -}// ddr4 }// spd }// mss diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C deleted file mode 100644 index 021130412..000000000 --- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C +++ /dev/null @@ -1,644 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -/// -/// @file rdimm_decoder.C -/// @brief RDIMM module specific SPD decoder definitions -/// -// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -// *HWP Team: Memory -// *HWP Level: 3 -// *HWP Consumed by: HB:FSP - -// std lib -#include <vector> - -// fapi2 -#include <fapi2.H> - -// mss lib -#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H> -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> -#include <generic/memory/lib/spd/spd_checker.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/find.H> - -using fapi2::TARGET_TYPE_MCBIST; -using fapi2::TARGET_TYPE_MCA; -using fapi2::TARGET_TYPE_MCS; -using fapi2::TARGET_TYPE_DIMM; - - -namespace mss -{ -namespace spd -{ -namespace ddr4 -{ -namespace rdimm -{ - -///////////////////////// -// Member Method implementation -// For RDIMM module rev 1.0 -///////////////////////// - -/// -/// @brief Decodes module nominal height max, in mm -/// @param[out] o_output height range encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 128 (Bits 4~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 48 -/// -fapi2::ReturnCode decoder_v1_0::max_module_nominal_height(uint8_t& o_output) const -{ - const uint8_t l_field_bits = extract_spd_field<MODULE_NOMINAL_HEIGHT>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b11111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - MODULE_NOMINAL_HEIGHT.iv_byte, - l_field_bits, - "Failed bound check for module nominal height max") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Max module nominal height: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes front module maximum thickness max, in mm -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 129 (Bits 3~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 48 -/// -fapi2::ReturnCode decoder_v1_0::front_module_max_thickness(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<FRONT_MODULE_THICKNESS>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b1111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - FRONT_MODULE_THICKNESS.iv_byte, - l_field_bits, - "Failed bound check for front module max thickness") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Front module max thickness: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes back module maximum thickness max, in mm -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 129 (Bits 7~4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 48 -/// -fapi2::ReturnCode decoder_v1_0::back_module_max_thickness(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<BACK_MODULE_THICKNESS>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b1111; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - BACK_MODULE_THICKNESS.iv_byte, - l_field_bits, - "Failed bound check for back module max thickness") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Back module max thickness: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes number of registers used on RDIMM -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 131 (Bits 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 50 -/// -fapi2::ReturnCode decoder_v1_0::num_registers_used(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<NUM_REGS_USED>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - NUM_REGS_USED.iv_byte, - l_field_bits, - "Failed bound check for number of registers used on RDIMM ") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Number of registers used on RDIMM : %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes number of rows of DRAMs on RDIMM -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 131 (Bits 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 50 -/// -fapi2::ReturnCode decoder_v1_0::num_rows_of_drams(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<ROWS_OF_DRAMS>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - ROWS_OF_DRAMS.iv_byte, - l_field_bits, - "Failed bound check for number of rows of DRAMs on RDIMM ") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Number of rows of DRAMs on RDIMM : %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes heat spreader thermal characteristics -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCEawSS if okay -/// @note SPD Byte 132 (Bits 6~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 51 -/// -fapi2::ReturnCode decoder_v1_0::heat_spreader_thermal_char(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<HEAT_SPREADER_CHAR>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - HEAT_SPREADER_CHAR.iv_byte, - l_field_bits, - "Failed bound check for heat spreader thermal characteristics") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Heat spreader thermal characteristics: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes heat spreader solution -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 132 (Bit 7) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 51 -/// -fapi2::ReturnCode decoder_v1_0::heat_spreader_solution(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<HEAT_SPREADER_SOL>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 1; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - HEAT_SPREADER_SOL.iv_byte, - l_field_bits, - "Failed bound check for heat spreader solution") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Heat spreader solution: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Decodes number of continuation codes -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 133 (bit 6~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 51 -/// -fapi2::ReturnCode decoder_v1_0::num_continuation_codes(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<CONTINUATION_CODES>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t MAX_VALID_VALUE = 10; // JEP106AS - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits <= MAX_VALID_VALUE, - CONTINUATION_CODES.iv_byte, - l_field_bits, - "Failed bound check for number of continuation codes") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Number of continuation codes: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes register manufacturer ID code -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 134 (bit 7~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 51 -/// -fapi2::ReturnCode decoder_v1_0::reg_manufacturer_id_code(uint8_t& o_output) const -{ - constexpr size_t BYTE_INDEX = 134; - uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX]; - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_raw_byte); - - o_output = l_raw_byte; - - FAPI_INF("%s. Manufacturer ID code: %d", - iv_target_str_storage, - o_output); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes register revision number -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 135 (bit 7~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 51 -/// -fapi2::ReturnCode decoder_v1_0::register_rev_num(uint8_t& o_output) const -{ - constexpr size_t BYTE_INDEX = 135; - uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX]; - - // Trace in the front assists w/ debug - FAPI_INF("%s SPD data at Byte %d: 0x%llX.", - iv_target_str_storage, - BYTE_INDEX, - l_raw_byte); - - o_output = l_raw_byte; - - FAPI_INF("%s. Register revision number: %d", - iv_target_str_storage, - o_output); - - return fapi2::FAPI2_RC_SUCCESS; -} - -/// -/// @brief Decodes address mapping from register to dram -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 136 (bit 0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 52 -/// -fapi2::ReturnCode decoder_v1_0::register_to_dram_addr_mapping(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<ADDR_MAPPING>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - ADDR_MAPPING.iv_byte, - l_field_bits, - "Failed bound check for to register to dram addr mapping") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Address mapping from register to dram: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for CKE signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 53 -/// -fapi2::ReturnCode decoder_v1_0::cke_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<CKE_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - CKE_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CKE") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CKE: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for ODT signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 53 -/// -fapi2::ReturnCode decoder_v1_0::odt_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<ODT_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - ODT_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for ODT") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for ODT: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for command/address (CA) signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 5~4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 53 -/// -fapi2::ReturnCode decoder_v1_0::ca_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<CA_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t INVALID_VAL = 3; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < INVALID_VAL, // extract sanity check - CA_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CA") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CA: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for control signal (CS) signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 6~7) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 53 -/// -fapi2::ReturnCode decoder_v1_0::cs_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<CS_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - CS_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CS") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CS: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (B side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (bit 1~0) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 53 -/// -fapi2::ReturnCode decoder_v1_0::b_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<YO_Y2_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, // extract sanity check - YO_Y2_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y0,Y2)") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (A side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (bit 3~2) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 2 -/// @note Page 4.1.2.12 - 53 -/// -fapi2::ReturnCode decoder_v1_0::a_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<Y1_Y3_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field_Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - l_field_bits < RESERVED, - Y1_Y3_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y1,Y3)") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -}// rdimm -}// ddr4 -}// spd -}// mss diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C deleted file mode 100644 index 9a6aa5446..000000000 --- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C +++ /dev/null @@ -1,268 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -// std lib -#include <vector> - -// fapi2 -#include <fapi2.H> - -// mss lib -#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H> -#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> -#include <generic/memory/lib/spd/spd_checker.H> -#include <generic/memory/lib/utils/c_str.H> -#include <generic/memory/lib/utils/find.H> - -using fapi2::TARGET_TYPE_MCBIST; -using fapi2::TARGET_TYPE_MCA; -using fapi2::TARGET_TYPE_MCS; -using fapi2::TARGET_TYPE_DIMM; - - -namespace mss -{ -namespace spd -{ -namespace ddr4 -{ -namespace rdimm -{ - -///////////////////////// -// Member Method implementation -// For RDIMM module rev 1.1 -///////////////////////// - -/// -/// @brief Decodes register type -/// @param[out] o_output encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 131 (Bits 7~4) -/// @note Item JEDEC Standard No. 21-C -/// @note DDR4 SPD Document Release 3 -/// @note Page 4.1.2.12.3 - 63 -/// -fapi2::ReturnCode decoder_v1_1::register_and_buffer_type(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<REGISTER_TYPE>(iv_target, iv_spd_data); - FAPI_INF("Field Bits value: %d", l_field_bits); - - // This checks my extracting params returns a value within bound - constexpr size_t RESERVED = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits < RESERVED), // extract sanity check - REGISTER_TYPE.iv_byte, - l_field_bits, - "Failed bounds check for Register and Data Buffer Types") ); - - // Update output only if check passes - o_output = l_field_bits; - - FAPI_INF("%s. Register Types: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; - -} - -/// -/// @brief Decodes register output drive strength for CKE signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 1~0) -/// @note Item JC-45-2220.01x -/// @note Page 76 -/// @note DDR4 SPD Document Release 4 -/// -fapi2::ReturnCode decoder_v1_1::cke_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<CKE_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // This really just checks my extract gives me a valid value - constexpr size_t MAX_VALID_VALUE = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits <= MAX_VALID_VALUE), // extract sanity check - CKE_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for CKE") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CKE: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for ODT signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 3~2) -/// @note Item JC-45-2220.01x -/// @note Page 76 -/// @note DDR4 SPD Document Release 4 -/// -fapi2::ReturnCode decoder_v1_1::odt_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<ODT_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // This really just checks my extract gives me a valid value - constexpr size_t MAX_VALID_VALUE = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits <= MAX_VALID_VALUE), // extract sanity check - ODT_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for ODT") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for ODT: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for control signal (CS) signal -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 137 (bit 6~7) -/// @note Item JC-45-2220.01x -/// @note Page 76 -/// @note DDR4 SPD Document Release 4 -/// -fapi2::ReturnCode decoder_v1_1::cs_signal_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<CS_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // This really just checks my extract gives me a valid value - constexpr size_t MAX_VALID_VALUE = 0b11; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits <= MAX_VALID_VALUE), // extract sanity check - CS_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for chip select") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for CS: %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (B side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (bit 1~0) -/// @note Item JC-45-2220.01x -/// @note Page 76 -/// @note DDR4 SPD Document Release 4 -/// -fapi2::ReturnCode decoder_v1_1::b_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<YO_Y2_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // This really just checks my extract gives me a valid value - constexpr size_t MAX_VALID_VAL = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits <= MAX_VALID_VAL), // extract sanity check - YO_Y2_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y0,Y2)") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Decodes register output drive strength for clock (A side) -/// @param[out] o_output drive strength encoding from SPD -/// @return FAPI2_RC_SUCCESS if okay -/// @note SPD Byte 138 (bit 3~2) -/// @note Item JC-45-2220.01x -/// @note Page 76 -/// @note DDR4 SPD Document Release 4 -/// -fapi2::ReturnCode decoder_v1_1::a_side_clk_output_driver(uint8_t& o_output) const -{ - // Extracting desired bits - const uint8_t l_field_bits = extract_spd_field<Y1_Y3_DRIVER>(iv_target, iv_spd_data); - FAPI_DBG("Field Bits value: %d", l_field_bits); - - // This really just checks my extract gives me a valid value - constexpr size_t MAX_VALID_VAL = 2; - - FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target, - (l_field_bits <= MAX_VALID_VAL), // extract sanity check - Y1_Y3_DRIVER.iv_byte, - l_field_bits, - "Failed bounds check for Register Output Driver for clock (Y1,Y3)") ); - - o_output = l_field_bits; - - FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d", - iv_target_str_storage, - o_output); - -fapi_try_exit: - return fapi2::current_err; -} - -}// rdimm -}// ddr4 -}// spd -}// mss diff --git a/src/import/generic/memory/lib/spd/spd_checker.H b/src/import/generic/memory/lib/spd/spd_checker.H index d3a85aaa4..a26ac4741 100644 --- a/src/import/generic/memory/lib/spd/spd_checker.H +++ b/src/import/generic/memory/lib/spd/spd_checker.H @@ -23,42 +23,130 @@ /* */ /* IBM_PROLOG_END_TAG */ +/// +/// @file spd_checker.H +/// @brief SPD functions to check boundaries +/// +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + #ifndef _SPD_CHECKER_H_ #define _SPD_CHECKER_H_ #include <fapi2.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> namespace mss { -namespace check + +/// +/// @brief Selectors for timing limits +/// @note BITS12 stands for a 12 bit range +/// @note BITS16 stands for a 16 bit range +/// +enum bit_len +{ + BITS12 = 12, + BITS16 = 16, +}; + +/// +/// @class bitRangeTraits +/// @brief Traits class to select +/// @tparam T bit_len selector +/// +template <bit_len T> +struct bitRangeTraits; + +/// +/// @class bitRangeTraits +/// @brief Traits class to select - BITS12 specialization +/// +template<> +struct bitRangeTraits<BITS12> +{ + enum + { + LOWER_BOUND = 0x1, + UPPER_BOUND = 0xfff, + }; +}; + +/// +/// @class bitRangeTraits +/// @brief Traits class to select - BITS16 specialization +/// +template<> +struct bitRangeTraits<BITS16> { + enum + { + LOWER_BOUND = 0x1, + UPPER_BOUND = 0xffff, + }; +}; + namespace spd { +namespace check +{ + +/// +/// @brief SPD timing boundary check +/// @tparam BL bit_len selector +/// @tparam T the TargetType +/// @tparam TT defaulted to bitRangeTraits<TB> +/// @param[in] i_target fapi2 target +/// @param[in] i_timing the timing value +/// @param[in] i_ffdc ffdc function code +/// @return FAPI2_RC_SUCCESS iff okay +/// +template < bit_len BL, fapi2::TargetType T, typename TT = bitRangeTraits<BL> > +fapi2::ReturnCode max_timing_range(const fapi2::Target<T>& i_target, + const int64_t i_timing, + const generic_ffdc_codes i_ffdc) +{ + FAPI_ASSERT( (i_timing <= TT::UPPER_BOUND) && + (i_timing >= TT::LOWER_BOUND), + fapi2::MSS_SPD_TIMING_FAIL() + .set_FUNCTION_CODE(i_ffdc) + .set_TARGET(i_target), + "Failed timing parameter check for %s", + spd::c_str(i_target)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} /// -/// @brief Checks conditional passes and implements traces & exits if it fails -/// @tparam T input data of any size -/// @param[in] i_target fapi2 dimm target -/// @param[in] i_conditional conditional that we are testing against -/// @param[in] i_spd_byte_index current SPD byte -/// @param[in] i_spd_data debug data -/// @param[in] i_err_str error string to print out when conditional fails -/// @return ReturnCode +/// @brief Checks conditional passes and implements traces & exits if it fails +/// @tparam T input data of any size +/// @param[in] i_target fapi2 dimm target +/// @param[in] i_conditional conditional that we are testing against +/// @param[in] i_spd_byte_index current SPD byte +/// @param[in] i_spd_data debug data +/// @param[in] i_err_str error string to print out when conditional fails +/// @return FAPI2_RC_SUCCESS iff okay /// template< typename T > inline fapi2::ReturnCode fail_for_invalid_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, const bool i_conditional, const size_t i_spd_byte_index, const T i_spd_data, - const char* i_err_str) + const char* i_err_str = "") { FAPI_ASSERT(i_conditional, fapi2::MSS_BAD_SPD(). set_VALUE(i_spd_data). set_BYTE(i_spd_byte_index). set_DIMM_TARGET(i_target), - "%s %s Byte %d, Data returned: %d.", - c_str(i_target), + "%s %s Byte %d, data 0x%02x, extracted value: 0x%02x.", + spd::c_str(i_target), i_err_str, i_spd_byte_index, i_spd_data); @@ -67,70 +155,136 @@ inline fapi2::ReturnCode fail_for_invalid_value(const fapi2::Target<fapi2::TARGE fapi_try_exit: return fapi2::current_err; -} // fail_for_invalid_value() +} // fail_for_invalid_value /// -/// @brief Checks conditional passes and implements traces if it fails. No FFDC collected. -/// @tparam T input data of any size -/// @param[in] i_target fapi2 dimm target -/// @param[in] i_conditional that we are testing against -/// @param[in] i_spd_byte_index -/// @param[in] i_spd_data debug data -/// @param[in] i_err_str string to print out when conditional fails -/// @return void +/// @brief Helper function to test if a DRAM generation is valid +/// @param[in] i_dram_gen the DRAM gen from SPD +/// @return true if this DRAM gen is valid, else false /// -template< typename T > -inline void warn_for_invalid_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const bool i_conditional, - const size_t i_spd_byte_index, - const T i_spd_data, - const char* i_err_str) +static inline bool is_dram_gen_valid(const uint8_t i_dram_gen) +{ + bool l_result = false; + + switch(i_dram_gen) + { + case DDR4: + l_result = true; + break; + + default: + l_result = false; + break; + } + + return l_result; +} + +/// +/// @brief Checks for valid DRAM generation +/// @param[in] i_target the DIMM target +/// @param[in] i_dram_gen the DRAM gen from SPD +/// @param[in] i_func_code mss ffdc code +/// @return FAPI2_RC_SUCCESS iff okay +/// +inline fapi2::ReturnCode dram_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const uint8_t i_dram_gen, + const generic_ffdc_codes i_func_code) +{ + FAPI_ASSERT(is_dram_gen_valid(i_dram_gen), + fapi2::MSS_INVALID_DRAM_GEN() + .set_DRAM_GEN(i_dram_gen) + .set_FUNCTION(i_func_code) + .set_DIMM_TARGET(i_target), + "Invalid DRAM gen recieved (%d) for %s", + i_dram_gen, spd::c_str(i_target)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function to test if a DIMM type is valid +/// @param[in] i_dimm_type the DIMM type from SPD +/// @return true if this DIMM type is valid, else false +/// +static inline bool is_dimm_type_valid(const uint8_t i_dimm_type) { - // Don't print warning conditional if true - if(!i_conditional) + bool l_result = false; + + switch(i_dimm_type) { - FAPI_IMP("%s. %s. Byte %d, Data returned: %d.", - c_str(i_target), - i_err_str, - i_spd_byte_index, - i_spd_data ); + case RDIMM: + case LRDIMM: + l_result = true; + break; + + default: + l_result = false; + break; } -}// warn_for_invalid_value - -/// -/// @brief Checks if valid factory parameters are given -/// @param[in] i_target fapi2 dimm target -/// @param[in] i_dimm_type DIMM type enumeration -/// @param[in] i_encoding_rev SPD encoding level rev number -/// @param[in] i_additions_rev SPD additions level rev number -/// @param[in] i_err_str string to print out when conditional fails -/// @return fapi2::ReturnCode -/// -inline fapi2::ReturnCode invalid_factory_sel(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const uint8_t i_dimm_type, - const uint8_t i_encoding_rev, - const uint8_t i_additions_rev, - const char* i_err_str) + + return l_result; +} + +/// +/// @brief Checks for valid DIMM type +/// @param[in] i_target the DIMM target +/// @param[in] i_dram_gen the DIMM type from SPD +/// @param[in] i_func_code mss ffdc code +/// @return FAPI2_RC_SUCCESS iff okay +/// +inline fapi2::ReturnCode dimm_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const uint8_t i_dimm_type, + const generic_ffdc_codes i_func_code) { - FAPI_ASSERT(false, - fapi2::MSS_INVALID_DIMM_REV_COMBO(). - set_DIMM_TYPE(i_dimm_type). - set_ENCODING_REV(i_encoding_rev). - set_ADDITIONS_REV(i_additions_rev). - set_DIMM_TARGET(i_target), - "%s. %s. Invalid combination for dimm type: %d, rev: %d.%d", - c_str(i_target), - i_err_str, - i_dimm_type, - i_encoding_rev, - i_additions_rev); + FAPI_ASSERT(is_dimm_type_valid(i_dimm_type), + fapi2::MSS_INVALID_DIMM_TYPE() + .set_DIMM_TYPE(i_dimm_type) + .set_FUNCTION(i_func_code) + .set_DIMM_TARGET(i_target), + "Invalid DIMM type recieved (%d) for %s", + i_dimm_type, spd::c_str(i_target)); + return fapi2::FAPI2_RC_SUCCESS; + fapi_try_exit: return fapi2::current_err; -}// invalid_factory_sel +} + +/// +/// @brief Helper function to check for reserved values +/// @tparam TT FAPI2 target type +/// @param[in] i_target the fapi2 target +/// @param[in] i_reserved_bits vector of SORTED reserved bits to sort through +/// @param[in] i_ffdc ffdc function code +/// @param[in] i_input value to check +/// @return FAPI2_RC_SUCCESS iff okay +/// +template < fapi2::TargetType TT > +inline fapi2::ReturnCode reserved_values(const fapi2::Target<TT>& i_target, + const std::vector<uint8_t>& i_reserved_bits, + const generic_ffdc_codes i_ffdc, + const uint8_t i_input) +{ + // Lets make an additional check that we aren't being set to a reserved field + FAPI_ASSERT( !std::binary_search(i_reserved_bits.begin(), i_reserved_bits.end(), i_input), + fapi2::MSS_INVALID_SPD_RESERVED_BITS() + .set_FUNCTION_CODE(i_ffdc) + .set_TARGET(i_target), + "Reserved bits seen on %s", + spd::c_str(i_target) ); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} -}// spd }// check +}// spd }// mss #endif diff --git a/src/import/generic/memory/lib/spd/spd_decoder_def.H b/src/import/generic/memory/lib/spd/spd_decoder_def.H index fe2ecc46b..9d8378145 100644 --- a/src/import/generic/memory/lib/spd/spd_decoder_def.H +++ b/src/import/generic/memory/lib/spd/spd_decoder_def.H @@ -22,3 +22,38 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file spd_decoder_def.H +/// @brief SPD decoder definition +/// +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _MSS_SPD_DECODER_DEF_H_ +#define _MSS_SPD_DECODER_DEF_H_ + +#include <generic/memory/lib/spd/spd_field.H> + +namespace mss +{ +namespace spd +{ + +/// +/// @class decoder +/// @tparam D device type (DDR4, etc.) +/// @tparam S JEDEC SPD parameters (LRDIMM_MODULE, GEN_SEC, etc.) +/// @tparam R SPD revision (e.g. rev 1.1, 1.2, etc.) +/// @brief Base SPD DRAM decoder +/// +template < device_type D, parameters S, rev R > +class decoder; + +}// spd +}// mss + +#endif //_MSS_SPD_DECODER_DEF_H_ diff --git a/src/import/generic/memory/lib/spd/spd_facade.H b/src/import/generic/memory/lib/spd/spd_facade.H index 440d9498a..5c86d7895 100644 --- a/src/import/generic/memory/lib/spd/spd_facade.H +++ b/src/import/generic/memory/lib/spd/spd_facade.H @@ -22,3 +22,1637 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +#ifndef _MSS_SPD_FACADE_H_ +#define _MSS_SPD_FACADE_H_ + +#include <generic/memory/lib/spd/spd_factory_pattern.H> +#include <generic/memory/lib/utils/find.H> +#include <fapi2_spd_access.H> + +namespace mss +{ +namespace spd +{ + +/// +/// @brief Retrieve SPD data +/// @param[in] i_target the DIMM target +/// @param[out] o_spd reference to std::vector +/// @return FAPI2_RC_SUCCESS iff okay +/// +inline fapi2::ReturnCode get_raw_data(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + std::vector<uint8_t>& o_spd) +{ + // Get SPD blob size + size_t l_size = 0; + FAPI_TRY( fapi2::getSPD(i_target, nullptr, l_size), + "%s. Failed to retrieve SPD blob size", spd::c_str(i_target) ); + + // Reassign container size with the retrieved size + // Arbitrarily set the data to zero since it will be overwritten + o_spd.assign(l_size, 0); + + // Retrieve SPD data content + FAPI_TRY( fapi2::getSPD(i_target, o_spd.data(), l_size), + "%s. Failed to retrieve SPD data", spd::c_str(i_target) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @class facade +/// @brief SDP facade to simplify decoder interface +/// @note the facade should be a pass through class, +/// shouldn't be subclassed. Factories should be the work horse. +/// +class facade final +{ + private: + + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + std::vector<uint8_t> iv_data; + std::shared_ptr<dimm_module_decoder> iv_dimm_module_decoder; + std::shared_ptr<base_cnfg_decoder> iv_base_cnfg_decoder; + + public: + + /// + /// @brief ctor + /// @param[in] i_target the DIMM target + /// @param[in] i_spd_data SPD data in a vector reference + /// @param[out] o_rc FAPI2_RC_SUCCESS iff okay + /// + facade( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + fapi2::ReturnCode& o_rc): + iv_target(i_target), + iv_data(i_spd_data) + { + factories l_factories(i_target, i_spd_data, o_rc); + FAPI_TRY(o_rc, "Failed to instantiate factories object for %s", spd::c_str(i_target)); + + FAPI_TRY(l_factories.create_decoder(iv_dimm_module_decoder)); + FAPI_TRY(l_factories.create_decoder(iv_base_cnfg_decoder)); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + + fapi_try_exit: + o_rc = fapi2::current_err; + } + + /// + /// @brief dtor + /// + ~facade() = default; + + /// + /// @brief Gets facade target + /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM> + /// + fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const + { + return iv_target; + } + + /// + /// @brief Gets facade SPD data + /// @return std::vector<uint8_t> + /// + std::vector<uint8_t> get_data() const + { + return iv_data; + } + + /// + /// @brief Sets facade SPD data + /// @param[in] i_spd_data SPD data in a vector reference + /// + void set_data(const std::vector<uint8_t>& i_spd_data) + { + // Keep SPD data changes consistent through decoders + iv_data = i_spd_data; + iv_base_cnfg_decoder->set_data(i_spd_data); + iv_dimm_module_decoder->set_data(i_spd_data); + } + + /// + /// @brief Decodes number of used SPD bytes + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode number_of_used_bytes( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->number_of_used_bytes(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes total SPD encoding for total bytes + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode number_of_total_bytes( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->number_of_total_bytes(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDP revision + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode revision( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->revision(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM device type + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode device_type( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->device_type(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes base module type + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode base_module( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->base_module(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM density from SPD + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode sdram_density( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->sdram_density(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes hybrid media + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode hybrid_media( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->hybrid_media(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes hybrid + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode hybrid( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->hybrid(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes number of SDRAM banks bits from SPD + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode bank_bits( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->bank_bits(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes number of SDRAM bank groups bits from SPD + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->bank_group_bits(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes number of SDRAM column address bits + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->column_address_bits(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes number of SDRAM row address bits + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->row_address_bits(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Primary SDRAM signal loading + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->prim_sdram_signal_loading(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Primary SDRAM die count + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->prim_sdram_die_count(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Primary SDRAM package type + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->prim_sdram_package_type(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode SDRAM Maximum activate count + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode maximum_activate_count( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->maximum_activate_count(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode maximum_activate_window_multiplier( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->maximum_activate_window_multiplier(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Post package repair (PPR) + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->post_package_repair(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Soft post package repair (soft PPR) + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->soft_post_package_repair(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Secondary SDRAM signal loading + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->sec_sdram_signal_loading(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Secondary DRAM Density Ratio + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->sec_dram_density_ratio(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Secondary SDRAM die count + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->sec_sdram_die_count(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Secondary SDRAM package type + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->sec_sdram_package_type(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Module Nominal Voltage, VDD + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->operable_nominal_voltage(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Module Nominal Voltage, VDD + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->endurant_nominal_voltage(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM device width + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode device_width( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->device_width(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes number of package ranks per DIMM + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->num_package_ranks_per_dimm(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Rank Mix + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode rank_mix( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->rank_mix(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes primary bus width + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->prim_bus_width(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes bus width extension + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->bus_width_extension(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Module Thermal Sensor + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->thermal_sensor(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Extended Base Module Type + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->extended_base_module_type(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Fine Timebase + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_timebase( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_timebase(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode Medium Timebase + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode medium_timebase( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->medium_timebase(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// + /// @brief Decodes SDRAM Minimum Cycle Time in MTB + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_tck( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_tck(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Maximum Cycle Time in MTB + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode max_tck( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->max_tck(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decode CAS Latencies Supported + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->supported_cas_latencies(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum CAS Latency Time in MTB + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_taa( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_taa(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trcd( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trcd(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trp( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trp(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_tras( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_tras(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trc( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trc(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1 + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trfc1( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trfc1(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2 + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trfc2( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trfc2(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4 + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trfc4( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trfc4(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes SDRAM Minimum Four Activate Window Delay Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_tfaw( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_tfaw(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trrd_s(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_trrd_l(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_tccd_l(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Minimum Write Recovery Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_twr( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_twr(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Minimum Write to Read Time - Different Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_twtr_s(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Minimum Write to Read Time - Same Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->min_twtr_l(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Package Rank Map + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode package_rank_map( std::vector<uint8_t>& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->package_rank_map(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Nibble Map + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode nibble_map( std::vector<uint8_t>& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->nibble_map(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_tccd_l(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trrd_l(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trrd_s(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trc(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trp(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trcd(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_taa(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_max_tck(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_tck(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->cyclical_redundancy_code(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes module manufacturer ID code + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->module_manufacturer_id_code(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Module Manufacturing Location + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->module_manufacturing_location(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodesmodule manufacturing date + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + fapi2::ReturnCode module_manufacturing_date( uint16_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->module_manufacturing_date(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes module's unique serial number + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode module_serial_number( uint32_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->module_serial_number(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes Module Revision Code + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->module_revision_code(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM Manufacturer ID code + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->dram_manufacturer_id_code(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM Stepping + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const + { + FAPI_TRY( iv_base_cnfg_decoder->dram_stepping(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + /// + /// @brief Decodes module nominal height max + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode max_module_nominal_height(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->max_module_nominal_height(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes raw card extension + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode raw_card_extension(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->raw_card_extension(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes front module maximum thickness max + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode front_module_max_thickness(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->front_module_max_thickness(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes back module maximum thickness max + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode back_module_max_thickness(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->back_module_max_thickness(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes reference raw card used + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode reference_raw_card(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->reference_raw_card(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes number of registers used on RDIMM + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode num_registers_used(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->num_registers_used(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes number of rows of DRAMs on RDIMM + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode num_rows_of_drams(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->num_rows_of_drams(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register and buffer type for LRDIMMs + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode register_and_buffer_type(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->register_and_buffer_type(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes heat spreader thermal characteristics + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCEawSS if okay + /// + fapi2::ReturnCode heat_spreader_thermal_char(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->heat_spreader_thermal_char(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes heat spreader solution + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode heat_spreader_solution(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->heat_spreader_solution(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register manufacturer ID code + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->reg_manufacturer_id_code(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register revision number + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode register_rev_num(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->register_rev_num(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes address mapping from register to dram + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->register_to_dram_addr_mapping(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for CKE signal + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->cke_signal_output_driver(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for ODT signal + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->odt_signal_output_driver(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for command/address (CA) signal + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->ca_signal_output_driver(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for control signal (CS) signal + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->cs_signal_output_driver(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for clock (B side) + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->b_side_clk_output_driver(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for clock (A side) + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->a_side_clk_output_driver(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE) + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->bcom_bcke_bodt_drive_strength(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes register output drive strength for data buffer control (BCK) + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->bck_output_drive_strength(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes RCD output slew rate control + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode slew_rate_control(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->slew_rate_control(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes data buffer revision number + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode data_buffer_rev(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->data_buffer_rev(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM VrefDQ for Package Rank 0 + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank0(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM VrefDQ for Package Rank 1 + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank1(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM VrefDQ for Package Rank 2 + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank2(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM VrefDQ for Package Rank 3 + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank3(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes data buffer VrefDQ for DRAM interface + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->data_buffer_vref_dq(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM interface MDQ Drive Strenth + /// of the data buffer component for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->data_buffer_mdq_drive_strength(i_dimm_speed, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM interface MDQ read termination strength + /// of the data buffer component for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->data_buffer_mdq_rtt(i_dimm_speed, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM drive strenth + /// for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_drive_strength(i_dimm_speed, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM ODT for RTT_NOM + /// for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_rtt_nom(i_dimm_speed, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM ODT for RTT_WR + /// for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_rtt_wr(i_dimm_speed, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1 + /// for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_rtt_park_ranks0_1(i_dimm_speed, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3 + /// for a particular dimm speed + /// @param[in] i_dimm_speed the dimm speed in MT/s + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_rtt_park_ranks2_3(i_dimm_speed, o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes VrefDQ range for DRAM interface range + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_range(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes data buffer VrefDQ range for DRAM interface range + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->data_buffer_vref_dq_range(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes data buffer gain adjustment + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->data_buffer_gain_adjustment(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Decodes data buffer Decision Feedback Equalization (DFE) + /// @param[out] o_value SPD encoded value + /// @return FAPI2_RC_SUCCESS if okay + /// + fapi2::ReturnCode data_buffer_dfe(uint8_t& o_value) const + { + FAPI_TRY( iv_dimm_module_decoder->data_buffer_dfe(o_value) ); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @brief Helper function to append SPD decoder to the end of a vector +/// @param[in] i_target the DIMM target +/// @param[in] i_spd_data SPD data in a vector reference +/// @param[in,out] io_spd_decoder reference to std::vector of SPD facades +/// @return FAPI2_RC_SUCCESS iff okay +/// +static fapi2::ReturnCode add_decoder_to_list( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + std::vector< facade >& io_spd_decoder ) +{ + fapi2::ReturnCode l_rc; + facade l_spd_decoder(i_target, i_spd_data, l_rc); + FAPI_TRY(l_rc, "Failed to instantiate SPD facade for %s", spd::c_str(i_target)); + + io_spd_decoder.push_back(l_spd_decoder); + +fapi_try_exit: + return fapi2::current_err; +} + + +/// +/// @brief Creates a list of SPD decoder from target +/// @tparam T the fapi2 target +/// @param[in] i_target the DIMM target +/// @param[out] o_spd_decoder reference to std::vector of SPD facades +/// @return FAPI2_RC_SUCCESS iff okay +/// +template < fapi2::TargetType T > +fapi2::ReturnCode get_spd_decoder_list( const fapi2::Target<T>& i_target, + std::vector< facade >& o_spd_decoder ) +{ + o_spd_decoder.clear(); + + for( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) ) + { + std::vector<uint8_t> l_spd; + FAPI_TRY( get_raw_data(l_dimm, l_spd) ); + + FAPI_TRY( add_decoder_to_list(l_dimm, l_spd, o_spd_decoder) ); + }// dimms + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Creates a list of SPD decoder of SPD data to target +/// @tparam T the fapi2 target +/// @param[in] i_target the DIMM target +/// @param[in] i_spd_data SPD data +/// @param[out] o_spd_decoder reference to std::vector of SPD facades +/// @return FAPI2_RC_SUCCESS iff okay +/// +template < fapi2::TargetType T > +fapi2::ReturnCode get_spd_decoder_list( const fapi2::Target<T>& i_target, + const std::vector<uint8_t>& i_spd_data, + std::vector< facade >& o_spd_decoder ) +{ + o_spd_decoder.clear(); + + for( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) ) + { + FAPI_TRY( add_decoder_to_list(l_dimm, i_spd_data, o_spd_decoder) ); + }// dimms + +fapi_try_exit: + return fapi2::current_err; +} + +}// spd +}// mss + +#endif //_MSS_SPD_FACADE_H_ diff --git a/src/import/generic/memory/lib/spd/spd_factory_pattern.C b/src/import/generic/memory/lib/spd/spd_factory_pattern.C index bc58ff24f..dceb944fa 100644 --- a/src/import/generic/memory/lib/spd/spd_factory_pattern.C +++ b/src/import/generic/memory/lib/spd/spd_factory_pattern.C @@ -22,3 +22,334 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +/// +/// @file spd_factory_pattern.C +/// @brief SPD factory pattern implementation +/// + +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: HB:FSP + +#include <generic/memory/lib/spd/spd_factory_pattern.H> + +namespace mss +{ +namespace spd +{ + +/// +/// @brief constexpr ctor +/// @param[in] i_dram_gen DRAM generation +/// @param[in] i_spd_param DIMM type +/// @param[in] i_rev SPD revision +/// +module_key::module_key(const uint8_t i_dram_gen, + const parameters i_spd_param, + const uint8_t i_rev): + iv_rev(i_rev), + iv_dram_gen(i_dram_gen), + iv_param(i_spd_param) +{} + +/// +/// @brief less-than operator +/// @param[in] i_rhs the module_key +/// @return true or false +/// +bool module_key::operator<(const module_key& i_rhs) const +{ + // Impose weak strict ordering for dram_gen + // by dram gen, dimm type, and then revision + if(iv_dram_gen != i_rhs.iv_dram_gen) + { + return iv_dram_gen < i_rhs.iv_dram_gen; + } + + // If we are here than iv_param == i_key.iv_param + // Impose weak strict ordering for encoding_level + if( iv_param != i_rhs.iv_param) + { + return iv_param < i_rhs.iv_param; + } + + // If we are here than iv_encoding_level == i_key.iv_encoding_leve + // Impose weak strict ordering for additions_level + if( iv_rev != i_rhs.iv_rev) + { + return iv_rev < i_rhs.iv_rev; + } + + return false; +} + +/// +/// @brief ctor +/// @param[in] i_target the DIMM target +/// @param[in] i_key the module_key +/// +rev_fallback::rev_fallback(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const module_key& i_key): + iv_target(i_target), + iv_key(i_key), + iv_encoding_level(0), + iv_additions_level(0), + LRDIMM_DDR4_V1_0{DDR4, LRDIMM_MODULE, rev::V1_0}, + LRDIMM_DDR4_V1_1{DDR4, LRDIMM_MODULE, rev::V1_1}, + LRDIMM_DDR4_V1_2{DDR4, LRDIMM_MODULE, rev::V1_2}, + RDIMM_DDR4_V1_0{DDR4, RDIMM_MODULE, rev::V1_0}, + RDIMM_DDR4_V1_1{DDR4, RDIMM_MODULE, rev::V1_1}, + NVDIMM_DDR4_V1_0{DDR4, NVDIMM_MODULE, rev::V1_0}, + NVDIMM_DDR4_V1_1{DDR4, NVDIMM_MODULE, rev::V1_1} +{ + // Member variable initialization + fapi2::buffer<uint8_t> l_buffer(i_key.iv_rev); + l_buffer.extractToRight<ENCODINGS_REV_START, LEN>(iv_encoding_level); + l_buffer.extractToRight<ADDITIONS_REV_START, LEN>(iv_additions_level); + + // Setup pre-defined maps available to search through + // 3 diff mappings because each map has an independently + // managed revision. + iv_rdimm_rev_map[RDIMM_DDR4_V1_0] = rev::V1_0; + iv_rdimm_rev_map[RDIMM_DDR4_V1_1] = rev::V1_1; + + iv_lrdimm_rev_map[LRDIMM_DDR4_V1_0] = rev::V1_0; + iv_lrdimm_rev_map[LRDIMM_DDR4_V1_1] = rev::V1_1; + iv_lrdimm_rev_map[LRDIMM_DDR4_V1_2] = rev::V1_2; + + iv_nvdimm_rev_map[NVDIMM_DDR4_V1_0] = rev::V1_1; + iv_nvdimm_rev_map[NVDIMM_DDR4_V1_1] = rev::V1_1; + + // Another small map to select the right map based on module + iv_spd_param_map[RDIMM_MODULE] = iv_rdimm_rev_map; + iv_spd_param_map[LRDIMM_MODULE] = iv_lrdimm_rev_map; + iv_spd_param_map[NVDIMM_MODULE] = iv_nvdimm_rev_map; +} + +/// +/// @brief Retrieves highest supported SPD revision +/// @param[out] o_rev SPD revision +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode rev_fallback::get_supported_rev(uint8_t& o_rev) const +{ + std::map<module_key, uint8_t> l_map; + + auto it = iv_spd_param_map.find(iv_key.iv_param); + FAPI_ASSERT(it != iv_spd_param_map.end(), + fapi2::MSS_INVALID_SPD_PARAMETER_RECEIVED() + .set_SPD_PARAM(iv_key.iv_param) + .set_FUNCTION_CODE(GET_SUPPORTED_REV) + .set_TARGET(iv_target), + "Invalid SPD parameter received %d for %s", + iv_key.iv_param, spd::c_str(iv_target)); + + l_map = it->second; + FAPI_TRY( check_encoding_level(l_map) ); + + // The logic is easier to handle only additions level changes. + // This source will need to be updated to handle encodings level changes + // (rare occurance that hasn't happened yet...) and will be caught with the conditional above. + select_highest_rev(l_map, o_rev); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function to select the largest SPD revision +/// @param[in] i_map a map of supported SPD revisions for a certain SPD param +/// @param[out] o_rev the SPD Revision +/// @return FAPI2_RC_SUCCESS iff okay +/// +void rev_fallback::select_highest_rev( const std::map<module_key, uint8_t>& i_map, + uint8_t& o_rev) const +{ + // When encoding revisions are the same and only + // addition revisions differ, setting are backward + // compatible. This means if we hit a case where + // the additions level is not in our existing list of + // decoders we can default to the highest decoded revision. + // (e.g. If the DRAM is rev 1.3 but we have only decoded up + // to rev 1.1, we can safely default to rev 1.1 accepting + // that we lose features that may exist in higher revisions). + auto it = i_map.end(); + o_rev = (--it)->second; +} + +/// +/// @brief Helper function to check non-backward compatible encoding level changes +/// @param[in] i_map Map of supported SPD revisions for a certain SPD param +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode rev_fallback::check_encoding_level(const std::map<module_key, uint8_t>& i_map) const +{ + // A change in encoding revision breaks backward compatability, + // (e.g. revision 2.# is not backwards compatible with revision 1.#, + // for some integer #). + auto it = --(i_map.end()); + const uint8_t l_highest_possible_rev = it->second; + const fapi2::buffer<uint8_t> l_buffer(l_highest_possible_rev); + + uint8_t l_last_valid_encoding_lvl = 0; + l_buffer.extractToRight<ENCODINGS_REV_START, LEN>(l_last_valid_encoding_lvl); + + FAPI_INF("Highest valid rev 0x%02x, Highest valid encoding level %d, encoding level received %d for %s", + l_highest_possible_rev, l_last_valid_encoding_lvl, iv_encoding_level, spd::c_str(iv_target)); + + FAPI_ASSERT( iv_encoding_level <= l_last_valid_encoding_lvl, + fapi2::MSS_SPD_REV_ENCODING_LEVEL_NOT_SUPPORTED() + .set_ENCODING_LEVEL(iv_encoding_level) + .set_TARGET(iv_target), + "SPD revision encoding level (%d) is greater than largest decode (%d) for %s", + iv_encoding_level, l_last_valid_encoding_lvl, spd::c_str(iv_target)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ctor +/// @param[in] i_target the DIMM target +/// @param[in] i_spd_data SPD data in a vector reference +/// @param[out] o_rc FAPI2_RC_SUCCESS iff okay +/// +factories::factories(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + fapi2::ReturnCode& o_rc): + iv_target(i_target), + iv_spd_data(i_spd_data) +{ + FAPI_TRY( (reader<init_fields::REVISION, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_rev)), + "Failed to read REVISION field for %s", spd::c_str(i_target) ); + FAPI_TRY( (reader<init_fields::BASE_MODULE, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_dimm_type)), + "Failed to read BASE_MODULE field for %s", spd::c_str(i_target) ); + FAPI_TRY( (reader<init_fields::DEVICE_TYPE, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_dram_gen)), + "Failed to read DEVICE_TYPE field for %s", spd::c_str(i_target) ); + FAPI_TRY( (reader<init_fields::HYBRID, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_hybrid)), + "Failed to read HYBRID field for %s", spd::c_str(i_target) ); + FAPI_TRY( (reader<init_fields::HYBRID_MEDIA, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_hybrid_media)), + "Failed to read HYBRID_MEDIA field for %s", spd::c_str(i_target) ); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; +} + +/// +/// @brief creates base_cnfg_decoder object +/// @param[out] o_decoder_ptr the base_cnfg_decoder object ptr +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode factories::create_decoder( std::shared_ptr<base_cnfg_decoder>& o_decoder_ptr ) const +{ + parameters l_param = UNINITIALIZED; + FAPI_TRY(base_cfg_select_param(l_param)); + + { + auto l_factory_key = module_key(iv_dram_gen, l_param, iv_rev); + + const module_factory<base_cnfg_decoder> l_decoder(iv_target, iv_spd_data); + FAPI_TRY( l_decoder.make_object(l_factory_key, o_decoder_ptr) ); + } + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief creates dimm_module_decoder object +/// @param[out] o_decoder_ptr the dimm_module_decoder object ptr +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode factories::create_decoder( std::shared_ptr<dimm_module_decoder>& o_decoder_ptr ) const +{ + parameters l_param = UNINITIALIZED; + FAPI_TRY(dimm_module_select_param(l_param)); + + { + auto l_factory_key = module_key(iv_dram_gen, l_param, iv_rev); + + const module_factory<dimm_module_decoder> l_decoder(iv_target, iv_spd_data); + FAPI_TRY( l_decoder.make_object(l_factory_key, o_decoder_ptr) ); + } + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper to select SPD parameter for the dimm module +/// @param[out] o_param SPD parameter +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode factories::dimm_module_select_param(parameters& o_param) const +{ + switch(iv_dimm_type) + { + case RDIMM: + o_param = RDIMM_MODULE; + break; + + case LRDIMM: + o_param = LRDIMM_MODULE; + break; + + default: + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_TYPE() + .set_DIMM_TYPE(iv_dimm_type) + .set_FUNCTION(DIMM_MODULE_PARAM_SELECT) + .set_DIMM_TARGET(iv_target), + "Invalid DIMM type recieved (%d) for %s", + iv_dimm_type, spd::c_str(iv_target)); + break; + } + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper to select SPD parameter for the base cfg +/// @param[out] o_param SPD parameter +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode factories::base_cfg_select_param(parameters& o_param) const +{ + if(iv_hybrid == HYBRID && iv_hybrid_media == NVDIMM_HYBRID) + { + // The general section used for NVDIMMs is different than + // those for LRDIMM and RDIMM modules. + o_param = NVDIMM_MODULE; + return fapi2::FAPI2_RC_SUCCESS; + } + + // If we are here let's make sure we are not hybrid, sanity + // check to assure we don't have invalid hybrid combination + FAPI_ASSERT(iv_hybrid == NOT_HYBRID && + iv_hybrid_media == NOT_HYBRID, + fapi2::MSS_INVALID_HYBRID_MODULE(). + set_HYBRID(iv_hybrid). + set_HYBRID_MEDIA(iv_hybrid_media). + set_FUNCTION(BASE_CFG_PARAM_SELECT). + set_TARGET(iv_target), + "Invalid hybrid (%d) or hybrid_media (%d) for %s", + iv_hybrid, iv_hybrid_media, spd::c_str(iv_target)); + + FAPI_TRY(dimm_module_select_param(o_param)); + +fapi_try_exit: + return fapi2::current_err; +} + +}// spd +}// mss diff --git a/src/import/generic/memory/lib/spd/spd_factory_pattern.H b/src/import/generic/memory/lib/spd/spd_factory_pattern.H index c0629c5c9..9d36738d4 100644 --- a/src/import/generic/memory/lib/spd/spd_factory_pattern.H +++ b/src/import/generic/memory/lib/spd/spd_factory_pattern.H @@ -22,3 +22,487 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +/// +/// @file spd_factory_pattern.H +/// @brief SPD factory pattern declaration +/// + +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: HB:FSP + +#ifndef _MSS_SPD_FACTORY_PATTERN_H_ +#define _MSS_SPD_FACTORY_PATTERN_H_ + +#include <fapi2.H> +#include <cstdint> +#include <map> +#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H> +#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H> +#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H> +#include <generic/memory/lib/spd/spd_checker.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> + +namespace mss +{ +/// +/// @class moduleFactoryTraits +/// @brief class that holds module factory traits +/// @tparam T the decoder type we want the factory to generate +/// +template < typename T > +struct moduleFactoryTraits; + +/// +/// @class moduleFactoryTraits - base_cnfg_decoder specialization +/// @brief class that holds module factory traits +/// +template< > +struct moduleFactoryTraits<spd::base_cnfg_decoder> +{ + static constexpr generic_ffdc_codes MODULE_FACTORY_FFDC_CODE = BASE_CFG_FACTORY; +}; + +/// +/// @class moduleFactoryTraits - dimm_module_decoder specialization +/// @brief class that holds module factory traits +/// +template< > +struct moduleFactoryTraits<spd::dimm_module_decoder> +{ + static constexpr generic_ffdc_codes MODULE_FACTORY_FFDC_CODE = DIMM_MODULE_FACTORY; +}; + +namespace spd +{ + +/// +/// @class module_key +/// @brief SPD module key for factory +/// +struct module_key +{ + uint8_t iv_rev; + uint8_t iv_dram_gen; + parameters iv_param; + + /// + /// @brief default ctor + /// + module_key() = default; + + /// + /// @brief constexpr ctor + /// @param[in] i_dram_gen DRAM generation + /// @param[in] i_spd_param DIMM type + /// @param[in] i_rev SPD revision + /// + module_key(const uint8_t i_dram_gen, + const parameters i_spd_param, + const uint8_t i_rev); + + /// + /// @brief default dtor + /// + ~module_key() = default; + + /// + /// @brief less-than operator + /// @param[in] i_rhs the module_key + /// @return true or false + /// + bool operator<(const module_key& i_rhs) const; + +};// module_key + +/// +/// @brief Class that performs revision fallback +/// @class rev_fallback +/// +class rev_fallback +{ + public: + + /// + /// @brief ctor + /// @param[in] i_target the DIMM target + /// @param[in] i_key the module_key + /// + rev_fallback(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const module_key& i_key); + + /// + /// @brief dtor + /// + ~rev_fallback() = default; + + /// + /// @brief Retrieves highest supported SPD revision + /// @param[out] o_rev SPD revision + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode get_supported_rev(uint8_t& o_rev) const; + + private: + + enum + { + LEN = 4, + ENCODINGS_REV_START = 0, + ADDITIONS_REV_START = 4, + }; + + fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + module_key iv_key; + uint8_t iv_encoding_level; + uint8_t iv_additions_level; + + // Constants convenient for map indexing + const module_key LRDIMM_DDR4_V1_0; + const module_key LRDIMM_DDR4_V1_1; + const module_key LRDIMM_DDR4_V1_2; + + const module_key RDIMM_DDR4_V1_0; + const module_key RDIMM_DDR4_V1_1; + + const module_key NVDIMM_DDR4_V1_0; + const module_key NVDIMM_DDR4_V1_1; + + std::map<module_key, uint8_t> iv_lrdimm_rev_map; + std::map<module_key, uint8_t> iv_rdimm_rev_map; + std::map<module_key, uint8_t> iv_nvdimm_rev_map; + std::map< parameters, std::map<module_key, uint8_t> > iv_spd_param_map; + + /// + /// @brief Helper function to select the largest SPD revision + /// @param[in] i_map a map of supported SPD revisions for a certain SPD param + /// @param[out] o_rev the SPD Revision + /// @return FAPI2_RC_SUCCESS iff okay + /// + void select_highest_rev( const std::map<module_key, uint8_t>& i_map, + uint8_t& o_rev) const; + + /// + /// @brief Helper function to check non-backward compatible encoding level changes + /// @param[in] i_map Map of supported SPD revisions for a certain SPD param + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode check_encoding_level(const std::map<module_key, uint8_t>& i_map) const; +}; + +/// +/// @class module_factory +/// @tparam T module decoder type (e.g. base_cnfg_decoder, dimm_module_decoder) +/// @tparam TT defaulted to moduleFactoryTraits<T> +/// @brief Factory method for SPD module parameters +/// +template < typename T, typename TT = moduleFactoryTraits<T> > +class module_factory +{ + public: + + /// + /// @brief ctor + /// @param[in] i_target the DIMM target + /// @param[in] i_spd_data SPD data in a vector reference + /// + module_factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data): + iv_target(i_target), + LRDIMM_DDR4_REV_1_0{DDR4, LRDIMM_MODULE, rev::V1_0}, + LRDIMM_DDR4_REV_1_1{DDR4, LRDIMM_MODULE, rev::V1_1}, + LRDIMM_DDR4_REV_1_2{DDR4, LRDIMM_MODULE, rev::V1_2}, + RDIMM_DDR4_REV_1_0{DDR4, RDIMM_MODULE, rev::V1_0}, + RDIMM_DDR4_REV_1_1{DDR4, RDIMM_MODULE, rev::V1_1}, + NVDIMM_DDR4_REV_1_0{DDR4, NVDIMM_MODULE, rev::V1_0}, + NVDIMM_DDR4_REV_1_1{DDR4, NVDIMM_MODULE, rev::V1_1} + { + // Setup pre-defined maps available to search through + init_map_vars(i_spd_data, iv_decoder_map); + } + + /// + /// @brief default dtor + /// + ~module_factory() = default; + + /// + /// @brief creates module_decoder object from key + /// @param[in,out] io_key the module key + /// @param[out] o_decoder_ptr the dimm_module_decoder object ptr + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode make_object(module_key& io_key, + std::shared_ptr<T>& o_decoder_ptr) const + { + auto it = iv_decoder_map.find(io_key); + + // If we found matching key, return that associated decoder + if(it != iv_decoder_map.end()) + { + o_decoder_ptr = it->second; + return fapi2::FAPI2_RC_SUCCESS; + } + + // If we are here that means we didn't find a matching key-value pair. + // So we will dig deeper to evaluate the issue and try to fallback to + // a supported (backward compatible) SPD revision. + FAPI_TRY( try_fallback(io_key, o_decoder_ptr) ); + + fapi_try_exit: + return fapi2::current_err; + } + + private: + + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + + // Indexing member vars for convenient map indexing + const module_key LRDIMM_DDR4_REV_1_0; + const module_key LRDIMM_DDR4_REV_1_1; + const module_key LRDIMM_DDR4_REV_1_2; + const module_key RDIMM_DDR4_REV_1_0; + const module_key RDIMM_DDR4_REV_1_1; + const module_key NVDIMM_DDR4_REV_1_0; + const module_key NVDIMM_DDR4_REV_1_1; + + std::map< module_key, std::shared_ptr<T> > iv_decoder_map; + + /// + /// @brief Helper function to initialize base_cnfg_decoder map + /// @param[out] o_map base_cnfg_decoder map + /// + void init_map_vars(const std::vector<uint8_t>& i_spd_data, + std::map< module_key, std::shared_ptr<base_cnfg_decoder> >& o_map) + { + // + // RDIMMs + // + + // Rev 1.0 + // Life starts out at base revision level + o_map[RDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_0> >(iv_target, i_spd_data); + + // Rev 1.1 + // Changes to both the general section & rdimm section occured + o_map[RDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data); + + // + // LRDIMMs + // + + // Rev 1.0 + // Life starts out at base revision level + o_map[LRDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_0> >(iv_target, i_spd_data); + + // Rev 1.1 + // Changes to both the general section & lrdimm section occured + o_map[LRDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data); + + // Rev 1.2 + // Changes lrdimm section occured + // General section remained the same + o_map[LRDIMM_DDR4_REV_1_2] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data); + + // + // NVDIMMs + // + + // Rev 1.0 + // NVDIMMs start out life w/the updated general section. + o_map[NVDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data); + + // Rev 1.1 + // Changes to the NVDIMM module occured, general section remains the same + o_map[NVDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data); + } + + /// + /// @brief Helper function to initialize dimm_module_decoder map + /// @param[out] o_map dimm_module_decoder map + /// + void init_map_vars(const std::vector<uint8_t>& i_spd_data, + std::map< module_key, std::shared_ptr<dimm_module_decoder> >& o_map) + { + // + // RDIMMs + // + + // Rev 1.0 + // Life starts out at base revision level + o_map[RDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, RDIMM_MODULE, rev::V1_0> >(iv_target, i_spd_data); + + // Rev 1.1 + // Changes to both the general section & rdimm section occured + o_map[RDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, RDIMM_MODULE, rev::V1_1> >(iv_target, i_spd_data); + + // + // LRDIMMs + // + + // Rev 1.0 + // Life starts out at base revision level + o_map[LRDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, LRDIMM_MODULE, rev::V1_0> >(iv_target, i_spd_data); + + // Rev 1.1 + // Changes to both the general section & lrdimm section occured + o_map[LRDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, LRDIMM_MODULE, rev::V1_1> >(iv_target, i_spd_data); + + // Rev 1.2 + // Changes lrdimm section occured + // General section remained the same + o_map[LRDIMM_DDR4_REV_1_2] = std::make_shared< decoder<DDR4, LRDIMM_MODULE, rev::V1_2> >(iv_target, i_spd_data); + } + + /// + /// @brief Try to fallback to a supported backward compatible decoder + /// @param[in,out] io_key the module key + /// @param[out] o_rev SPD revision we are falling back to + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode find_backward_compatible_rev(module_key& io_key) const + { + const rev_fallback l_rev_fallback(iv_target, io_key); + + // Overwrite io_key.iv_rev with a supported revision + FAPI_TRY(l_rev_fallback.get_supported_rev(io_key.iv_rev)); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Create a decoder with the fallback module_key + /// @param[in] i_key the module key + /// @param[out] o_decoder_ptr decoder ptr + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode create_fallback_decoder(const module_key& i_key, + std::shared_ptr<T>& o_decoder_ptr) const + { + auto it = iv_decoder_map.find(i_key); + + // Sanity check, should never fail unless it's a programming error... + constexpr generic_ffdc_codes FFDC_CODE = TT::MODULE_FACTORY_FFDC_CODE; + + FAPI_ASSERT( it != iv_decoder_map.end(), + fapi2::MSS_FAILED_SPD_REVISION_FALLBACK() + .set_FAILED_REVISION(i_key.iv_rev) + .set_FUNCTION_CODE(FFDC_CODE) + .set_TARGET(iv_target), + "Failed to find a map value for the key (rev 0x%02, param %d, dram gen: %d", + i_key.iv_rev, i_key.iv_param, i_key.iv_dram_gen); + + // Update SPD rev to fallback rev + { + constexpr size_t REV_BYTE = 1; + o_decoder_ptr = it->second; + std::vector<uint8_t> l_spd_data = o_decoder_ptr->get_data(); + l_spd_data[REV_BYTE] = i_key.iv_rev; + o_decoder_ptr->set_data(l_spd_data); + } + + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Try to fallback to a supported backward compatible decoder + /// @param[in,out] io_key the module key + /// @param[out] o_decoder_ptr the o_decoder_ptr object ptr + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode try_fallback(module_key& io_key, + std::shared_ptr<T>& o_decoder_ptr) const + { + const uint8_t l_dimm_type = io_key.iv_param == RDIMM_MODULE ? RDIMM : LRDIMM; + + // Invalid DRAM gen is a hard fail + FAPI_TRY(check::dram_gen(iv_target, io_key.iv_dram_gen, TT::MODULE_FACTORY_FFDC_CODE)); + + // Invalid DIMM type is a hard fail + FAPI_TRY(check::dimm_type(iv_target, l_dimm_type, TT::MODULE_FACTORY_FFDC_CODE)); + + // We can circumvent SPD revision fails by using backward compatible revisions + FAPI_TRY(find_backward_compatible_rev(io_key)); + + // Let's create a new decoder that we can fall back to + FAPI_TRY(create_fallback_decoder(io_key, o_decoder_ptr)); + + fapi_try_exit: + return fapi2::current_err; + } +}; + +/// +/// @class factories +/// @brief Factory method that creates the right decoder based on SPD data +/// +class factories +{ + public: + + /// + /// @brief ctor + /// @param[in] i_target the DIMM target + /// @param[in] i_spd_data SPD data in a vector reference + /// @param[out] o_rc FAPI2_RC_SUCCESS iff okay + /// + factories(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + fapi2::ReturnCode& o_rc); + + /// + /// @brief default dtor + /// + ~factories() = default; + + + /// + /// @brief creates base_cnfg_decoder object + /// @param[out] o_decoder_ptr the base_cnfg_decoder object ptr + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode create_decoder( std::shared_ptr<base_cnfg_decoder>& o_decoder_ptr ) const; + + /// + /// @brief creates dimm_module_decoder object + /// @param[out] o_decoder_ptr the dimm_module_decoder object ptr + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode create_decoder( std::shared_ptr<dimm_module_decoder>& o_decoder_ptr ) const; + + private: + + const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target; + std::vector<uint8_t> iv_spd_data; + uint8_t iv_rev; + uint8_t iv_dram_gen; + uint8_t iv_dimm_type; + uint8_t iv_hybrid; + uint8_t iv_hybrid_media; + + /// + /// @brief Helper to select SPD parameter for the dimm module + /// @param[out] o_param SPD parameter + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode dimm_module_select_param(parameters& o_param) const; + + /// + /// @brief Helper to select SPD parameter for the base cfg + /// @param[out] o_param SPD parameter + /// @return FAPI2_RC_SUCCESS iff okay + /// + fapi2::ReturnCode base_cfg_select_param(parameters& o_param) const; + +}; + +}// spd +}// mss + +#endif //_MSS_SPD_FACTORY_PATTERN_H_ diff --git a/src/import/generic/memory/lib/spd/spd_fields_ddr4.H b/src/import/generic/memory/lib/spd/spd_fields_ddr4.H index 97413367d..15c95ff77 100644 --- a/src/import/generic/memory/lib/spd/spd_fields_ddr4.H +++ b/src/import/generic/memory/lib/spd/spd_fields_ddr4.H @@ -460,7 +460,6 @@ class fields<DDR4, BASE_CNFG> static constexpr field_t OFFSET_TCK_MIN{125, OFFSET_TCK_MIN_START, OFFSET_TCK_MIN_LEN}; static constexpr field_t CRC_LSB{126, CRC_LSB_START, CRC_LSB_LEN}; static constexpr field_t CRC_MSB{127, CRC_MSB_START, CRC_MSB_LEN}; - static constexpr field_t REF_RAW_CARD{130, REF_RAW_CARD_START, REF_RAW_CARD_LEN}; static constexpr field_t CONTINUATION_CODES{320, CONTINUATION_CODES_START, CONTINUATION_CODES_LEN}; static constexpr field_t LAST_NON_ZERO_BYTE{321, LAST_NON_ZERO_BYTE_START, LAST_NON_ZERO_BYTE_LEN}; static constexpr field_t MODULE_MFG_LOCATION{322, MODULE_MFG_LOC_START, MODULE_MFG_LOC_LEN}; diff --git a/src/import/generic/memory/lib/spd/spd_reader.H b/src/import/generic/memory/lib/spd/spd_reader.H index 90b9df1da..c67db544b 100644 --- a/src/import/generic/memory/lib/spd/spd_reader.H +++ b/src/import/generic/memory/lib/spd/spd_reader.H @@ -51,6 +51,94 @@ namespace spd { /// +/// @brief Helper function to find bit length of an integral type +/// @tparam T integral type +/// @return bit length for given integral type +/// +template < typename T > +constexpr size_t get_bit_length() +{ + return sizeof(T) * BITS_PER_BYTE; +} + +/// +/// @brief Helper function to find bit length of an input param +/// @tparam T input type +/// @param[in] i_input argument we want to get bit length of +/// @return bit length for given input +/// +template < typename T > +constexpr size_t get_bit_length(const T& i_input) +{ + return sizeof(T) * BITS_PER_BYTE; +} + +/// +/// @brief Variadic helper function to find bit length of integral types +/// @tparam T input type +/// @tparam Types input type for a list in input params +/// @param[in] i_first first argument we want to get bit length of +/// @param[in] i_args list of arguments we want to get the total bit length of +/// @return total bit length for given input +// +template < typename T, typename... Types > +constexpr size_t get_bit_length (const T& i_first, const Types& ... i_args) +{ + // Recursive-ish pattern to add up bit length of passed in params + return get_bit_length(i_first) + get_bit_length(i_args...); +} + +/// +/// @tparam T input type +/// @tparam T +/// @param[in] i_data data to insert +/// @param[in,out] io_out buffer we wish to insert values to +/// +template <size_t INPUT_BIT_LEN, typename T, typename OT> +static void set_buffer_helper(const T i_data, fapi2::buffer<OT>& io_out) +{ + constexpr size_t l_output_bit_length = get_bit_length<OT>(); + + constexpr size_t l_start_bit = l_output_bit_length - INPUT_BIT_LEN; + constexpr size_t l_len = get_bit_length<T>(); + + FAPI_DBG("Total input bit length %d, output bit length %d, insert start bit %d, insert length %d, data %d", + INPUT_BIT_LEN, l_output_bit_length, l_start_bit, l_len, i_data); + + io_out.template insertFromRight<l_start_bit, l_len >(i_data); +} + +/// +/// @brief Helper function to insert entire values of any integral value into a buffer +/// @tparam T input type +/// @tparam OT output type of fapi2::buffer +/// @param[in,out] io_out buffer we wish to insert values to +/// @param[in] i_input argument we want to get bit length of +/// +template <typename T, typename OT> +void rightAlignedInsert(fapi2::buffer<OT>& io_out, const T& i_input) +{ + constexpr size_t l_input_total_args_bit_length = get_bit_length(i_input); + set_buffer_helper<l_input_total_args_bit_length>(i_input, io_out); +} + +/// +/// @tparam T input type +/// @tparam Types input type for a list in input params +/// @param[in,out] io_out buffer we wish to insert values to +/// @param[in] i_first first argument we want to get bit length of +/// @param[in] i_args list of arguments we want to get the total bit length of +/// +template <typename T, typename OT, typename... Types> +void rightAlignedInsert(fapi2::buffer<OT>& io_out, const T& first, const Types& ... args) +{ + constexpr size_t l_input_total_args_bit_length = get_bit_length(first, args...); + set_buffer_helper<l_input_total_args_bit_length>(first, io_out); + + rightAlignedInsert(io_out, args...); +} + +/// /// @brief Helper function to extract byte information /// @tparam F the SPD field to extract /// @param[in] i_target the dimm target @@ -85,6 +173,8 @@ fapi2::ReturnCode extract_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_ o_value); } + return fapi2::FAPI2_RC_SUCCESS; + fapi_try_exit: return fapi2::current_err; } @@ -107,18 +197,20 @@ fapi2::ReturnCode reader( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target OT& o_value) { T l_temp = 0; - FAPI_TRY(extract_field<F>(i_target, i_spd_data, l_temp)); + FAPI_TRY( extract_field<F>(i_target, i_spd_data, l_temp), + "Failed extract_field() for %s", spd::c_str(i_target) ); FAPI_DBG("extracted %s value: 0x%02x for %s", TT::FIELD_STR, l_temp, spd::c_str(i_target)); // Test if retrieved data seems valid - FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target, - conditional( l_temp, - TT::COMPARISON_VAL, - typename TT::template COMPARISON_OP<T>() ), - F.get_byte(), - l_temp) ); + FAPI_TRY( check::fail_for_invalid_value(i_target, + conditional( l_temp, + TT::COMPARISON_VAL, + typename TT::template COMPARISON_OP<T>() ), + F.get_byte(), + l_temp), + "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) ); // Output should only change if data check passes o_value = static_cast<OT>(l_temp); diff --git a/src/import/generic/memory/lib/spd/spd_traits.H b/src/import/generic/memory/lib/spd/spd_traits.H index 9eb546302..b05f2c447 100644 --- a/src/import/generic/memory/lib/spd/spd_traits.H +++ b/src/import/generic/memory/lib/spd/spd_traits.H @@ -67,9 +67,8 @@ bool conditional(const T i_spd_field, /// @brief trait structure to hold static SPD information /// @tparam F holds SPD field info /// @tparam R the revision of the SPD field -/// @tparam B boolean required to activate trait class - defaulted to true_type /// -template< const field_t& F, rev R, typename B = std::true_type > +template< const field_t& F, rev R > class readerTraits; /// diff --git a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H index 5d2323bba..e9bda39ea 100644 --- a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H +++ b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H @@ -46,19 +46,15 @@ namespace mss namespace spd { -// Note: The 3rd template parameter is a compile-time conditional -// to activate trait class based on a valid SPD revision. - /// /// @class readerTraits /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note BYTES_USED field partial specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template<rev R> -class readerTraits < fields<DDR4, BASE_CNFG>::BYTES_USED, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::BYTES_USED, R> { public: @@ -74,11 +70,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BYTES_USED, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TOTAL_BYTES field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template<rev R> -class readerTraits < fields<DDR4, BASE_CNFG>::TOTAL_BYTES, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TOTAL_BYTES, R > { public: @@ -94,11 +89,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TOTAL_BYTES, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note REVISION field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::REVISION, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::REVISION, R > { public: @@ -136,8 +130,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, R > { public: @@ -153,11 +146,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note BASE_MODULE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::BASE_MODULE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::BASE_MODULE, R > { public: @@ -193,8 +185,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID, rev::V1_0 > /// @note valid for rev >= 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID, R > { public: @@ -227,11 +218,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, rev::V1_0 > /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note HYBRID_MEDIA field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, R > { public: @@ -247,11 +237,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note BANK_GROUP_BITS field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::BANK_GROUP_BITS, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::BANK_GROUP_BITS, R > { public: @@ -270,8 +259,7 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BANK_GROUP_BITS, R, /// @note rev 1.0 specialization /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::BANKS_ADDR_BITS, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::BANKS_ADDR_BITS, R > { public: @@ -304,11 +292,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, rev::V1_0 > /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note SDRAM_CAPACITY, field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, R > { public: @@ -324,11 +311,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note COL_ADDR_BITS field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::COL_ADDR_BITS, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::COL_ADDR_BITS, R > { public: @@ -344,11 +330,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::COL_ADDR_BITS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note ROW_ADDR_BITS field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::ROW_ADDR_BITS, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::ROW_ADDR_BITS, R > { public: @@ -364,11 +349,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::ROW_ADDR_BITS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note PRIM_SIGNAL_LOADING field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_SIGNAL_LOADING, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_SIGNAL_LOADING, R > { public: @@ -384,11 +368,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_SIGNAL_LOADING, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note PRIM_DIE_COUNT field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_DIE_COUNT, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_DIE_COUNT, R > { public: @@ -404,11 +387,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_DIE_COUNT, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note PRIM_PACKAGE_TYPE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::PRIM_PACKAGE_TYPE, R, - std::integral_constant<bool, (R >= rev::V1_0)> > +class readerTraits< fields<DDR4, BASE_CNFG>::PRIM_PACKAGE_TYPE, R > { public: @@ -424,11 +406,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::PRIM_PACKAGE_TYPE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MAC field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MAC, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MAC, R > { public: @@ -447,8 +428,7 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MAC, R, /// @note rev 1.0 specialization /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::TMAW, R, - std::integral_constant<bool, (R >= rev::V1_0)> > +class readerTraits< fields<DDR4, BASE_CNFG>::TMAW, R > { public: @@ -464,11 +444,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::TMAW, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note PPR field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::PPR, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::PPR, R > { public: @@ -483,32 +462,15 @@ class readerTraits < fields<DDR4, BASE_CNFG>::PPR, R, /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note SOFT_PPR field specialization -/// @note rev 1.0 specialization -/// -template<> -class readerTraits< fields<DDR4, BASE_CNFG>::SOFT_PPR, rev::V1_0 > -{ - public: - - static constexpr size_t COMPARISON_VAL = 0; - static constexpr const char* FIELD_STR = "Soft post package repair (SPPR)"; - - template <typename T> - using COMPARISON_OP = std::equal_to<T>; -}; - -/// -/// @class readerTraits -/// @brief trait structure to hold static SPD information -/// @note SOFT_PPR field specialization -/// @note valid for rev >= 1.1 +/// @note valid for revs /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::SOFT_PPR, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::SOFT_PPR, R > { public: + // Some existing HW has a soft PPR value of 0b01 despite being rev 1.0 + // So we'll allow even thought it doesn't match the SPD spec.... static constexpr size_t COMPARISON_VAL = 0b01; static constexpr const char* FIELD_STR = "Soft post package repair (SPPR)"; @@ -541,8 +503,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_SIGNAL_LOADING, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::SEC_SIGNAL_LOADING, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::SEC_SIGNAL_LOADING, R > { public: @@ -578,8 +539,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DENSITY_RATIO, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DENSITY_RATIO, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DENSITY_RATIO, R > { public: @@ -615,8 +575,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DIE_COUNT, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DIE_COUNT, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DIE_COUNT, R > { public: @@ -652,8 +611,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, R > { public: @@ -669,11 +627,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OPERABLE_FLD field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OPERABLE_FLD, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OPERABLE_FLD, R > { public: @@ -689,11 +646,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OPERABLE_FLD, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note ENDURANT_FLD field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::ENDURANT_FLD, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::ENDURANT_FLD, R > { public: @@ -709,11 +665,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::ENDURANT_FLD, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note SDRAM_WIDTH field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::SDRAM_WIDTH, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::SDRAM_WIDTH, R > { public: @@ -749,8 +704,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::PACKAGE_RANKS, rev::V1_0 > /// @note valid for rev >= 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::PACKAGE_RANKS, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::PACKAGE_RANKS, R > { public: @@ -786,8 +740,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, rev::V1_0 > /// @note rev 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, R > { public: @@ -803,11 +756,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note BUS_WIDTH field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::BUS_WIDTH, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::BUS_WIDTH, R > { public: @@ -823,11 +775,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BUS_WIDTH, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note BUS_EXT_WIDTH field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::BUS_EXT_WIDTH, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::BUS_EXT_WIDTH, R > { public: @@ -843,11 +794,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BUS_EXT_WIDTH, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note THERM_SENSOR field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::THERM_SENSOR, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::THERM_SENSOR, R > { public: @@ -863,11 +813,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::THERM_SENSOR, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note EXTENDED_MODULE_TYPE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::EXTENDED_MODULE_TYPE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::EXTENDED_MODULE_TYPE, R > { public: @@ -883,11 +832,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::EXTENDED_MODULE_TYPE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MED_TIMEBASE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MEDIUM_TIMEBASE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MEDIUM_TIMEBASE, R > { public: @@ -903,11 +851,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MEDIUM_TIMEBASE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note FINE_TIMEBASE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::FINE_TIMEBASE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::FINE_TIMEBASE, R > { public: @@ -923,11 +870,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::FINE_TIMEBASE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TCK_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MIN, R > { public: @@ -943,11 +889,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TCK_MAX field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MAX, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MAX, R > { public: @@ -963,11 +908,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MAX, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CL_FIRST_BYTE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::CL_FIRST_BYTE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::CL_FIRST_BYTE, R > { public: @@ -984,11 +928,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CL_FIRST_BYTE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CL_SECOND_BYTE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::CL_SECOND_BYTE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::CL_SECOND_BYTE, R > { public: @@ -1024,8 +967,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::CL_THIRD_BYTE, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::CL_THIRD_BYTE, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::CL_THIRD_BYTE, R > { public: @@ -1061,8 +1003,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, R > { public: @@ -1078,11 +1019,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TAA_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TAA_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TAA_MIN, R > { public: @@ -1098,11 +1038,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TAA_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRCD_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRCD_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRCD_MIN, R > { public: @@ -1118,11 +1057,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRCD_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRP_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRP_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRP_MIN, R > { public: @@ -1138,11 +1076,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRP_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRASMIN_MSN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_MSN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_MSN, R > { public: @@ -1158,11 +1095,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_MSN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRASMIN_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_LSB, R > { public: @@ -1178,11 +1114,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRCMIN_MSN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_MSN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_MSN, R > { public: @@ -1197,11 +1132,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_MSN, R, /// @class readerTraits /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_LSB, R > { public: @@ -1217,11 +1151,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRFC1MIN_MSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_MSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_MSB, R > { public: @@ -1237,11 +1170,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_MSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRFC1MIN_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_LSB, R > { public: @@ -1257,11 +1189,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRFC2MIN_MSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_MSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_MSB, R > { public: @@ -1277,11 +1208,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_MSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRFC2MIN_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_LSB, R > { public: @@ -1297,11 +1227,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRFC4MIN_MSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_MSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_MSB, R > { public: @@ -1318,11 +1247,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_MSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRFC4MIN_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_LSB, R > { public: @@ -1338,11 +1266,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TFAWMIN_MSN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_MSN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_MSN, R > { public: @@ -1358,11 +1285,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_MSN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TFAWMIN_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_LSB, R > { public: @@ -1378,11 +1304,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRRD_S_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_S_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_S_MIN, R > { public: @@ -1398,11 +1323,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_S_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TRRD_L_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_L_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_L_MIN, R > { public: @@ -1418,11 +1342,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_L_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TCCD_L_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TCCD_L_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TCCD_L_MIN, R > { public: @@ -1439,11 +1362,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TCCD_L_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TWRMIN_MSN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_MSN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_MSN, R > { public: @@ -1459,11 +1381,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_MSN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TWRMIN_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_LSB, R > { public: @@ -1480,11 +1401,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TWTRMIN_S_MSN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_MSN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_MSN, R > { public: @@ -1500,11 +1420,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_MSN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TWTRMIN_S_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_LSB, R > { public: @@ -1520,11 +1439,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TWTRMIN_L_MSN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_MSN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_MSN, R > { public: @@ -1541,11 +1459,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_MSN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note TWTRMIN_L_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_LSB, R > { public: @@ -1562,11 +1479,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TCCD_L_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCCD_L_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCCD_L_MIN, R > { public: @@ -1584,11 +1500,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCCD_L_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TRRD_L_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_L_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_L_MIN, R > { public: @@ -1605,11 +1520,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_L_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TRRD_S_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_S_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_S_MIN, R > { public: @@ -1626,11 +1540,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_S_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TRC_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRC_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRC_MIN, R > { public: @@ -1646,11 +1559,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRC_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TRP_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRP_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRP_MIN, R > { public: @@ -1667,11 +1579,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRP_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TAA_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TAA_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TAA_MIN, R > { public: @@ -1687,11 +1598,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TAA_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TRCD_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRCD_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRCD_MIN, R > { public: @@ -1707,11 +1617,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRCD_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TCK_MIN field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MIN, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MIN, R > { public: @@ -1727,11 +1636,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MIN, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note OFFSET_TCK_MAX field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MAX, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MAX, R > { public: @@ -1747,11 +1655,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MAX, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CRC_MSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::CRC_MSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::CRC_MSB, R > { public: @@ -1767,11 +1674,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CRC_MSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CRC_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::CRC_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::CRC_LSB, R > { public: @@ -1787,11 +1693,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CRC_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CONTINUATION_CODES field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::CONTINUATION_CODES, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::CONTINUATION_CODES, R > { public: @@ -1807,11 +1712,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CONTINUATION_CODES, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note LAST_NON_ZERO_BYTE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::LAST_NON_ZERO_BYTE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::LAST_NON_ZERO_BYTE, R > { public: @@ -1827,11 +1731,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::LAST_NON_ZERO_BYTE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_MFG_LOCATION field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_LOCATION, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_LOCATION, R > { public: @@ -1847,11 +1750,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_LOCATION, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_MFG_DATE_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_LSB, R > { public: @@ -1867,11 +1769,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_MFG_DATE_MSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_MSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_MSB, R > { public: @@ -1887,11 +1788,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_MSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_SERIAL_NUM_BYTE1 field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE1, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE1, R > { public: @@ -1907,11 +1807,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE1, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_SERIAL_NUM_BYTE2 field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE2, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE2, R > { public: @@ -1927,11 +1826,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE2, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_SERIAL_NUM_BYTE3 field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE3, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE3, R > { public: @@ -1947,11 +1845,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE3, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_SERIAL_NUM_BYTE4 field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE4, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE4, R > { public: @@ -1967,11 +1864,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE4, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_REV_CODE field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_REV_CODE, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_REV_CODE, R > { public: @@ -1987,11 +1883,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_REV_CODE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_MFR_ID_CODE_LSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_LSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_LSB, R > { public: @@ -2007,11 +1902,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_LSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_MFR_ID_CODE_MSB field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_MSB, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_MSB, R > { public: @@ -2027,11 +1921,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_MSB, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_STEPPING field specialization -/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_STEPPING, R, - std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> > +class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_STEPPING, R > { public: @@ -2047,11 +1940,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_STEPPING, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_NOMINAL_HEIGHT field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R > { public: @@ -2068,11 +1960,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note FRONT_MODULE_THICKNESS field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::FRONT_MODULE_THICKNESS, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::FRONT_MODULE_THICKNESS, R > { public: @@ -2089,11 +1980,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::FRONT_MODULE_THICKNESS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note BACK_MODULE_THICKNESS field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::BACK_MODULE_THICKNESS, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::BACK_MODULE_THICKNESS, R > { public: @@ -2109,11 +1999,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::BACK_MODULE_THICKNESS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note REF_RAW_CARD field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::REF_RAW_CARD, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::REF_RAW_CARD, R > { public: @@ -2129,11 +2018,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::REF_RAW_CARD, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note NUM_REGS_USED field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::NUM_REGS_USED, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::NUM_REGS_USED, R > { public: @@ -2149,11 +2037,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::NUM_REGS_USED, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note ROWS_OF_DRAMS field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::ROWS_OF_DRAMS, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::ROWS_OF_DRAMS, R > { public: @@ -2169,11 +2056,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::ROWS_OF_DRAMS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note REGISTER_TYPE field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_TYPE, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_TYPE, R > { public: @@ -2189,11 +2075,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_TYPE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note HEAT_SPREADER_CHAR field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_CHAR, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_CHAR, R > { public: @@ -2209,11 +2094,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_CHAR, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note HEAT_SPREADER_SOL field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_SOL, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_SOL, R > { public: @@ -2229,11 +2113,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_SOL, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CONTINUATION_CODES field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::CONTINUATION_CODES, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::CONTINUATION_CODES, R > { public: @@ -2249,11 +2132,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::CONTINUATION_CODES, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note LAST_NON_ZERO_BYTE field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::LAST_NON_ZERO_BYTE, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::LAST_NON_ZERO_BYTE, R > { public: @@ -2269,11 +2151,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::LAST_NON_ZERO_BYTE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note REGISTER_REV field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_REV, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_REV, R > { public: @@ -2289,12 +2170,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_REV, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note ADDR_MAP_REG_TO_DRAM field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R, - - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R > { public: @@ -2309,7 +2188,7 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R, /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note CKE_DRIVER field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template<> class readerTraits< fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, rev::V1_0 > @@ -2327,11 +2206,10 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, rev::V1_0 > /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note CKE_DRIVER field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, R > { public: @@ -2346,7 +2224,7 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, R, /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note ODT_DRIVER field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template<> class readerTraits< fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, rev::V1_0 > @@ -2364,11 +2242,10 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, rev::V1_0 > /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note ODT_DRIVER field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, R > { public: @@ -2384,11 +2261,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CA_DRIVER field specialization -/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev) +/// @note valid for all revisionsRDIMM_MAX (largest decoded rev) /// template< rev R > -class readerTraits < fields<DDR4, RDIMM_MODULE>::CA_DRIVER, R, - std::integral_constant<bool, (R <= rev::RDIMM_MAX)> > +class readerTraits < fields<DDR4, RDIMM_MODULE>::CA_DRIVER, R > { public: @@ -2424,8 +2300,7 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::CS_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, RDIMM_MODULE>::CS_DRIVER, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, RDIMM_MODULE>::CS_DRIVER, R > { public: @@ -2461,8 +2336,7 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::YO_Y2_DRIVER, rev::V1_0 > /// @note rev 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, RDIMM_MODULE>::YO_Y2_DRIVER, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, RDIMM_MODULE>::YO_Y2_DRIVER, R > { public: @@ -2498,8 +2372,7 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, R > { public: @@ -2515,11 +2388,10 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note MODULE_NOMINAL_HEIGHT field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R > { public: @@ -2535,11 +2407,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note RAW_CARD_EXT field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::RAW_CARD_EXT, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::RAW_CARD_EXT, R > { public: @@ -2555,11 +2426,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::RAW_CARD_EXT, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note FRONT_MODULE_THICKNESS field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::FRONT_MODULE_THICKNESS, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::FRONT_MODULE_THICKNESS, R > { public: @@ -2575,11 +2445,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::FRONT_MODULE_THICKNESS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note BACK_MODULE_THICKNESS field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::BACK_MODULE_THICKNESS, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::BACK_MODULE_THICKNESS, R > { public: @@ -2595,11 +2464,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::BACK_MODULE_THICKNESS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note REF_RAW_CARD field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::REF_RAW_CARD, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::REF_RAW_CARD, R > { public: @@ -2615,11 +2483,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::REF_RAW_CARD, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note NUM_REGS_USED field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::NUM_REGS_USED, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::NUM_REGS_USED, R > { public: @@ -2635,11 +2502,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::NUM_REGS_USED, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note ROWS_OF_DRAMS field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::ROWS_OF_DRAMS, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::ROWS_OF_DRAMS, R > { public: @@ -2655,11 +2521,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::ROWS_OF_DRAMS, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note REGISTER_TYPE field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_TYPE, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_TYPE, R > { public: @@ -2675,11 +2540,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_TYPE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note HEAT_SPREADER_SOL field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::HEAT_SPREADER_SOL, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::HEAT_SPREADER_SOL, R > { public: @@ -2695,11 +2559,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::HEAT_SPREADER_SOL, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CONTINUATION_CODES field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::CONTINUATION_CODES, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::CONTINUATION_CODES, R > { public: @@ -2715,11 +2578,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::CONTINUATION_CODES, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note LAST_NON_ZERO_BYTE field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::LAST_NON_ZERO_BYTE, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::LAST_NON_ZERO_BYTE, R > { public: @@ -2735,11 +2597,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::LAST_NON_ZERO_BYTE, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note REGISTER_REV field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_REV, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_REV, R > { public: @@ -2755,11 +2616,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_REV, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note ADDR_MAP_REG_TO_DRAM field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R > { public: @@ -2796,8 +2656,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::CKE_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::CKE_DRIVER, R, - std::integral_constant<bool, R >= rev::V1_1 > > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::CKE_DRIVER, R > { public: @@ -2833,8 +2692,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, R, - std::integral_constant<bool, R >= rev::V1_1 > > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, R > { public: @@ -2850,11 +2708,10 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note CA_DRIVER field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::CA_DRIVER, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::CA_DRIVER, R > { public: @@ -2890,8 +2747,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::CS_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::CS_DRIVER, R, - std::integral_constant<bool, R >= rev::V1_1 > > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::CS_DRIVER, R > { public: @@ -2928,8 +2784,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::YO_Y2_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::YO_Y2_DRIVER, R, - std::integral_constant<bool, R >= rev::V1_1> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::YO_Y2_DRIVER, R > { public: @@ -2965,8 +2820,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::Y1_Y3_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::Y1_Y3_DRIVER, R, - std::integral_constant<bool, R >= rev::V1_1> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::Y1_Y3_DRIVER, R > { public: @@ -3002,8 +2856,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCOM_BODT_BCKE_DRIVER, rev::V1_ /// @note valid for rev >= 1.1 specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCOM_BODT_BCKE_DRIVER, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCOM_BODT_BCKE_DRIVER, R > { public: @@ -3039,8 +2892,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, rev::V1_0 > /// @note valid for rev >= 1.1 /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, R, - std::integral_constant<bool, (R >= rev::V1_1)> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, R > { public: @@ -3055,11 +2907,28 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, R, /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note RCD_SLEW_CNTRL field specialization -/// @note rev 1.0 & 1.1 specialization +/// @note rev 1.0 specialization /// -template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R, - std::integral_constant<bool, (R <= rev::V1_1)> > +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, rev::V1_0 > +{ + public: + + static constexpr size_t COMPARISON_VAL = 0; + static constexpr const char* FIELD_STR = "RCD output slew rate control"; + + template <typename T> + using COMPARISON_OP = std::equal_to<T>; +}; + +/// +/// @class readerTraits +/// @brief trait structure to hold static SPD information +/// @note RCD_SLEW_CNTRL field specialization +/// @note rev 1.1 specialization +/// +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, rev::V1_1 > { public: @@ -3077,8 +2946,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R, /// @note valid for rev >= 1.2 /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R, - std::integral_constant<bool, (R >= rev::V1_2)> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R > { public: @@ -3094,11 +2962,10 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DATA_BUFFER_REV field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_REV, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_REV, R > { public: @@ -3106,18 +2973,17 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_REV, R, static constexpr const char* FIELD_STR = "Data buffer revision"; template <typename T> - using COMPARISON_OP = std::less_equal<T>; + using COMPARISON_OP = std::less<T>; }; /// /// @class readerTraits /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note VREF_DQ_RANK0 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK0, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK0, R > { public: @@ -3133,11 +2999,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK0, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note VREF_DQ_RANK1 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK1, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK1, R > { public: @@ -3153,11 +3018,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK1, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note VREF_DQ_RANK2 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK2, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK2, R > { public: @@ -3173,11 +3037,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK2, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note VREF_DQ_RANK3 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK3, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK3, R > { public: @@ -3194,12 +3057,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK3, R, /// @tparam R the revision of the SPD field /// @note DATA_BUFFER_VREF_DQ field specialization /// @note rev 1.0 specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ, R, - - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ, R > { public: @@ -3215,11 +3076,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DB_MDQ_LTE_1866 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_1866, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_1866, R > { public: @@ -3235,11 +3095,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_1866, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DB_MDQ_LTE_2400 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_2400, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_2400, R > { public: @@ -3255,11 +3114,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_2400, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DB_MDQ_LTE_3200 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_3200, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_3200, R > { public: @@ -3275,11 +3133,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_3200, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DB_MDQ_RTT_LTE_1866 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_1866, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_1866, R > { public: @@ -3295,11 +3152,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_1866, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DB_MDQ_RTT_LTE_2400 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_2400, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_2400, R > { public: @@ -3315,11 +3171,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_2400, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DB_MDQ_RTT_LTE_3200 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_3200, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_3200, R > { public: @@ -3335,11 +3190,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_3200, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_DRIVE_STRENGTH_LTE_1866 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_1866, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_1866, R > { public: @@ -3355,11 +3209,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_1866, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_DRIVE_STRENGTH_LTE_2400 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_2400, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_2400, R > { public: @@ -3375,11 +3228,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_2400, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_DRIVE_STRENGTH_LTE_3200 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_3200, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_3200, R > { public: @@ -3395,11 +3247,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_3200, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_NOM_LTE_1866 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_1866, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_1866, R > { public: @@ -3415,11 +3266,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_1866, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_NOM_LTE_2400 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_2400, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_2400, R > { public: @@ -3435,11 +3285,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_2400, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_NOM_LTE_3200 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_3200, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_3200, R > { public: @@ -3455,11 +3304,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_3200, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_WR_LTE_1866 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_1866, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_1866, R > { public: @@ -3475,11 +3323,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_1866, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_WR_LTE_2400 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_2400, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_2400, R > { public: @@ -3495,11 +3342,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_2400, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_WR_LTE_3200 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_3200, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_3200, R > { public: @@ -3515,11 +3361,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_3200, R, /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_PARK_R01_LTE_1866 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_1866, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_1866, R > { public: @@ -3535,11 +3380,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_1866 /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_PARK_R01_LTE_2400 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_2400, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_2400, R > { public: @@ -3555,11 +3399,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_2400 /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_PARK_R01_LTE_3200 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_3200, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_3200, R > { public: @@ -3575,11 +3418,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_3200 /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_PARK_R23_LTE_1866 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_1866, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_1866, R > { public: @@ -3595,11 +3437,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_1866 /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_PARK_R23_LTE_2400 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_2400, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_2400, R > { public: @@ -3615,11 +3456,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_2400 /// @brief trait structure to hold static SPD information /// @tparam R the revision of the SPD field /// @note DRAM_ODT_RTT_PARK_R23_LTE_3200 field specialization -/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev) +/// @note valid for all revisions /// template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_3200, R, - std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_3200, R > { public: @@ -3634,11 +3474,28 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_3200 /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note DRAM_VREF_DQ_RANGE field specialization -/// @note rev 1.0 & 1.1 specialization +/// @note rev 1.0 specialization /// -template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R, - std::integral_constant<bool, (R <= rev::V1_1)> > +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, rev::V1_0 > +{ + public: + + static constexpr size_t COMPARISON_VAL = 0b1111; + static constexpr const char* FIELD_STR = "VrefDQ range for DRAM interface range"; + + template <typename T> + using COMPARISON_OP = std::less_equal<T>; +}; + +/// +/// @class readerTraits +/// @brief trait structure to hold static SPD information +/// @note DRAM_VREF_DQ_RANGE field specialization +/// @note rev 1.1 specialization +/// +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, rev::V1_1 > { public: @@ -3656,8 +3513,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R, /// @note rev 1.2+ specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R, - std::integral_constant<bool, (R >= rev::V1_2)> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R > { public: @@ -3672,11 +3528,28 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R, /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note DATA_BUFFER_VREF_DQ field specialization -/// @note rev 1.0 & 1.1 specialization +/// @note rev 1.0 specialization /// -template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R, - std::integral_constant<bool, (R <= rev::V1_1)> > +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, rev::V1_0 > +{ + public: + + static constexpr size_t COMPARISON_VAL = 0; + static constexpr const char* FIELD_STR = "Data Buffer VrefDQ range for DRAM interface range"; + + template <typename T> + using COMPARISON_OP = std::equal_to<T>; +}; + +/// +/// @class readerTraits +/// @brief trait structure to hold static SPD information +/// @note DATA_BUFFER_VREF_DQ field specialization +/// @note rev 1.1 specialization +/// +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, rev::V1_1 > { public: @@ -3694,8 +3567,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R, /// @note rev 1.2+ specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R, - std::integral_constant<bool, (R >= rev::V1_2)> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R > { public: @@ -3712,9 +3584,26 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R, /// @note DATA_BUFFER_DFE field specialization /// @note rev 1.0 & 1.1 specialization /// -template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R, - std::integral_constant<bool, (R <= rev::V1_1)> > +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, rev::V1_0 > +{ + public: + + static constexpr size_t COMPARISON_VAL = 0; + static constexpr const char* FIELD_STR = "Data Buffer DFE"; + + template <typename T> + using COMPARISON_OP = std::equal_to<T>; +}; + +/// +/// @class readerTraits +/// @brief trait structure to hold static SPD information +/// @note DATA_BUFFER_DFE field specialization +/// @note rev 1.1 specialization +/// +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, rev::V1_1 > { public: @@ -3732,8 +3621,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R, /// @note rev 1.2+ specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R, - std::integral_constant<bool, (R >= rev::V1_2)> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R > { public: @@ -3748,11 +3636,28 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R, /// @class readerTraits /// @brief trait structure to hold static SPD information /// @note DATA_BUFFER_GAIN_ADJUST field specialization -/// @note rev 1.0 & 1.1 specialization +/// @note rev 1.0 specialization /// -template< rev R > -class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R, - std::integral_constant<bool, (R <= rev::V1_1)> > +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, rev::V1_0 > +{ + public: + + static constexpr size_t COMPARISON_VAL = 1; + static constexpr const char* FIELD_STR = "Data Buffer Gain Adjust"; + + template <typename T> + using COMPARISON_OP = std::less_equal<T>; +}; + +/// +/// @class readerTraits +/// @brief trait structure to hold static SPD information +/// @note DATA_BUFFER_GAIN_ADJUST field specialization +/// @note rev 1.1 specialization +/// +template< > +class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, rev::V1_1 > { public: @@ -3770,8 +3675,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R, /// @note rev 1.2+ specialization /// template< rev R > -class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R, - std::integral_constant<bool, (R >= rev::V1_2)> > +class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R > { public: diff --git a/src/import/generic/memory/lib/spd/spd_utils.C b/src/import/generic/memory/lib/spd/spd_utils.C index 3a977ccf6..bfe380dc5 100644 --- a/src/import/generic/memory/lib/spd/spd_utils.C +++ b/src/import/generic/memory/lib/spd/spd_utils.C @@ -22,3 +22,204 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file spd_utls.C +/// @brief SPD utility function implimentations +/// +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + + +#include <generic/memory/lib/spd/spd_utils.H> +#include <generic/memory/lib/utils/find.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> + +namespace mss +{ +namespace spd +{ + +/// +/// @brief Helper function to retrieves medium and fine timebase values +/// @param[in] i_spd_decoder the SPD decoder +/// @param[out] o_mtb the medium timebase (MTB) from SPD +/// @param[out] o_ftb the fine timebase (FTB) from SPD +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_timebases( const mss::spd::facade& i_spd_decoder, + int64_t& o_mtb, + int64_t& o_ftb ) +{ + // ========================================================= + // Byte 17 maps + // Item JC-45-2220.01x + // Page 29 + // DDR4 SPD Document Release 3 + // Byte 17 (0x011): Timebases + // ========================================================= + // Created a maps of a single value in case mapping expands to more values + static const std::vector<std::pair<int64_t, int64_t> > FINE_TIMEBASE_MAP = + { + // {key byte, fine timebase (in picoseconds) + {0, 1} + // All others reserved + }; + + // ========================================================= + // Byte 17 maps + // Item JC-45-2220.01x + // Page 29 + // DDR4 SPD Document Release 3 + // Byte 17 (0x011): Timebases + // ========================================================= + // Created a maps of a single value in case mapping expands to more values + static const std::vector<std::pair<int64_t, int64_t> > MEDIUM_TIMEBASE_MAP = + { + // {key byte, medium timebase (in picoseconds) + {0, 125} + // All others reserved + }; + + // Retrieve timing parameters + const auto l_target = i_spd_decoder.get_dimm_target(); + + int64_t l_spd_ftb = 0; + int64_t l_spd_mtb = 0; + + FAPI_TRY( i_spd_decoder.medium_timebase(l_spd_mtb), + "%s. Failed medium_timebase()", spd::c_str(l_target) ); + + FAPI_ASSERT( mss::find_value_from_key(MEDIUM_TIMEBASE_MAP, l_spd_mtb, o_mtb), + fapi2::MSS_LOOKUP_FAILED() + .set_KEY(l_spd_mtb) + .set_DATA(o_mtb) + .set_FUNCTION(GET_TIMEBASES_MTB) + .set_TARGET(l_target), + "Could not find a mapped value that matched the key (%d) for %s", + l_spd_mtb, spd::c_str(l_target) ); + FAPI_TRY( i_spd_decoder.fine_timebase(l_spd_ftb), + "%s. Failed fine_timebase()", spd::c_str(l_target) ); + + FAPI_ASSERT( mss::find_value_from_key(FINE_TIMEBASE_MAP, l_spd_ftb, o_ftb), + fapi2::MSS_LOOKUP_FAILED() + .set_KEY(l_spd_ftb) + .set_DATA(o_ftb) + .set_FUNCTION(GET_TIMEBASES_FTB) + .set_TARGET(l_target), + "Could not find a mapped value that matched the key (%d) for %s", + l_spd_ftb, spd::c_str(l_target) ); + + FAPI_INF("MTB: %d, FTB: %d for %s", o_mtb, o_ftb, spd::c_str(l_target)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD +/// @param[in] i_spd_decoder the SPD decoder +/// @param[out] o_value tCKmin value in ps +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_tckmin( const mss::spd::facade& i_spd_decoder, + uint64_t& o_value ) +{ + int64_t l_timing_ftb = 0; + int64_t l_timing_mtb = 0; + int64_t l_medium_timebase = 0; + int64_t l_fine_timebase = 0; + int64_t l_temp = 0; + + // Retrieve timing parameters + const auto l_target = i_spd_decoder.get_dimm_target(); + + FAPI_TRY( get_timebases(i_spd_decoder, l_medium_timebase, l_fine_timebase), + "%s. Failed get_timebases", spd::c_str(l_target) ); + FAPI_TRY( i_spd_decoder.min_tck(l_timing_mtb), + "%s. Failed min_tck()", spd::c_str(l_target) ); + FAPI_TRY( i_spd_decoder.fine_offset_min_tck(l_timing_ftb), + "%s. Failed fine_offset_min_tck()", spd::c_str(l_target) ); + + // Calculate timing value + l_temp = spd::calc_timing_from_timebase(l_timing_mtb, + l_medium_timebase, + l_timing_ftb, + l_fine_timebase); + + // Sanity check + FAPI_ASSERT(l_temp > 0, + fapi2::MSS_INVALID_TIMING_VALUE(). + set_VALUE(l_temp). + set_FUNCTION(GET_TCKMIN). + set_DIMM_TARGET(l_target), + "%s. tCKmin invalid (<= 0) : %d", + spd::c_str(l_target), + l_temp); + + o_value = l_temp; + + FAPI_INF("%s. tCKmin (ps): %d", + spd::c_str(l_target), + o_value ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD +/// @param[in] i_spd_decoder SPD decoder +/// @param[out] o_value tCKmax value in ps +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_tckmax( const mss::spd::facade& i_spd_decoder, + uint64_t& o_value ) +{ + int64_t l_timing_ftb = 0; + int64_t l_timing_mtb = 0; + int64_t l_medium_timebase = 0; + int64_t l_fine_timebase = 0; + int64_t l_temp = 0; + + // Retrieve timing parameters + const auto l_target = i_spd_decoder.get_dimm_target(); + + FAPI_TRY( get_timebases(i_spd_decoder, l_medium_timebase, l_fine_timebase), + "%s. Failed get_timebases", spd::c_str(l_target) ); + FAPI_TRY( i_spd_decoder.max_tck(l_timing_mtb), + "%s. Failed max_tck()", spd::c_str(l_target) ); + FAPI_TRY( i_spd_decoder.fine_offset_max_tck(l_timing_ftb), + "%s. Failed fine_offset_max_tck()", spd::c_str(l_target) ); + + // Calculate timing value + l_temp = spd::calc_timing_from_timebase(l_timing_mtb, + l_medium_timebase, + l_timing_ftb, + l_fine_timebase); + + // Sanity check + FAPI_ASSERT(l_temp > 0, + fapi2::MSS_INVALID_TIMING_VALUE(). + set_VALUE(l_temp). + set_FUNCTION(GET_TCKMAX). + set_DIMM_TARGET(l_target), + "%s. tCKmax invalid (<= 0) : %d", + spd::c_str(l_target), + l_temp); + + o_value = l_temp; + + FAPI_INF( "%s. tCKmax (ps): %d", + spd::c_str(l_target), + o_value); + +fapi_try_exit: + return fapi2::current_err; +} + +}// spd +}// mss diff --git a/src/import/generic/memory/lib/spd/spd_utils.H b/src/import/generic/memory/lib/spd/spd_utils.H index 4674e71aa..916c41d39 100644 --- a/src/import/generic/memory/lib/spd/spd_utils.H +++ b/src/import/generic/memory/lib/spd/spd_utils.H @@ -22,3 +22,150 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file spd_utls.H +/// @brief SPD utility functions definitions +/// +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: HB:FSP + +#ifndef _MSS_SPD_UTILS_H_ +#define _MSS_SPD_UTILS_H_ + +#include <fapi2.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> +#include <generic/memory/lib/spd/spd_facade.H> + +namespace mss +{ +namespace spd +{ + +/// +/// @brief Calculates timing value +/// @param[in] i_timing_mtb timing value in MTB units +/// @param[in] i_mtb_multiplier SPD medium timebase +/// @param[in] i_timing_ftb fine offset of timing value +/// @param[in] i_ftb_multiplier SPD fine timebase +/// @return the timing value in picoseconds +/// +inline int64_t calc_timing_from_timebase(const int64_t i_timing_mtb, + const int64_t i_mtb_multiplier, + const int64_t i_timing_ftb, + const int64_t i_ftb_multiplier) +{ + // JEDEC algorithm + const int64_t l_timing_val = i_timing_mtb * i_mtb_multiplier; + const int64_t l_fine_offset = i_timing_ftb * i_ftb_multiplier; + + return l_timing_val + l_fine_offset; +} + +/// +/// @brief Helper to compute JEDEC's SPD rounding algorithm +/// to convert ps to nCK +/// @tparam T input type +/// @tparam OT output type +/// @param[in] i_timing_in_ps timing parameter in ps +/// @param[in] i_tck_in_ps clock period in ps +/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC) +/// @param[out] o_value_nck the end calculation in nck +/// @return true if overflow didn't occur, false otherwise +/// @note DDR4 SPD Contents Rounding Algorithm +/// @note Item 2220.46 +/// +template<typename T, typename OT> +static inline bool jedec_spd_rounding_alg(const T& i_timing_in_ps, + const T& i_tck_in_ps, + const guard_band i_inverse_corr_factor, + OT& o_val_nck) +{ + // Preliminary nCK calculation, scaled by 1000 per JDEC algorithm + T l_temp_nck = (i_timing_in_ps * mss::CONVERT_PS_IN_A_NS) / (i_tck_in_ps == 0 ? 1 : i_tck_in_ps); + l_temp_nck += i_inverse_corr_factor; + l_temp_nck = l_temp_nck / mss::CONVERT_PS_IN_A_NS; + + // Check for overflow + // static_cast needed for HB compiler that complains about + // comparision of two different integral types + o_val_nck = l_temp_nck; + + FAPI_DBG("Input timing (ps) %d, tCK (ps) %d, temp output %d, output (nCK) %d", + i_timing_in_ps, i_tck_in_ps, l_temp_nck, o_val_nck); + + return (static_cast<T>(o_val_nck) == l_temp_nck); +} + +/// +/// @brief Returns clock cycles based on input application period +/// @tparam T input type +/// @tparam OT output type +/// @param[in] i_timing_in_ps timing parameter in ps +/// @param[in] i_tck_in_ps clock period in ps +/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC) +/// @param[out] o_value_nck the end calculation in nck +/// @return FAPI2_RC_SUCCESS iff okay +/// @note DDR4 SPD Contents Rounding Algorithm +/// @note Item 2220.46 +/// +template<typename T, typename OT> +inline fapi2::ReturnCode calc_nck(const T& i_timing_in_ps, + const T& i_tck_in_ps, + const guard_band i_inverse_corr_factor, + OT& o_val_nck) +{ + FAPI_ASSERT( jedec_spd_rounding_alg(i_timing_in_ps, + i_tck_in_ps, + i_inverse_corr_factor, + o_val_nck), + fapi2::MSS_INVALID_CAST_CALC_NCK(). + set_TIMING_PS(i_timing_in_ps). + set_NCK_NS(i_tck_in_ps). + set_CORRECTION_FACTOR(i_inverse_corr_factor), + "Overflow occured. Returned data is %d", o_val_nck); + + // If we don't assert, we don't know what's in current_err ... + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function to retrieves medium and fine timebase values +/// @param[in] i_spd_decoder the SPD decoder +/// @param[out] o_mtb the medium timebase (MTB) from SPD +/// @param[out] o_ftb the fine timebase (FTB) from SPD +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_timebases( const mss::spd::facade& i_spd_decoder, + int64_t& o_mtb, + int64_t& o_ftb ); + +/// +/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD +/// @param[in] i_spd_decoder the SPD decoder +/// @param[out] o_value tCKmin value in ps +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_tckmin( const mss::spd::facade& i_spd_decoder, + uint64_t& o_value ); + +/// +/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD +/// @param[in] i_spd_decoder SPD decoder +/// @param[out] o_value tCKmax value in ps +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode get_tckmax( const mss::spd::facade& i_spd_decoder, + uint64_t& o_value ); + +}// spd + +}// mss + +#endif // _MSS_SPD_UTILS_H_ 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 4bdaf09b7..736827295 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 @@ -43,6 +43,20 @@ namespace mss { /// +/// @brief Common conversions +/// +enum conversions +{ + CONVERT_PS_IN_A_NS = 1000, ///< 1000 pico in an nano + CONVERT_PS_IN_A_US = 1000000, ///< 1000000 picos in a micro + MHZ_TO_KHZ = 1000, + SEC_IN_HOUR = 60 * 60, ///< seconds in an hour, used for scrub times + NIBBLES_PER_BYTE = 2, + BITS_PER_NIBBLE = 4, + BITS_PER_BYTE = 8, +}; + +/// /// @brief FFDC generic codes /// enum generic_ffdc_codes @@ -58,22 +72,58 @@ enum generic_ffdc_codes PRE_DATA_ENGINE_CTOR = 0x1005, EXTRACT_SPD_FLD = 0x1006, SPD_READER = 0x1007, - BASE_CNFG_MAKE_OBJ = 0x1008, - DIMM_MODULE_MAKE_OBJ = 0x1009, - CREATE_BASE_CNFG_FACTORY = 0x100A, - CREATE_MODULE_FACTORY = 0x100B, + BASE_CFG_PARAM_SELECT = 0x1008, + DIMM_MODULE_PARAM_SELECT = 0x1009, + BASE_CFG_FACTORY = 0x100A, + DIMM_MODULE_FACTORY = 0x100B, + GET_TAAMIN = 0x100C, + GET_TCKMIN = 0x100D, + GET_TCKMAX = 0x100E, GET_TIMEBASES_FTB = 0x100F, GET_TIMEBASES_MTB = 0x1010, + GET_SUPPORTED_REV = 0x1011, + TRASMIN = 0x1012, + TRCMIN = 0x1013, + TRFC1MIN = 0x1014, + TRFC2MIN = 0x1015, + TRFC4MIN = 0x1016, + TFAWMIN = 0x1017, + TWTR_S_MIN = 0x1018, + TWRMIN = 0x1019, + TWTR_L_MIN = 0x101A, + DEVICE_TYPE = 0x101B, + BASE_MODULE_TYPE = 0x101C, }; /// -/// @brief DRAM generation selector +/// @brief Supported proc types /// -enum device_type +enum proc_type { - DDR4 = 0x0c, + NIMBUS, + AXONE, }; +/// +/// @brief JEDEC supported DDR4 speeds +/// +enum ddr4_dimm_speeds +{ + DIMM_SPEED_1600 = 1600, + DIMM_SPEED_1866 = 1866, + DIMM_SPEED_2133 = 2133, + DIMM_SPEED_2400 = 2400, + DIMM_SPEED_2666 = 2666, + DIMM_SPEED_2933 = 2933, + DIMM_SPEED_3200 = 3200, +}; + +namespace spd +{ + +/// +/// @brief SPD revisions - not tied any particular module +/// enum rev : uint8_t { V1_0 = 0x10, ///< represents Rev 1.0 @@ -93,11 +143,43 @@ enum rev : uint8_t /// enum parameters { + UNINITIALIZED, BASE_CNFG, RDIMM_MODULE, LRDIMM_MODULE, + NVDIMM_MODULE, +}; + +/// +/// @brief DRAM generation selector +/// @note values set to SPD settings +/// +enum device_type +{ + DDR4 = 0x0c, +}; + +/// +/// @brief DIMM type selector +/// @note values set to SPD settings +/// +enum dimm_type +{ + RDIMM = 0b0001, + LRDIMM = 0b0100, +}; + +enum guard_band : uint16_t +{ + // Used for caclulating spd timing values - from JEDEC rounding algorithm + // Correction factor is 1% (for DDR3) or 2.5% (for DDR4) + // when doing integer math, we add-in the inverse correction factor + // Formula used for derivation: + // Guardband = 1000 * (1000* correction_factor) - 1 + INVERSE_DDR4_CORRECTION_FACTOR = 974, ///< DDR4 correction factor }; +}// spd }// mss #endif |