summaryrefslogtreecommitdiffstats
path: root/src/import/generic/memory/lib/spd/common/ddr4
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/generic/memory/lib/spd/common/ddr4')
-rw-r--r--src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H1960
-rw-r--r--src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C3021
-rw-r--r--src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C760
3 files changed, 1049 insertions, 4692 deletions
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
OpenPOWER on IntegriCloud