summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C734
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H143
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C54
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H30
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C239
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H104
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C34
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C17
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H56
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_kind.H14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C1017
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H203
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H23
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C1
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C19
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C28
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C1
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C21
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_general_errors.xml24
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml205
-rw-r--r--src/import/generic/memory/lib/data_engine/pre_data_init.H496
-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
-rw-r--r--src/import/generic/memory/lib/spd/common/dimm_module_decoder.H110
-rw-r--r--src/import/generic/memory/lib/spd/common/spd_decoder_base.H354
-rw-r--r--src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H875
-rw-r--r--src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C1368
-rw-r--r--src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C276
-rw-r--r--src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C310
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H436
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C644
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C268
-rw-r--r--src/import/generic/memory/lib/spd/spd_checker.H282
-rw-r--r--src/import/generic/memory/lib/spd/spd_decoder_def.H35
-rw-r--r--src/import/generic/memory/lib/spd/spd_facade.H1634
-rw-r--r--src/import/generic/memory/lib/spd/spd_factory_pattern.C331
-rw-r--r--src/import/generic/memory/lib/spd/spd_factory_pattern.H484
-rw-r--r--src/import/generic/memory/lib/spd/spd_fields_ddr4.H1
-rw-r--r--src/import/generic/memory/lib/spd/spd_reader.H106
-rw-r--r--src/import/generic/memory/lib/spd/spd_traits.H3
-rw-r--r--src/import/generic/memory/lib/spd/spd_traits_ddr4.H900
-rw-r--r--src/import/generic/memory/lib/spd/spd_utils.C201
-rw-r--r--src/import/generic/memory/lib/spd/spd_utils.H147
-rw-r--r--src/import/generic/memory/lib/utils/shared/mss_generic_consts.H96
48 files changed, 7528 insertions, 10551 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
index f8d7cfc7c..4e52d5083 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
@@ -22,8 +22,8 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *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: FSP:HB
@@ -37,8 +37,6 @@
// mss lib
#include <lib/utils/fake_vpd.H>
#include <lib/mss_vpd_decoder.H>
-#include <lib/spd/spd_factory.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
#include <generic/memory/lib/spd/common/rcw_settings.H>
#include <lib/eff_config/timing.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
@@ -48,9 +46,9 @@
#include <lib/dimm/eff_dimm.H>
#include <lib/dimm/mrs_load.H>
#include <lib/shared/mss_kind.H>
-#include <generic/memory/lib/spd/common/dimm_module_decoder.H>
#include <lib/phy/dp16.H>
#include <lib/mss_attribute_accessors_manual.H>
+#include <endian.h>
namespace mss
{
@@ -60,6 +58,147 @@ using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCBIST;
+//
+// Note SPD mappings included are settings only supported by Nimbus.
+// We purposely omit certain settings that exist in the JEDEC SPD spec
+// if they are not supported in HW. This simplifies error catching and
+// explicitly depicts supported mappings.
+//
+
+// =========================================================
+// Byte 4 maps
+// Item JC-45-2220.01x
+// Page 18
+// DDR4 SPD Document Release 3
+// Byte 4 (0x004): SDRAM Density and Banks
+// =========================================================
+const std::vector<std::pair<uint8_t, uint8_t> > eff_dimm::SDRAM_DENSITY_MAP =
+{
+ // {key byte, capacity in GBs}
+ {4, fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_4G},
+ {5, fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_8G},
+ {6, fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G},
+};
+
+// =========================================================
+// Byte 4 maps
+// Item JC-45-2220.01x
+// Page 18
+// DDR4 SPD Document Release 3
+// Byte 4 (0x004): SDRAM Density and Banks
+// =========================================================
+const std::vector< std::pair<uint8_t, uint8_t> > eff_dimm::BANK_ADDR_BITS_MAP =
+{
+ // {key byte, number of bank address bits}
+ {0, 2},
+ {1, 3}
+};
+
+// =========================================================
+// Byte 5 maps
+// Item JC-45-2220.01x
+// Page 18
+// DDR4 SPD Document Release 3
+// Byte 5 (0x005): SDRAM Addressing
+// =========================================================
+const std::vector<std::pair<uint8_t, uint8_t> > eff_dimm::ROW_ADDRESS_BITS_MAP =
+{
+ //{key byte,row address bits}
+ {2, fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM14},
+ {3, fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM15},
+ {4, fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM16},
+ {5, fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM17},
+ {6, fapi2::ENUM_ATTR_EFF_DRAM_ROW_BITS_NUM18}
+};
+
+// =========================================================
+// Byte 6 maps
+// Item JC-45-2220.01x
+// Page 19
+// DDR4 SPD Document Release 3
+// Byte 6 (0x006): Primary SDRAM Package Type
+// =========================================================
+const std::vector<std::pair<uint8_t, uint8_t> > eff_dimm::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}
+};
+
+// =========================================================
+// Byte 9 maps
+// Item JC-45-2220.01x
+// Page 21
+// DDR4 SPD Document Release 3
+// Byte 9 (0x009): Other SDRAM Optional Features
+// =========================================================
+const std::vector<std::pair<uint8_t, uint8_t> > eff_dimm::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}
+};
+
+// =========================================================
+// Byte 10 maps
+// Item JC-45-2220.01x
+// Page 21-22
+// DDR4 SPD Document Release 3
+// Byte 10 (0x00A): Secondary SDRAM Package Type
+// =========================================================
+const std::vector<std::pair<uint8_t, uint8_t> > eff_dimm::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}
+};
+
+// =========================================================
+// Byte 12 maps
+// Item JC-45-2220.01x
+// Page 23
+// DDR4 SPD Document Release 3
+// Byte 12 (0x00C): Module Organization
+// =========================================================
+const std::vector<std::pair<uint8_t, uint8_t> > eff_dimm::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
+};
+
+// =========================================================
+// Byte 13 maps
+// Item JC-45-2220.01x
+// Page 27
+// DDR4 SPD Document Release 3
+// Byte 13 (0x00D): Module Memory Bus Width
+// =========================================================
+const std::vector<std::pair<uint8_t, uint8_t> > eff_dimm::BUS_WIDTH_MAP =
+{
+ // {key byte, bus width (in bits)
+ {0, 8},
+ {1, 16},
+ {2, 32},
+ {3, 64}
+ // All others reserved
+};
+
///
/// @brief bit encodings for RC02
/// From DDR4 Register v1.0
@@ -141,7 +280,7 @@ enum rc0d_encode : uint8_t
/// @brief bit encodings for RC0E
/// From DDR4 Register v1.0
///
-enum rc0e_encode
+enum rc0e_encode : uint8_t
{
RC0E_PARITY_ENABLE_BIT = 7,
RC0E_PARITY_ENABLE = 1,
@@ -204,7 +343,7 @@ enum lrdimm_databuffers
///
/// @brief encoding for MSS_INVALID_FREQ so we can look up functions based on encoding
///
-enum invalid_freq_function_encoding
+enum invalid_freq_function_encoding : uint8_t
{
RC0A = 0x0a,
RC3X = 0x30,
@@ -214,17 +353,124 @@ enum invalid_freq_function_encoding
///
/// @brief encoding for MSS_INVALID_TIMING so we can look up functions based on encoding
///
-enum invalid_timing_function_encoding
+enum invalid_timing_function_encoding : uint8_t
{
TRRD_S = 0,
TRRD_L = 1,
TFAW = 2,
};
+
/////////////////////////
// Non-member function implementations
/////////////////////////
///
+/// @brief Helper function to calculate logical ranks
+/// @param[in] i_signal_loading signal loading from SPD
+/// @param[in] i_dram_die_count DRAM die count from SPD
+/// @param[in] i_master_ranks number of master ranks from SPD
+///
+static uint8_t calc_logical_ranks(const uint8_t i_signal_loading,
+ const uint8_t i_dram_die_count,
+ const uint8_t i_master_ranks)
+{
+ // For single-load-stack(3DS) the logical ranks per package ends up being the same as the die count.
+ // 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 has no meaning and is used for calculation purposes as defined by the SPD spec.
+ const uint8_t l_multiplier = (i_signal_loading == spd::SINGLE_LOAD_STACK) ? i_dram_die_count : 1;
+
+ return (i_master_ranks * l_multiplier);
+}
+
+///
+/// @brief Returns logical ranks in Primary SDRAM type
+/// @param[out] o_logical_ranks number of logical ranks
+/// @return fapi2::FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode eff_dimm::prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const
+{
+ uint8_t l_signal_loading = 0;
+ uint8_t l_master_ranks = 0;
+
+ // Number of master ranks taken from attribute since we need mapped value
+ // and not the encoded raw value from SPD.
+ FAPI_TRY( mss::eff_num_master_ranks_per_dimm(iv_dimm, l_master_ranks) );
+ FAPI_TRY( iv_spd_decoder.prim_sdram_signal_loading(l_signal_loading) );
+
+ o_logical_ranks = calc_logical_ranks(l_signal_loading, iv_dram_die_count, l_master_ranks);
+
+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 eff_dimm::sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const
+{
+ uint8_t l_signal_loading = 0;
+ uint8_t l_master_ranks = 0;
+ uint8_t l_spd_die_count = 0;
+ uint8_t l_die_count = 0;
+
+ // Grabbing signal loading
+ FAPI_TRY( iv_spd_decoder.sec_sdram_signal_loading(l_signal_loading) );
+
+ // Number of master ranks taken from attribute since we need mapped value
+ // and not the encoded raw value from SPD.
+ FAPI_TRY( mss::eff_num_master_ranks_per_dimm(iv_dimm, l_master_ranks) );
+
+ // Getting die count
+ FAPI_TRY( iv_spd_decoder.sec_sdram_die_count(l_spd_die_count) );
+
+ FAPI_ASSERT( mss::find_value_from_key(SEC_DIE_COUNT_MAP, l_spd_die_count, l_die_count),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_spd_die_count)
+ .set_DATA(l_die_count)
+ .set_TARGET(iv_dimm),
+ "Could not a mapped value that matched the key (%d) for %s",
+ l_spd_die_count, mss::c_str(iv_dimm) );
+
+ o_logical_ranks = calc_logical_ranks(l_signal_loading, l_die_count, l_master_ranks);
+
+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 iff okay
+///
+fapi2::ReturnCode eff_dimm::logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const
+{
+ uint8_t l_prim_logical_rank_per_dimm = 0;
+ uint8_t l_rank_mix = 0;
+
+ FAPI_TRY( iv_spd_decoder.rank_mix(l_rank_mix) );
+ FAPI_TRY( prim_sdram_logical_ranks(l_prim_logical_rank_per_dimm) );
+
+ if(l_rank_mix == fapi2::ENUM_ATTR_EFF_DRAM_RANK_MIX_SYMMETRICAL)
+ {
+ o_logical_rank_per_dimm = l_prim_logical_rank_per_dimm;
+ }
+ else
+ {
+ // Rank mix is ASYMMETRICAL
+ uint8_t l_sec_logical_rank_per_dimm = 0;
+ 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;
+}
+
+///
/// @brief Gets the JEDEC train and range values from the encoded VPD value
/// @param[in] i_target - the DIMM target on which to operate
/// @param[out] o_range - the JEDEC VREFDQ range
@@ -293,28 +539,105 @@ static uint64_t ibt_helper(const uint8_t i_ibt)
}
///
+/// @brief Helper function to set dram width instance variable
+/// @return fapi2::FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode eff_dimm::set_dram_width_instance()
+{
+ uint8_t l_spd_device_width = 0;
+ FAPI_TRY( iv_spd_decoder.device_width(l_spd_device_width),
+ "Failed accessing device width from SPD %s", mss::c_str(iv_dimm) );
+
+ FAPI_ASSERT( mss::find_value_from_key(DEVICE_WIDTH_MAP, l_spd_device_width, iv_dram_width),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_spd_device_width)
+ .set_DATA(iv_dram_width)
+ .set_FUNCTION(SET_DRAM_WIDTH_INSTANCE)
+ .set_TARGET(iv_dimm),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_spd_device_width, mss::c_str(iv_dimm) );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to set dram density instance variable
+/// @return fapi2::FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode eff_dimm::set_dram_density_instance()
+{
+ uint8_t l_spd_dram_density = 0;
+ FAPI_TRY( iv_spd_decoder.sdram_density(l_spd_dram_density), "Failed to get dram_density from SPD %s",
+ mss::c_str(iv_dimm) );
+
+ FAPI_ASSERT( mss::find_value_from_key(SDRAM_DENSITY_MAP, l_spd_dram_density, iv_dram_density),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_spd_dram_density)
+ .set_DATA(iv_dram_density)
+ .set_FUNCTION(SET_DRAM_DENSITY_INSTANCE)
+ .set_TARGET(iv_dimm),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_spd_dram_density, mss::c_str(iv_dimm) );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to set dram density instance variable
+/// @return fapi2::FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode eff_dimm::set_prim_dram_die_count_instance()
+{
+ uint8_t l_decoder_val = 0;
+ FAPI_TRY( iv_spd_decoder.prim_sdram_die_count(l_decoder_val),
+ "Failed to get the die count for the dimm %s", mss::c_str(iv_dimm) );
+
+ FAPI_ASSERT( mss::find_value_from_key(PRIM_DIE_COUNT_MAP, l_decoder_val, iv_dram_die_count),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_decoder_val)
+ .set_DATA(iv_dram_die_count)
+ .set_FUNCTION(PRIM_DIE_COUNT)
+ .set_TARGET(iv_dimm),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_decoder_val, mss::c_str(iv_dimm) );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+///
/// @brief factory to make an eff_config DIMM object based on dimm kind (type, gen, and revision number)
-/// @param[in] i_pDecoder the spd::decoder for the dimm target
+/// @param[in] i_spd_decoder the spd::decoder for the dimm target
/// @param[out] o_fact_obj a shared pointer of the eff_dimm type
///
-fapi2::ReturnCode eff_dimm::eff_dimm_factory ( const std::shared_ptr<spd::decoder>& i_pDecoder,
- std::shared_ptr<eff_dimm>& o_fact_obj )
+fapi2::ReturnCode eff_dimm::factory ( const spd::facade& i_spd_decoder,
+ std::shared_ptr<eff_dimm>& o_fact_obj )
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
uint8_t l_buffer_type = 0;
kind_t l_dimm_kind = DEFAULT_KIND;
+ rcw_settings l_raw_card;
fapi2::ReturnCode l_rc;
- const auto& l_dimm = i_pDecoder->iv_target;
+ const auto l_dimm = i_spd_decoder.get_dimm_target();
// Now time to get the three attributes to tell which dimm we're working with.
- // Dram_gen and dimm_type are set in the SPD factory and we'll call the SPD decoder to get the reg and buff type
- FAPI_TRY( eff_dram_gen(l_dimm, l_gen), "Failed eff_dram_gen() accessor for %s", l_dimm );
- FAPI_TRY( eff_dimm_type(l_dimm, l_type), "Failed eff_dimm_type() accessor for %s",
- l_dimm );
- FAPI_TRY( i_pDecoder->iv_module_decoder->register_and_buffer_type(l_buffer_type),
- "Failed decoding register and buffer type from SPD for %s", l_dimm );
+ // Dram_gen and dimm_type are set in mss_freq and we'll call the SPD decoder to get the reg and buff type
+ FAPI_TRY( eff_dram_gen(l_dimm, l_gen), "Failed eff_dram_gen() accessor for %s", mss::c_str(l_dimm) );
+ FAPI_TRY( eff_dimm_type(l_dimm, l_type), "Failed eff_dimm_type() accessor for %s", mss::c_str(l_dimm) );
+
+ FAPI_TRY( i_spd_decoder.register_and_buffer_type(l_buffer_type),
+ "Failed decoding register and buffer type from SPD for %s", mss::c_str(l_dimm) );
+
+ FAPI_TRY(raw_card_factory(l_dimm, i_spd_decoder, l_raw_card));
l_dimm_kind = mss::dimm_kind(l_type, l_gen);
@@ -324,7 +647,7 @@ fapi2::ReturnCode eff_dimm::eff_dimm_factory ( const std::shared_ptr<spd::decode
switch (l_buffer_type)
{
case LRDIMM_DB01:
- o_fact_obj = std::make_shared<eff_lrdimm_db01>( i_pDecoder, l_rc );
+ o_fact_obj = std::make_shared<eff_lrdimm_db01>( i_spd_decoder, l_raw_card, l_rc );
// Assert that l_rc is good and o_fact_object isn't null
FAPI_ASSERT( ((l_rc == fapi2::FAPI2_RC_SUCCESS) && (o_fact_obj != nullptr)),
@@ -339,7 +662,7 @@ fapi2::ReturnCode eff_dimm::eff_dimm_factory ( const std::shared_ptr<spd::decode
break;
case LRDIMM_DB02:
- o_fact_obj = std::make_shared<eff_lrdimm_db02>( i_pDecoder, l_rc );
+ o_fact_obj = std::make_shared<eff_lrdimm_db02>( i_spd_decoder, l_raw_card, l_rc );
// Assert that l_rc is good and o_fact_object isn't null
FAPI_ASSERT( ((l_rc == fapi2::FAPI2_RC_SUCCESS) && (o_fact_obj != nullptr)),
@@ -367,7 +690,7 @@ fapi2::ReturnCode eff_dimm::eff_dimm_factory ( const std::shared_ptr<spd::decode
break;
case KIND_RDIMM_DDR4:
- o_fact_obj = std::make_shared<eff_rdimm>( i_pDecoder, l_rc );
+ o_fact_obj = std::make_shared<eff_rdimm>( i_spd_decoder, l_raw_card, l_rc );
// Assert that l_rc is good and o_fact_object isn't null
FAPI_ASSERT( ((l_rc == fapi2::FAPI2_RC_SUCCESS) && (o_fact_obj != nullptr)),
fapi2::MSS_ERROR_CREATING_EFF_CONFIG_DIMM_OBJECT().
@@ -410,7 +733,8 @@ fapi2::ReturnCode eff_dimm::rcd_mfg_id()
// Get & update MCS attribute
FAPI_TRY( eff_rcd_mfg_id(iv_mcs, &l_mcs_attrs[0][0]), "Failed accessing ATTR_MSS_EFF_RCD_MFG_ID" );
- FAPI_TRY( iv_pDecoder->reg_manufacturer_id_code(l_decoder_val), "Failed getting rcd id code from SPD %s",
+ FAPI_TRY( iv_spd_decoder.reg_manufacturer_id_code(l_decoder_val),
+ "Failed getting rcd id code from SPD %s",
mss::c_str(iv_dimm) );
switch (l_decoder_val)
@@ -451,7 +775,7 @@ fapi2::ReturnCode eff_dimm::register_type()
// Get & update MCS attribute
FAPI_TRY( eff_register_type(iv_mcs, &l_mcs_attrs[0][0]), "Failed accessing ATTR_MSS_REGISTER_TYPE" );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->register_and_buffer_type(l_decoder_val),
+ FAPI_TRY( iv_spd_decoder.register_and_buffer_type(l_decoder_val),
"Failed getting register_type code from SPD %s",
mss::c_str(iv_dimm) );
@@ -475,7 +799,8 @@ fapi2::ReturnCode eff_dimm::register_rev()
// Get & update MCS attribute
FAPI_TRY( eff_register_rev(iv_mcs, &l_mcs_attrs[0][0]), "Failed accessing ATTR_MSS_REGISTER_REV" );
- FAPI_TRY( iv_pDecoder->register_rev_num(l_decoder_val), "Failed getting register_rev code from SPD %s",
+ FAPI_TRY( iv_spd_decoder.register_rev_num(l_decoder_val),
+ "Failed getting register_rev code from SPD %s",
mss::c_str(iv_dimm) );
FAPI_INF("%s Register rev is 0x%02x", mss::c_str(iv_dimm), l_decoder_val);
@@ -498,9 +823,11 @@ fapi2::ReturnCode eff_dimm::dram_mfg_id()
// Get & update MCS attribute
FAPI_TRY( eff_dram_mfg_id(iv_mcs, &l_mcs_attrs[0][0]), "Failed accessing ATTR_MSS_EFF_DRAM_MFG_ID" );
- FAPI_TRY( iv_pDecoder->dram_manufacturer_id_code(l_decoder_val), "Failed getting dram id code from SPD %s",
+ FAPI_TRY( iv_spd_decoder.dram_manufacturer_id_code(l_decoder_val), "Failed getting dram id code from SPD %s",
mss::c_str(iv_dimm) );
+ endian_swap(l_decoder_val);
+
switch (l_decoder_val)
{
case fapi2::ENUM_ATTR_EFF_DRAM_MFG_ID_MICRON:
@@ -534,24 +861,12 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dram_width()
{
- uint8_t l_decoder_val = 0;
uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
// Get & update MCS attribute
- FAPI_TRY( iv_pDecoder->device_width(l_decoder_val), "Failed accessing device width from SPD %s", mss::c_str(iv_dimm) );
FAPI_TRY( eff_dram_width(iv_mcs, &l_mcs_attrs[0][0]), "Failed getting EFF_DRAM_WIDTH" );
- // Enforcing NIMBUS restrictions
- FAPI_ASSERT( (l_decoder_val == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ||
- (l_decoder_val == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4),
- fapi2::MSS_INVALID_DRAM_WIDTH()
- .set_DRAM_WIDTH(l_decoder_val)
- .set_DIMM_TARGET(iv_dimm),
- "Unsupported DRAM width with %d for target %s",
- l_decoder_val,
- mss::c_str(iv_dimm));
-
- l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val;
+ l_mcs_attrs[iv_port_index][iv_dimm_index] = iv_dram_width;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_WIDTH, iv_mcs, l_mcs_attrs), "Failed setting ATTR_EFF_DRAM_WIDTH" );
fapi_try_exit:
@@ -564,17 +879,12 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dram_density()
{
- uint8_t l_decoder_val = 0;
- FAPI_TRY( iv_pDecoder->sdram_density(l_decoder_val), "Failed to get dram_density from SPD %s", mss::c_str(iv_dimm) );
-
// Get & update MCS attribute
- {
- uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( eff_dram_density(iv_mcs, &l_mcs_attrs[0][0]), "Failed to get ATTR_MSS_EFF_DRAM_DENSITY" );
+ uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY( eff_dram_density(iv_mcs, &l_mcs_attrs[0][0]), "Failed to get ATTR_MSS_EFF_DRAM_DENSITY" );
- l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DENSITY, iv_mcs, l_mcs_attrs), "Failed to set ATTR_EFF_DRAM_DENSITY" );
- }
+ l_mcs_attrs[iv_port_index][iv_dimm_index] = iv_dram_density;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DENSITY, iv_mcs, l_mcs_attrs), "Failed to set ATTR_EFF_DRAM_DENSITY" );
fapi_try_exit:
return fapi2::current_err;
@@ -591,8 +901,8 @@ fapi2::ReturnCode eff_dimm::ranks_per_dimm()
// Get & update MCS attribute
FAPI_TRY( eff_num_ranks_per_dimm(iv_mcs, &l_attrs_ranks_per_dimm[0][0]), "Failed to get EFF_NUM_RANKS_PER_DIMM" );
- FAPI_TRY( iv_pDecoder->logical_ranks_per_dimm(l_ranks_per_dimm),
- "Failed to get logical_ranks_per_dimm from SPD %s", mss::c_str(iv_dimm) );
+ FAPI_TRY( logical_ranks_per_dimm(l_ranks_per_dimm),
+ "Failed to get logical_ranks_per_dimm %s", mss::c_str(iv_dimm) );
l_attrs_ranks_per_dimm[iv_port_index][iv_dimm_index] = l_ranks_per_dimm;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_NUM_RANKS_PER_DIMM, iv_mcs, l_attrs_ranks_per_dimm),
@@ -608,15 +918,12 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::prim_die_count()
{
- uint8_t l_die_count = 0;
uint8_t l_attr[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
// Get & update MCS attribute
FAPI_TRY( eff_prim_die_count(iv_mcs, &l_attr[0][0]), "Failed to get EFF_PRIM_DIE_COUNT" );
- FAPI_TRY( iv_pDecoder->prim_sdram_die_count(l_die_count),
- "Failed to get the die count for the dimm %s", mss::c_str(iv_dimm) );
- l_attr[iv_port_index][iv_dimm_index] = l_die_count;
+ l_attr[iv_port_index][iv_dimm_index] = iv_dram_die_count;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_PRIM_DIE_COUNT, iv_mcs, l_attr),
"Failed to set ATTR_EFF_PRIM_DIE_COUNT" );
@@ -633,9 +940,9 @@ fapi2::ReturnCode eff_dimm::primary_stack_type()
uint8_t l_stack_type = 0;
uint8_t l_package_type = 0;
- FAPI_TRY( iv_pDecoder->prim_sdram_signal_loading(l_stack_type),
+ FAPI_TRY( iv_spd_decoder.prim_sdram_signal_loading(l_stack_type),
"Failed to get dram_signal_loading from SPD %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->prim_sdram_package_type(l_package_type),
+ FAPI_TRY( iv_spd_decoder.prim_sdram_package_type(l_package_type),
"Failed to get prim_sdram_package_type from SPD %s", mss::c_str(iv_dimm) );
// Check to see if monolithic DRAM/ SDP
@@ -700,14 +1007,24 @@ fapi2::ReturnCode eff_dimm::dimm_size()
// Retrieve values needed to calculate dimm size
uint8_t l_bus_width = 0;
- uint8_t l_sdram_width = 0;
- uint8_t l_sdram_density = 0;
uint8_t l_logical_rank_per_dimm = 0;
- FAPI_TRY( iv_pDecoder->device_width(l_sdram_width), "Failed to get device width from SPD %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->prim_bus_width(l_bus_width), "Failed to get prim bus width from SPD %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->sdram_density(l_sdram_density), "Failed to get dram density from SPD %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->logical_ranks_per_dimm(l_logical_rank_per_dimm),
+ {
+ uint8_t l_spd_bus_width = 0;
+ FAPI_TRY( iv_spd_decoder.prim_bus_width(l_spd_bus_width), "Failed to get prim bus width from SPD %s",
+ mss::c_str(iv_dimm) );
+
+ FAPI_ASSERT( mss::find_value_from_key(BUS_WIDTH_MAP, l_spd_bus_width, l_bus_width),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_spd_bus_width)
+ .set_DATA(l_bus_width)
+ .set_FUNCTION(DIMM_SIZE)
+ .set_TARGET(iv_dimm),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_spd_bus_width, mss::c_str(iv_dimm) );
+ }
+
+ FAPI_TRY( logical_ranks_per_dimm(l_logical_rank_per_dimm),
"Failed to get logical ranks from SPD %s", mss::c_str(iv_dimm) );
// Let's sort the dimm size vector just to be super duper safe
@@ -716,9 +1033,9 @@ fapi2::ReturnCode eff_dimm::dimm_size()
// Double checking to avoid divide by zero errors
// If this fails, there was a problem with the check in SPD function
- FAPI_ASSERT( l_sdram_density != 0,
+ FAPI_ASSERT( iv_dram_density != 0,
fapi2::MSS_BAD_SDRAM_DENSITY_DECODER()
- .set_DRAM_DENSITY(l_sdram_density)
+ .set_DRAM_DENSITY(iv_dram_density)
.set_DIMM_TARGET(iv_dimm),
"SPD decoder messed up and returned a 0. Should have been caught already %s",
mss::c_str(iv_dimm));
@@ -726,23 +1043,23 @@ fapi2::ReturnCode eff_dimm::dimm_size()
// Calculate dimm size
// Formula from SPD Spec (seriously, they don't have parenthesis in the spec)
// Total = SDRAM Capacity / 8 * Primary Bus Width / SDRAM Width * Logical Ranks per DIMM
- const uint32_t l_dimm_size = (l_sdram_density * l_bus_width * l_logical_rank_per_dimm) / (8 * l_sdram_width);
+ const uint32_t l_dimm_size = (iv_dram_density * l_bus_width * l_logical_rank_per_dimm) / (8 * iv_dram_width);
FAPI_ASSERT( (std::binary_search(l_dimm_sizes.begin(), l_dimm_sizes.end(), l_dimm_size) == true),
fapi2::MSS_INVALID_CALCULATED_DIMM_SIZE()
.set_CALCULATED_SIZE(l_dimm_size)
- .set_SDRAM_WIDTH(l_sdram_width)
+ .set_SDRAM_WIDTH(iv_dram_width)
.set_BUS_WIDTH(l_bus_width)
- .set_DRAM_DENSITY(l_sdram_density)
+ .set_DRAM_DENSITY(iv_dram_density)
.set_LOGICAL_RANKS(l_logical_rank_per_dimm)
.set_DIMM_TARGET(iv_dimm),
"Recieved an invalid dimm size (%d) for calculated DIMM_SIZE for target %s"
- "(l_sdram_density %d * l_bus_width %d * l_logical_rank_per_dimm %d) / (8 * l_sdram_width %d",
+ "(iv_dram_density %d * l_bus_width %d * l_logical_rank_per_dimm %d) / (8 * iv_dram_width %d",
l_dimm_size,
mss::c_str(iv_dimm),
- l_sdram_width,
+ iv_dram_width,
l_bus_width,
- l_sdram_density,
+ iv_dram_density,
l_logical_rank_per_dimm);
// Get & update MCS attribute
@@ -820,7 +1137,7 @@ fapi2::ReturnCode eff_dimm::dram_trefi()
// Calculate nck
FAPI_TRY( spd::calc_nck( l_trefi_in_ps,
static_cast<uint64_t>(iv_tCK_in_ps),
- INVERSE_DDR4_CORRECTION_FACTOR,
+ spd::INVERSE_DDR4_CORRECTION_FACTOR,
l_trefi_in_nck),
"Error in calculating tREFI for target %s, with value of l_trefi_in_ps: %d", mss::c_str(iv_dimm), l_trefi_in_ps);
@@ -866,19 +1183,19 @@ fapi2::ReturnCode eff_dimm::dram_trfc()
switch(iv_refresh_mode)
{
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:
- FAPI_TRY( iv_pDecoder->min_trfc1(l_trfc_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trfc1(l_trfc_mtb),
"Failed to decode SPD for tRFC1" );
break;
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_2X:
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:
- FAPI_TRY( iv_pDecoder->min_trfc2(l_trfc_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trfc2(l_trfc_mtb),
"Failed to decode SPD for tRFC2" );
break;
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FIXED_4X:
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:
- FAPI_TRY( iv_pDecoder->min_trfc4(l_trfc_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trfc4(l_trfc_mtb),
"Failed to decode SPD for tRFC4" );
break;
@@ -916,7 +1233,7 @@ fapi2::ReturnCode eff_dimm::dram_trfc()
"Failed to retrieve tRFC attribute" );
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_trfc_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_in_nck),
+ FAPI_TRY( spd::calc_nck(l_trfc_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_in_nck),
"Error in calculating l_tRFC for target %s, with value of l_trfc_in_ps: %d", mss::c_str(iv_dimm), l_trfc_in_ps);
FAPI_INF("tCK (ps): %d, tRFC (ps): %d, tRFC (nck): %d",
@@ -943,27 +1260,23 @@ fapi_try_exit:
fapi2::ReturnCode eff_dimm::dram_trfc_dlr()
{
- uint8_t l_density = 0;
uint64_t l_tCK_in_ps = 0;
uint64_t l_trfc_dlr_in_ps = 0;
uint8_t l_trfc_dlr_in_nck = 0;
std::vector<uint8_t> l_mcs_attrs_trfc_dlr(PORTS_PER_MCS, 0);
// Retrieve map params
- FAPI_TRY( iv_pDecoder->sdram_density(l_density), "Failed to get sdram density");
- FAPI_TRY( mss::mrw_fine_refresh_mode(iv_refresh_mode), "Failed to get MRW attribute for fine refresh mode" );
-
FAPI_INF("Retrieved SDRAM density: %d, fine refresh mode: %d",
- l_density, iv_refresh_mode);
+ iv_dram_density, iv_refresh_mode);
// Calculate refresh cycle time in ps
- FAPI_TRY( calc_trfc_dlr(iv_dimm, iv_refresh_mode, l_density, l_trfc_dlr_in_ps), "Failed calc_trfc_dlr()" );
+ FAPI_TRY( calc_trfc_dlr(iv_dimm, iv_refresh_mode, iv_dram_density, l_trfc_dlr_in_ps), "Failed calc_trfc_dlr()" );
// Calculate clock period (tCK) from selected freq from mss_freq
FAPI_TRY( clock_period(iv_dimm, l_tCK_in_ps), "Failed to calculate clock period (tCK)");
// Calculate refresh cycle time in nck
- FAPI_TRY( spd::calc_nck(l_trfc_dlr_in_ps, l_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_dlr_in_nck));
+ FAPI_TRY( spd::calc_nck(l_trfc_dlr_in_ps, l_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trfc_dlr_in_nck));
FAPI_INF("tCK (ps): %d, tRFC_DLR (ps): %d, tRFC_DLR (nck): %d",
l_tCK_in_ps, l_trfc_dlr_in_ps, l_trfc_dlr_in_nck);
@@ -996,7 +1309,7 @@ fapi2::ReturnCode eff_dimm::rcd_mirror_mode()
FAPI_TRY( eff_dimm_rcd_mirror_mode(iv_mcs, &l_attrs_mirror_mode[0][0]) );
// Update MCS attribute
- FAPI_TRY( iv_pDecoder->iv_module_decoder->register_to_dram_addr_mapping(l_mirror_mode) );
+ FAPI_TRY( iv_spd_decoder.register_to_dram_addr_mapping(l_mirror_mode) );
l_attrs_mirror_mode[iv_port_index][iv_dimm_index] = l_mirror_mode;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RCD_MIRROR_MODE, iv_mcs, l_attrs_mirror_mode) );
@@ -1012,10 +1325,20 @@ fapi_try_exit:
fapi2::ReturnCode eff_dimm::dram_bank_bits()
{
uint8_t l_bank_bits = 0;
+ uint8_t l_decoder_val = 0;
uint8_t l_attrs_bank_bits[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
FAPI_TRY( eff_dram_bank_bits(iv_mcs, &l_attrs_bank_bits[0][0]) );
- FAPI_TRY( iv_pDecoder->bank_bits(l_bank_bits) );
+ FAPI_TRY( iv_spd_decoder.bank_bits(l_decoder_val) );
+
+ FAPI_ASSERT( mss::find_value_from_key(BANK_ADDR_BITS_MAP, l_decoder_val, l_bank_bits),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_decoder_val)
+ .set_DATA(l_bank_bits)
+ .set_FUNCTION(DRAM_BANK_BITS)
+ .set_TARGET(iv_dimm),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_decoder_val, mss::c_str(iv_dimm) );
l_attrs_bank_bits[iv_port_index][iv_dimm_index] = l_bank_bits;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_BANK_BITS, iv_mcs, l_attrs_bank_bits) );
@@ -1030,11 +1353,21 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dram_row_bits()
{
+ uint8_t l_decoder_val = 0;
uint8_t l_row_bits = 0;
uint8_t l_attrs_row_bits[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
FAPI_TRY( eff_dram_row_bits(iv_mcs, &l_attrs_row_bits[0][0]) );
- FAPI_TRY( iv_pDecoder->row_address_bits(l_row_bits) );
+ FAPI_TRY( iv_spd_decoder.row_address_bits(l_decoder_val) );
+
+ FAPI_ASSERT( mss::find_value_from_key(ROW_ADDRESS_BITS_MAP, l_decoder_val, l_row_bits),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_decoder_val)
+ .set_DATA(l_row_bits)
+ .set_FUNCTION(DRAM_ROW_BITS)
+ .set_TARGET(iv_dimm),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_decoder_val, mss::c_str(iv_dimm) );
l_attrs_row_bits[iv_port_index][iv_dimm_index] = l_row_bits;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_ROW_BITS, iv_mcs, l_attrs_row_bits) );
@@ -1051,27 +1384,13 @@ fapi_try_exit:
fapi2::ReturnCode eff_dimm::dram_dqs_time()
{
uint8_t l_attrs_dqs_time[PORTS_PER_MCS] = {};
- uint8_t l_dram_width = 0;
-
- // Get the DRAM width
- FAPI_TRY( iv_pDecoder->device_width(l_dram_width) );
// Get & update MCS attribute
FAPI_TRY( eff_dram_tdqs(iv_mcs, &l_attrs_dqs_time[0]) );
- FAPI_INF("SDRAM width: %d for target %s", l_dram_width, mss::c_str(iv_dimm));
-
- // Enforcing current NIMBUS standards.
- FAPI_ASSERT( (l_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ||
- (l_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4),
- fapi2::MSS_INVALID_DRAM_WIDTH()
- .set_DRAM_WIDTH(l_dram_width)
- .set_DIMM_TARGET(iv_dimm),
- "Invalid DRAM width with %d for target %s",
- l_dram_width,
- mss::c_str(iv_dimm));
+ FAPI_INF("SDRAM width: %d for target %s", iv_dram_width, mss::c_str(iv_dimm));
// Only possible dram width are x4, x8. If x8, tdqs is available, else not available
- l_attrs_dqs_time[iv_port_index] = (l_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ?
+ l_attrs_dqs_time[iv_port_index] = (iv_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8) ?
fapi2::ENUM_ATTR_EFF_DRAM_TDQS_ENABLE : fapi2::ENUM_ATTR_EFF_DRAM_TDQS_DISABLE;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_TDQS, iv_mcs, l_attrs_dqs_time) );
@@ -1098,9 +1417,9 @@ fapi2::ReturnCode eff_dimm::dram_tccd_l()
int64_t l_tccd_mtb = 0;
int64_t l_tccd_ftb = 0;
- FAPI_TRY( iv_pDecoder->min_tccd_l(l_tccd_mtb),
+ FAPI_TRY( iv_spd_decoder.min_tccd_l(l_tccd_mtb),
"Failed min_tccd_l() for %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_tccd_l(l_tccd_ftb),
+ FAPI_TRY( iv_spd_decoder.fine_offset_min_tccd_l(l_tccd_ftb),
"Failed fine_offset_min_tccd_l() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, tCCD_L (MTB): %ld, tCCD_L(FTB): %ld",
@@ -1119,7 +1438,7 @@ fapi2::ReturnCode eff_dimm::dram_tccd_l()
"Failed to retrieve tCCD attribute" );
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_tccd_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_tccd_in_nck),
+ FAPI_TRY( spd::calc_nck(l_tccd_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_tccd_in_nck),
"Error in calculating tccd for target %s, with value of l_tccd_in_ps: %d", mss::c_str(iv_dimm), l_tccd_in_ps);
FAPI_INF("tCK (ps): %d, tCCD_L (ps): %d, tCCD_L (nck): %d",
@@ -1151,7 +1470,7 @@ fapi2::ReturnCode eff_dimm::dimm_rc00()
FAPI_TRY( eff_dimm_ddr4_rc00(iv_mcs, &l_attrs_dimm_rc00[0][0]) );
// Update MCS attribute
- l_attrs_dimm_rc00[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc00;
+ l_attrs_dimm_rc00[iv_port_index][iv_dimm_index] = iv_raw_card.iv_rc00;
FAPI_INF("%s: RC00 settting: 0x%02x", mss::c_str(iv_dimm), l_attrs_dimm_rc00[iv_port_index][iv_dimm_index] );
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC00, iv_mcs, l_attrs_dimm_rc00) );
@@ -1172,7 +1491,7 @@ fapi2::ReturnCode eff_dimm::dimm_rc01()
FAPI_TRY( eff_dimm_ddr4_rc01(iv_mcs, &l_attrs_dimm_rc01[0][0]) );
// Update MCS attribute
- l_attrs_dimm_rc01[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc01;
+ l_attrs_dimm_rc01[iv_port_index][iv_dimm_index] = iv_raw_card.iv_rc01;
FAPI_INF("%s: RC01 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc01[iv_port_index][iv_dimm_index] );
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC01, iv_mcs, l_attrs_dimm_rc01) );
@@ -1218,8 +1537,8 @@ fapi2::ReturnCode eff_dimm::dimm_rc03()
uint8_t l_cs_output_drive = 0;
uint8_t l_ca_output_drive = 0;
- FAPI_TRY( iv_pDecoder->iv_module_decoder->cs_signal_output_driver(l_cs_output_drive) );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->ca_signal_output_driver(l_ca_output_drive) );
+ FAPI_TRY( iv_spd_decoder.cs_signal_output_driver(l_cs_output_drive) );
+ FAPI_TRY( iv_spd_decoder.ca_signal_output_driver(l_ca_output_drive) );
FAPI_INF( "%s: Retrieved register output drive, for CA: %d, CS: %d",
mss::c_str(iv_dimm), l_ca_output_drive, l_cs_output_drive );
@@ -1259,8 +1578,8 @@ fapi2::ReturnCode eff_dimm::dimm_rc04()
fapi2::buffer<uint8_t> l_buffer;
- FAPI_TRY( iv_pDecoder->iv_module_decoder->odt_signal_output_driver(l_odt_output_drive) );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->cke_signal_output_driver(l_cke_output_drive) );
+ FAPI_TRY( iv_spd_decoder.odt_signal_output_driver(l_odt_output_drive) );
+ FAPI_TRY( iv_spd_decoder.cke_signal_output_driver(l_cke_output_drive) );
FAPI_INF( "%s: Retrieved signal driver output, for CKE: %d, ODT: %d",
mss::c_str(iv_dimm), l_cke_output_drive, l_odt_output_drive );
@@ -1301,8 +1620,8 @@ fapi2::ReturnCode eff_dimm::dimm_rc05()
fapi2::buffer<uint8_t> l_buffer;
- FAPI_TRY( iv_pDecoder->iv_module_decoder->a_side_clk_output_driver(l_a_side_output_drive) );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->b_side_clk_output_driver(l_b_side_output_drive) );
+ FAPI_TRY( iv_spd_decoder.a_side_clk_output_driver(l_a_side_output_drive) );
+ FAPI_TRY( iv_spd_decoder.b_side_clk_output_driver(l_b_side_output_drive) );
FAPI_INF( "%s: Retrieved register output drive for clock, b-side (Y0,Y2): %d, a-side (Y1,Y3): %d",
mss::c_str(iv_dimm), l_b_side_output_drive, l_a_side_output_drive );
@@ -1718,15 +2037,15 @@ fapi2::ReturnCode eff_dimm::dimm_rc0d()
constexpr uint8_t l_cs_mode = rc0d_encode::DIRECT_CS_MODE;
uint8_t l_mirror_mode = 0;
uint8_t l_dimm_type = 0;
- uint8_t l_module_type = 0;
+ uint8_t l_rc0d_dimm_type = 0;
- FAPI_TRY( spd::base_module_type(iv_dimm, iv_pDecoder->iv_spd_data, l_module_type) );
+ FAPI_TRY(mss::eff_dimm_type(iv_dimm, l_dimm_type));
- l_dimm_type = (l_module_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) ?
- rc0d_encode::RDIMM :
- rc0d_encode::LRDIMM;
+ l_rc0d_dimm_type = (l_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) ?
+ rc0d_encode::RDIMM :
+ rc0d_encode::LRDIMM;
- FAPI_TRY( iv_pDecoder->iv_module_decoder->register_to_dram_addr_mapping(l_mirror_mode) );
+ FAPI_TRY( iv_spd_decoder.register_to_dram_addr_mapping(l_mirror_mode) );
// Lets construct encoding byte for RCD setting
{
@@ -1743,7 +2062,7 @@ fapi2::ReturnCode eff_dimm::dimm_rc0d()
constexpr size_t MIRROR_LEN = 1;
l_buffer.insertFromRight<CS_START, CS_LEN>(l_cs_mode)
- .insertFromRight<DIMM_TYPE_START, DIMM_TYPE_LEN>(l_dimm_type)
+ .insertFromRight<DIMM_TYPE_START, DIMM_TYPE_LEN>(l_rc0d_dimm_type)
.insertFromRight<MIRROR_START, MIRROR_LEN>(l_mirror_mode);
}
@@ -1751,7 +2070,6 @@ fapi2::ReturnCode eff_dimm::dimm_rc0d()
FAPI_TRY( eff_dimm_ddr4_rc0d(iv_mcs, &l_attrs_dimm_rc0d[0][0]) );
// Update MCS attribute
- FAPI_TRY( spd::base_module_type(iv_dimm, iv_pDecoder->iv_spd_data, l_dimm_type) );
l_attrs_dimm_rc0d[iv_port_index][iv_dimm_index] = l_buffer;
FAPI_INF( "%s: RC0D setting: 0x%02x", mss::c_str(iv_dimm), l_attrs_dimm_rc0d[iv_port_index][iv_dimm_index] );
@@ -2183,7 +2501,7 @@ fapi2::ReturnCode eff_dimm::dram_twr()
constexpr int64_t l_twr_ftb = 0;
int64_t l_twr_mtb = 0;
- FAPI_TRY( iv_pDecoder->min_twr(l_twr_mtb),
+ FAPI_TRY( iv_spd_decoder.min_twr(l_twr_mtb),
"Failed min_twr() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, tWR (MTB): %ld, tWR(FTB): %ld",
@@ -2198,7 +2516,7 @@ fapi2::ReturnCode eff_dimm::dram_twr()
uint8_t l_twr_in_nck = 0;
// Calculate tNCK
- FAPI_TRY( spd::calc_nck(l_twr_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twr_in_nck),
+ FAPI_TRY( spd::calc_nck(l_twr_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_twr_in_nck),
"Error in calculating l_twr_in_nck for target %s, with value of l_twr_in_ps: %d", mss::c_str(iv_dimm), l_twr_in_ps);
FAPI_INF( "tCK (ps): %d, tWR (ps): %d, tWR (nck): %d for target: %s",
@@ -2269,20 +2587,18 @@ fapi2::ReturnCode eff_dimm::dram_cwl()
// Taken from DDR4 JEDEC spec 1716.78C
// Proposed DDR4 Full spec update(79-4A)
// Page 26, Table 7
- static std::pair<uint64_t, uint8_t> CWL_TABLE_1 [6] =
+ static constexpr std::pair<uint64_t, uint8_t> CWL_TABLE_1 [] =
{
- {1600, 9},
- {1866, 10},
- {2133, 11},
- {2400, 12},
- {2666, 14},
- {3200, 16},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT1866, 10},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2133, 11},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2400, 12},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2666, 14},
};
- static std::pair<uint64_t, uint8_t> CWL_TABLE_2 [3] =
+
+ static constexpr std::pair<uint64_t, uint8_t> CWL_TABLE_2 [] =
{
- {2400, 14},
- {2666, 16},
- {3200, 18},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2400, 14},
+ {fapi2::ENUM_ATTR_MSS_FREQ_MT2666, 16},
};
std::vector<uint8_t> l_attrs_cwl(PORTS_PER_MCS, 0);
@@ -2744,7 +3060,7 @@ fapi2::ReturnCode eff_dimm::post_package_repair()
uint8_t l_attrs_dram_ppr[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
FAPI_TRY( eff_dram_ppr(iv_mcs, &l_attrs_dram_ppr[0][0]) );
- FAPI_TRY( iv_pDecoder->post_package_repair(l_decoder_val) );
+ FAPI_TRY( iv_spd_decoder.post_package_repair(l_decoder_val) );
l_attrs_dram_ppr[iv_port_index][iv_dimm_index] = l_decoder_val;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_PPR, iv_mcs, l_attrs_dram_ppr),
@@ -2755,6 +3071,53 @@ fapi_try_exit:
}
///
+/// @brief Determines & sets effective config for soft post package repair
+/// @return fapi2::FAPI2_RC_SUCCESS if okay
+///
+fapi2::ReturnCode eff_dimm::soft_post_package_repair()
+{
+ uint8_t l_sppr_decoder_val = 0;
+ uint8_t l_rev_decoder_val = 0;
+
+ uint8_t l_sppr = 0;
+ uint8_t l_attrs_dram_soft_ppr[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( eff_dram_soft_ppr(iv_mcs, &l_attrs_dram_soft_ppr[0][0]) );
+
+ FAPI_TRY( iv_spd_decoder.soft_post_package_repair(l_sppr_decoder_val) );
+ FAPI_TRY( iv_spd_decoder.revision(l_rev_decoder_val) );
+
+ if(l_rev_decoder_val == spd::rev::V1_0 &&
+ l_sppr_decoder_val == fapi2::ENUM_ATTR_EFF_DRAM_SOFT_PPR_SUPPORTED)
+ {
+ // Lab observes DIMMs that are SPD rev 1.0 but have sPPR enabled that is considered
+ // invalid per the SPD spec. For backward compatability of those DIMMs (known past vendor issue)
+ // we set it to a valid value.
+ FAPI_INF("Invalid sPPR (0x%02x) for SPD rev 0x%02x on %s. Setting sPPR to 0x%02x",
+ l_sppr_decoder_val, l_rev_decoder_val, mss::c_str(iv_dimm),
+ fapi2::ENUM_ATTR_EFF_DRAM_SOFT_PPR_NOT_SUPPORTED);
+
+ l_sppr_decoder_val = fapi2::ENUM_ATTR_EFF_DRAM_SOFT_PPR_NOT_SUPPORTED;
+ }
+
+ FAPI_ASSERT( mss::find_value_from_key(SOFT_PPR_MAP, l_sppr_decoder_val, l_sppr),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_sppr_decoder_val)
+ .set_DATA(l_sppr)
+ .set_FUNCTION(SOFT_POST_PACKAGE_REPAIR)
+ .set_TARGET(iv_dimm),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_sppr_decoder_val, mss::c_str(iv_dimm) );
+
+ l_attrs_dram_soft_ppr[iv_port_index][iv_dimm_index] = l_sppr;
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_SOFT_PPR, iv_mcs, l_attrs_dram_soft_ppr),
+ "Failed setting attribute for DRAM_SOFT_PPR");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Determines & sets effective config for rd_preamble_train
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
@@ -3197,10 +3560,10 @@ fapi2::ReturnCode eff_dimm::dram_trp()
int64_t l_trp_mtb = 0;
int64_t l_trp_ftb = 0;
- FAPI_TRY( iv_pDecoder->min_trp(l_trp_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trp(l_trp_mtb),
"Failed min_trp() for %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trp(l_trp_ftb),
+ FAPI_TRY( iv_spd_decoder.fine_offset_min_trp(l_trp_ftb),
"Failed fine_offset_min_trp() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, tRP (MTB): %ld, tRP(FTB): %ld",
@@ -3221,7 +3584,7 @@ fapi2::ReturnCode eff_dimm::dram_trp()
uint8_t l_trp_in_nck = 0;
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_trp_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trp_in_nck),
+ FAPI_TRY( spd::calc_nck(l_trp_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trp_in_nck),
"Error in calculating dram_tRP nck for target %s, with value of l_trp_in_ps: %d", mss::c_str(iv_dimm), l_trp_in_ps);
FAPI_INF( "tCK (ps): %d, tRP (ps): %d, tRP (nck): %d for target: %s",
@@ -3259,10 +3622,10 @@ fapi2::ReturnCode eff_dimm::dram_trcd()
int64_t l_trcd_mtb = 0;
int64_t l_trcd_ftb = 0;
- FAPI_TRY( iv_pDecoder->min_trcd(l_trcd_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trcd(l_trcd_mtb),
"Failed min_trcd() for %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trcd(l_trcd_ftb),
+ FAPI_TRY( iv_spd_decoder.fine_offset_min_trcd(l_trcd_ftb),
"Failed fine_offset_min_trcd() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase MTB (ps): %ld, fine timebase FTB (ps): %ld, tRCD (MTB): %ld, tRCD (FTB): %ld",
@@ -3276,7 +3639,7 @@ fapi2::ReturnCode eff_dimm::dram_trcd()
uint8_t l_trcd_in_nck = 0;
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_trcd_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trcd_in_nck),
+ FAPI_TRY( spd::calc_nck(l_trcd_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trcd_in_nck),
"Error in calculating trcd for target %s, with value of l_trcd_in_ps: %d", mss::c_str(iv_dimm), l_trcd_in_ps);
FAPI_INF("tCK (ps): %d, tRCD (ps): %d, tRCD (nck): %d for target: %s",
@@ -3309,10 +3672,10 @@ fapi2::ReturnCode eff_dimm::dram_trc()
int64_t l_trc_mtb = 0;
int64_t l_trc_ftb = 0;
- FAPI_TRY( iv_pDecoder->min_trc(l_trc_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trc(l_trc_mtb),
"Failed min_trc() for %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trc(l_trc_ftb),
+ FAPI_TRY( iv_spd_decoder.fine_offset_min_trc(l_trc_ftb),
"Failed fine_offset_min_trc() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase MTB (ps): %ld, fine timebase FTB (ps): %ld, tRCmin (MTB): %ld, tRCmin(FTB): %ld",
@@ -3326,7 +3689,7 @@ fapi2::ReturnCode eff_dimm::dram_trc()
uint8_t l_trc_in_nck = 0;
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_trc_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trc_in_nck),
+ FAPI_TRY( spd::calc_nck(l_trc_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trc_in_nck),
"Error in calculating trc for target %s, with value of l_trc_in_ps: %d",
mss::c_str(iv_dimm), l_trc_in_ps );
@@ -3360,7 +3723,7 @@ fapi2::ReturnCode eff_dimm::dram_twtr_l()
constexpr int64_t l_twtr_l_ftb = 0;
int64_t l_twtr_l_mtb = 0;
- FAPI_TRY( iv_pDecoder->min_twtr_l(l_twtr_l_mtb) );
+ FAPI_TRY( iv_spd_decoder.min_twtr_l(l_twtr_l_mtb) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, tWTR_S (MTB): %ld, tWTR_S (FTB): %ld",
mss::c_str(iv_dimm), iv_mtb, iv_ftb, l_twtr_l_mtb, l_twtr_l_ftb );
@@ -3374,7 +3737,7 @@ fapi2::ReturnCode eff_dimm::dram_twtr_l()
int8_t l_twtr_l_in_nck = 0;
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_twtr_l_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_l_in_nck),
+ FAPI_TRY( spd::calc_nck(l_twtr_l_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_l_in_nck),
"Error in calculating tWTR_L for target %s, with value of l_twtr_in_ps: %d", mss::c_str(iv_dimm), l_twtr_l_in_ps );
FAPI_INF( "tCK (ps): %d, tWTR_L (ps): %d, tWTR_L (nck): %d for target: %s",
@@ -3407,7 +3770,7 @@ fapi2::ReturnCode eff_dimm::dram_twtr_s()
constexpr int64_t l_twtr_s_ftb = 0;
int64_t l_twtr_s_mtb = 0;
- FAPI_TRY( iv_pDecoder->min_twtr_s(l_twtr_s_mtb) );
+ FAPI_TRY( iv_spd_decoder.min_twtr_s(l_twtr_s_mtb) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, tWTR_S (MTB): %ld, tWTR_S (FTB): %ld",
mss::c_str(iv_dimm), iv_mtb, iv_ftb, l_twtr_s_mtb, l_twtr_s_ftb );
@@ -3420,7 +3783,7 @@ fapi2::ReturnCode eff_dimm::dram_twtr_s()
uint8_t l_twtr_s_in_nck = 0;
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_twtr_s_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_s_in_nck),
+ FAPI_TRY( spd::calc_nck(l_twtr_s_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_twtr_s_in_nck),
"Error in calculating tWTR_S for target %s, with value of l_twtr_in_ps: %d", mss::c_str(iv_dimm), l_twtr_s_in_ps);
FAPI_INF("tCK (ps): %d, tWTR_S (ps): %d, tWTR_S (nck): %d for target: %s",
@@ -3449,7 +3812,7 @@ fapi2::ReturnCode eff_dimm::nibble_map()
uint8_t l_attr[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_DQ_NIBBLES] = {};
std::vector<uint8_t> l_nibble_bitmap;
- FAPI_TRY( iv_pDecoder->nibble_map(l_nibble_bitmap) );
+ FAPI_TRY( iv_spd_decoder.nibble_map(l_nibble_bitmap) );
// Sanity check we retrieved a vector w/the right size
FAPI_ASSERT( l_nibble_bitmap.size() == MAX_DQ_NIBBLES,
@@ -3482,7 +3845,7 @@ fapi2::ReturnCode eff_dimm::package_rank_map()
uint8_t l_attr[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_DQ_NIBBLES] = {};
std::vector<uint8_t> l_package_rank_map;
- FAPI_TRY( iv_pDecoder->package_rank_map(l_package_rank_map) );
+ FAPI_TRY( iv_spd_decoder.package_rank_map(l_package_rank_map) );
// Sanity check we retrieved a vector w/the right size
FAPI_ASSERT( l_package_rank_map.size() == MAX_DQ_NIBBLES,
@@ -3540,17 +3903,16 @@ fapi2::ReturnCode eff_dimm::dram_trrd_s()
uint64_t l_trrd_s_in_nck = 0;
int64_t l_trrd_s_in_ps = 0;
uint64_t l_jedec_trrd = 0;
- uint8_t l_dram_width = 0;
// Calculate tRRD_S
{
int64_t l_trrd_s_mtb = 0;
int64_t l_trrd_s_ftb = 0;
- FAPI_TRY( iv_pDecoder->min_trrd_s(l_trrd_s_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trrd_s(l_trrd_s_mtb),
"Failed min_trrd_s() for %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trrd_s(l_trrd_s_ftb),
+ FAPI_TRY( iv_spd_decoder.fine_offset_min_trrd_s(l_trrd_s_ftb),
"Failed fine_offset_min_trrd_s() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, trrd_s (MTB): %ld",
@@ -3569,16 +3931,13 @@ fapi2::ReturnCode eff_dimm::dram_trrd_s()
FAPI_DBG("TRRD_S in ps is %d", l_trrd_s_in_ps);
- FAPI_TRY( spd::calc_nck(l_trrd_s_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trrd_s_in_nck),
+ FAPI_TRY( spd::calc_nck(l_trrd_s_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trrd_s_in_nck),
"Error in calculating l_tFAW for target %s, with value of l_trrd_s_in_ps: %d",
mss::c_str(iv_dimm),
l_trrd_s_in_nck);
}
- FAPI_TRY( iv_pDecoder->device_width(l_dram_width),
- "Failed device_width()");
-
- FAPI_TRY( trrd_s( iv_dimm, l_dram_width, l_jedec_trrd) );
+ FAPI_TRY( trrd_s( iv_dimm, iv_dram_width, l_jedec_trrd) );
// Taking the worst case between the required minimum JEDEC value and the proposed value from SPD
if (l_jedec_trrd != l_trrd_s_in_nck)
@@ -3587,14 +3946,14 @@ fapi2::ReturnCode eff_dimm::dram_trrd_s()
mss::c_str(iv_dimm),
l_jedec_trrd,
l_trrd_s_in_nck,
- l_dram_width,
+ iv_dram_width,
iv_freq);
l_trrd_s_in_nck = std::max( l_jedec_trrd, l_trrd_s_in_nck);
}
FAPI_INF("SDRAM width: %d, tFAW (nck): %d for target: %s",
- l_dram_width, l_trrd_s_in_nck, mss::c_str(iv_dimm));
+ iv_dram_width, l_trrd_s_in_nck, mss::c_str(iv_dimm));
// Get & update MCS attribute
FAPI_TRY( eff_dram_trrd_s(iv_mcs, l_attrs_dram_trrd_s.data()) );
@@ -3619,17 +3978,16 @@ fapi2::ReturnCode eff_dimm::dram_trrd_l()
std::vector<uint8_t> l_attrs_dram_trrd_l(PORTS_PER_MCS, 0);
uint64_t l_trrd_l_in_nck = 0;
int64_t l_trrd_l_in_ps = 0;
- uint8_t l_dram_width = 0;
uint64_t l_jedec_trrd = 0;
// Calculate tRRD_L
{
int64_t l_trrd_l_mtb = 0;
int64_t l_trrd_l_ftb = 0;
- FAPI_TRY( iv_pDecoder->min_trrd_l(l_trrd_l_mtb),
+ FAPI_TRY( iv_spd_decoder.min_trrd_l(l_trrd_l_mtb),
"Failed min_trrd_l() for %s", mss::c_str(iv_dimm) );
- FAPI_TRY( iv_pDecoder->fine_offset_min_trrd_l(l_trrd_l_ftb),
+ FAPI_TRY( iv_spd_decoder.fine_offset_min_trrd_l(l_trrd_l_ftb),
"Failed fine_offset_min_trrd_l() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, trrd_l (MTB): %ld",
@@ -3649,16 +4007,13 @@ fapi2::ReturnCode eff_dimm::dram_trrd_l()
FAPI_DBG("TRRD_L in ps is %d", l_trrd_l_in_ps);
- FAPI_TRY( spd::calc_nck(l_trrd_l_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_trrd_l_in_nck),
+ FAPI_TRY( spd::calc_nck(l_trrd_l_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_trrd_l_in_nck),
"Error in calculating l_tFAW for target %s, with value of l_trrd_l_in_ps: %d",
mss::c_str(iv_dimm),
l_trrd_l_in_nck);
}
- FAPI_TRY( iv_pDecoder->device_width(l_dram_width),
- "Failed device_width()");
-
- FAPI_TRY( trrd_l( iv_dimm, l_dram_width, l_jedec_trrd) );
+ FAPI_TRY( trrd_l( iv_dimm, iv_dram_width, l_jedec_trrd) );
// Taking the worst case between the required minimum JEDEC value and the proposed value from SPD
if (l_jedec_trrd != l_trrd_l_in_nck)
@@ -3667,14 +4022,14 @@ fapi2::ReturnCode eff_dimm::dram_trrd_l()
mss::c_str(iv_dimm),
l_jedec_trrd,
l_trrd_l_in_nck,
- l_dram_width,
+ iv_dram_width,
iv_freq);
l_trrd_l_in_nck = std::max( l_jedec_trrd, l_trrd_l_in_nck);
}
FAPI_INF("SDRAM width: %d, tFAW (nck): %d for target: %s",
- l_dram_width, l_trrd_l_in_nck, mss::c_str(iv_dimm));
+ iv_dram_width, l_trrd_l_in_nck, mss::c_str(iv_dimm));
// Get & update MCS attribute
FAPI_TRY( eff_dram_trrd_l(iv_mcs, l_attrs_dram_trrd_l.data()) );
@@ -3726,14 +4081,13 @@ fapi2::ReturnCode eff_dimm::dram_tfaw()
uint64_t l_tfaw_in_nck = 0;
uint64_t l_jedec_tfaw_in_nck = 0;
int64_t l_tfaw_in_ps = 0;
- uint8_t l_dram_width = 0;
int64_t l_tfaw_ftb = 0;
// Calculate tFAW
{
int64_t l_tfaw_mtb = 0;
- FAPI_TRY( iv_pDecoder->min_tfaw(l_tfaw_mtb),
+ FAPI_TRY( iv_spd_decoder.min_tfaw(l_tfaw_mtb),
"Failed min_tfaw() for %s", mss::c_str(iv_dimm) );
FAPI_INF("%s medium timebase (ps): %ld, fine timebase (ps): %ld, tfaw (MTB): %ld",
@@ -3752,16 +4106,13 @@ fapi2::ReturnCode eff_dimm::dram_tfaw()
FAPI_DBG("%s TFAW in ps is %d", mss::c_str(iv_dimm), l_tfaw_in_ps);
- FAPI_TRY( spd::calc_nck(l_tfaw_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_tfaw_in_nck),
+ FAPI_TRY( spd::calc_nck(l_tfaw_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_tfaw_in_nck),
"Error in calculating l_tFAW for target %s, with value of l_tfaw_in_ps: %d",
mss::c_str(iv_dimm),
l_tfaw_in_nck);
}
- FAPI_TRY( iv_pDecoder->device_width(l_dram_width),
- "Failed device_width()");
-
- FAPI_TRY( mss::tfaw(iv_dimm, l_dram_width, l_jedec_tfaw_in_nck), "Failed tfaw()" );
+ FAPI_TRY( mss::tfaw(iv_dimm, iv_dram_width, l_jedec_tfaw_in_nck), "Failed tfaw()" );
// Taking the worst case between the required minimum JEDEC value and the proposed value from SPD
if (l_jedec_tfaw_in_nck != l_tfaw_in_nck)
@@ -3770,14 +4121,14 @@ fapi2::ReturnCode eff_dimm::dram_tfaw()
mss::c_str(iv_dimm),
l_jedec_tfaw_in_nck,
l_tfaw_in_nck,
- l_dram_width,
+ iv_dram_width,
iv_freq);
l_tfaw_in_nck = std::max(l_jedec_tfaw_in_nck, l_tfaw_in_nck);
}
FAPI_INF("SDRAM width: %d, tFAW (nck): %d for target: %s",
- l_dram_width, l_tfaw_in_nck, mss::c_str(iv_dimm));
+ iv_dram_width, l_tfaw_in_nck, mss::c_str(iv_dimm));
// Get & update MCS attribute
FAPI_TRY( eff_dram_tfaw(iv_mcs, l_attrs_dram_tfaw.data()) );
@@ -3842,7 +4193,7 @@ fapi2::ReturnCode eff_dimm::dram_tras()
// addition with negative integers.
FAPI_TRY( spd::calc_nck(l_tras_in_ps,
static_cast<uint64_t>(iv_tCK_in_ps),
- INVERSE_DDR4_CORRECTION_FACTOR,
+ spd::INVERSE_DDR4_CORRECTION_FACTOR,
l_tras_in_nck),
"Error in calculating tras_l for target %s, with value of l_twtr_in_ps: %d",
mss::c_str(iv_dimm), l_tras_in_ps);
@@ -3878,7 +4229,7 @@ fapi2::ReturnCode eff_dimm::dram_trtp()
uint8_t l_calc_trtp_in_nck = 0;
// Calculate nck
- FAPI_TRY( spd::calc_nck(l_max_trtp_in_ps, iv_tCK_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_calc_trtp_in_nck),
+ FAPI_TRY( spd::calc_nck(l_max_trtp_in_ps, iv_tCK_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_calc_trtp_in_nck),
"Error in calculating trtp for target %s, with value of l_twtr_in_ps: %d",
mss::c_str(iv_dimm), l_max_trtp_in_ps);
@@ -3974,7 +4325,7 @@ fapi2::ReturnCode eff_lrdimm::dram_rtt_nom()
FAPI_TRY( eff_dram_rtt_nom(iv_mcs, &l_mcs_attrs[0][0][0]) );
// Get the value from the LRDIMM SPD
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_nom(iv_freq, l_decoder_val));
+ FAPI_TRY( iv_spd_decoder.dram_rtt_nom(iv_freq, l_decoder_val));
// Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
// Same value for every rank for LRDIMMs
@@ -4057,7 +4408,7 @@ fapi2::ReturnCode eff_lrdimm::dram_rtt_wr()
uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM] = {};
// Get the value from the LRDIMM SPD
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_wr(iv_freq, l_decoder_val));
+ FAPI_TRY( iv_spd_decoder.dram_rtt_wr(iv_freq, l_decoder_val));
// Plug into every rank position for the attribute so it'll fit the same style as the RDIMM value
// Same value for every rank for LRDIMMs
@@ -4090,10 +4441,10 @@ fapi2::ReturnCode eff_rdimm::dram_rtt_park()
// for mss::index 1. So this doesn't correspond directly with the table in the JEDEC spec,
// as that's not in "denominator order."
constexpr uint64_t RTT_PARK_COUNT = 8;
- // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
- constexpr uint8_t rtt_park_map[RTT_PARK_COUNT] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
+ // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
+ constexpr uint8_t const rtt_park_map[RTT_PARK_COUNT] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
- uint8_t l_rtt_park[MAX_RANK_PER_DIMM];
+ uint8_t l_rtt_park[MAX_RANK_PER_DIMM] = {};
FAPI_TRY( mss::vpd_mt_dram_rtt_park(iv_dimm, &(l_rtt_park[0])) );
FAPI_TRY( eff_dram_rtt_park(iv_mcs, &l_mcs_attrs[0][0][0]) );
@@ -4133,8 +4484,8 @@ fapi2::ReturnCode eff_lrdimm::dram_rtt_park()
FAPI_TRY( eff_dram_rtt_park(iv_mcs, &l_mcs_attrs[0][0][0]) );
// Get the value from the LRDIMM SPD
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_park_ranks0_1(iv_freq, l_decoder_val_01) );
- FAPI_TRY( iv_pDecoder->iv_module_decoder->dram_rtt_park_ranks2_3(iv_freq, l_decoder_val_23) );
+ FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks0_1(iv_freq, l_decoder_val_01) );
+ FAPI_TRY( iv_spd_decoder.dram_rtt_park_ranks2_3(iv_freq, l_decoder_val_23) );
// Setting the four rank values for this dimm
// Rank 0 and 1 have the same value, l_decoder_val_01
@@ -4457,7 +4808,7 @@ fapi2::ReturnCode eff_lrdimm::dimm_bc04()
// So the encoding from the SPD is the same as the encoding for the buffer control encoding
// Simple grab and insert
// Value is checked in decoder function for validity
- FAPI_TRY( iv_pDecoder->iv_module_decoder->data_buffer_mdq_rtt(iv_freq, l_decoder_val) );
+ FAPI_TRY( iv_spd_decoder.data_buffer_mdq_rtt(iv_freq, l_decoder_val) );
// Update MCS attribute
@@ -4485,7 +4836,7 @@ fapi2::ReturnCode eff_lrdimm::dimm_bc05()
FAPI_TRY( eff_dimm_ddr4_bc05(iv_mcs, &l_attrs_dimm_bc05[0][0]) );
// Same as BC04, grab from SPD and put into BC
- FAPI_TRY( iv_pDecoder->iv_module_decoder->data_buffer_mdq_drive_strength(iv_freq, l_decoder_val) );
+ FAPI_TRY( iv_spd_decoder.data_buffer_mdq_drive_strength(iv_freq, l_decoder_val) );
l_attrs_dimm_bc05[iv_port_index][iv_dimm_index] = l_decoder_val;
FAPI_INF("%s: BC05 settting (MDQ Drive Strenght): %d", mss::c_str(iv_dimm),
@@ -4509,15 +4860,14 @@ fapi2::ReturnCode eff_lrdimm::dimm_bc07()
// Map for the bc07 attribute, Each bit and its position represents one rank
// 0b0 == enabled, 0b1 == disabled
// 1 rank 2 rank 3 rank 4 rank
- constexpr uint8_t dram_map [MAX_RANK_PER_DIMM] = {0b1110, 0b1100, 0b1000, 0b0000};
-
+ constexpr uint8_t const dram_map [MAX_RANK_PER_DIMM] = {0b1110, 0b1100, 0b1000, 0b0000};
uint8_t l_ranks_per_dimm = 0;
// Retrieve MCS attribute data
uint8_t l_attrs_dimm_bc07[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- FAPI_TRY( iv_pDecoder->num_package_ranks_per_dimm(l_ranks_per_dimm) );
-
+ // It is safe to use the attribute accessor directly since it is set in mss_freq
+ FAPI_TRY( eff_num_master_ranks_per_dimm(iv_dimm, l_ranks_per_dimm) );
FAPI_TRY( eff_dimm_ddr4_bc07(iv_mcs, &l_attrs_dimm_bc07[0][0]) );
// Subtract so 1 rank == 0, 2 rank == 1, etc. For array mss::indexing
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
index 85d36d904..7e33c0bdb 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
@@ -28,14 +28,19 @@
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
-
#ifndef _MSS_EFF_DIMM_H_
#define _MSS_EFF_DIMM_H_
#include <fapi2.H>
#include <lib/shared/mss_kind.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
+#include <lib/shared/mss_const.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/spd/common/rcw_settings.H>
+#include <lib/spd/spd_factory.H>
#include <lib/eff_config/timing.H>
+#include <generic/memory/lib/data_engine/pre_data_init.H>
+#include <generic/memory/lib/spd/spd_utils.H>
+
namespace mss
{
@@ -65,11 +70,15 @@ class eff_dimm
size_t iv_dimm_index;
int64_t iv_ftb; // fine timebase
int64_t iv_mtb; // medium timebase
+ rcw_settings iv_raw_card;
+ uint8_t iv_dram_width;
+ uint8_t iv_dram_die_count;
public:
uint64_t iv_freq;
int64_t iv_tCK_in_ps;
- const std::shared_ptr<spd::decoder> iv_pDecoder;
+ spd::facade iv_spd_decoder;
+ uint8_t iv_dram_density;
// Assists testing with write ability on these MRW
// settings that are normally NOT writable
@@ -91,34 +100,48 @@ class eff_dimm
};
+ // eff_config SPD raw values to attribute mappings
+ static const std::vector<std::pair<uint8_t, uint8_t> > DEVICE_WIDTH_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > SDRAM_DENSITY_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > SOFT_PPR_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > BUS_WIDTH_MAP;
+ static const std::vector< std::pair<uint8_t, uint8_t> > BANK_ADDR_BITS_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > ROW_ADDRESS_BITS_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_DIE_COUNT_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > SEC_DIE_COUNT_MAP;
+
//Delete the default
eff_dimm () = delete;
///
/// @brief constructor for the base eff_dimm class
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_rc fapi2::ReturnCode
/// @note also sets class variables for parent MCA/ MCS and for freqs
///
- eff_dimm( const std::shared_ptr<spd::decoder>& i_pDecoder,
+ eff_dimm( const spd::facade& i_spd_decoder,
+ const rcw_settings& i_rcw,
fapi2::ReturnCode& o_rc ):
- iv_pDecoder(i_pDecoder)
+ iv_raw_card(i_rcw),
+ iv_spd_decoder(i_spd_decoder)
{
- FAPI_DBG("Constructing eff_dimm object");
- iv_dimm = iv_pDecoder->iv_target;
+ // Targeting and index info
+ iv_dimm = i_spd_decoder.get_dimm_target();
+ FAPI_DBG("Constructing eff_dimm object for %s", mss::c_str(iv_dimm));
+
iv_mca = find_target<fapi2::TARGET_TYPE_MCA>(iv_dimm);
iv_mcs = find_target<fapi2::TARGET_TYPE_MCS>(iv_dimm);
iv_port_index = mss::index(iv_mca);
iv_dimm_index = mss::index(iv_dimm);
- FAPI_TRY( iv_pDecoder->medium_timebase(iv_mtb), "Failed medium timebase in eff_dimm()" );
- FAPI_TRY( iv_pDecoder->fine_timebase(iv_ftb), "Failed medium timebase in eff_dimm()" );
-
+ // Set widely used parameters
+ FAPI_TRY( spd::get_timebases(iv_spd_decoder, iv_mtb, iv_ftb) );
+ FAPI_TRY( set_dram_width_instance() );
+ FAPI_TRY( set_prim_dram_die_count_instance() );
+ FAPI_TRY( set_dram_density_instance() );
FAPI_TRY( clock_period(iv_dimm, iv_tCK_in_ps), "Failed to calculate clock period (tCK)" );
-
FAPI_TRY( mss::mrw_refresh_rate_request(iv_refresh_rate_request), "Failed mrw_temp_refresh_rate_request()" );
FAPI_TRY( mss::mrw_fine_refresh_mode(iv_refresh_mode), "Failed mrw_fine_refresh_mode()" );
-
FAPI_TRY( mss::freq(find_target<fapi2::TARGET_TYPE_MCBIST>(iv_dimm), iv_freq),
"Failed accessing mss::freq in eff_dimm");
@@ -139,20 +162,20 @@ class eff_dimm
///
/// @brief factory to make an eff_config DIMM object based on dimm kind (type, gen, and revision number)
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_fact_obj a shared pointer of the eff_dimm type
///
- static fapi2::ReturnCode eff_dimm_factory ( const std::shared_ptr<spd::decoder>& i_pDecoder,
- std::shared_ptr<eff_dimm>& o_fact_obj);
+ static fapi2::ReturnCode factory ( const spd::facade& i_spd_decoder,
+ std::shared_ptr<eff_dimm>& o_fact_obj);
///
- /// @brief Determines & sets effective config for buffer and rev density
+ /// @brief Determines & sets effective config for buffer and rev type
/// @param[in] i_target FAPI2 target
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
static fapi2::ReturnCode register_and_buffer_type( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::shared_ptr<spd::decoder>& i_pDecoder );
+ const spd::facade& i_spd_decoder );
///
/// @brief Default destructor
@@ -567,6 +590,12 @@ class eff_dimm
fapi2::ReturnCode post_package_repair();
///
+ /// @brief Determines & sets effective config for Soft Post Package Repair
+ /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode soft_post_package_repair();
+
+ ///
/// @brief Determines & sets effective config for rd_preamble_train
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
@@ -916,6 +945,46 @@ class eff_dimm
///
virtual fapi2::ReturnCode dimm_bc0f() = 0;
+ private:
+
+ ///
+ /// @brief Returns Logical ranks in Primary SDRAM type
+ /// @param[out] o_logical_ranks number of logical ranks
+ /// @return fapi2::FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const;
+
+ ///
+ /// @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 sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const;
+
+ ///
+ /// @brief Returns Logical ranks per DIMM
+ /// @param[out] o_logical_ranks number of logical ranks
+ /// @return fapi2::FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const;
+
+ ///
+ /// @brief Helper function to set dram width instance variable
+ /// @return fapi2::FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode set_dram_width_instance();
+
+ ///
+ /// @brief Helper function to set dram density instance variable
+ /// @return fapi2::FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode set_dram_density_instance();
+
+ ///
+ /// @brief Helper function to set dram density instance variable
+ /// @return fapi2::FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode set_prim_dram_die_count_instance();
};
///
@@ -928,16 +997,17 @@ class eff_lrdimm : public eff_dimm
public:
///
/// @brief constructor for the eff_lrdimm class
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_rc fapi2::ReturnCode
/// @note also sets class variables for parent MCA/ MCS and for freqs
/// @note calls eff_dimm ctor
///
- eff_lrdimm( const std::shared_ptr<spd::decoder>& i_pDecoder,
+ eff_lrdimm( const spd::facade& i_spd_decoder,
+ const rcw_settings& i_rcw,
fapi2::ReturnCode& o_rc ):
- eff_dimm ( i_pDecoder, o_rc )
+ eff_dimm ( i_spd_decoder, i_rcw, o_rc )
{
- FAPI_DBG("Constructing LRDIMM");
+ FAPI_DBG("Constructing LRDIMM for %s", mss::c_str(iv_dimm));
}
///
@@ -1070,16 +1140,17 @@ class eff_lrdimm_db01 : public eff_lrdimm
///
/// @brief constructor for the eff_lrdimm_db01 (LRDIMM DataBuffer 1) class
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_rc fapi2::ReturnCode
/// @note also sets class variables for parent MCA/ MCS and for freqs
/// @note calls eff_dimm ctor
///
- eff_lrdimm_db01( const std::shared_ptr<spd::decoder>& i_pDecoder,
+ eff_lrdimm_db01( const spd::facade& i_spd_decoder,
+ const rcw_settings& i_rcw,
fapi2::ReturnCode& o_rc ) :
- eff_lrdimm( i_pDecoder, o_rc )
+ eff_lrdimm( i_spd_decoder, i_rcw, o_rc )
{
- FAPI_DBG("Constructing LRDIMM_DB01");
+ FAPI_DBG("Constructing LRDIMM_DB01 for %s", mss::c_str(iv_dimm))
}
///
@@ -1126,16 +1197,17 @@ class eff_lrdimm_db02 : public eff_lrdimm
///
/// @brief constructor for the eff_lrdimm_db02 (LRDIMM DataBuffer 2) class
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_rc fapi2::ReturnCode
/// @note also sets class variables for parent MCA/ MCS and for freqs
/// @note calls eff_dimm ctor
///
- eff_lrdimm_db02( const std::shared_ptr<spd::decoder>& i_pDecoder,
+ eff_lrdimm_db02( const spd::facade& i_spd_decoder,
+ const rcw_settings& i_rcw,
fapi2::ReturnCode& o_rc ) :
- eff_lrdimm( i_pDecoder, o_rc )
+ eff_lrdimm( i_spd_decoder, i_rcw, o_rc )
{
- FAPI_DBG("Constructing LRDIMM_DB02");
+ FAPI_DBG("Constructing LRDIMM_DB02 for %s", mss::c_str(iv_dimm));
}
///
@@ -1179,16 +1251,17 @@ class eff_rdimm : public eff_dimm
///
/// @brief constructor for the eff_rdimm_db01 (LRDIMM DataBuffer 1) class
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_rc fapi2::ReturnCode
/// @note also sets class variables for parent MCA/ MCS and for freqs
/// @note calls eff_dimm ctor
///
- eff_rdimm( const std::shared_ptr<spd::decoder>& i_pDecoder,
+ eff_rdimm( const spd::facade& i_spd_decoder,
+ const rcw_settings& i_rcw,
fapi2::ReturnCode& o_rc ) :
- eff_dimm( i_pDecoder, o_rc )
+ eff_dimm( i_spd_decoder, i_rcw, o_rc )
{
- FAPI_DBG("Constructing RDIMM");
+ FAPI_DBG("Constructing RDIMM for %s", mss::c_str(iv_dimm));
}
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C
index ef49471e9..aeb61f126 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -25,9 +25,8 @@
/// @file attr_setters.C
/// @brief Create setter functions for mss attributes
///
-// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
-// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP
@@ -35,27 +34,62 @@
#include <fapi2.H>
#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/data_engine/pre_data_init.H>
namespace mss
{
+
///
/// @brief Set ATTR_MSS_VOLT_VDDR and ATTR_MSS_VOLT_VPP
/// @param[in] i_target_mcs the MCS target
-/// @param[in] l_selected_dram_voltage the voltage in millivolts for nominal voltage
-/// @param[in] l_selected_dram_voltage_vpp voltage in millivolts for the VPP
+/// @param[in] i_selected_dram_voltage the voltage in millivolts for nominal voltage
+/// @param[in] i_selected_dram_voltage_vpp voltage in millivolts for the VPP
+/// @note dram_voltage and dram_voltage_vpp are not const due to FAPI_ATTR_SET template deduction
/// @return FAPI2_RC_SUCCESS iff ok
///
-
fapi2::ReturnCode set_voltage_attributes(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs,
- uint32_t l_selected_dram_voltage,
- uint32_t l_selected_dram_voltage_vpp)
+ uint32_t i_selected_dram_voltage,
+ uint32_t i_selected_dram_voltage_vpp)
{
const auto l_target_mcbist = find_target<fapi2::TARGET_TYPE_MCBIST>(i_target_mcs);
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VDDR, l_target_mcbist, l_selected_dram_voltage) );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VPP, l_target_mcbist, l_selected_dram_voltage_vpp) );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VDDR, l_target_mcbist, i_selected_dram_voltage) );
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VPP, l_target_mcbist, i_selected_dram_voltage_vpp) );
fapi_try_exit:
return fapi2::current_err;
}
+
+///
+/// @brief Sets pre_eff_config attributes
+/// @param[in] i_target the DIMM target
+/// @param[in] i_spd_decoder SPD decoder
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode set_pre_init_attrs( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const spd::facade& i_spd_decoder )
+{
+ fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS);
+ mss::pre_data_engine<mss::NIMBUS> l_data_engine(i_target, i_spd_decoder, l_rc);
+ FAPI_TRY(l_rc, "Failed to instantiate pre_data_engine object for %s", spd::c_str(i_target));
+
+ // Set attributes needed before eff_config
+ // DIMM type and DRAM gen are needed for c_str to aid debugging
+ FAPI_TRY(l_data_engine.set_dimm_type(), "Failed to set DIMM type %s", spd::c_str(i_target) );
+ FAPI_TRY(l_data_engine.set_dram_gen(), "Failed to set DRAM gen %s", spd::c_str(i_target) );
+
+ // Hybrid and hybrid media help detect hybrid modules, specifically NVDIMMs for Nimbus
+ FAPI_TRY(l_data_engine.set_hybrid(), "Failed to set Hybrid %s", spd::c_str(i_target) );
+ FAPI_TRY(l_data_engine.set_hybrid_media(), "Failed to set Hybrid Media %s", spd::c_str(i_target) );
+
+ // Number of master ranks needed for VPD decoding
+ // and dimm_ranks_configured is a PRD attr...
+ FAPI_TRY(l_data_engine.set_master_ranks(), "Failed to set Master ranks %s", spd::c_str(i_target) );
+ FAPI_TRY(l_data_engine.set_dimm_ranks_configured(), "Failed to set DIMM ranks configured %s", spd::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H
index 793d92fc9..976c1077d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,37 +27,41 @@
/// @file attr_setters.H
/// @brief Create setter functions for mss attributes
///
-// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
-// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP
-
-
-
#ifndef _MSS_ATTR_SETTERS_H_
#define _MSS_ATTR_SETTERS_H_
#include <fapi2.H>
-
-
+#include <generic/memory/lib/spd/spd_facade.H>
namespace mss
{
+
///
/// @brief Set ATTR_MSS_VOLT_VDDR and ATTR_MSS_VOLT_VPP
/// @param[in] i_target_mcs the MCS target
-/// @param[in] l_selected_dram_voltage the voltage in millivolts for nominal voltage
-/// @param[in] l_selected_dram_voltage_vpp voltage in millivolts for the VPP
+/// @param[in] i_selected_dram_voltage the voltage in millivolts for nominal voltage
+/// @param[in] i_selected_dram_voltage_vpp voltage in millivolts for the VPP
+/// @note dram_voltage and dram_voltage_vpp are not const due to FAPI_ATTR_SET template deduction
/// @return FAPI2_RC_SUCCESS iff ok
///
-
fapi2::ReturnCode set_voltage_attributes(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs,
- uint32_t l_selected_dram_voltage,
- uint32_t l_selected_dram_voltage_vpp);
+ uint32_t i_selected_dram_voltage,
+ uint32_t i_selected_dram_voltage_vpp);
+///
+/// @brief Sets pre_eff_config attributes
+/// @param[in] i_target the DIMM target
+/// @param[in] i_spd_decoder SPD decoder
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode set_pre_init_attrs( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const spd::facade& i_spd_decoder );
} // mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C
new file mode 100644
index 000000000..7cf3b7b3d
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C
@@ -0,0 +1,239 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 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 nimbus_pre_data_engine.C
+/// @brief pre_data_engine implimentation for Nimbus
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: CI
+
+#include <generic/memory/lib/utils/index.H>
+#include <lib/mss_attribute_accessors.H>
+#include <lib/eff_config/attr_setters.H>
+#include <generic/memory/lib/data_engine/pre_data_init.H>
+#include <generic/memory/lib/utils/find.H>
+
+namespace mss
+{
+
+// =========================================================
+// DDR4 SPD Document Release 4
+// Byte 2 (0x002): Key Byte / DRAM Device Type
+// =========================================================
+const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::DRAM_GEN_MAP =
+{
+ //{key value, dram gen}
+ {0x0C, fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4}
+ // Other key bytes reserved or not supported
+};
+
+// =========================================================
+// DDR4 SPD Document Release 4
+// Byte 3 (0x003): Key Byte / Module Type - Hybrid
+// =========================================================
+const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::HYBRID_MAP =
+{
+ //{key byte, dimm type}
+ {0, fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID},
+ {1, fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID},
+ // All others reserved or not supported
+};
+
+
+// =========================================================
+// DDR4 SPD Document Release 4
+// Byte 3 (0x003): Key Byte / Module Type - Hybrid
+// =========================================================
+const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::HYBRID_MEMORY_TYPE_MAP =
+{
+
+ //{key byte, dimm type}
+ {0, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE},
+ {1, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM},
+ // All others reserved or not supported
+};
+
+// =========================================================
+// DDR4 SPD Document Release 4
+// Byte 3 (0x003): Key Byte / Module Type
+// =========================================================
+const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::BASE_MODULE_TYPE_MAP =
+{
+ //{key byte, dimm type}
+ {1, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM},
+ {2, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM},
+ {4, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM},
+ // All others reserved or not supported
+};
+
+// =========================================================
+// DDR4 SPD Document Release 4
+// Byte 12 (0x00C): Module Organization
+// =========================================================
+const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::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},
+};
+
+///
+/// @brief ctor
+/// @param[in] i_target the DIMM target
+/// @param[in] i_spd_data SPD data
+/// @param[out] o_rc ReturnCode for failure to init object
+///
+pre_data_engine<NIMBUS>::pre_data_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const spd::facade& i_spd_data,
+ fapi2::ReturnCode& o_rc):
+ iv_dimm(i_target),
+ iv_spd_data(i_spd_data)
+{
+ // Sets up commonly used member variables
+ uint8_t l_master_ranks = 0;
+ FAPI_TRY(iv_spd_data.num_package_ranks_per_dimm(l_master_ranks));
+ FAPI_TRY(lookup_table_check(i_target, NUM_PACKAGE_RANKS_MAP, PRE_DATA_ENGINE_CTOR, l_master_ranks, iv_master_ranks));
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ return;
+}
+
+///
+/// @brief Set ATTR_EFF_DIMM_TYPE
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dimm_type()
+{
+ uint8_t l_base_module_type = 0;
+ uint8_t l_dimm_type = 0;
+
+ FAPI_TRY(iv_spd_data.base_module(l_base_module_type));
+ FAPI_TRY(lookup_table_check(iv_dimm, BASE_MODULE_TYPE_MAP, SET_ATTR_DIMM_TYPE, l_base_module_type, l_dimm_type));
+ FAPI_TRY( (set_field<NIMBUS, DIMM_TYPE>(iv_dimm, l_dimm_type)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set ATTR_EFF_DRAM_GEN
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dram_gen()
+{
+ uint8_t l_device_type = 0;
+ uint8_t l_dram_gen = 0;
+
+ FAPI_TRY(iv_spd_data.device_type(l_device_type));
+ FAPI_TRY(lookup_table_check(iv_dimm, DRAM_GEN_MAP, SET_ATTR_DRAM_GEN, l_device_type, l_dram_gen));
+
+ FAPI_TRY( (set_field<NIMBUS, DRAM_GEN>(iv_dimm, l_dram_gen)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set ATTR_EFF_HYBRID
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode pre_data_engine<NIMBUS>::set_hybrid()
+{
+ uint8_t l_spd_hybrid_type = 0;
+ uint8_t l_hybrid = 0;
+
+ FAPI_TRY(iv_spd_data.hybrid(l_spd_hybrid_type));
+ FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_type, l_hybrid));
+
+ FAPI_TRY( (set_field<NIMBUS, HYBRID>(iv_dimm, l_hybrid)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set ATTR_EFF_HYBRID_MEMORY_TYPE
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode pre_data_engine<NIMBUS>::set_hybrid_media()
+{
+ uint8_t l_hybrid_media = 0;
+ uint8_t l_spd_hybrid_media = 0;
+
+ FAPI_TRY(iv_spd_data.hybrid_media(l_spd_hybrid_media));
+ FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_media, l_hybrid_media));
+
+ FAPI_TRY( (set_field<NIMBUS, HYBRID_MEDIA>(iv_dimm, l_hybrid_media)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode pre_data_engine<NIMBUS>::set_master_ranks()
+{
+ FAPI_TRY( (set_field<NIMBUS, MRANKS>(iv_dimm, iv_master_ranks)) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets ATTR_EFF_DIMM_RANKS_CONFIGED
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dimm_ranks_configured()
+{
+ // Set configed ranks. Set the bit representing the master rank configured (0 being left most.) So,
+ // a 4R DIMM would be 0b11110000 (0xF0). This is used by PRD.
+ fapi2::buffer<uint8_t> l_ranks_configed;
+
+ FAPI_TRY( l_ranks_configed.setBit(0, iv_master_ranks),
+ "%s. Failed to setBit", spd::c_str(iv_dimm) );
+
+ FAPI_TRY( (set_field<NIMBUS, DIMM_RANKS_CNFG>(iv_dimm, uint8_t(l_ranks_configed))) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}//mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
index cb500c798..b4a715fb7 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
@@ -38,6 +38,7 @@
#include <cstdint>
#include <fapi2.H>
#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <lib/utils/conversions.H>
namespace mss
@@ -62,17 +63,6 @@ enum functions
TDLLK = 11,
};
-enum guard_band : uint16_t
-{
- // Used for caclulating spd timing values - from JEDEC rounding algorithm
- // Correction factor is 1% (for DDR3) or 2.5% (for DDR4)
- // when doing integer math, we add-in the inverse correction factor
- // Formula used for derivation:
- // Guardband = 1000 * (1000* correction_factor) - 1
- INVERSE_DDR3_CORRECTION_FACTOR = 989, ///< DDR3 correction factor
- INVERSE_DDR4_CORRECTION_FACTOR = 974, ///< DDR4 correction factor
-};
-
enum refresh_rate : uint8_t
{
REF1X = 1, ///< Refresh rate 1X
@@ -84,96 +74,6 @@ namespace spd
{
///
-/// @brief Calculates timing value
-/// @param[in] i_timing_mtb timing value in MTB units
-/// @param[in] i_mtb_multiplier SPD medium timebase
-/// @param[in] i_timing_ftb fine offset of timing value
-/// @param[in] i_ftb_multiplier SPD fine timebase
-/// @return the timing value in picoseconds
-///
-inline int64_t calc_timing_from_timebase(const int64_t i_timing_mtb,
- const int64_t i_mtb_multiplier,
- const int64_t i_timing_ftb,
- const int64_t i_ftb_multiplier)
-{
- // JEDEC algorithm
- const int64_t l_timing_val = i_timing_mtb * i_mtb_multiplier;
- const int64_t l_fine_offset = i_timing_ftb * i_ftb_multiplier;
-
- return l_timing_val + l_fine_offset;
-}
-
-///
-/// @brief Helper to compute JEDEC's SPD rounding algorithm
-/// to convert ps to nCK
-/// @tparam T input type
-/// @tparam OT output type
-/// @param[in] i_timing_in_ps timing parameter in ps
-/// @param[in] i_tck_in_ps clock period in ps
-/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC)
-/// @param[out] o_value_nck the end calculation in nck
-/// @return true if overflow didn't occur, false otherwise
-/// @note DDR4 SPD Contents Rounding Algorithm
-/// @note Item 2220.46
-///
-template<typename T, typename OT>
-static inline bool jedec_spd_rounding_alg(const T& i_timing_in_ps,
- const T& i_tck_in_ps,
- const guard_band i_inverse_corr_factor,
- OT& o_val_nck)
-{
- // Preliminary nCK calculation, scaled by 1000 per JDEC algorithm
- T l_temp_nck = (i_timing_in_ps * CONVERT_PS_IN_A_NS) / (i_tck_in_ps == 0 ? 1 : i_tck_in_ps);
- l_temp_nck += i_inverse_corr_factor;
- l_temp_nck = l_temp_nck / CONVERT_PS_IN_A_NS;
-
- // Check for overflow
- // static_cast needed for HB compiler that complains about
- // comparision of two different integral types
- o_val_nck = l_temp_nck;
-
- FAPI_DBG("Input timing (ps) %d, tCK (ps) %d, temp output %d, output (nCK) %d",
- i_timing_in_ps, i_tck_in_ps, l_temp_nck, o_val_nck);
-
- return (static_cast<T>(o_val_nck) == l_temp_nck);
-}
-
-///
-/// @brief Returns clock cycles based on input application period
-/// @tparam T input type
-/// @tparam OT output type
-/// @param[in] i_timing_in_ps timing parameter in ps
-/// @param[in] i_tck_in_ps clock period in ps
-/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC)
-/// @param[out] o_value_nck the end calculation in nck
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note DDR4 SPD Contents Rounding Algorithm
-/// @note Item 2220.46
-///
-template<typename T, typename OT>
-inline fapi2::ReturnCode calc_nck(const T& i_timing_in_ps,
- const T& i_tck_in_ps,
- const guard_band i_inverse_corr_factor,
- OT& o_val_nck)
-{
- FAPI_ASSERT( jedec_spd_rounding_alg(i_timing_in_ps,
- i_tck_in_ps,
- i_inverse_corr_factor,
- o_val_nck),
- fapi2::MSS_INVALID_CAST_CALC_NCK().
- set_TIMING_PS(i_timing_in_ps).
- set_NCK_NS(i_tck_in_ps).
- set_CORRECTION_FACTOR(i_inverse_corr_factor),
- "Overflow occured. Returned data is %d", o_val_nck);
-
- // If we don't assert, we don't know what's in current_err ...
- return fapi2::FAPI2_RC_SUCCESS;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Returns clock cycles form picoseconds based on speed bin
/// Uses SPD rounding algorithm for DDR4
/// @tparam T the target type from which to get the mt/s
@@ -201,7 +101,7 @@ inline OT ps_to_nck( const fapi2::Target<T>& i_target, const OT& i_timing_in_ps)
FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps),
"Failed freq() accessor" );
- FAPI_TRY( calc_nck(i_timing_in_ps, l_tck_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_temp_nck),
+ FAPI_TRY( calc_nck(i_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_temp_nck),
"Failed calc_nck()" );
return l_temp_nck;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C b/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C
index b81796771..1e1494560 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.C
@@ -42,8 +42,9 @@
// mss lib
#include <lib/freq/cas_latency.H>
-#include <lib/spd/spd_factory.H>
+#include <generic/memory/lib/data_engine/pre_data_init.H>
#include <lib/eff_config/timing.H>
+#include <generic/memory/lib/spd/spd_utils.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/utils/checker.H>
@@ -66,7 +67,7 @@ namespace mss
/// @param[out] o_rc returns FAPI2_RC_SUCCESS if constructor initialzed successfully
///
cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- const std::vector< std::shared_ptr<spd::decoder> >& i_caches,
+ const std::vector< spd::facade >& i_caches,
const std::vector<uint32_t>& i_supported_freqs,
fapi2::ReturnCode& o_rc):
iv_dimm_list_empty(false),
@@ -88,16 +89,16 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
for ( const auto& l_cache : i_caches )
{
// Retrieve timing values from the SPD
- const auto l_target = l_cache->iv_target;
+ const auto l_target = l_cache.get_dimm_target();
uint64_t l_taa_min_in_ps = 0;
uint64_t l_tckmax_in_ps = 0;
uint64_t l_tck_min_in_ps = 0;
FAPI_TRY( get_taamin(l_cache, l_taa_min_in_ps),
"%s. Failed to get tAAmin", mss::c_str(l_target) );
- FAPI_TRY( get_tckmax(l_cache, l_tckmax_in_ps),
+ FAPI_TRY( spd::get_tckmax(l_cache, l_tckmax_in_ps),
"%s. Failed to get tCKmax", mss::c_str(l_target) );
- FAPI_TRY( get_tckmin(l_cache, l_tck_min_in_ps),
+ FAPI_TRY( spd::get_tckmin(l_cache, l_tck_min_in_ps),
"%s. Failed to get tCKmin", mss::c_str(l_target) );
// Determine largest tAAmin value
@@ -114,7 +115,7 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
if( iv_is_3ds != loading::IS_3DS)
{
uint8_t l_stack_type = 0;
- FAPI_TRY( l_cache->prim_sdram_signal_loading(l_stack_type) );
+ FAPI_TRY( l_cache.prim_sdram_signal_loading(l_stack_type) );
// Is there a more algorithmic efficient approach? - AAM
iv_is_3ds = (l_stack_type == fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS) ?
@@ -124,7 +125,7 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
{
// Retrieve dimm supported cas latencies from SPD
uint64_t l_dimm_supported_cl = 0;
- FAPI_TRY( l_cache->supported_cas_latencies(l_dimm_supported_cl),
+ FAPI_TRY( l_cache.supported_cas_latencies(l_dimm_supported_cl),
"%s. Failed to get supported CAS latency", mss::c_str(l_target) );
// Bitwise ANDING the bitmap from all modules creates a bitmap w/a common CL
@@ -312,11 +313,11 @@ fapi_try_exit:
///
/// @brief Retrieves SDRAM Minimum CAS Latency Time (tAAmin) from SPD
-/// @param[in] i_pDecoder the SPD decoder
+/// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_value tCKmin value in ps
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode cas_latency::get_taamin( const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
+fapi2::ReturnCode cas_latency::get_taamin( const mss::spd::facade& i_spd_decoder,
uint64_t& o_value )
{
int64_t l_timing_ftb = 0;
@@ -326,15 +327,14 @@ fapi2::ReturnCode cas_latency::get_taamin( const std::shared_ptr<mss::spd::decod
int64_t l_temp = 0;
// Retrieve timing parameters
- const auto l_target = i_pDecoder->iv_target;
+ const auto l_target = i_spd_decoder.get_dimm_target();
- FAPI_TRY( i_pDecoder->medium_timebase(l_medium_timebase),
- "%s. Failed medium_timebase()", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->fine_timebase(l_fine_timebase),
- "%s. Failed fine_timebase()", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->min_taa(l_timing_mtb),
+ FAPI_TRY( get_timebases(i_spd_decoder, l_medium_timebase, l_fine_timebase),
+ "%s. Failed Failed get_timebases", mss::c_str(l_target) );
+
+ FAPI_TRY( i_spd_decoder.min_taa(l_timing_mtb),
"%s. Failed min_taa()", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->fine_offset_min_taa(l_timing_ftb),
+ FAPI_TRY( i_spd_decoder.fine_offset_min_taa(l_timing_ftb),
"%s. Failed fine_offset_min_taa()", mss::c_str(l_target) );
// Calculate timing value
@@ -409,7 +409,7 @@ inline fapi2::ReturnCode cas_latency::calc_cas_latency(const uint64_t i_taa,
const uint64_t i_tck,
uint64_t& o_cas_latency) const
{
- FAPI_TRY( spd::calc_nck(i_taa, i_tck, INVERSE_DDR4_CORRECTION_FACTOR, o_cas_latency) );
+ FAPI_TRY( spd::calc_nck(i_taa, i_tck, spd::INVERSE_DDR4_CORRECTION_FACTOR, o_cas_latency) );
FAPI_INF("%s. tAA (ps): %d, tCK (ps): %d, CL (nck): %d",
mss::c_str(iv_target),
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H b/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H
index 6c9ad087c..bd01e5dc9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H
@@ -45,7 +45,7 @@
#include <fapi2.H>
// mss lib
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
+#include <generic/memory/lib/spd/spd_facade.H>
#include <lib/utils/conversions.H>
#include <lib/freq/sync.H>
@@ -132,7 +132,7 @@ class cas_latency
/// @param[out] o_rc returns FAPI2_RC_SUCCESS if constructor initialzed successfully
///
cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target_mcs,
- const std::vector< std::shared_ptr<spd::decoder> >& i_caches,
+ const std::vector< spd::facade >& i_caches,
const std::vector<uint32_t>& i_supported_freqs,
fapi2::ReturnCode& o_rc);
@@ -277,11 +277,11 @@ class cas_latency
///
/// @brief Retrieves SDRAM Minimum CAS Latency Time (tAAmin) from SPD
- /// @param[in] i_pDecoder the SPD decoder
+ /// @param[in] i_spd_decoder the SPD decoder
/// @param[out] o_value tCKmin value in ps
/// @return FAPI2_RC_SUCCESS iff ok
///
- fapi2::ReturnCode get_taamin(const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
+ fapi2::ReturnCode get_taamin(const mss::spd::facade& i_spd_decoder,
uint64_t& o_value);
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
index 35f6daa10..0d9d4c0f8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
@@ -42,8 +42,9 @@
#include <lib/freq/sync.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/utils/assert_noexit.H>
-#include <lib/spd/spd_factory.H>
#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/spd/spd_utils.H>
using fapi2::TARGET_TYPE_DIMM;
using fapi2::TARGET_TYPE_MCS;
@@ -445,25 +446,23 @@ fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TARGET_TYPE_MCBIST>& i_
o_supported_freqs = std::vector<uint32_t>(PORTS_PER_MCBIST, ~(0));
// Get cached decoder
- std::vector< std::shared_ptr<mss::spd::decoder> > l_factory_caches;
-
- FAPI_TRY( mss::spd::populate_decoder_caches(i_target, l_factory_caches),
- "%s. Failed to populate decoder cache", mss::c_str(i_target) );
+ std::vector< mss::spd::facade > l_spd_facades;
+ FAPI_TRY( get_spd_decoder_list(i_target, l_spd_facades) );
// Looking for the biggest application period on an MC.
// This will further reduce supported frequencies the system can run on.
- for ( const auto& l_cache : l_factory_caches )
+ for ( const auto& l_cache : l_spd_facades )
{
- const auto l_dimm = l_cache->iv_target;
+ const auto l_dimm = l_cache.get_dimm_target();
const auto l_mca = mss::find_target<TARGET_TYPE_MCA>(l_dimm);
const auto l_port_pos = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(l_mca);
uint64_t l_tckmax_in_ps = 0;
uint64_t l_tck_min_in_ps = 0;
uint32_t l_dimm_freq = 0;
- FAPI_TRY( get_tckmax(l_cache, l_tckmax_in_ps),
+ FAPI_TRY( spd::get_tckmax(l_cache, l_tckmax_in_ps),
"%s. Failed to get tCKmax", mss::c_str(l_dimm) );
- FAPI_TRY( get_tckmin(l_cache, l_tck_min_in_ps),
+ FAPI_TRY( spd::get_tckmin(l_cache, l_tck_min_in_ps),
"%s. Failed to get tCKmin", mss::c_str(l_dimm) );
// Determine a proposed tCK value that is greater than or equal tCKmin
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
index 0589d11ae..a0622f929 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
@@ -39,7 +39,7 @@
// mss lib
#include <lib/power_thermal/throttle.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <mss.H>
+
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_DIMM;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
index 768917bcf..189583cfa 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
@@ -37,7 +37,9 @@
#define _MSS_POWER_THROTTLE_
#include <fapi2.H>
-#include <mss.H>
+#include <lib/shared/mss_const.H>
+#include <lib/mss_attribute_accessors.H>
+
namespace mss
{
namespace power_thermal
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
index 63ab07aa1..6535cab1e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
@@ -37,6 +37,7 @@
#define _MSS_CONST_H_
#include <cstdint>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/mss_math.H>
namespace mss
@@ -51,9 +52,6 @@ enum sizes
MCBIST_PER_MC = 1,
MAX_DIMM_PER_PORT = 2,
MAX_RANK_PER_DIMM = 4,
- NIBBLES_PER_BYTE = 2,
- BITS_PER_NIBBLE = 4,
- BITS_PER_BYTE = 8,
BITS_PER_DP = 16,
NIBBLES_PER_DP = BITS_PER_DP / BITS_PER_NIBBLE,
BYTES_PER_DP = BITS_PER_DP / BITS_PER_BYTE,
@@ -122,9 +120,6 @@ enum sizes
enum times
{
- CONVERT_PS_IN_A_NS = 1000, ///< 1000 pico in an nano
- CONVERT_PS_IN_A_US = 1000000, ///< 1000000 picos in a micro
-
DELAY_1NS = 1,
DELAY_10NS = 10 , ///< general purpose 10 ns delay for HW mode
DELAY_100NS = 100, ///< general purpose 100 ns delay for HW mode
@@ -134,9 +129,6 @@ enum times
DELAY_1MS = 1000000, ///< general purpose 1 ms delay for HW mode
// Not *exactly* a time but go with it.
- MHZ_TO_KHZ = 1000,
-
- SEC_IN_HOUR = 60 * 60, ///< seconds in an hour, used for scrub times
BG_SCRUB_IN_HOURS = 12,
CMD_TIMEBASE = 8192, ///< Represents the timebase multiplier for the MCBIST inter cmd gap
@@ -145,13 +137,34 @@ enum times
};
///
-/// @brief ID codes so we can lookup which function triggered the ffdc fail
+/// @brief function ID codes for FFDC functions
+/// @note If we get a fail in HB, we can trace back to the function that failed
///
enum ffdc_function_codes
{
+ // Following are used in rank.H
+ RANK_PAIR_TO_PHY = 0,
+ RANK_PAIR_FROM_PHY = 1,
+ SET_RANKS_IN_PAIR = 2,
+ GET_RANKS_IN_PAIR = 3,
+ GET_RANK_FIELD = 4,
+ GET_PAIR_VALID = 5,
+ SET_RANK_FIELD = 6,
+ RD_CTR_WORKAROUND_READ_DATA = 7,
+ OVERRIDE_ODT_WR_CONFIG = 8,
+ RECORD_BAD_BITS_HELPER = 9,
+ SET_PAIR_VALID = 10,
+
// Used in eff_dimm.C
+ SET_DRAM_DENSITY_INSTANCE = 19,
NIBBLE_MAP_FUNC = 20,
PACKAGE_RANK_MAP_FUNC = 21,
+ SET_DRAM_WIDTH_INSTANCE = 22,
+ PRIM_DIE_COUNT = 23,
+ DIMM_SIZE = 24,
+ DRAM_BANK_BITS = 25,
+ DRAM_ROW_BITS = 26,
+ SOFT_POST_PACKAGE_REPAIR = 27,
// Used in fw_mark_store.H for MSS_INVALID_RANK_PASSED
FWMS_READ = 30,
@@ -186,10 +199,6 @@ enum ffdc_function_codes
GET_DRAM_DISABLE_REG_AND_POS = 94,
GET_STARTING_WR_DQ_DELAY_VALUE = 95,
- GET_TAAMIN = 96,
- GET_TCKMIN = 97,
- GET_TCKMAX = 98,
-
SUPPORTED_FREQS = 99,
SELECT_SUPPORTED_FREQ = 100,
@@ -228,25 +237,6 @@ enum states
NO_CHIP_SELECT_ACTIVE = 0xFF,
};
-///
-/// @brief function ID codes for FFDC functions
-/// @note If we get a fail in HB, we can trace back to the function that failed
-///
-enum ffdc_functions
-{
- // Following are used in rank.H
- RANK_PAIR_TO_PHY = 0,
- RANK_PAIR_FROM_PHY = 1,
- SET_RANKS_IN_PAIR = 2,
- GET_RANKS_IN_PAIR = 3,
- GET_RANK_FIELD = 4,
- GET_PAIR_VALID = 5,
- SET_RANK_FIELD = 6,
- RD_CTR_WORKAROUND_READ_DATA = 7,
- OVERRIDE_ODT_WR_CONFIG = 8,
- RECORD_BAD_BITS_HELPER = 9,
- SET_PAIR_VALID = 10,
-};
// Static consts describing the bits used in the cal_step_enable attribute
// These are bit positions. 0 is the left most bit.
enum cal_steps : uint64_t
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_kind.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_kind.H
index 6ffea0585..c1b07f643 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_kind.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_kind.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -62,18 +62,18 @@ enum kind_t
FORCE_DISPATCH = 4 + 1,
};
-inline mss::kind_t dimm_kind( const uint64_t l_type, const uint64_t l_gen )
+inline mss::kind_t dimm_kind( const uint64_t i_type, const uint64_t i_gen )
{
// This is the conditional needed to differentiate dimm type/generation
- switch (l_type)
+ switch (i_type)
{
case fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM:
- if (l_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_EMPTY)
+ if (i_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_EMPTY)
{
return KIND_RDIMM_EMPTY;
}
- if (l_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
+ if (i_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
{
return KIND_RDIMM_DDR4;
}
@@ -82,12 +82,12 @@ inline mss::kind_t dimm_kind( const uint64_t l_type, const uint64_t l_gen )
break;
case fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM:
- if (l_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_EMPTY)
+ if (i_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_EMPTY)
{
return KIND_LRDIMM_EMPTY;
}
- if (l_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
+ if (i_gen == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
{
return KIND_LRDIMM_DDR4;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C
index 10e23a6f2..1dd9cb759 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C
@@ -46,10 +46,11 @@
#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H>
#include <generic/memory/lib/spd/common/rcw_settings.H>
+#include <generic/memory/lib/spd/spd_facade.H>
#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H>
#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_raw_cards.H>
#include <generic/memory/lib/spd/spd_checker.H>
-#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/spd/spd_utils.H>
#include <lib/utils/conversions.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/eff_config/timing.H>
@@ -62,883 +63,39 @@ using fapi2::FAPI2_RC_SUCCESS;
namespace mss
{
-
-///
-/// @brief Helper function to retrieves medium and fine timebase values
-/// @param[in] i_pDecoder the SPD decoder
-/// @param[out] o_mtb the medium timebase (MTB) from SPD
-/// @param[out] o_ftb the fine timebase (FTB) from SPD
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-static fapi2::ReturnCode get_timebases( const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
- int64_t& o_mtb,
- int64_t& o_ftb )
-{
- // Retrieve timing parameters
- const auto l_target = i_pDecoder->iv_target;
-
- FAPI_TRY( i_pDecoder->medium_timebase(o_mtb),
- "%s. Failed medium_timebase()", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->fine_timebase(o_ftb),
- "%s. Failed fine_timebase()", mss::c_str(l_target) );
-
- FAPI_INF("MTB: %d, FTB: %d for %s", o_mtb, o_ftb, mss::c_str(l_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD
-/// @param[in] i_pDecoder the SPD decoder
-/// @param[out] o_value tCKmin value in ps
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode get_tckmin( const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
- uint64_t& o_value )
-{
- int64_t l_timing_ftb = 0;
- int64_t l_timing_mtb = 0;
- int64_t l_medium_timebase = 0;
- int64_t l_fine_timebase = 0;
- int64_t l_temp = 0;
-
- // Retrieve timing parameters
- const auto l_target = i_pDecoder->iv_target;
-
- FAPI_TRY( get_timebases(i_pDecoder, l_medium_timebase, l_fine_timebase),
- "%s. Failed get_timebases", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->min_tck(l_timing_mtb),
- "%s. Failed min_tck()", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->fine_offset_min_tck(l_timing_ftb),
- "%s. Failed fine_offset_min_tck()", mss::c_str(l_target) );
-
- // Calculate timing value
- l_temp = spd::calc_timing_from_timebase(l_timing_mtb,
- l_medium_timebase,
- l_timing_ftb,
- l_fine_timebase);
-
- // Sanity check
- FAPI_ASSERT(l_temp > 0,
- fapi2::MSS_INVALID_TIMING_VALUE().
- set_VALUE(l_temp).
- set_FUNCTION(GET_TCKMIN).
- set_DIMM_TARGET(l_target),
- "%s. tCKmin invalid (<= 0) : %d",
- mss::c_str(l_target),
- l_temp);
-
- o_value = l_temp;
-
- FAPI_INF("%s. tCKmin (ps): %d",
- mss::c_str(l_target),
- o_value );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD
-/// @param[in] i_pDecoder SPD decoder
-/// @param[out] o_value tCKmax value in ps
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode get_tckmax( const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
- uint64_t& o_value )
-{
- int64_t l_timing_ftb = 0;
- int64_t l_timing_mtb = 0;
- int64_t l_medium_timebase = 0;
- int64_t l_fine_timebase = 0;
- int64_t l_temp = 0;
-
- // Retrieve timing parameters
- const auto l_target = i_pDecoder->iv_target;
-
- FAPI_TRY( get_timebases(i_pDecoder, l_medium_timebase, l_fine_timebase),
- "%s. Failed get_timebases", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->max_tck(l_timing_mtb),
- "%s. Failed max_tck()", mss::c_str(l_target) );
- FAPI_TRY( i_pDecoder->fine_offset_max_tck(l_timing_ftb),
- "%s. Failed fine_offset_max_tck()", mss::c_str(l_target) );
-
- // Calculate timing value
- l_temp = spd::calc_timing_from_timebase(l_timing_mtb,
- l_medium_timebase,
- l_timing_ftb,
- l_fine_timebase);
-
- // Sanity check
- FAPI_ASSERT(l_temp > 0,
- fapi2::MSS_INVALID_TIMING_VALUE().
- set_VALUE(l_temp).
- set_FUNCTION(GET_TCKMAX).
- set_DIMM_TARGET(l_target),
- "%s. tCKmax invalid (<= 0) : %d",
- mss::c_str(l_target),
- l_temp);
-
- o_value = l_temp;
-
- FAPI_INF( "%s. tCKmax (ps): %d",
- mss::c_str(l_target),
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
namespace spd
{
-enum factory_byte_extract
-{
- // Byte 1
- ENCODING_LEVEL_START = 0, ///< SPD encoding level start bit
- ENCODING_LEVEL_LEN = 4, ///< SPD encoding level bit length
-
- ADDITIONS_LEVEL_START = 4, ///< SPD additions level start bit
- ADDITIONS_LEVEL_LEN = 4, ///< SPD additions level bit length
-
- // Byte 3
- HYBRID_START = 0, ///< SPD hybrid start bit
- HYBRID_LEN = 1, ///< SPD hybrid bit length
- HYBRID_TYPE_START = 1, ///< SPD hybrid type start bit
- HYBRID_TYPE_LEN = 3, ///< SPD hybrid type bit length
- BASE_MODULE_START = 4, ///< SPD base module start bit
- BASE_MODULE_LEN = 4, ///< SPD base module bit length
-};
-
-///
-/// @brief Decodes SPD Revision encoding level
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value encoding revision num
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 1 (3~0).
-/// @note Item JC-45-2220.01x
-/// @note Page 14-15
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode rev_encoding_level(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value)
-{
- constexpr size_t BYTE_INDEX = 1;
- constexpr field_t ENCODING_LEVEL{BYTE_INDEX, ENCODING_LEVEL_START, ENCODING_LEVEL_LEN};
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field(i_target, ENCODING_LEVEL, i_spd_data);
- FAPI_DBG("%s. Field Bits value: %d", mss::c_str(i_target), l_field_bits);
-
- // Check that value is valid
- constexpr size_t UNDEFINED = 0xF; // per JEDEC spec this value is undefined
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target,
- (l_field_bits != UNDEFINED),
- ENCODING_LEVEL.iv_byte,
- l_field_bits,
- "Failed check on SPD rev encoding level") );
-
- // Update output only after check passes
- o_value = l_field_bits;
-
- // Print decoded info
- FAPI_INF("%s. Rev - Encoding Level : %d",
- mss::c_str(i_target),
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SPD Revision additions level
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value additions revision num
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 1 (bits 7~4).
-/// @note Item JC-45-2220.01x
-/// @note Page 14-15
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode rev_additions_level(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value)
-{
- constexpr size_t BYTE_INDEX = 1;
- constexpr field_t ADDITIONS_LEVEL{BYTE_INDEX, ADDITIONS_LEVEL_START, ADDITIONS_LEVEL_LEN};
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field(i_target, ADDITIONS_LEVEL, i_spd_data);
- FAPI_DBG("%s. Field Bits value: %d", mss::c_str(i_target), l_field_bits);
-
- // Check that value is valid
- constexpr size_t UNDEFINED = 0xF; // per JEDEC spec this value is undefined
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target,
- (l_field_bits != UNDEFINED),
- ADDITIONS_LEVEL.iv_byte,
- l_field_bits,
- "Failed check on SPD rev encoding level") );
-
- // Update output only after check passes
- o_value = l_field_bits;
-
- // Print decoded info
- FAPI_INF("%s. Rev - Additions Level : %d",
- mss::c_str(i_target),
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes hybrid type (whether or not the DIMM is a hybrid) from SPD
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value hybrid
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 3 (bit 7)
-/// @note Item JC-45-2220.01x
-/// @note Page 17
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode hybrid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value)
-{
- // =========================================================
- // Byte 3 maps
- // Item JC-45-2220.01x
- // Page 17
- // DDR4 SPD Document Release 3
- // Byte 3 (0x003): Key Byte / Module Type - Hybrid
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_MAP =
- {
- //{key byte, dimm type}
- {0, fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID},
- {1, fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID},
- // All others reserved or not supported
- };
-
- constexpr size_t BYTE_INDEX = 3;
- constexpr field_t HYBRID{BYTE_INDEX, HYBRID_START, HYBRID_LEN};
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field(i_target, HYBRID, i_spd_data);
- FAPI_DBG("%s. Field Bits value: %d", mss::c_str(i_target), l_field_bits);
-
- // Check that value is valid
- const bool l_is_val_found = find_value_from_key(HYBRID_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target,
- l_is_val_found,
- HYBRID.iv_byte,
- l_field_bits,
- "Failed check on Hybrid") );
-
- FAPI_INF("%s. Hybrid Media: %d",
- mss::c_str(i_target),
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes hybrid type (hybrid DIMM type) from SPD
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value hybrid module type
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 3 (bits 6~4)
-/// @note Item JC-45-2220.01x
-/// @note Page 17
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode hybrid_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value)
-{
- // =========================================================
- // Byte 3 maps
- // Item JC-45-2220.01x
- // Page 17
- // DDR4 SPD Document Release 3
- // Byte 3 (0x003): Key Byte / Module Type - Hybrid
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_TYPE_MAP =
- {
- //{key byte, dimm type}
- {0, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE},
- {1, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM},
- // All others reserved or not supported
- };
-
- constexpr size_t BYTE_INDEX = 3;
- constexpr field_t HYBRID_TYPE{BYTE_INDEX, HYBRID_TYPE_START, HYBRID_TYPE_LEN};
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field(i_target, HYBRID_TYPE, i_spd_data);
- FAPI_DBG("%s. Field Bits value: %d", mss::c_str(i_target), l_field_bits);
-
- // Check that value is valid
- const bool l_is_val_found = find_value_from_key(HYBRID_TYPE_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target,
- l_is_val_found,
- HYBRID_TYPE.iv_byte,
- l_field_bits,
- "Failed check on Hybrid Memory Type") );
-
- FAPI_INF("%s. Hybrid Memory Type: %d",
- mss::c_str(i_target),
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes base module type (DIMM type) from SPD
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value base module type
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 3 (bits 3~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 17
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode base_module_type(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value)
-{
- // =========================================================
- // Byte 3 maps
- // Item JC-45-2220.01x
- // Page 17
- // DDR4 SPD Document Release 3
- // Byte 3 (0x003): Key Byte / Module Type
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > BASE_MODULE_TYPE_MAP =
- {
- //{key byte, dimm type}
- {1, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM},
- {2, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM},
- {4, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM},
- // All others reserved or not supported
- };
-
- constexpr size_t BYTE_INDEX = 3;
- constexpr field_t BASE_MODULE{BYTE_INDEX, BASE_MODULE_START, BASE_MODULE_LEN};
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field(i_target, BASE_MODULE, i_spd_data);
- FAPI_DBG("%s. Field Bits value: %d", mss::c_str(i_target), l_field_bits);
-
- // Check that value is valid
- const bool l_is_val_found = find_value_from_key(BASE_MODULE_TYPE_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target,
- l_is_val_found,
- BASE_MODULE.iv_byte,
- l_field_bits,
- "Failed check on Base Module Type") );
-
- FAPI_INF("%s. Base Module Type: %d",
- mss::c_str(i_target),
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM Device Type
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value dram device type enumeration
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 2
-/// @note Item JC-45-2220.01x
-/// @note Page 16
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode dram_device_type(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value)
-{
- // =========================================================
- // Byte 2 maps
- // Item JC-45-2220.01x
- // Page 16
- // DDR4 SPD Document Release 3
- // Byte 2 (0x002): Key Byte / DRAM Device Type
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > DRAM_GEN_MAP =
- {
- //{key value, dram gen}
- {0x0B, fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR3},
- {0x0C, fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4}
- // Other key bytes reserved or not supported
- };
-
- constexpr size_t BYTE_INDEX = 2;
- const uint8_t l_raw_byte = i_spd_data[BYTE_INDEX];
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- mss::c_str(i_target),
- BYTE_INDEX,
- l_raw_byte);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(DRAM_GEN_MAP, l_raw_byte, o_value);
-
- FAPI_TRY( mss::check::spd:: fail_for_invalid_value(i_target,
- l_is_val_found,
- BYTE_INDEX,
- l_raw_byte,
- "Failed check on SPD dram device type") );
-
- // Print decoded info
- FAPI_INF("%s Device type : %d",
- mss::c_str(i_target),
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes reference raw card
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 130 (Bits 7~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @Note Page 4.1.2.12 - 49
-///
-fapi2::ReturnCode reference_raw_card(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_output)
-{
- // Extracting desired bits
- constexpr size_t BYTE_INDEX = 130;
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- mss::c_str(i_target),
- BYTE_INDEX,
- i_spd_data[BYTE_INDEX]);
-
- // Byte taken directly, all bits are an encoding value so no fail check
- o_output = i_spd_data[BYTE_INDEX];
-
- FAPI_INF("%s. Reference raw card: %d",
- mss::c_str(i_target),
- o_output);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Helper function to set dimm type attribute
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_dimm_type dimm type encoding needed by factory
-/// @return FAPI2_RC_SUCCESS if okay
-///
-static fapi2::ReturnCode dimm_type_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_dimm_type)
-{
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- const auto l_mcs = mss::find_target<TARGET_TYPE_MCS>(i_target);
-
- // Get dimm type & set attribute (needed by c_str)
- uint8_t l_dimm_types_mcs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( base_module_type(i_target, i_spd_data, o_dimm_type),
- "%s. Failed to find base module type", mss::c_str(i_target) );
- FAPI_TRY( eff_dimm_type(l_mcs, &l_dimm_types_mcs[0][0]),
- "%s. Failed to invoke DIMM type accessor", mss::c_str(i_target));
-
- l_dimm_types_mcs[l_port_num][l_dimm_num] = o_dimm_type;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_TYPE, l_mcs, l_dimm_types_mcs),
- "%s. Failed to set ATTR_EFF_DIMM_TYPE", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to set hybrid attribute
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_hybrid dimm type encoding needed by factory
-/// @return FAPI2_RC_SUCCESS if okay
-///
-static fapi2::ReturnCode hybrid_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_hybrid)
-{
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- const auto l_mcs = mss::find_target<TARGET_TYPE_MCS>(i_target);
-
- // Get dimm type & set attribute (needed by c_str)
- uint8_t l_dimm_types_mcs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( hybrid(i_target, i_spd_data, o_hybrid),
- "%s. Failed to find hybrid", mss::c_str(i_target) );
- FAPI_TRY( eff_hybrid(l_mcs, &l_dimm_types_mcs[0][0]),
- "%s. Failed to invoke hybrid accessor", mss::c_str(i_target));
-
- l_dimm_types_mcs[l_port_num][l_dimm_num] = o_hybrid;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID, l_mcs, l_dimm_types_mcs),
- "%s. Failed to set ATTR_EFF_HYBRID", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to set hybrid_type attribute
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_hybrid_type dimm type encoding needed by factory
-/// @return FAPI2_RC_SUCCESS if okay
-///
-static fapi2::ReturnCode hybrid_type_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_hybrid_type)
-{
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- const auto l_mcs = mss::find_target<TARGET_TYPE_MCS>(i_target);
-
- // Get dimm type & set attribute (needed by c_str)
- uint8_t l_dimm_types_mcs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( hybrid_type(i_target, i_spd_data, o_hybrid_type),
- "%s. Failed to find hybrid_memory_type", mss::c_str(i_target) );
- FAPI_TRY( eff_hybrid_memory_type(l_mcs, &l_dimm_types_mcs[0][0]),
- "%s. Failed to invoke hybrid_memory_type accessor", mss::c_str(i_target));
-
- l_dimm_types_mcs[l_port_num][l_dimm_num] = o_hybrid_type;
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, l_mcs, l_dimm_types_mcs),
- "%s. Failed to set ATTR_EFF_HYBRID_MEMORY", mss::c_str(i_target));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to set dram gen attribute
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @return FAPI2_RC_SUCCESS if okay
-///
-static fapi2::ReturnCode dram_gen_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data)
-{
- const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) );
- const auto l_dimm_num = index(i_target);
- const auto l_mcs = mss::find_target<TARGET_TYPE_MCS>(i_target);
-
- // Get dram generation & set attribute (needed by c_str)
- uint8_t l_dram_gen = 0;
- uint8_t l_dram_gen_mcs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( eff_dram_gen(l_mcs, &l_dram_gen_mcs[0][0]),
- "%s. Failed to inboke DRAM gen accesssor", mss::c_str(i_target) );
- FAPI_TRY( dram_device_type(i_target, i_spd_data, l_dram_gen),
- "%s. Failed to find base module type", mss::c_str(i_target) );
-
- l_dram_gen_mcs[l_port_num][l_dimm_num] = l_dram_gen;
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_GEN, l_mcs, l_dram_gen_mcs),
- "%s. Failed to set ATTR_EFF_DRAM_GEN", mss::c_str(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Determines & sets effective config for number of master ranks per dimm
-/// @param[in] i_target FAPI2 target
-/// @param[in] the SPD cache
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note This is done after the SPD cache is configured so that it can reflect the results of the
-/// factory and we don't need to worry about SPD versions. This is expressly different than the dram and dimm setters
-///
-fapi2::ReturnCode master_ranks_per_dimm_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::shared_ptr<decoder>& i_pDecoder)
-{
- const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
- const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
-
- uint8_t l_decoder_val = 0;
- fapi2::buffer<uint8_t> l_ranks_configed;
- uint8_t l_attrs_master_ranks_per_dimm[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
- uint8_t l_attrs_dimm_ranks_configed[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
-
- // Get & update MCS attribute
- FAPI_TRY( i_pDecoder->num_package_ranks_per_dimm(l_decoder_val),
- "%s. Failed num_package_ranks_per_dimm()", mss::c_str(i_target) );
- FAPI_TRY(eff_num_master_ranks_per_dimm(l_mcs, &l_attrs_master_ranks_per_dimm[0][0]),
- "%s. Failed eff_num_master_ranks_per_dimm()", mss::c_str(i_target) );
- FAPI_TRY(eff_dimm_ranks_configed(l_mcs, &l_attrs_dimm_ranks_configed[0][0]),
- "%s. Failed eff_dimm_ranks_configed()", mss::c_str(i_target) );
-
- l_attrs_master_ranks_per_dimm[index(l_mca)][index(i_target)] = l_decoder_val;
-
- // Set configed ranks. Set the bit representing the master rank configured (0 being left most.) So,
- // a 4R DIMM would be 0b11110000 (0xF0). This is used by PRD.
- FAPI_TRY( l_ranks_configed.setBit(0, l_decoder_val),
- "%s. Failed to setBit", mss::c_str(i_target) );
-
- l_attrs_dimm_ranks_configed[index(l_mca)][index(i_target)] = l_ranks_configed;
-
- FAPI_INF( "%s Num Master Ranks %d, DIMM Ranks Configed 0x%x",
- mss::c_str(i_target),
- l_attrs_master_ranks_per_dimm[index(l_mca)][index(i_target)],
- l_attrs_dimm_ranks_configed[index(l_mca)][index(i_target)] );
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, l_mcs, l_attrs_master_ranks_per_dimm),
- "%s. Failed to set ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM", mss::c_str(i_target) );
-
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, l_mcs, l_attrs_dimm_ranks_configed),
- "%s. Failed to set ATTR_EFF_DIMM_RANKS_CONFIGED", mss::c_str(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to return RDIMM decoder
-/// @param[in] i_target dimm target
-/// @param[in] i_encoding_rev encoding revision
-/// @param[in] i_additions_rev additions revision
-/// @param[in] i_raw_card raw card reference revision
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_fact_obj shared pointer to the factory object
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Factory dependent on SPD revision & dimm type
-///
-static fapi2::ReturnCode rdimm_rev_helper(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_encoding_rev,
- const uint8_t i_additions_rev,
- const rcw_settings i_raw_card,
- const std::vector<uint8_t>& i_spd_data,
- std::shared_ptr<decoder>& o_fact_obj)
-{
- // This needs to be updated for added revisions
- constexpr uint64_t HIGHEST_ENCODING_LEVEL = 1;
- constexpr uint64_t HIGHEST_ADDITIONS_LEVEL = 1;
-
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- std::shared_ptr<dimm_module_decoder> l_module_decoder;
-
- // SPD Revision format #.#
- // 1st # = encoding level
- // 2nd # = additions level
- switch(i_encoding_rev)
- {
- // Skipping case 0 since we shouldn't be using pre-production revisions
- case 1:
- switch(i_additions_rev)
- {
- // Rev 1.0
- case 0:
- // Life starts out at base revision level
- FAPI_INF( "%s. Creating decoder for RDIMM SPD revision 1.0", mss::c_str(i_target) );
- l_module_decoder = std::make_shared<ddr4::rdimm::decoder_v1_0>(i_target, i_spd_data);
- o_fact_obj = std::make_shared<ddr4::decoder_v1_0>( i_target, i_spd_data, l_module_decoder, i_raw_card );
- break;
-
- case 1:
- // Rev 1.1
- // Changes to both the general section & rdimm section occured
- FAPI_INF( "%s. Creating decoder for RDIMM SPD revision 1.1", mss::c_str(i_target) );
- l_module_decoder = std::make_shared<ddr4::rdimm::decoder_v1_1>(i_target, i_spd_data);
- o_fact_obj = std::make_shared<ddr4::decoder_v1_1>( i_target, i_spd_data, l_module_decoder, i_raw_card );
- break;
-
- default:
- // For additions level retrieved from SPD higher than highest decoded revision level,
- // we default to be highest decoded additions level because they are backward compatable.
- // This will need to be updated for every new additions level that is decoded.
- FAPI_INF( "%s. Unable to create decoder for retrieved SPD RDIMM revision %d.%d",
- mss::c_str(i_target), i_encoding_rev, i_additions_rev );
-
- FAPI_INF("%s. Falling back to highest supported, backward-comptable decoder, "
- "for SPD RDIMM revision %d.%d",
- mss::c_str(i_target), HIGHEST_ENCODING_LEVEL, HIGHEST_ADDITIONS_LEVEL );
-
- l_module_decoder = std::make_shared<ddr4::rdimm::decoder_v1_1>(i_target, i_spd_data);
- o_fact_obj = std::make_shared<ddr4::decoder_v1_1>( i_target, i_spd_data, l_module_decoder, i_raw_card );
- break;
-
- }//end additions
-
- break;
-
- default:
- // For encodings level retrieved from SPD higher than highest decoded revision level,
- // we error out because encoding level changes are NOT backward comptable.
- // Current this means Rev 2.0+ is no supported
- FAPI_TRY( mss::check::spd::invalid_factory_sel(i_target,
- fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM,
- i_encoding_rev,
- i_additions_rev,
- "Encoding Level unsupported!"),
- "%s. Invalid encoding level received: %d",
- mss::c_str(i_target), i_encoding_rev);
-
- break;
- }// end encodings
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function to return LRDIMM decoder
-/// @param[in] i_target dimm target
-/// @param[in] i_encoding_rev encoding revision
-/// @param[in] i_additions_rev additions revision
-/// @param[in] i_raw_card raw card reference revision
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_fact_obj shared pointer to the factory object
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Factory dependent on SPD revision & dimm type
-///
-static fapi2::ReturnCode lrdimm_rev_helper(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_encoding_rev,
- const uint8_t i_additions_rev,
- const rcw_settings i_raw_card,
- const std::vector<uint8_t>& i_spd_data,
- std::shared_ptr<decoder>& o_fact_obj)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- std::shared_ptr<dimm_module_decoder> l_module_decoder;
-
- // This needs to be updated for added revisions
- constexpr uint64_t HIGHEST_ENCODING_LEVEL = 2;
- constexpr uint64_t HIGHEST_ADDITIONS_LEVEL = 1;
-
- // SPD Revision format #.#
- // 1st # = encoding level
- // 2nd # = additions level
- switch(i_encoding_rev)
- {
- // Skipping case 0 since we shouldn't be using pre-production revisions
- case 1:
- switch(i_additions_rev)
- {
- // Rev 1.0
- case 0:
- // Life starts out at base revision level
- FAPI_INF( "%s. Creating decoder for LRDIMM SPD revision 1.0", mss::c_str(i_target) );
- l_module_decoder = std::make_shared<ddr4::lrdimm::decoder_v1_0>(i_target, i_spd_data);
- o_fact_obj = std::make_shared<decoder>( i_target, i_spd_data, l_module_decoder, i_raw_card );
- break;
-
- case 1:
- // Rev 1.1
- // Changes to both the general section & lrdimm section occured
- FAPI_INF( "%s. Creating decoder for LRDIMM SPD revision 1.1", mss::c_str(i_target) );
- l_module_decoder = std::make_shared<ddr4::lrdimm::decoder_v1_1>(i_target, i_spd_data);
- o_fact_obj = std::make_shared<ddr4::decoder_v1_1>( i_target, i_spd_data, l_module_decoder, i_raw_card );
- break;
-
- case 2:
- // Rev 1.2
- // Changes lrdimm section occured
- // General section remained the same
- FAPI_INF( "%s. Creating decoder for LRDIMM SPD revision 1.2", mss::c_str(i_target) );
- l_module_decoder = std::make_shared<ddr4::lrdimm::decoder_v1_2>(i_target, i_spd_data);
- o_fact_obj = std::make_shared<ddr4::decoder_v1_1>( i_target, i_spd_data, l_module_decoder, i_raw_card );
- break;
-
- default:
- // For additions level retrieved from SPD higher than highest decoded revision level,
- // we default to be highest decoded additions level because they are backward compatable.
- // This will need to be updated for every new additions level that is decoded.
- FAPI_INF( "%s. Unable to create decoder for retrieved SPD LRDIMM revision %d.%d",
- mss::c_str(i_target), i_encoding_rev, i_additions_rev );
-
- FAPI_INF("%s. Falling back to highest supported, backward-comptable decoder, "
- "for SPD LRDIMM revision %d.%d",
- mss::c_str(i_target), HIGHEST_ENCODING_LEVEL, HIGHEST_ADDITIONS_LEVEL );
-
- l_module_decoder = std::make_shared<ddr4::lrdimm::decoder_v1_2>(i_target, i_spd_data);
- o_fact_obj = std::make_shared<ddr4::decoder_v1_1>( i_target, i_spd_data, l_module_decoder, i_raw_card );
- break;
-
- }//end additions
-
- break;
-
- default:
- // For encodings level retrieved from SPD higher than highest decoded revision level,
- // we error out because encoding level changes are NOT backward comptable.
- // Currently this means Rev 2.0+ is not supported
- FAPI_TRY( mss::check::spd::invalid_factory_sel(i_target,
- fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM,
- i_encoding_rev,
- i_additions_rev,
- "Encoding Level unsupported!"),
- "%s. Invalid encoding level received: %d",
- mss::c_str(i_target), i_encoding_rev);
- break;
- }// end encodings
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
///
/// @brief Retrieve current raw card settings
/// based on dimm type and raw card reference rev
/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
+/// @param[in] i_data SPD data
/// @param[out] o_raw_card raw card settings
/// @return FAPI2_RC_SUCCESS if okay
///
fapi2::ReturnCode raw_card_factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
+ const facade& i_data,
rcw_settings& o_raw_card)
{
+ // Lets find out what raw card we are and grab the right
+ // raw card settings
uint8_t l_dimm_type = 0;
uint8_t l_hybrid = 0;
uint8_t l_hybrid_type = 0;
uint8_t l_ref_raw_card_rev = 0;
- // Lets find out what raw card we are and grab the right
- // raw card settings
- FAPI_TRY( mss::eff_dimm_type(i_target, l_dimm_type) );
- FAPI_TRY( mss::eff_hybrid(i_target, l_hybrid) );
- FAPI_TRY( mss::eff_hybrid_memory_type(i_target, l_hybrid_type) );
- FAPI_TRY( reference_raw_card(i_target, i_spd_data, l_ref_raw_card_rev) );
+ FAPI_TRY(i_data.base_module(l_dimm_type) );
+ FAPI_TRY(i_data.hybrid(l_hybrid));
+ FAPI_TRY(i_data.hybrid_media(l_hybrid_type));
+ FAPI_TRY(i_data.reference_raw_card(l_ref_raw_card_rev));
- FAPI_INF( "Retrieved dimm_type: %d, raw card reference: 0x%lx from SPD",
- l_dimm_type, l_ref_raw_card_rev);
+ FAPI_INF("Retrieved dimm_type: %d, raw card reference: 0x%lx from SPD for %s",
+ l_dimm_type, l_ref_raw_card_rev, spd::c_str(i_target));
switch(l_dimm_type)
{
- case fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM:
+ case RDIMM:
// TODO:RTC178807 - Update how NVDIMMs are handled once more are up and running in the lab
// NVDIMM is currently considered differently than all other rdimm raw cards, due to settings differences
@@ -947,20 +104,20 @@ fapi2::ReturnCode raw_card_factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_targ
{
l_ref_raw_card_rev = mss::rdimm::raw_card_rev::NVDIMM;
FAPI_INF("%s is an NVDIMM, overwrote l_ref_raw_card_rev to be 0x%02x",
- mss::c_str(i_target),
+ mss::spd::c_str(i_target),
l_ref_raw_card_rev);
}
FAPI_TRY( find_raw_card( i_target,
- fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM,
+ RDIMM,
l_ref_raw_card_rev,
mss::rdimm::RAW_CARDS,
o_raw_card) );
break;
- case fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM:
+ case LRDIMM:
FAPI_TRY( find_raw_card( i_target,
- fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM,
+ LRDIMM,
l_ref_raw_card_rev,
mss::lrdimm::RAW_CARDS,
o_raw_card) );
@@ -972,7 +129,7 @@ fapi2::ReturnCode raw_card_factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_targ
.set_DIMM_TYPE(l_dimm_type)
.set_DIMM_TARGET(i_target),
"Recieved invalid dimm type: %d for %s",
- l_dimm_type, mss::c_str(i_target) );
+ l_dimm_type, mss::spd::c_str(i_target) );
break;
}
@@ -981,100 +138,6 @@ fapi_try_exit:
}
///
-/// @brief Object factory to select correct decoder
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_fact_obj shared pointer to the factory object
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Factory dependent on SPD revision & dimm type
-///
-fapi2::ReturnCode factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- std::shared_ptr<decoder>& o_fact_obj)
-{
- if( i_spd_data.empty() )
- {
- // This won't work with no data
- FAPI_ERR( "%s. SPD vector of data is empty! Factory requires valid SPD data.", mss::c_str(i_target) );
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint8_t l_dimm_type = 0;
- uint8_t l_hybrid = 0;
- uint8_t l_hybrid_type = 0;
- uint8_t l_encoding_rev = 0;
- uint8_t l_additions_rev = 0;
- rcw_settings l_raw_card;
-
- // Attribute setting needed by mss::c_str() which is used in
- // the SPD decoder for debugging help
- FAPI_TRY( dimm_type_setter(i_target, i_spd_data, l_dimm_type),
- "%s. Failed to set DIMM type", mss::c_str(i_target) );
- FAPI_TRY( hybrid_setter(i_target, i_spd_data, l_hybrid),
- "%s. Failed to set hybrid", mss::c_str(i_target) );
- FAPI_TRY( hybrid_type_setter(i_target, i_spd_data, l_hybrid_type),
- "%s. Failed to set hybrid_type", mss::c_str(i_target) );
- FAPI_TRY( dram_gen_setter(i_target, i_spd_data),
- "%s. Failed to set DRAM generation", mss::c_str(i_target) );
- FAPI_TRY( raw_card_factory(i_target, i_spd_data, l_raw_card),
- "%s. Failed raw_card_factory()", mss::c_str(i_target) );
-
- // Get revision levels to figure out what SPD version we are
- FAPI_TRY( rev_encoding_level(i_target, i_spd_data, l_encoding_rev),
- "%s. Failed to decode encoding level", mss::c_str(i_target) );
- FAPI_TRY( rev_additions_level(i_target, i_spd_data, l_additions_rev),
- "%s. Failed to decode additons level", mss::c_str(i_target) );
-
- // Get decoder object needed for current dimm type and spd rev
- switch(l_dimm_type)
- {
- // Each dimm type rev is independent
- case fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM:
- FAPI_TRY( rdimm_rev_helper(i_target,
- l_encoding_rev,
- l_additions_rev,
- l_raw_card,
- i_spd_data,
- o_fact_obj),
- "%s. Failed to decode SPD revision for RDIMM, "
- "encoding rev: %d, additions rev: %d",
- mss::c_str(i_target), l_encoding_rev, l_additions_rev );
- break;
-
- // Each dimm type rev is independent
- case fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM:
- FAPI_TRY( lrdimm_rev_helper(i_target,
- l_encoding_rev,
- l_additions_rev,
- l_raw_card,
- i_spd_data,
- o_fact_obj),
- "%s. Failed to decode SPD revision for LRDIMM, "
- "encoding rev: %d, additions rev: %d",
- mss::c_str(i_target), l_encoding_rev, l_additions_rev);
- break;
-
- default:
- FAPI_TRY( mss::check::spd::invalid_factory_sel(i_target,
- l_dimm_type,
- l_encoding_rev,
- l_additions_rev,
- "DIMM Type unsupported!") );
- break;
-
- } // end dimm type
-
- FAPI_INF( "%s: Decoder created for DIMM type: %d, SPD revision %d.%d",
- mss::c_str(i_target),
- l_dimm_type,
- l_encoding_rev,
- l_additions_rev );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Wrapper function for finding the raw card -- helper for testing
/// @param[in] i_target the dimm target
/// @param[in] i_dimm_type
@@ -1100,7 +163,7 @@ fapi2::ReturnCode find_raw_card_helper( const fapi2::Target<TARGET_TYPE_DIMM>& i
FAPI_INF("Unsupported raw cards %s allowed for %s",
i_mrw_supported_rc ? "are" : "are NOT",
- mss::c_str(i_target));
+ mss::spd::c_str(i_target));
FAPI_ASSERT(find_value_from_key( i_map, i_ref_raw_card_rev, o_raw_card),
fapi2::MSS_INVALID_RAW_CARD(fapi2::FAPI2_ERRL_SEV_RECOVERED, l_rc)
@@ -1109,9 +172,9 @@ fapi2::ReturnCode find_raw_card_helper( const fapi2::Target<TARGET_TYPE_DIMM>& i
.set_DIMM_TARGET(i_target)
.set_MCA_TARGET(l_mca),
"Invalid reference raw card received for %s: %d for %s",
- (i_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) ? "RDIMM" : "LRDIMM",
+ (i_dimm_type == RDIMM) ? "RDIMM" : "LRDIMM",
i_ref_raw_card_rev,
- mss::c_str(i_target));
+ mss::spd::c_str(i_target));
return fapi2::FAPI2_RC_SUCCESS;
@@ -1124,7 +187,7 @@ fapi_try_exit:
{
fapi2::logError(l_rc, fapi2::FAPI2_ERRL_SEV_RECOVERED);
l_rc = fapi2::FAPI2_RC_SUCCESS;
- o_raw_card = (i_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) ? rdimm_rc_default : lrdimm_rc_default;
+ o_raw_card = (i_dimm_type == RDIMM) ? rdimm_rc_default : lrdimm_rc_default;
}
return l_rc;
@@ -1151,41 +214,7 @@ fapi2::ReturnCode find_raw_card( const fapi2::Target<TARGET_TYPE_DIMM>& i_target
FAPI_TRY( mrw_allow_unsupported_rcw(l_allow_unsupported_rcw) );
FAPI_TRY( find_raw_card_helper(i_target, i_dimm_type, i_ref_raw_card_rev, l_allow_unsupported_rcw, i_map, o_raw_card),
- "Failed find_raw_card_helper for %s", mss::c_str(i_target) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Creates factory object & SPD data caches
-/// @param[in] i_target the dimm target
-/// @param[out] o_factory_caches vector of factory objects
-/// @param[in] i_pDecoder custom decoder to populate cache (nullptr default)
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note This specialization is suited for creating a cache with custom
-/// SPD data (e.g. testing custom SPD).
-///
-template<>
-fapi2::ReturnCode populate_decoder_caches( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< std::shared_ptr<decoder> >& o_factory_caches,
- const std::shared_ptr<decoder>& i_pDecoder)
-{
- if(i_pDecoder == nullptr)
- {
- // This won't work w/a null parameter
- FAPI_ERR("%s. Received decoder is NULL!", mss::c_str(i_target) );
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- // Custom decoder provided (usually done for testing)
- // Populate custom spd caches maps one dimm at a time
- o_factory_caches.push_back( i_pDecoder );
-
- // Populate some of the DIMM attributes early. This allows the following code to make
- // decisions based on DIMM information. Expressly done after the factory has decided on the SPD version
- FAPI_TRY( master_ranks_per_dimm_setter(i_target, i_pDecoder),
- "%s. Failed master_ranks_per_dimm_setter()", mss::c_str(i_target) );
+ "Failed find_raw_card_helper for %s", mss::spd::c_str(i_target) );
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H
index ab9872ca6..9d8786452 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H
@@ -45,8 +45,8 @@
#include <fapi2_spd_access.H>
// mss lib
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/spd/common/rcw_settings.H>
namespace mss
{
@@ -54,93 +54,6 @@ namespace spd
{
///
-/// @brief Decodes SPD Revision encoding level
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value encoding revision num
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 1 (3~0).
-/// @note Item JC-45-2220.01x
-/// @note Page 14-15
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode rev_encoding_level(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value);
-///
-/// @brief Decodes SPD Revision additions level
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD blob
-/// @param[out] o_value additions revision num
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 1 (bits 7~4).
-/// @note Item JC-45-2220.01x
-/// @note Page 14-15
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode rev_additions_level(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value);
-
-///
-/// @brief Decodes hybrid type (whether or not the DIMM is a hybrid) from SPD
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value hybrid
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 3 (bit 7)
-/// @note Item JC-45-2220.01x
-/// @note Page 17
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode hybrid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value);
-
-///
-/// @brief Decodes hybrid type (hybrid DIMM type) from SPD
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value hybrid module type
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 3 (bits 6~4)
-/// @note Item JC-45-2220.01x
-/// @note Page 17
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode hybrid_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value);
-
-///
-/// @brief Decodes base module type (DIMM type) from SPD
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_value base module type
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 3 (bits 3~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 17
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode base_module_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value);
-///
-/// @brief Decodes DRAM Device Type
-/// @param[in] i_target dimm target
-/// @param[out] o_value dram device type enumeration
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Decodes SPD Byte 2
-/// @note Item JC-45-2220.01x
-/// @note Page 16
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode dram_device_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_value);
-
-///
/// @brief Wrapper function for finding the raw card -- helper for testing
/// @param[in] i_target the dimm target
/// @param[in] i_dimm_type
@@ -179,126 +92,18 @@ fapi2::ReturnCode find_raw_card( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i
rcw_settings& o_raw_card);
///
-/// @brief Decodes reference raw card
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 130 (Bits 7~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @Note Page 4.1.2.12 - 49
-///
-fapi2::ReturnCode reference_raw_card(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- uint8_t& o_output);
-
-///
/// @brief Retrieve current raw card settings
/// based on dimm type and raw card reference rev
/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
+/// @param[in] i_data SPD data
/// @param[out] o_raw_card raw card settings
/// @return FAPI2_RC_SUCCESS if okay
///
fapi2::ReturnCode raw_card_factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
+ const facade& i_data,
rcw_settings& o_raw_card);
-///
-/// @brief Object factory to select correct decoder
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data
-/// @param[out] o_fact_obj shared pointer to the factory object
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note Factory dependent on SPD revision & dimm type
-///
-fapi2::ReturnCode factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- std::shared_ptr<decoder>& o_fact_obj);
-
-
-///
-/// @brief Determines & sets effective config for number of master ranks per dimm
-/// @param[in] i_target DIMM fapi2::Target
-/// @param[in] i_pDecoder shared_ptr to SPD decoder
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-/// @note This is done after the SPD cache is configured so that it can reflect the results of the
-/// factory and we don't need to worry about SPD versions. This is expressly different than the dram and dimm setters
-///
-fapi2::ReturnCode master_ranks_per_dimm_setter(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::shared_ptr<decoder>& i_pDecoder);
-
-///
-/// @brief Creates factory object & SPD data caches
-/// @tparam T fapi2::TargetType, MCA, MCS, MCBIST, PROC_CHIP are possible TargetTypes
-/// @param[in] i_target the fapi2 target to find DIMMs on
-/// @param[out] o_factory_caches vector of factory objects
-/// @param[in] i_pDecoder optional input decoder to insert custom decoder (nullptr default)
-/// @return FAPI2_RC_SUCCESS if okay
-///
-template<fapi2::TargetType T>
-fapi2::ReturnCode populate_decoder_caches(const fapi2::Target<T>& i_target,
- std::vector< std::shared_ptr<decoder> >& o_factory_caches,
- const std::shared_ptr<decoder>& i_pDecoder = nullptr)
-{
- // Input decoder for this version of populating cache would get overriden
- // so I don't bother with it in this specialization
- std::shared_ptr<decoder> l_pDecoder;
-
- for( const auto& l_dimm : find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
- {
- size_t l_size = 0;
- FAPI_TRY( fapi2::getSPD(l_dimm, nullptr, l_size),
- "%s. Failed to retrieve SPD blob size", mss::c_str(i_target) );
-
- {
- // "Container" for SPD data
- std::vector<uint8_t> l_spd(l_size);
-
- // Retrieve SPD data
- FAPI_TRY( fapi2::getSPD(l_dimm, l_spd.data(), l_size),
- "%s. Failed to retrieve SPD data", mss::c_str(i_target) );
-
- // Retrieve factory object instance & populate spd data for that instance
- FAPI_TRY( factory(l_dimm, l_spd, l_pDecoder),
- "%s. Failed SPD factory, could not instantiate decoder object", mss::c_str(i_target) );
-
- // Populate spd caches
- o_factory_caches.push_back( l_pDecoder );
- }
-
- // Populate some of the DIMM attributes early. This allows the following code to make
- // decisions based on DIMM information. Expressly done after the factory has decided on the SPD version
- FAPI_TRY( master_ranks_per_dimm_setter(l_dimm, l_pDecoder),
- "%s. Failed master_ranks_per_dimm_setter()", mss::c_str(i_target) );
-
- }// end dimm
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
}// spd
-
-///
-/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD
-/// @param[in] i_pDecoder the SPD decoder
-/// @param[out] o_value tCKmin value in ps
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode get_tckmin(const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
- uint64_t& o_value);
-
-///
-/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD
-/// @param[in] i_pDecoder SPD decoder
-/// @param[out] o_value tCKmax value in ps
-/// @return FAPI2_RC_SUCCESS iff ok
-///
-fapi2::ReturnCode get_tckmax(const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
- uint64_t& o_value);
-
}// mss
#endif //_MSS_SPD_FACTORY_H_
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H
index 260197a66..57523f5bd 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,6 +42,27 @@ namespace mss
{
///
+/// @brief Endian swapping
+/// @tparam T input type
+/// @param[in,out] io_input integral input
+/// @note https://stackoverflow.com/questions/105252/how-do-i-convert-between-big-endian-and-little-endian-values-in-c
+///
+template < typename T >
+void endian_swap(T& io_input)
+{
+ constexpr size_t MIN_BYTES = 2;
+ static_assert(sizeof(T) >= MIN_BYTES, "Byte swapping requires at least 2 bytes of data");
+
+ uint8_t* l_varArray = reinterpret_cast<uint8_t*>(&io_input);
+
+ for(size_t i = 0; i < sizeof(io_input) / 2; i++)
+ {
+ const size_t BYTE_SWAP_INDEX = sizeof(io_input) - 1 - i;
+ std::swap(l_varArray[BYTE_SWAP_INDEX], l_varArray[i]);
+ }
+}
+
+///
/// @brief Swap two bits in a buffer
/// @tparam TB the bit in the buffer to move to SB
/// @tparam SB the bit in the buffer to move to TB
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
index 17ebcba7e..57b40397b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
@@ -34,7 +34,6 @@
// *HWP Consumed by: FSP:HB
#include <vector>
-#include <mss.H>
#include <fapi2.H>
#include <p9_mss_bulk_pwr_throttles.H>
#include <generic/memory/lib/utils/find.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
index 711eca0ad..c05c51992 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
@@ -43,7 +43,6 @@
// mss lib
#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <lib/spd/spd_factory.H>
#include <generic/memory/lib/utils/pos.H>
#include <lib/utils/checker.H>
#include <generic/memory/lib/utils/find.H>
@@ -67,12 +66,8 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
return fapi2::FAPI2_RC_SUCCESS;
}
- fapi2::ReturnCode l_rc;
- std::vector< std::shared_ptr<mss::spd::decoder> > l_factory_caches;
-
- // Caches
- FAPI_TRY( mss::spd::populate_decoder_caches(i_target, l_factory_caches),
- "Failed populate_decoder_caches for %s", mss::c_str(i_target));
+ std::vector< mss::spd::facade > l_spd_facades;
+ FAPI_TRY( get_spd_decoder_list(i_target, l_spd_facades) );
// Need to check dead load before we get the VPD.
// MR and MT VPD depends on DIMM ranks and freaks out if it receives 0 ranks from DIMM 0 and 1 or more ranks for DIMM 1
@@ -93,13 +88,13 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
"Unable to decode VPD for %s", mss::c_str(i_target) );
}
- for( const auto& l_cache : l_factory_caches )
+ for( const auto& l_spd : l_spd_facades )
{
- const auto l_dimm = l_cache->iv_target;
+ const auto l_dimm = l_spd.get_dimm_target();
std::shared_ptr<mss::eff_dimm> l_eff_dimm;
- FAPI_TRY( mss::eff_dimm::eff_dimm_factory( l_cache, l_eff_dimm),
- "Failed eff_dimm_factory for %s", mss::c_str(l_dimm));
+ FAPI_TRY( mss::eff_dimm::factory( l_spd, l_eff_dimm),
+ "Failed factory for %s", mss::c_str(l_dimm));
FAPI_INF("Running eff_config on %s", mss::c_str(l_dimm) );
@@ -225,6 +220,8 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
"Failed odt_input_buffer for %s", mss::c_str(l_dimm) );
FAPI_TRY( l_eff_dimm->post_package_repair(),
"Failed post_package_repair for %s", mss::c_str(l_dimm) );
+ FAPI_TRY( l_eff_dimm->soft_post_package_repair(),
+ "Failed soft_post_package_repair for %s", mss::c_str(l_dimm) );
FAPI_TRY( l_eff_dimm->read_preamble_train(),
"Failed read_preamble_train for %s", mss::c_str(l_dimm) );
FAPI_TRY( l_eff_dimm->read_preamble(),
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
index c767e87b7..e01918cd7 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C
@@ -45,8 +45,7 @@
#include <fapi2.H>
// mss lib
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <lib/spd/spd_factory.H>
+#include <generic/memory/lib/spd/spd_facade.H>
#include <lib/freq/cas_latency.H>
#include <lib/freq/sync.H>
#include <lib/workarounds/freq_workarounds.H>
@@ -55,6 +54,7 @@
#include <generic/memory/lib/utils/count_dimm.H>
#include <generic/memory/lib/utils/index.H>
#include <lib/shared/mss_const.H>
+#include <lib/eff_config/attr_setters.H>
using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_MCA;
@@ -79,7 +79,7 @@ extern "C"
// So for now, iterate over all the MCBIST. This isn't great as we do this work
// twice for every MC. However, attribute access is cheap so this will suffice for
// the time being.
- const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
+ const auto l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target);
std::vector< std::vector<uint64_t> > l_min_dimm_freq(mss::MCS_PER_MC, std::vector<uint64_t> (mss::PORTS_PER_MCS, 0) );
std::vector<uint32_t> l_supported_freqs;
@@ -93,6 +93,21 @@ extern "C"
return FAPI2_RC_SUCCESS;
}
+ // We will first set pre-eff_config attributes
+ for( const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(l_mcbist))
+ {
+ std::vector<uint8_t> l_raw_spd;
+ FAPI_TRY(mss::spd::get_raw_data(d, l_raw_spd));
+
+ {
+ fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS);
+ mss::spd::facade l_spd_decoder(d, l_raw_spd, l_rc);
+
+ FAPI_TRY(l_rc, "Failed to initialize SPD facade for %s", mss::spd::c_str(d));
+ FAPI_TRY(mss::set_pre_init_attrs(d, l_spd_decoder));
+ }
+ }
+
// Get supported freqs for this MCBIST
FAPI_TRY( mss::supported_freqs(l_mcbist, l_supported_freqs) );
@@ -105,15 +120,14 @@ extern "C"
for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs) )
{
const auto l_mca_index = mss::index(l_mca);
- std::vector< std::shared_ptr<mss::spd::decoder> > l_factory_caches;
fapi2::ReturnCode l_rc;
// Get cached decoder
- FAPI_TRY( mss::spd::populate_decoder_caches(l_mca, l_factory_caches),
- "%s. Failed to populate decoder cache", mss::c_str(l_mca) );
+ std::vector< mss::spd::facade > l_spd_facades;
+ FAPI_TRY( get_spd_decoder_list(l_mca, l_spd_facades) );
// Instantiation of class that calculates CL algorithm
- mss::cas_latency l_cas_latency( l_mca, l_factory_caches, l_supported_freqs, l_rc );
+ mss::cas_latency l_cas_latency( l_mca, l_spd_facades, l_supported_freqs, l_rc );
FAPI_TRY( l_rc, "%s. Failed to initialize cas_latency ctor", mss::c_str(l_mca) );
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
index d8bf63b9c..487824835 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
@@ -47,7 +47,6 @@
#include <generic/memory/lib/utils/index.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/utils/conversions.H>
-#include <lib/power_thermal/throttle.H>
#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C
index 04a6c0b34..0c8f9d98a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,8 +42,7 @@
#include <fapi2.H>
// mss lib
-#include <lib/spd/spd_factory.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
+#include <generic/memory/lib/spd/spd_facade.H>
#include <lib/eff_config/attr_setters.H>
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/pos.H>
@@ -72,19 +71,19 @@ extern "C"
FAPI_INF("Populating decoder cache for %s", mss::c_str(l_mcs));
//Factory cache is per MCS
- std::vector< std::shared_ptr<mss::spd::decoder> > l_factory_caches;
- FAPI_TRY( mss::spd::populate_decoder_caches(l_mcs, l_factory_caches),
- "Failed to populate decoder cache for %s", l_mcs);
+ std::vector< mss::spd::facade > l_spd_facades;
+ FAPI_TRY( get_spd_decoder_list(l_mcs, l_spd_facades) );
// Get dimms for each MCS
- for ( const auto& l_cache : l_factory_caches )
+ for ( const auto& l_cache : l_spd_facades )
{
+ const auto l_dimm = l_cache.get_dimm_target();
uint8_t l_dimm_nominal = 0;
uint8_t l_dimm_endurant = 0;
// Read nominal and endurant bits from SPD, 0 = 1.2V is not operable and endurant, 1 = 1.2 is valid
- FAPI_TRY( l_cache->operable_nominal_voltage(l_dimm_nominal) );
- FAPI_TRY( l_cache->endurant_nominal_voltage(l_dimm_endurant) );
+ FAPI_TRY( l_cache.operable_nominal_voltage(l_dimm_nominal) );
+ FAPI_TRY( l_cache.endurant_nominal_voltage(l_dimm_endurant) );
//Check to make sure 1.2 V is both operable and endurant, fail if it is not
FAPI_ASSERT ( (l_dimm_nominal == mss::spd::OPERABLE) && (l_dimm_endurant == mss::spd::ENDURANT),
@@ -93,10 +92,10 @@ extern "C"
set_ACTUAL_ENDURANT(l_dimm_endurant).
set_EXPECTED_OPERABLE(mss::spd::OPERABLE).
set_EXPECTED_ENDURANT(mss::spd::ENDURANT).
- set_DIMM_TARGET(l_cache->iv_target),
+ set_DIMM_TARGET(l_dimm),
"%s: DIMM is not operable (%d) expected (%d)"
" and/or endurant (%d) expected (%d) at 1.2V",
- mss::c_str(l_cache->iv_target),
+ mss::c_str(l_dimm),
l_dimm_nominal,
mss::spd::OPERABLE,
l_dimm_endurant,
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_general_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_general_errors.xml
index 2e57876e7..4f63f6bc1 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_general_errors.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_general_errors.xml
@@ -71,30 +71,6 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_DIMM_TYPE</rc>
- <description>
- An invalid/unsupported DIMM type was received. This is possibly due
- to SPD decoding errors or incorrect setting of ATTR_EFF_DIMM_TYPE attribute.
- </description>
- <ffdc>DIMM_TYPE</ffdc>
- <callout>
- <procedure>MEMORY_PLUGGING_ERROR</procedure>
- <priority>HIGH</priority>
- </callout>
- <callout>
- <target>DIMM_TARGET</target>
- <priority>MEDIUM</priority>
- </callout>
- <deconfigure>
- <target>DIMM_TARGET</target>
- </deconfigure>
- <callout>
- <procedure>CODE</procedure>
- <priority>LOW</priority>
- </callout>
- </hwpError>
-
- <hwpError>
<rc>RC_MSS_INVALID_RTT_WR_ENCODING</rc>
<description>
An invalid/unsupported RTT_WR encoding was received
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml
index a67cfa73f..e37308594 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_spd_decode.xml
@@ -37,6 +37,66 @@
<hwpErrors>
<hwpError>
+ <rc>RC_MSS_INVALID_SPD_RESERVED_BITS</rc>
+ <description>
+ Invalid SPD reserved bits received.
+ This could be code problem (decoding) or bad SPD.
+ </description>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DIMM_SPEED</rc>
+ <description>
+ Invalid DIMM speed received. Possibly a programming error.
+ </description>
+ <ffdc>DIMM_SPEED</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DB_MDQ_DRIVE_STRENGTH</rc>
+ <description>
+ Bad SPD data for bytes 145 - 147.
+ Reserved settings for data buffer MDQ drive strength received.
+ This could be code problem (decoding) or bad SPD.
+ </description>
+ <ffdc>DATA_RATE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_BAD_SPD</rc>
<description>
Bad SPD data received.
@@ -59,15 +119,62 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_INVALID_DIMM_REV_COMBO</rc>
+ <rc>RC_MSS_INVALID_DRAM_GEN</rc>
+ <description>
+ Received a DRAM gen unsupported by the SPD decoder factory
+ </description>
+ <ffdc>DRAM_GEN</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>LOW</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_HYBRID_MODULE</rc>
<description>
- Received a dimm type (e.g. RDIMM, LRDIMM) and SPD revision
- (e.g. 1.0, 1.1) combination unsupported by the spd_decoder
- object "factory"
+ Received an invalid or unsupported hybrid media (SPD byte 3, bits [6:4])
+ for a specified hybrid modue (SPD byte 3, bit [7])
+ </description>
+ <ffdc>HYBRID</ffdc>
+ <ffdc>HYBRID_MEDIA</ffdc>
+ <ffdc>FUNCTION</ffdc>
+ <callout>
+ <procedure>MEMORY_PLUGGING_ERROR</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>LOW</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DIMM_TYPE</rc>
+ <description>
+ Received a DIMM type unsupported by the SPD decoder factory
</description>
<ffdc>DIMM_TYPE</ffdc>
- <ffdc>ENCODING_REV</ffdc>
- <ffdc>ADDITIONS_REV</ffdc>
+ <ffdc>FUNCTION</ffdc>
<callout>
<procedure>MEMORY_PLUGGING_ERROR</procedure>
<priority>HIGH</priority>
@@ -108,4 +215,90 @@
<target>MCA_TARGET</target>
</deconfigure>
</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_FAILED_SPD_REVISION_FALLBACK</rc>
+ <description>
+ Unable to fall back SPD decoder to the highest decoded
+ revision. Most likely a programming error.
+ </description>
+ <ffdc>FAILED_REVISION</ffdc>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_SPD_TIMING_FAIL</rc>
+ <description>
+ Timing SPD parameter failed to meet JEDEC SPD timing
+ bounds. FUNCTION_CODE ffdc field encodes which timing param.
+ </description>
+ <ffdc>FAILED_REVISION</ffdc>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_SPD_PARAMETER_RECEIVED</rc>
+ <description>
+ Unable to fall back SPD decoder to the highest decoded
+ revision. Most likely a programming error.
+ </description>
+ <ffdc>SPD_PARAM</ffdc>
+ <ffdc>FUNCTION_CODE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_SPD_REV_ENCODING_LEVEL_NOT_SUPPORTED</rc>
+ <description>
+ SPD revision on byte 1 (bits 7~4) has a unsupported encoding level
+ that is greater than the largest decoded SPD decoder. There is
+ no backward compatible revision to fallback to. This could be
+ bad SPD or a programming error.
+ </description>
+ <ffdc>ENCODING_LEVEL</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <callout>
+ <target>TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+ </hwpError>
+
</hwpErrors>
diff --git a/src/import/generic/memory/lib/data_engine/pre_data_init.H b/src/import/generic/memory/lib/data_engine/pre_data_init.H
index 1f20e6b75..aa061a530 100644
--- a/src/import/generic/memory/lib/data_engine/pre_data_init.H
+++ b/src/import/generic/memory/lib/data_engine/pre_data_init.H
@@ -22,3 +22,499 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file pre_data_init.H
+/// @brief Class to set preliminary eff_config attributes
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: CI
+
+#ifndef _MSS_PRE_DATA_INIT_H_
+#define _MSS_PRE_DATA_INIT_H_
+
+#include <cstring>
+#include <fapi2.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+
+///
+/// @brief enum list of preliminary data fields
+///
+enum pre_data_init_fields
+{
+ DIMM_TYPE,
+ DRAM_GEN,
+ HYBRID,
+ HYBRID_MEDIA,
+ MRANKS,
+ DIMM_RANKS_CNFG,
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class preDataInitTraits
+/// @tparam T proc_type (e.g. Nimbus, Axone, etc.)
+/// @tparam TT pre_data_init_fields (e.g. DIMM_TYPE, MRANK, etc.)
+///
+template< proc_type T, pre_data_init_fields TT >
+class preDataInitTraits;
+
+///
+/// @brief Traits for pre_data_engine
+/// @class preDataInitTraits
+/// @note NIMBUS, DIMM_TYPE specialization
+///
+template<>
+class preDataInitTraits<NIMBUS, DIMM_TYPE>
+{
+ public:
+ using attr_type = fapi2::ATTR_EFF_DIMM_TYPE_Type;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_DIMM_TYPE_TargetType;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the MCS target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_DIMM_TYPE, i_target, o_setting) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the MCS target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ const attr_type& i_setting)
+ {
+ attr_type l_data = {};
+ memcpy(l_data, i_setting, sizeof(l_data));
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_TYPE, i_target, l_data) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class preDataInitTraits
+/// @note NIMBUS, DRAM_GEN specialization
+///
+template<>
+class preDataInitTraits<NIMBUS, DRAM_GEN>
+{
+ public:
+ using attr_type = fapi2::ATTR_EFF_DRAM_GEN_Type;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_DRAM_GEN_TargetType;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the MCS target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_DRAM_GEN, i_target, o_setting) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the MCS target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ const attr_type& i_setting)
+ {
+ attr_type l_data = {};
+ memcpy(l_data, i_setting, sizeof(l_data));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_GEN, i_target, l_data) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class preDataInitTraits
+/// @note NIMBUS, HYBRID specialization
+///
+template<>
+class preDataInitTraits<NIMBUS, HYBRID>
+{
+ public:
+ using attr_type = fapi2::ATTR_EFF_HYBRID_Type;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_HYBRID_TargetType;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the MCS target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_HYBRID, i_target, o_setting) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the MCS target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ const attr_type& i_setting)
+ {
+ attr_type l_data = {};
+ memcpy(l_data, i_setting, sizeof(l_data));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID, i_target, l_data) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class preDataInitTraits
+/// @note NIMBUS, HYBRID_MEDIA specialization
+///
+template<>
+class preDataInitTraits<NIMBUS, HYBRID_MEDIA>
+{
+ public:
+ using attr_type = fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE_Type;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE_TargetType;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the MCS target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, i_target, o_setting) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the MCS target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ const attr_type& i_setting)
+ {
+ attr_type l_data = {};
+ memcpy(l_data, i_setting, sizeof(l_data));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, i_target, l_data) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class preDataInitTraits
+/// @note NIMBUS, MRANKS specialization
+///
+template<>
+class preDataInitTraits<NIMBUS, MRANKS>
+{
+ public:
+ using attr_type = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_Type;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_TargetType;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the MCS target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, i_target, o_setting) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the MCS target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ const attr_type& i_setting)
+ {
+ attr_type l_data = {};
+ memcpy(l_data, i_setting, sizeof(l_data));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, i_target, l_data) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Traits for pre_data_engine
+/// @class preDataInitTraits
+/// @note NIMBUS, DIMM_RANKS_CNFG specialization
+///
+template<>
+class preDataInitTraits<NIMBUS, DIMM_RANKS_CNFG>
+{
+ public:
+ using attr_type = fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED_Type;
+ static const fapi2::TargetType TARGET_TYPE = fapi2::ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_TargetType;
+
+ ///
+ /// @brief attribute getter
+ /// @param[in] i_target the MCS target
+ /// @param[out] o_setting array to populate
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode get_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ attr_type& o_setting)
+ {
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, o_setting) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief attribute setter
+ /// @param[in] i_target the MCS target
+ /// @param[in] i_setting array to set
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode set_attr(const fapi2::Target<TARGET_TYPE>& i_target,
+ const attr_type& i_setting)
+ {
+ attr_type l_data = {};
+ memcpy(l_data, i_setting, sizeof(l_data));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_RANKS_CONFIGED, i_target, l_data) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Helper function for attribute setting
+/// @tparam T processor type (e.g. NIMBUS, AXONE, etc.)
+/// defaulted to NIMBUS
+/// @tparam X size of 1st array index
+/// @tparam Y size of 2nd array index
+/// @tparam TT FAPI2 target type
+/// @tparam IT Input/outpu data type
+/// @param[in] i_target the MCS target
+/// @param[in] i_setting array to set
+/// @param[out] o_data attribute data structure to set
+/// @warning This is Nimbus specific
+///
+template < size_t X, size_t Y, typename IT >
+void data_setter( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const IT i_setting,
+ IT (&o_data)[X][Y])
+{
+ const size_t l_port_index = mss::index( find_target<fapi2::TARGET_TYPE_MCA>(i_target) );
+ const size_t l_dimm_index = mss::index(i_target);
+
+ o_data[l_port_index][l_dimm_index] = i_setting;
+}
+
+///
+/// @brief Mapping boilerplate check
+/// @tparam T FAPI2 target type
+/// @tparam IT map key type
+/// @tparam OT map value type
+/// @param[in] i_map SPD to attribute data mapping
+/// @param[in] i_ffdc_code FFDC function code
+/// @param[in] i_key Key to query map
+/// @param[out] o_output value from key
+///
+template< fapi2::TargetType T, typename IT, typename OT >
+fapi2::ReturnCode lookup_table_check(const fapi2::Target<T>& i_target,
+ const std::vector<std::pair<IT, OT>>& i_map,
+ const generic_ffdc_codes i_ffdc_code,
+ const IT i_key,
+ OT& o_output)
+{
+ const bool l_is_val_found = mss::find_value_from_key(i_map, i_key, o_output);
+
+ FAPI_ASSERT( l_is_val_found,
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(i_key)
+ .set_DATA(o_output)
+ .set_FUNCTION(i_ffdc_code)
+ .set_TARGET(i_target),
+ "Failed to find a mapped value for %d on %s",
+ i_key,
+ spd::c_str(i_target) );
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets preliminary data fields
+/// @tparam P processor type (e.g. NIMBUS, AXONE, etc.)
+/// @tparam F pre_data_init_fields
+/// @tparam T FAPI2 target type
+/// @tparam IT Input data type
+/// @tparam TT defaulted to preDataInitTraits<T>
+/// @param[in] i_setting value we want to set attr with
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< proc_type P,
+ pre_data_init_fields F,
+ fapi2::TargetType T,
+ typename IT,
+ typename TT = preDataInitTraits<P, F>
+ >
+fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target, const IT i_setting)
+{
+ const auto l_target = mss::find_target<TT::TARGET_TYPE>(i_target);
+ typename TT::attr_type l_attr_list = {};
+ IT l_mapping_value = i_setting;
+
+ FAPI_TRY( TT::get_attr(l_target, l_attr_list) );
+
+ // Indexing isn't very general
+ data_setter(i_target, l_mapping_value, l_attr_list);
+
+ FAPI_TRY( TT::set_attr(l_target, l_attr_list) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Data structure to set pre-effective config data
+/// @class pre_data_engine
+/// @tparam T supported processor type (e.g. Nimbus, Axone, etc.)
+///
+template< proc_type T >
+class pre_data_engine;
+
+///
+/// @brief Data structure to set pre-effective config data
+/// @class pre_data_engine
+/// @note NIMBUS specialization
+///
+template< >
+class pre_data_engine< NIMBUS >
+{
+ private:
+
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_dimm;
+ uint8_t iv_master_ranks;
+ spd::facade iv_spd_data;
+ size_t iv_port_index;
+ size_t iv_dimm_index;
+
+ public:
+
+ static const std::vector<std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > BASE_MODULE_TYPE_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > DRAM_GEN_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_MAP;
+ static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_MEMORY_TYPE_MAP;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_spd_data SPD decoder
+ /// @param[out] o_rc ReturnCode for failure to init object
+ ///
+ pre_data_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const spd::facade& i_spd_data,
+ fapi2::ReturnCode& o_rc);
+
+ ///
+ /// @brief default dtor
+ ///
+ ~pre_data_engine() = default;
+
+ ///
+ /// @brief Set ATTR_EFF_DIMM_TYPE
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode set_dimm_type();
+
+ ///
+ /// @brief Set ATTR_EFF_DRAM_GEN
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode set_dram_gen();
+
+ ///
+ /// @brief Set ATTR_EFF_HYBRID
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode set_hybrid();
+
+ ///
+ /// @brief Set ATTR_EFF_HYBRID_MEMORY_TYPE
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode set_hybrid_media();
+
+ ///
+ /// @brief Set ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
+ fapi2::ReturnCode set_master_ranks();
+
+ ///
+ /// @brief Sets ATTR_EFF_DIMM_RANKS_CONFIGED
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode set_dimm_ranks_configured();
+};
+
+}//mss
+
+#endif
diff --git a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H
index e7fee6e6d..422d95443 100644
--- a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H
+++ b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H
@@ -45,17 +45,55 @@
#include <fapi2.H>
// mss lib
+#include <generic/memory/lib/spd/spd_decoder_def.H>
#include <generic/memory/lib/spd/common/dimm_module_decoder.H>
#include <generic/memory/lib/spd/common/rcw_settings.H>
-#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
-#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H>
-#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/spd/common/spd_decoder_base.H>
#include <generic/memory/lib/spd/spd_checker.H>
namespace mss
{
+namespace spd
+{
+
+///
+/// @brief sdram package types. Follows encodings in SPD
+///
+enum sdram_package_type : uint8_t
+{
+ // Package Type
+ MONOLITHIC = 0, ///< Monolithic DRAM device
+ NON_MONOLITHIC = 1, ///< NonMonolithic DRAM device (3DS, Dual/Quad Die, etc)
+
+ // Signal loading
+ UNSPECIFIED = MONOLITHIC, ///< Not specified
+ MULTI_LOAD_STACK = 1, ///< Multi laod stack
+ SINGLE_LOAD_STACK = 2, ///< Single load stack (3DS)
+};
+
+///
+/// @brief module type DDR4 encoding
+///
+enum module_type
+{
+ NOT_HYBRID = 0,
+ HYBRID = 1,
+ NVDIMM_HYBRID = 1
+};
+
+///
+/// @brief enum for voltage information. Encoding comes from SPD
+///
+enum nominal_voltage : uint8_t
+{
+ NOT_OPERABLE = 0, ///< Not operable at 1.2V
+ OPERABLE = 1, ///< Operable at 1.2V
+
+ NOT_ENDURANT = 0, ///< Not endurant at 1.2V
+ ENDURANT = 1 ///< Endurant at 1.2 V
+};
+
///
/// @brief Connector to SDRAM Bit Mapping field positions
/// @note Bytes 60 - 77 . Mapping to Package rank map and
@@ -117,11 +155,11 @@ static fapi2::ReturnCode nibble_map_helper( const fapi2::Target<fapi2::TARGET_TY
const bool VALID_LOWER_NIBBLE = (i_bit_order >= LOW_BIT_ORDER_MIN) && (i_bit_order <= LOW_BIT_ORDER_MAX);
const bool VALID_UPPER_NIBBLE = (i_bit_order >= UP_BIT_ORDER_MIN) && (i_bit_order <= UP_BIT_ORDER_MAX);
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(i_target,
- (VALID_LOWER_NIBBLE || VALID_UPPER_NIBBLE),
- i_byte,
- i_bit_order,
- "Failed check on the NIBBLE_MAP field") );
+ FAPI_TRY(check::fail_for_invalid_value(i_target,
+ (VALID_LOWER_NIBBLE || VALID_UPPER_NIBBLE),
+ i_byte,
+ i_bit_order,
+ "Failed check on the NIBBLE_MAP field") );
fapi_try_exit:
return fapi2::current_err;
}
@@ -139,11 +177,11 @@ static fapi2::ReturnCode package_rank_map_helper( const fapi2::Target<fapi2::TAR
{
// Taken from the SPD JEDEC spec, only valid encoding, the rest are reserved
constexpr uint64_t VALID_VALUE = 0;
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(i_target,
- (i_pkg_rank_map == VALID_VALUE),
- i_byte,
- i_pkg_rank_map,
- "Failed check on Package Rank Map") );
+ FAPI_TRY(check::fail_for_invalid_value(i_target,
+ (i_pkg_rank_map == VALID_VALUE),
+ i_byte,
+ i_pkg_rank_map,
+ "Failed check on Package Rank Map") );
fapi_try_exit:
return fapi2::current_err;
}
@@ -374,1353 +412,1453 @@ class connectorTraits<CB0_7, PKG_RANK_MAP>
}
};
-namespace spd
-{
-
-///
-/// @brief sdram package types. Follows encodings in SPD
-///
-enum sdram_package_type : uint8_t
-{
- // Package Type
- MONOLITHIC = 0, ///< Monolithic DRAM device
- NON_MONOLITHIC = 1, ///< Non-Monolithic DRAM device (3DS, Dual/Quad Die, etc)
-
- // Signal loading
- UNSPECIFIED = MONOLITHIC, ///< Not specified
- MULTI_LOAD_STACK = 1, ///< Multi laod stack
- SINGLE_LOAD_STACK = 2, ///< Single load stack (3DS)
-};
-
-///
-/// @brief enum for voltage information. Encoding comes from SPD
-///
-enum nominal_voltage : uint8_t
-{
- NOT_OPERABLE = 0, ///< Not operable at 1.2V
- OPERABLE = 1, ///< Operable at 1.2V
-
- NOT_ENDURANT = 0, ///< Not endurant at 1.2V
- ENDURANT = 1 ///< Endurant at 1.2 V
-};
-
-namespace ddr4
-{
-
///
/// @class decoder
+/// @tparam R SPD revision - partial specialization
/// @brief Base SPD DRAM decoder
///
-class decoder_v1_0 : public decoder
+template < rev R >
+class decoder<DDR4, BASE_CNFG, R> : public base_cnfg_decoder
{
- protected:
- enum
- {
- // Byte 0
- BYTES_USED_START = 4,
- BYTES_USED_LEN = 4,
-
- BYTES_TOTAL_START = 1,
- BYTES_TOTAL_LEN = 3,
-
- // Byte 1 - see factory byte enum
- // Byte 2 - Entire byte used
- // Byte 3 - used in the SPD factory
-
- // Byte 4
- SDRAM_CAPACITY_START = 4,
- SDRAM_CAPACITY_LEN = 4,
-
- SDRAM_BANKS_START = 2,
- SDRAM_BANKS_LEN = 2,
-
- BANK_GROUP_START = 0,
- BANK_GROUP_LEN = 2,
-
- // Byte 5
- COL_ADDRESS_START = 5,
- COL_ADDRESS_LEN = 3,
-
- ROW_ADDRESS_START = 2,
- ROW_ADDRESS_LEN = 3,
-
- // Byte 6
- PRIM_SIGNAL_LOAD_START = 6,
- PRIM_SIGNAL_LOAD_LEN = 2,
-
- PRIM_DIE_COUNT_START = 1,
- PRIM_DIE_COUNT_LEN = 3,
-
- PRIM_PACKAGE_TYPE_START = 0,
- PRIM_PACKAGE_TYPE_LEN = 1,
-
- // Byte 7
- MAC_START = 4,
- MAC_LEN = 4,
-
- TMAW_START = 2,
- TMAW_LEN = 2,
-
- // Byte 8 reserved
-
- // Byte 9
- SOFT_PPR_START = 2,
- SOFT_PPR_LEN = 1,
-
- PPR_START = 0,
- PPR_LEN = 2,
-
- // Byte 10
- SEC_SIGNAL_LOAD_START = 5,
- SEC_SIGNAL_LOAD_LEN = 2,
-
- DENSITY_RATIO_START = 4,
- DENSITY_RATIO_LEN = 2,
-
- SEC_DIE_COUNT_START = 1,
- SEC_DIE_COUNT_LEN = 3,
-
- SEC_PACKAGE_TYPE_START = 0,
- SEC_PACKAGE_TYPE_LEN = 1,
-
- // Byte 11
- OPERABLE_START = 7,
- OPERABLE_LEN = 1,
-
- ENDURANT_START = 6,
- ENDURANT_LEN = 1,
-
- NOM_VOLT_START = 0,
- NOM_VOLT_LEN = 6,
-
- // Byte 12
- SDRAM_WIDTH_START = 5,
- SDRAM_WIDTH_LEN = 3,
-
- PACKAGE_RANKS_START = 2,
- PACKAGE_RANKS_LEN = 3,
-
- RANK_MIX_START = 1,
- RANK_MIX_LEN = 1,
-
- // Byte 13
- BUS_WIDTH_START = 5,
- BUS_WIDTH_LEN = 3,
+ private:
- BUS_EXT_WIDTH_START = 3,
- BUS_EXT_WIDTH_LEN = 2,
+ using fields_t = fields<DDR4, BASE_CNFG>;
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ std::vector<uint8_t> iv_data;
- // Byte 14
- THERM_SENSOR_RESERV_START = 1,
- THERM_SENSOR_RESERV_LEN = 7,
+ ///
+ /// @brief SPD byte field threshold check
+ /// @param[out] o_value list of connector_field values from SPD
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ template< connector_bits T, connector_field OT, typename TT = connectorTraits<T, OT> >
+ fapi2::ReturnCode sdram_connector_helper( std::vector<uint8_t>& o_value ) const
+ {
+ for( size_t byte = TT::START; byte <= TT::END; ++byte )
+ {
+ uint8_t l_field = 0;
- THERM_SENSOR_START = 0,
- THERM_SENSOR_LEN = 1,
+ fapi2::buffer<uint8_t> l_buffer(iv_data[byte]);
+ l_buffer.extractToRight<TT::EXTRACT_START, TT::EXTRACT_LEN>(l_field);
- // Byte 15
- EXT_MOD_TYPE_START = 5,
- EXT_MOD_TYPE_LEN = 3,
+ FAPI_DBG("%s SPD byte %d, data: %d, field value: %d, starting bit: %d, bit length: %d",
+ spd::c_str(iv_target), byte, iv_data[byte], l_field, TT::EXTRACT_START, TT::EXTRACT_LEN);
- // Byte 16 - reserved
+ FAPI_TRY( TT::fail_check(iv_target, byte, l_field) );
- // Byte 17
- FINE_TIMEBASE_START = 6,
- FINE_TIMEBASE_LEN = 2,
+ o_value.push_back(l_field);
+ }
- MED_TIMEBASE_START = 4,
- MED_TIMEBASE_LEN = 2,
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
- // Byte 18 - Entire byte used
- // Byte 19 - Entire byte used
+ ///
+ /// @class proxy
+ /// @brief Nested class to help specialize certain decoder methods
+ /// @tparam U SPD revision
+ /// @tparam B dummy var to faciliate partial specialization - defaulted to true
+ /// @note explicit specialization of a class isn't allowed on the HB compiler.
+ /// This is a helper class to workaround specialization for just a few methods
+ /// instead of having the explicitly specialize the entire class itself.
+ /// Since nested classes also can't be explicitly specialized...we use a bool
+ /// template param to facilitate partial specialzation of the nested helper class.
+ ///
+ template< rev U, bool B = true >
+ struct proxy
+ {
+ ///
+ /// @brief Decodes Minimum Write Recovery Time
+ /// @param[in] i_target dimm target
+ /// @param[in] i_data SPD data vector
+ /// @param[out] o_value tWRmin in MTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode min_twr( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_data,
+ int64_t& o_value )
+ {
+ uint8_t l_twrmin_msn = 0;
+ uint8_t l_twrmin_lsb = 0;
+
+ FAPI_TRY( (mss::spd::reader<fields_t::TWRMIN_MSN, U>(i_target, i_data, l_twrmin_msn)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TWRMIN_LSB, U>(i_target, i_data, l_twrmin_lsb)) );
+
+ {
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_twrmin_msn, l_twrmin_lsb);
+
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWRMIN));
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Minimum Write Recovery Time (tWRmin) in MTB units: %d",
+ spd::c_str(i_target),
+ o_value);
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
- // Byte 20-23
- CAS_BYTE_1_START = 56,
- CAS_BYTE_1_LEN = 8,
- CAS_BYTE_2_START = 48,
- CAS_BYTE_2_LEN = 8,
- CAS_BYTE_3_START = 40,
- CAS_BYTE_3_LEN = 8,
- CAS_BYTE_4_START = 32,
- CAS_BYTE_4_LEN = 8,
+ ///
+ /// @brief Decodes Minimum Write to Read Time - Same Bank Group
+ /// @param[in] i_target dimm target
+ /// @param[in] i_data SPD data vector
+ /// @param[out] o_value tWRT_Lmin in MTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode min_twtr_l( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_data,
+ int64_t& o_value )
+ {
+ uint8_t l_twtr_lmin_msn = 0;
+ uint8_t l_twtr_lmin_lsb = 0;
- // Byte 24 - Entire byte used
- // Byte 25 - Entire byte used
- // Byte 26 - Entire byte used
+ FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_L_MSN, U>(i_target, i_data, l_twtr_lmin_msn)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_L_LSB, U>(i_target, i_data, l_twtr_lmin_lsb)) );
- // Byte 27
- TRASMIN_MSN_START = 4, // MSN = most significant nibble
- TRASMIN_MSN_LEN = 4,
+ {
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_twtr_lmin_msn, l_twtr_lmin_lsb);
- TRCMIN_MSN_START = 0, // MSN = most significant nibble
- TRCMIN_MSN_LEN = 4,
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWTR_L_MIN));
+ o_value = l_buffer;
- // Byte 28
- TRASMIN_LSB_START = 0, // LSB = least significant byte
- TRASMIN_LSB_LEN = 8,
+ FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Lmin) in MTB units: %d",
+ spd::c_str(i_target),
+ o_value);
+ }
- // Byte 29
- TRCMIN_LSB_START = 0, // LSB = least significant byte
- TRCMIN_LSB_LEN = 8,
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
- // Byte 30
- TRFC1MIN_LSB_START = 0,
- TRFC1MIN_LSB_LEN = 8,
+ ///
+ /// @brief Decodes Minimum Write to Read Time - Different Bank Group
+ /// @param[in] i_target dimm target
+ /// @param[in] i_data SPD data vector
+ /// @param[out] o_value tWRT_Smin in MTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode min_twtr_s( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_data,
+ int64_t& o_value )
+ {
+ uint8_t l_twtr_smin_msn = 0;
+ uint8_t l_twtr_smin_lsb = 0;
- // Byte 31
- TRFC1MIN_MSB_START = 0,
- TRFC1MIN_MSB_LEN = 8,
+ FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_S_MSN, U>(i_target, i_data, l_twtr_smin_msn)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TWTRMIN_S_LSB, U>(i_target, i_data, l_twtr_smin_lsb)) );
- // Byte 32
- TRFC2MIN_LSB_START = 0,
- TRFC2MIN_LSB_LEN = 8,
+ {
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_twtr_smin_msn, l_twtr_smin_lsb);
- // Byte 33
- TRFC2MIN_MSB_START = 0,
- TRFC2MIN_MSB_LEN = 8,
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS12>(i_target, l_buffer, TWTR_S_MIN));
+ o_value = l_buffer;
- // Byte 34 & Byte 35
- TRFC4MIN_LSB_START = 0,
- TRFC4MIN_LSB_LEN = 8,
+ FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Smin) in MTB units: %d",
+ spd::c_str(i_target),
+ o_value);
+ }
- TRFC4MIN_MSB_START = 0,
- TRFC4MIN_MSB_LEN = 8,
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+ };
- // Byte 36
- TFAWMIN_MSN_START = 4,
- TFAWMIN_MSN_LEN = 4,
+ ///
+ /// @class proxy - rev::V1_0 specialization
+ /// @brief Nested class to help specialize certain decoder methods
+ /// @tparam B dummy var to faciliatate partial specialization
+ /// @note If the decoder methods are rev::v1_0 hardcode them to these values
+ ///
+ template< bool B >
+ struct proxy<rev::V1_0, B>
+ {
- // Byte 37
- TFAWMIN_LSB_START = 0,
- TFAWMIN_LSB_LEN = 8,
+ ///
+ /// @brief Decodes Minimum Write Recovery Time
+ /// @param[in] i_target dimm target
+ /// @param[in] i_data SPD data vector
+ /// @param[out] o_value tWRmin in MTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode min_twr( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_data,
+ int64_t& o_value )
+ {
+ // For General Section rev 1.0 of the SPD,
+ // SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) were reserved
+ // and coded as zeros.
+ // Default as 0x78 for all DDR4 bins for rev 1.0
+ o_value = 0x78;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
- // Byte 38 - Entire byte used
- // Byte 39 - Entire byte used
- // Byte 40 - Entire byte used
+ ///
+ /// @brief Decodes Minimum Write to Read Time - Same Bank Group
+ /// @param[in] i_target dimm target
+ /// @param[in] i_data SPD data vector
+ /// @param[out] o_value tWRT_Lmin in MTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode min_twtr_l( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_data,
+ int64_t& o_value )
+ {
+ // For General Section rev 1.0 of the SPD,
+ // SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) were reserved
+ // and coded as zeros.
+ // Default as 0x3C for all DDR4 bins for rev 1.0
+ o_value = 0x3C;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
- // Byte 41
- TWRMIN_MSN_START = 4, // MSN = most significant nibble
- TWRMIN_MSN_LEN = 4,
+ ///
+ /// @brief Decodes Minimum Write to Read Time - Different Bank Group
+ /// @param[in] i_target dimm target
+ /// @param[in] i_data SPD data vector
+ /// @param[out] o_value tWRT_Smin in MTB units
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ static fapi2::ReturnCode min_twtr_s( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_data,
+ int64_t& o_value )
+ {
+ // For General Section rev 1.0 of the SPD,
+ // SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) were reserved
+ // and coded as zeros.
+ // Default as 0x14 for all DDR4 bins for rev 1.0
+ o_value = 0x14;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
- // Byte 42
- TWRMIN_LSB_START = 0, // LSB = least significant nibble
- TWRMIN_LSB_LEN = 8,
+ };
- // Byte 43
- TWTRMIN_L_MSN_START = 0, // MSN = most significant nibble
- TWTRMIN_L_MSN_LEN = 4,
+ public:
- TWTRMIN_S_MSN_START = 4, // MSN = most significant nibble
- TWTRMIN_S_MSN_LEN = 4,
+ ///
+ /// @brief default ctor
+ ///
+ decoder() = default;
- // Byte 44
- TWTRMIN_S_LSB_START = 0, // LSB = least significant byte
- TWTRMIN_S_LSB_LEN = 8,
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data SPD data vector
+ ///
+ decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data):
+ base_cnfg_decoder(i_target, i_spd_data),
+ iv_target(i_target),
+ iv_data(i_spd_data)
+ {
+ static_assert( R <= rev::GEN_SEC_MAX, " R > rev::GEN_SEC_MAX");
+ }
- // Byte 45
- TWTRMIN_L_LSB_START = 0,
- TWTRMIN_L_LSB_LEN = 8,
+ ///
+ /// @brief Default dtor
+ ///
+ virtual ~decoder() = default;
- // Bytes 46 - 59 - reserved
+ /////////////////////////
+ // Member Methods
+ /////////////////////////
- // Bytes 78 - 116 - reserved
+ ///
+ /// @brief Gets decoder target
+ /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ ///
+ virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_target;
+ }
- // Bytes 117 - 125 : Entire byte used
+ ///
+ /// @brief Gets decoder SPD data
+ /// @return std::vector<uint8_t>
+ ///
+ virtual std::vector<uint8_t> get_data() const
+ {
+ return iv_data;
+ }
- // Byte 126
- CRC_LSB_START = 0,
- CRC_LSB_LEN = 8,
+ ///
+ /// @brief Sets decoder SPD data
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ virtual void set_data(const std::vector<uint8_t>& i_spd_data)
+ {
+ iv_data = i_spd_data;
+ }
- // Byte 127
- CRC_MSB_START = 0,
- CRC_MSB_LEN = 8,
+ ///
+ /// @brief Decodes number of used SPD bytes
+ /// @param[out] o_value number of SPD bytes used
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ virtual fapi2::ReturnCode number_of_used_bytes( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BYTES_USED, R>(iv_target, iv_data, o_value)) );
- // Byte 320
- // Skip SPD most signigicant bit, so our 0
- MOD_MFG_LSB_START = 0,
- MOD_MFG_LSB_LEN = 8,
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
- // Byte 321
- MOD_MFG_MSB_START = 0,
- MOD_MFG_MSB_LEN = 8,
+ ///
+ /// @brief Decodes total number of SPD bytes
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ virtual fapi2::ReturnCode number_of_total_bytes( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TOTAL_BYTES, R>(iv_target, iv_data, o_value)) );
- };
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Helper function that turns Logical ranks in Primary SDRAM type
- /// @param[out] o_logical_ranks number of logical ranks
- /// @return fapi2::FAPI2_RC_SUCCESS iff okay
+ /// @brief Decodes SDP revision
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const;
-
- public:
+ virtual fapi2::ReturnCode revision( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::REVISION, R>(iv_target, iv_data, o_value)) );
- // First field is byte index
- // Second field is the decoding start bit
- // Third field is the decoding bit length
- static constexpr field_t BYTES_USED{0, BYTES_USED_START, BYTES_USED_LEN};
- static constexpr field_t TOTAL_BYTES_USED{0, BYTES_TOTAL_START, BYTES_TOTAL_LEN};
- static constexpr field_t SDRAM_CAPACITY{4, SDRAM_CAPACITY_START, SDRAM_CAPACITY_LEN};
- static constexpr field_t SDRAM_BANKS{4, SDRAM_BANKS_START, SDRAM_BANKS_LEN};
- static constexpr field_t BANK_GROUP{4, BANK_GROUP_START, BANK_GROUP_LEN};
- static constexpr field_t COL_ADDRESS{5, COL_ADDRESS_START, COL_ADDRESS_LEN};
- static constexpr field_t ROW_ADDRESS{5, ROW_ADDRESS_START, ROW_ADDRESS_LEN};
- static constexpr field_t PRIM_SIGNAL_LOADING{6, PRIM_SIGNAL_LOAD_START, PRIM_SIGNAL_LOAD_LEN};
- static constexpr field_t PRIM_DIE_COUNT{6, PRIM_DIE_COUNT_START, PRIM_DIE_COUNT_LEN};
- static constexpr field_t PRIM_PACKAGE_TYPE{6, PRIM_PACKAGE_TYPE_START, PRIM_PACKAGE_TYPE_LEN};
- static constexpr field_t MAC{7, MAC_START, MAC_LEN};
- static constexpr field_t TMAW{7, TMAW_START, TMAW_LEN};
- static constexpr field_t PPR{9, PPR_START, PPR_LEN};
- static constexpr field_t SOFT_PPR{9, SOFT_PPR_START, SOFT_PPR_LEN};
- static constexpr field_t SEC_SIGNAL_LOADING{10, SEC_SIGNAL_LOAD_START, SEC_SIGNAL_LOAD_LEN};
- static constexpr field_t SEC_DENSITY_RATIO{10, DENSITY_RATIO_START, DENSITY_RATIO_LEN};
- static constexpr field_t SEC_DIE_COUNT{10, SEC_DIE_COUNT_START, SEC_DIE_COUNT_LEN};
- static constexpr field_t SEC_PACKAGE_TYPE{10, SEC_PACKAGE_TYPE_START, SEC_PACKAGE_TYPE_LEN};
- static constexpr field_t OPERABLE_FLD{11, OPERABLE_START, OPERABLE_LEN};
- static constexpr field_t ENDURANT_FLD{11, ENDURANT_START, ENDURANT_LEN};
- static constexpr field_t SDRAM_WIDTH{12, SDRAM_WIDTH_START, SDRAM_WIDTH_LEN};
- static constexpr field_t RANK_MIX{12, RANK_MIX_START, RANK_MIX_LEN};
- static constexpr field_t PACKAGE_RANKS{12, PACKAGE_RANKS_START, PACKAGE_RANKS_LEN};
- static constexpr field_t BUS_WIDTH{13, BUS_WIDTH_START, BUS_WIDTH_LEN};
- static constexpr field_t BUS_EXT_WIDTH{13, BUS_EXT_WIDTH_START, BUS_EXT_WIDTH_LEN};
- static constexpr field_t THERM_SENSOR{14, THERM_SENSOR_START, THERM_SENSOR_LEN};
- static constexpr field_t EXTENDED_MODULE_TYPE{15, EXT_MOD_TYPE_START, EXT_MOD_TYPE_LEN};
- static constexpr field_t FINE_TIMEBASE{17, FINE_TIMEBASE_START, FINE_TIMEBASE_LEN};
- static constexpr field_t MEDIUM_TIMEBASE{17, MED_TIMEBASE_START, MED_TIMEBASE_LEN};
- static constexpr field_t TRASMIN_MSN{27, TRASMIN_MSN_START, TRASMIN_MSN_LEN};
- static constexpr field_t TRASMIN_LSB{28, TRASMIN_LSB_START, TRASMIN_LSB_LEN};
- static constexpr field_t TRCMIN_MSN{27, TRCMIN_MSN_START, TRCMIN_MSN_LEN};
- static constexpr field_t TRCMIN_LSB{29, TRCMIN_LSB_START, TRCMIN_LSB_LEN};
- static constexpr field_t TRFC1MIN_MSB{31, TRFC1MIN_MSB_START, TRFC1MIN_MSB_LEN};
- static constexpr field_t TRFC1MIN_LSB{30, TRFC1MIN_LSB_START, TRFC1MIN_LSB_LEN};
- static constexpr field_t TRFC2MIN_MSB{33, TRFC2MIN_MSB_START, TRFC2MIN_MSB_LEN};
- static constexpr field_t TRFC2MIN_LSB{32, TRFC2MIN_LSB_START, TRFC2MIN_LSB_LEN};
- static constexpr field_t TRFC4MIN_MSB{35, TRFC4MIN_MSB_START, TRFC4MIN_MSB_LEN};
- static constexpr field_t TRFC4MIN_LSB{34, TRFC4MIN_LSB_START, TRFC4MIN_LSB_LEN};
- static constexpr field_t TFAWMIN_MSN{36, TFAWMIN_MSN_START, TFAWMIN_MSN_LEN};
- static constexpr field_t TFAWMIN_LSB{37, TFAWMIN_LSB_START, TFAWMIN_LSB_LEN};
- static constexpr field_t TWRMIN_MSN{41, TWRMIN_MSN_START, TWRMIN_MSN_LEN};
- static constexpr field_t TWRMIN_LSB{42, TWRMIN_LSB_START, TWRMIN_LSB_LEN};
- static constexpr field_t TWTRMIN_S_MSN{43, TWTRMIN_S_MSN_START, TWTRMIN_S_MSN_LEN};
- static constexpr field_t TWTRMIN_S_LSB{44, TWTRMIN_S_LSB_START, TWTRMIN_S_LSB_LEN};
- static constexpr field_t TWTRMIN_L_MSN{43, TWTRMIN_L_MSN_START, TWTRMIN_L_MSN_LEN};
- static constexpr field_t TWTRMIN_L_LSB{45, TWTRMIN_L_LSB_START, TWTRMIN_L_LSB_LEN};
- static constexpr field_t CRC_MSB{127, CRC_MSB_START, CRC_MSB_LEN};
- static constexpr field_t CRC_LSB{126, CRC_LSB_START, CRC_LSB_LEN};
-
- // Default constructor deleted
- decoder_v1_0() = delete;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief ctor
- /// @param[in] i_target dimm target
- /// @param[in] i_spd_data SPD data vector
- /// @param[in] i_module_decoder shared_ptr to dimm module decoder
- /// @param[in] i_raw_card raw pointer to rcd data
+ /// @brief Decodes DRAM device type
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- const std::shared_ptr<dimm_module_decoder>& i_module_decoder,
- const rcw_settings& i_raw_card);
+ virtual fapi2::ReturnCode device_type( uint8_t& o_value ) const override
+ {
+ // Sparsed reserved bits within valid SPD field range
+ static const std::vector<uint8_t> l_reserved_bits{0x00, 0x0D};
+ FAPI_TRY( (mss::spd::reader<fields_t::DEVICE_TYPE, R>(iv_target, iv_data, o_value)) );
+ FAPI_TRY( check::reserved_values(iv_target, l_reserved_bits, DEVICE_TYPE, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Default dtor
+ /// @brief Decodes base module type
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual ~decoder_v1_0() = default;
+ virtual fapi2::ReturnCode base_module( uint8_t& o_value ) const override
+ {
+ // Sparsed reserved bits within valid SPD field range
+ static const std::vector<uint8_t> l_reserved_bits{0b0111, 0b1010, 0b1011, 0b1110, 0b1111};
+ FAPI_TRY( (mss::spd::reader<fields_t::BASE_MODULE, R>(iv_target, iv_data, o_value)) );
+ FAPI_TRY( check::reserved_values(iv_target, l_reserved_bits, BASE_MODULE_TYPE, o_value) );
- /////////////////////////
- // Member Methods
- /////////////////////////
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Decodes number of used SPD bytes
- /// @param[out] o_value number of SPD bytes used
+ /// @brief Decodes hybrid media
+ /// @param[out] o_value number of total SPD bytes
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note Decodes SPD Byte 0 (3~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 14
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode number_of_used_bytes( uint16_t& o_value ) const override;
+ virtual fapi2::ReturnCode hybrid_media( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::HYBRID_MEDIA, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Decodes total number of SPD bytes
+ /// @brief Decodes hybrid
/// @param[out] o_value number of total SPD bytes
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note Decodes SPD Byte 0 (bits 6~4)
- /// @note Item JC-45-2220.01x
- /// @note Page 14
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode number_of_total_bytes( uint16_t& o_value ) const override;
+ virtual fapi2::ReturnCode hybrid( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::HYBRID, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM density from SPD
/// @param[out] o_value SDRAM density in GBs
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 4 (bits 3~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 18
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::SDRAM_CAPACITY, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of SDRAM banks bits from SPD
/// @param[out] o_value Number of SDRAM bank bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 4 (bits 5~4)
- /// @note Item JC-45-2220.01x
- /// @note Page 18
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode bank_bits( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode bank_bits( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BANKS_ADDR_BITS, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of SDRAM bank groups bits from SPD
/// @param[out] o_value Number of SDRAM bank groups bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 4 (bits 7~6)
- /// @note Item JC-45-2220.01x
- /// @note Page 18
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BANK_GROUP_BITS, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of SDRAM column address bits
+ /// @param[out] o_value Number of SDRAM bank bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 5 (bits 2~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 18
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::COL_ADDR_BITS, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of SDRAM row address bits
+ /// @param[out] o_value Number of SDRAM bank bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 5 (bits 5~3)
- /// @note Item JC-45-2220.01x
- /// @note Page 18
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ROW_ADDR_BITS, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Primary SDRAM signal loading
+ /// @param[out] o_value Number of SDRAM bank bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 6 (bits 1~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 19
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PRIM_SIGNAL_LOADING, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Primary SDRAM die count
+ /// @param[out] o_value Number of SDRAM bank bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 6 (bits 6~4)
- /// @note Item JC-45-2220.01x
- /// @note Page 19
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PRIM_DIE_COUNT, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Primary SDRAM package type
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 6 (bit 7)
- /// @note Item JC-45-2220.01x
- /// @note Page 19
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PRIM_PACKAGE_TYPE, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode SDRAM Maximum activate count
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 7 (bits 3~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 20
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode maximum_activate_count( uint32_t& o_value ) const override;
+ virtual fapi2::ReturnCode maximum_activate_count( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::MAC, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 7 (bits 3~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 20
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint32_t& o_value ) const override;
+ virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TMAW, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Post package repair (PPR)
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 9 (bits 7~6)
- /// @note Item JC-45-2220.01x
- /// @note Page 21
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PPR, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Soft post package repair (soft PPR)
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 9 (bit 5)
- /// @note Item JC-45-2220.01x
- /// @note Page 21
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::SOFT_PPR, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Secondary SDRAM signal loading
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bits 1~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::SEC_SIGNAL_LOADING, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Secondary DRAM Density Ratio
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bits 3~2)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::SEC_DENSITY_RATIO, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Secondary SDRAM die count
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bits 6~4)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::SEC_DIE_COUNT, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Secondary SDRAM package type
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bit 7)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::SEC_PACKAGE_TYPE, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Module Nominal Voltage, VDD
/// @param[out] o_value enum representing if 1.2V is operable
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 11 (bit 0)
- /// @note Item JC-45-2220.01x
- /// @note Page 23
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OPERABLE_FLD, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Module Nominal Voltage, VDD
/// @param[out] o_value enum representing if 1.2V is endurant
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 11 (bit 1)
- /// @note Item JC-45-2220.01x
- /// @note Page 23
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ENDURANT_FLD, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes SDRAM device width
/// @param[out] o_value device width in bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 12 (bits 2~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 23
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode device_width( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode device_width( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::SDRAM_WIDTH, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of package ranks per DIMM
/// @param[out] o_value number of package ranks per DIMM
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 12 (bits 5~3)
- /// @note Item JC-45-2220.01x
- /// @note Page 23
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::PACKAGE_RANKS, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Rank Mix
/// @param[out] o_value rank mix value from SPD
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 12 (bit 6)
- /// @note Item JC-45-2220.01x
- /// @note Page 23
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::RANK_MIX, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes primary bus width
/// @param[out] o_value primary bus width in bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 13 (bits 2~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 27
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BUS_WIDTH, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes bus width extension
/// @param[out] o_value bus width extension in bits
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 13 (bits 4~3)
- /// @note Item JC-45-2220.01x
- /// @note Page 27
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BUS_EXT_WIDTH, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Module Thermal Sensor
/// @param[out] o_value thermal sensor value from SPD
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 14 (bit 7)
- /// @note Item JC-45-2220.01x
- /// @note Page 28
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::THERM_SENSOR, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Extended Base Module Type
/// @param[out] o_value extended base module type value from SPD
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 15 (bits 3~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 28
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::EXTENDED_MODULE_TYPE, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Fine Timebase
/// @param[out] o_value fine_timebase from SPD in picoseconds
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 17 (bits 1~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 29
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_timebase( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_timebase( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::FINE_TIMEBASE, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode Medium Timebase
/// @param[out] o_value fine_timebase from SPD in picoseconds
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 17 (bits 3~2)
- /// @note Item JC-45-2220.01x
- /// @note Page 29
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode medium_timebase( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode medium_timebase( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::MEDIUM_TIMEBASE, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
///
/// @brief Decodes SDRAM Minimum Cycle Time in MTB
/// @param[out] o_value tCKmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 18
- /// @note Item JC-45-2220.01x
- /// @note Page 31-32
- /// @note DDR4 SPD Document Release 3
- /// @warning If tCKmin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tCKmin (SPD byte 125)
- /// used for correction to get the actual value.
///
- virtual fapi2::ReturnCode min_tck( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_tck( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TCK_MIN, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Maximum Cycle Time in MTB
/// @param[out] o_value tCKmax in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 19
- /// @note Item JC-45-2220.01x
- /// @note Page 32
- /// @note DDR4 SPD Document Release 3
- /// @warning If tCKmax cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tCKmax (SPD byte 124)
- /// used for correction to get the actual value.
///
- virtual fapi2::ReturnCode max_tck( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode max_tck( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TCK_MAX, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decode CAS Latencies Supported
/// @param[out] o_value bitmap of supported CAS latencies
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Bytes 20-23
- /// @note Item JC-45-2220.01x
- /// @note Page 33-34
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const override;
+ virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const override
+ {
+ uint8_t l_first_raw_byte = 0;
+ uint8_t l_sec_raw_byte = 0;
+ uint8_t l_third_raw_byte = 0;
+ uint8_t l_fourth_raw_byte = 0;
+
+ FAPI_TRY( (mss::spd::reader<fields_t::CL_FIRST_BYTE, R>(iv_target, iv_data, l_first_raw_byte)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::CL_SECOND_BYTE, R>(iv_target, iv_data, l_sec_raw_byte)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::CL_THIRD_BYTE, R>(iv_target, iv_data, l_third_raw_byte)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::CL_FOURTH_BYTE, R>(iv_target, iv_data, l_fourth_raw_byte)) );
+
+ {
+ // Buffers used for bit manipulation
+ // Combine Bytes to create bitmap - right aligned
+ fapi2::buffer<uint64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_fourth_raw_byte, l_third_raw_byte, l_sec_raw_byte, l_first_raw_byte);
+
+ // According to the JEDEC spec:
+ // Byte 22 (Bits 7~0) and Byte 23 are reserved and thus not supported
+ // Check for a valid value
+ constexpr size_t MAX_VALID_VAL = 0x3FFFF;
+ FAPI_TRY( check::fail_for_invalid_value(iv_target,
+ l_buffer <= MAX_VALID_VAL,
+ 23,
+ l_buffer,
+ "Failed check on CAS latencies supported") );
+
+ // Update output value only if range check passes
+ o_value = int64_t(l_buffer);
+
+ FAPI_INF("%s. CAS latencies supported (bitmap): 0x%llX",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum CAS Latency Time in MTB
/// @param[out] o_value tAAmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 24
- /// @note Item JC-45-2220.01x
- /// @note Page 34
- /// @note DDR4 SPD Document Release 3
- /// @warning If tAAmin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tAAmin (SPD byte 123)
- /// used for correction to get the actual value.
///
- virtual fapi2::ReturnCode min_taa( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_taa( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TAA_MIN, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB
/// @param[out] o_value tRCDmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 25
- /// @note Item JC-45-2220.01x
- /// @note Page 35
- /// @note DDR4 SPD Document Release 3
- /// @warning If tRCDmin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tRCDmin (SPD byte 122)
- /// used for correction to get the actual value
///
- virtual fapi2::ReturnCode min_trcd( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trcd( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TRCD_MIN, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB
/// @param[out] o_value tRPmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 26
- /// @note Item JC-45-2220.01x
- /// @note Page 36-37
- /// @note DDR4 SPD Document Release 3
- /// @warning If tRPmin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tRPmin (SPD byte 121)
- /// used for correction to get the actual value
///
- virtual fapi2::ReturnCode min_trp( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trp( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TRP_MIN, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB
/// @param[out] o_value tRASmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 28 (bits 7~4) & SPD Byte 27 (bits 3~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 38
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_tras( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_tras( int64_t& o_value ) const override
+ {
+ uint8_t l_tRASmin_msn = 0;
+ uint8_t l_tRASmin_lsb = 0;
+ FAPI_TRY( (mss::spd::reader<fields_t::TRASMIN_MSN, R>(iv_target, iv_data, l_tRASmin_msn)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TRASMIN_LSB, R>(iv_target, iv_data, l_tRASmin_lsb)) );
+
+ {
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_tRASmin_msn, l_tRASmin_lsb);
+
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TRASMIN));
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Minimum Active to Precharge Delay Time (tRASmin) in MTB units: %d",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB
/// @param[out] o_value tRCmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 27 (bits 7~4) & SPD Byte 29 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 38
- /// @note DDR4 SPD Document Release 3
- /// @warning If tRCmin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tRCmin (SPD byte 120)
- /// used for correction to get the actual value.
///
- virtual fapi2::ReturnCode min_trc( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trc( int64_t& o_value ) const override
+ {
+ uint8_t l_trcmin_msn = 0;
+ uint8_t l_trcmin_lsb = 0;
+ FAPI_TRY( (mss::spd::reader<fields_t::TRCMIN_MSN, R>(iv_target, iv_data, l_trcmin_msn)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TRCMIN_LSB, R>(iv_target, iv_data, l_trcmin_lsb)) );
+
+ {
+ // Combining bits to create timing value (in a buffer)
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_trcmin_msn, l_trcmin_lsb);
+
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TRCMIN));
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Minimum Active to Active/Refresh Delay Time (tRCmin) in MTB units: %d",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1
/// @param[out] o_value tRFC1min in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 30 & Byte 31
- /// @note Item JC-45-2220.01x
- /// @note Page 39-40
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_trfc1( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trfc1( int64_t& o_value ) const override
+ {
+ uint8_t l_trfc1min_msb = 0;
+ uint8_t l_trfc1min_lsb = 0;
+
+ FAPI_TRY( (mss::spd::reader<fields_t::TRFC1MIN_MSB, R>(iv_target, iv_data, l_trfc1min_msb)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TRFC1MIN_LSB, R>(iv_target, iv_data, l_trfc1min_lsb)) );
+
+ {
+ // Combining bits to create timing value (in a buffer)
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_trfc1min_msb, l_trfc1min_lsb);
+
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC1MIN));
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Minimum Refresh Recovery Delay Time 1 (tRFC1min) in MTB units: %d",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2
/// @param[out] o_value tRFC2min in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 32 & Byte 33
- /// @note Item JC-45-2220.01x
- /// @note Page 40
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_trfc2( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trfc2( int64_t& o_value ) const override
+ {
+ uint8_t l_trfc2min_msb = 0;
+ uint8_t l_trfc2min_lsb = 0;
+ FAPI_TRY( (mss::spd::reader<fields_t::TRFC2MIN_MSB, R>(iv_target, iv_data, l_trfc2min_msb)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TRFC2MIN_LSB, R>(iv_target, iv_data, l_trfc2min_lsb)) );
+
+ {
+ // Combining bits to create timing value (in a buffer)
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_trfc2min_msb, l_trfc2min_lsb);
+
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC2MIN));
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Minimum Refresh Recovery Delay Time 2 (tRFC2min) in MTB units: %d",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4
/// @param[out] o_value tRFC4min in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 34 & Byte 35
- /// @note Item JC-45-2220.01x
- /// @note Page 40
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_trfc4( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trfc4( int64_t& o_value ) const override
+ {
+ uint8_t l_trfc4min_msb = 0;
+ uint8_t l_trfc4min_lsb = 0;
+ FAPI_TRY( (mss::spd::reader<fields_t::TRFC4MIN_MSB, R>(iv_target, iv_data, l_trfc4min_msb)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TRFC4MIN_LSB, R>(iv_target, iv_data, l_trfc4min_lsb)) );
+
+ {
+ // Combining bits to create timing value (in a buffer)
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_trfc4min_msb, l_trfc4min_lsb);
+
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS16>(iv_target, l_buffer, TRFC4MIN));
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Minimum Refresh Recovery Delay Time 4 (tRFC4min) in MTB units: %d",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes SDRAM Minimum Four Activate Window Delay Time
/// @param[out] o_value tFAWmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 36 (bits 3~0) & Byte 37 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 42
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_tfaw( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_tfaw( int64_t& o_value ) const override
+ {
+ uint8_t l_tfawmin_msn = 0;
+ uint8_t l_tfawmin_lsb = 0;
+ FAPI_TRY( (mss::spd::reader<fields_t::TFAWMIN_MSN, R>(iv_target, iv_data, l_tfawmin_msn)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::TFAWMIN_LSB, R>(iv_target, iv_data, l_tfawmin_lsb)) );
+
+ {
+ // Combining bits to create timing value (in a buffer)
+ fapi2::buffer<int64_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_tfawmin_msn, l_tfawmin_lsb);
+
+ // Update output only after check passes
+ FAPI_TRY( check::max_timing_range<BITS12>(iv_target, l_buffer, TFAWMIN));
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Minimum Four Activate Window Delay Time (tFAWmin) in MTB units: %d",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group
/// @param[out] o_value tRRD_Smin MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 38
- /// @note Item JC-45-2220.01x
- /// @note Page 43
- /// @note DDR4 SPD Document Release 3
- /// @warning If tRRD_Smin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tRRD_Smin (SPD byte 119)
- /// used for correction to get the actual value.
///
- virtual fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TRRD_S_MIN, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group
/// @param[out] o_value tRRD_Lmin MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 39
- /// @note Item JC-45-2220.01x
- /// @note Page 43-44
- /// @note DDR4 SPD Document Release 3
- /// @warning If tRRD_Lmin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tRRD_Lmin (SPD byte 118)
- /// used for correction to get the actual value.
///
- virtual fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TRRD_L_MIN, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group
/// @param[out] o_value tCCD_Lmin MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 40
- /// @note Item JC-45-2220.01x
- /// @note Page 44-45
- /// @note DDR4 SPD Document Release 3
- /// @warning If tCCD_Lmin cannot be divided evenly by the MTB,
- /// this byte must be rounded up to the next larger
- /// integer and the Fine Offset for tCCD_Lmin (SPD byte 117)
- /// used for correction to get the actual value.
///
- virtual fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::TCCD_L_MIN, R>(iv_target, iv_data, o_value)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Minimum Write Recovery Time
/// @param[out] o_value tWRmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 40
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const override
+ {
+ FAPI_TRY( proxy<R>::min_twr(iv_target, iv_data, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Minimum Write to Read Time - Different Bank Group
/// @param[out] o_value tWRT_Smin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 40
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const override
+ {
+ FAPI_TRY( proxy<R>::min_twtr_s(iv_target, iv_data, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes Minimum Write to Read Time - Same Bank Group
/// @param[out] o_value tWRT_Lmin in MTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 46
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const override
+ {
+ FAPI_TRY( proxy<R>::min_twtr_l(iv_target, iv_data, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Package Rank Map
/// @param[out] o_value vector of package rank maps for SPD bytes 60 - 77
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 60 - 77
- /// @note JEDEC Standard No. 21-C
- /// @note Page 45
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode package_rank_map( std::vector<uint8_t>& o_value ) const override;
+ virtual fapi2::ReturnCode package_rank_map( std::vector<uint8_t>& o_value ) const override
+ {
+ o_value.clear();
+
+ FAPI_TRY( (sdram_connector_helper<DQ0_31, PKG_RANK_MAP>(o_value)),
+ "%s Failed to sdram_connector_helper for DQ0_31, PKG_RANK_MAP", spd::c_str(iv_target) );
+
+ FAPI_TRY( (sdram_connector_helper<DQ32_63, PKG_RANK_MAP>(o_value)),
+ "%s Failed to sdram_connector_helper for DQ32_63, PKG_RANK_MAP", spd::c_str(iv_target) );
+
+ FAPI_TRY( (sdram_connector_helper<CB0_7, PKG_RANK_MAP>(o_value)),
+ "%s Failed to sdram_connector_helper for CB0_7, PKG_RANK_MAP", spd::c_str(iv_target) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Nibble Map
/// @param[out] o_value vector of nibble map encoding for SPD bytes 60 - 77
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 60 - 77
- /// @note JEDEC Standard No. 21-C
- /// @note Page 45
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode nibble_map( std::vector<uint8_t>& o_value ) const override;
+ virtual fapi2::ReturnCode nibble_map( std::vector<uint8_t>& o_value ) const override
+ {
+ o_value.clear();
+
+ FAPI_TRY( (sdram_connector_helper<DQ0_31, NIBBLE_MAP>(o_value)),
+ "%s Failed to sdram_connector_helper for DQ0_31, NIBBLE_MAP", spd::c_str(iv_target) );
+
+ FAPI_TRY( (sdram_connector_helper<DQ32_63, NIBBLE_MAP>(o_value)),
+ "%s Failed to sdram_connector_helper for DQ32_63, NIBBLE_MAP", spd::c_str(iv_target) );
+
+ FAPI_TRY( (sdram_connector_helper<CB0_7, NIBBLE_MAP>(o_value)),
+ "%s Failed to sdram_connector_helper for CB0_7, NIBBLE_MAP", spd::c_str(iv_target) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for Minimum CAS to CAS Delay Time - Same Bank Group
/// @param[out] o_value tCCD_Lmin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 117
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TCCD_L_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group
/// @param[out] o_value tRRD_Lmin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 118
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRRD_L_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group
/// @param[out] o_value tRRD_Smin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 119
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRRD_S_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time
/// @param[out] o_value tRCmin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 120
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRC_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time
/// @param[out] o_value tRPmin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 121
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRP_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time
/// @param[out] o_value tRCDmin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 122
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TRCD_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time
/// @param[out] o_value tAAmin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 123
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TAA_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time
/// @param[out] o_value tCKmax offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 124
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TCK_MAX, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time
/// @param[out] o_value tCKmin offset in FTB units
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 125
- /// @note Item JC-45-2220.01x
- /// @note Page 52
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::OFFSET_TCK_MIN, R>(iv_target, iv_data, o_value)) );
+ o_value = static_cast<int8_t>(o_value);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section
/// @param[out] o_value crc value from SPD
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 127 & Byte 126
- /// @note Item JC-45-2220.01x
- /// @note Page 53
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const override;
+ virtual fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const override
+ {
+ uint8_t l_crc_msb = 0;
+ uint8_t l_crc_lsb = 0;
+ FAPI_TRY( (mss::spd::reader<fields_t::CRC_MSB, R>(iv_target, iv_data, l_crc_msb)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::CRC_LSB, R>(iv_target, iv_data, l_crc_lsb)) );
+
+ {
+ // Combining bits to create timing value (in a buffer)
+ fapi2::buffer<uint16_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_crc_msb, l_crc_lsb);
+
+ // This value isn't bounded in the SPD document
+ o_value = l_buffer;
+
+ FAPI_INF("%s. Cyclical Redundancy Code (CRC): %d",
+ spd::c_str(iv_target),
+ o_value);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes module manufacturer ID code
/// @param[out] o_output module manufacturing id code
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 320 (bit 7~0), 321 (6~0)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12 - 54
- ///
- virtual fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const override;
-
///
- /// @brief Decodes Module Manufacturing Location
- /// @param[out] o_value uint8_t identifier for manufacturing location of memory module
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 322
- /// @note Item JC-45-2220.01x
- /// @note Page 55
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const override;
- ///
- /// @brief Decodesmodule manufacturing date
- /// @param[out] o_output the 2 byte date of manufacturing in BCD format
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 323 & 324
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 54
- /// @note in Binary Coded Decimal (BCD)
- /// @note MSB = year, LSB = week
- ///
- virtual fapi2::ReturnCode module_manufacturing_date( uint16_t& o_output ) const override;
+ virtual fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const override
+ {
+ uint8_t l_cont_codes = 0;
+ uint8_t l_last_nonzero_byte = 0;
- ///
- /// @brief Decodes module's unique serial number
- /// @param[out] o_output
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 325-328
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 54
- ///
- virtual fapi2::ReturnCode module_serial_number( uint32_t& o_output ) const override;
+ FAPI_TRY( (mss::spd::reader<fields_t::CONTINUATION_CODES, R>(iv_target, iv_data, l_cont_codes)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::LAST_NON_ZERO_BYTE, R>(iv_target, iv_data, l_last_nonzero_byte)) );
- ///
- /// @brief Decodes Module Revision Code
- /// @param[out] o_value uint8_t identifier for revision code
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 349
- /// @note Item JC-45-2220.01x
- /// @note Page 55
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const override;
+ {
+ fapi2::buffer<uint16_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_last_nonzero_byte, l_cont_codes);
- ///
- /// @brief Decodes DRAM Manufacturer ID code
- /// @param[out] o_output dram manufacturing id code
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 350 - 351
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 54
- ///
- virtual fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_output ) const override;
+ o_value = l_buffer;
- ///
- /// @brief Decodes RCD Manufacturer ID code
- /// @param[out] o_value rcd manufacturing id code
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 133 134
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 54
- ///
- virtual fapi2::ReturnCode reg_manufacturer_id_code( uint16_t& o_value ) const override;
+ FAPI_INF("%s.Module Manufacturer ID Code: %x",
+ spd::c_str(iv_target),
+ o_value);
+ }
- ///
- /// @brief Decodes Register Revision Number
- /// @param[out] o_value register revision number
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 135
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 54
- ///
- virtual fapi2::ReturnCode register_rev_num( uint8_t& o_value ) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Decodes DRAM Stepping
- /// @param[out] o_value uint8_t DRAM Stepping val
+ /// @brief Decodes Module Manufacturing Location
+ /// @param[out] o_value uint8_t identifier for manufacturing location of memory module
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 352
- /// @note Item JC-45-2220.01x
- /// @note Page 56
- /// @note DDR4 SPD Document Release 3
- /// @note also called die revision level
- ///
- virtual fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const override;
-
- ///
- /// @brief Returns Logical ranks per DIMM
- /// @param[out] o_logical_ranks number of logical ranks
- /// @return fapi2::FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const override;
+ virtual fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_MFG_LOCATION, R>(iv_target, iv_data, o_value)) );
- private:
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief SPD byte field threshold check
- /// @param[out] o_value list of connector_field values from SPD
+ /// @brief Decodesmodule manufacturing date
+ /// @param[out] o_value the 2 byte date of manufacturing in BCD format
/// @return FAPI2_RC_SUCCESS iff okay
- ///
- template< mss::connector_bits T, mss::connector_field OT, typename TT = mss::connectorTraits<T, OT> >
- fapi2::ReturnCode sdram_connector_helper( std::vector<uint8_t>& o_value ) const
+ virtual fapi2::ReturnCode module_manufacturing_date( uint16_t& o_value ) const override
{
- for( size_t byte = TT::START; byte <= TT::END; ++byte )
- {
- uint8_t l_field = 0;
+ uint8_t l_date_msb = 0;
+ uint8_t l_date_lsb = 0;
- fapi2::buffer<uint8_t> l_buffer(iv_spd_data[byte]);
- l_buffer.extractToRight<TT::EXTRACT_START, TT::EXTRACT_LEN>(l_field);
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_MFG_DATE_MSB, R>(iv_target, iv_data, l_date_msb)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_MFG_DATE_LSB, R>(iv_target, iv_data, l_date_lsb)) );
- FAPI_DBG("%s SPD byte %d, data: %d, field value: %d, starting bit: %d, bit length: %d",
- iv_target_str_storage, byte, iv_spd_data[byte], l_field, TT::EXTRACT_START, TT::EXTRACT_LEN);
+ {
+ fapi2::buffer<uint16_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_date_msb, l_date_lsb);
- FAPI_TRY( TT::fail_check(iv_target, byte, l_field) );
+ o_value = l_buffer;
- o_value.push_back(l_field);
+ FAPI_INF("%s.Module Manufacturer ID date: %x",
+ spd::c_str(iv_target),
+ o_value);
}
fapi_try_exit:
return fapi2::current_err;
}
-};// decoder
-
-///
-/// @class decoder_v1_1
-/// @brief Base SPD DRAM decoder, 1st addition to general section
-///
-class decoder_v1_1 : public decoder_v1_0
-{
- protected:
-
- ///
- /// @brief Helper functions that returns Logical ranks in Secondary SDRAM type
- /// @param[out] o_logical_ranks number of logical ranks
- /// @return fapi2::FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const;
-
- public:
- ///
- /// @brief Default constructor
+ /// @brief Decodes module's unique serial number
+ /// @param[out] o_value module's serial number
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- decoder_v1_1() = default;
+ virtual fapi2::ReturnCode module_serial_number( uint32_t& o_value ) const override
+ {
+ uint8_t l_sn_byte_0 = 0;
+ uint8_t l_sn_byte_1 = 0;
+ uint8_t l_sn_byte_2 = 0;
+ uint8_t l_sn_byte_3 = 0;
- ///
- /// @brief ctor
- /// @param[in] i_target dimm target
- /// @param[in] i_spd_data SPD data vector
- /// @param[in] i_module_decoder shared_ptr to dimm module decoder
- /// @param[in] i_raw_card raw pointer to rcd data
- ///
- decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- const std::shared_ptr<dimm_module_decoder>& i_module_decoder,
- const rcw_settings& i_raw_card);
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE1, R>(iv_target, iv_data, l_sn_byte_0)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE2, R>(iv_target, iv_data, l_sn_byte_1)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE3, R>(iv_target, iv_data, l_sn_byte_2)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_SERIAL_NUM_BYTE4, R>(iv_target, iv_data, l_sn_byte_3)) );
- ///
- /// @brief Default dtor
- ///
- virtual ~decoder_v1_1() = default;
+ {
+ fapi2::buffer<uint32_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_sn_byte_3, l_sn_byte_2, l_sn_byte_1, l_sn_byte_0);
- /////////////////////////
- // Member Methods
- /////////////////////////
+ o_value = l_buffer;
- ///
- /// @brief Decodes SDRAM density from SPD
- /// @param[out] o_value SDRAM density in GBs
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 4 (bits 3~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 18
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const override;
-
- ///
- /// @brief Decode Soft post package repair (soft PPR)
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 9 (bit 5)
- /// @note Item JC-45-2220.01x
- /// @note Page 21
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const override;
+ FAPI_INF("%s.Module Serial Number : 0x%08x",
+ spd::c_str(iv_target),
+ o_value);
+ }
- ///
- /// @brief Decodes Secondary SDRAM signal loading
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bits 1~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Decodes Secondary DRAM Density Ratio
+ /// @brief Decodes Module Revision Code
+ /// @param[out] o_value uint8_t identifier for revision code
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bits 3~2)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_REV_CODE, R>(iv_target, iv_data, o_value)) );
- ///
- /// @brief Decodes Secondary SDRAM die count
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bits 6~4)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Decodes Secondary SDRAM package type
+ /// @brief Decodes DRAM Manufacturer ID code
+ /// @param[out] o_value dram manufacturing id code
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 10 (bit 7)
- /// @note Item JC-45-2220.01x
- /// @note Page 22
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const override;
+ virtual fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const override
+ {
+ uint8_t l_mfgid_msb = 0;
+ uint8_t l_mfgid_lsb = 0;
- ///
- /// @brief Decodes number of package ranks per DIMM
- /// @param[out] o_value number of package ranks per DIMM
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 12 (bits 5~3)
- /// @note Item JC-45-2220.01x
- /// @note Page 23
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const override;
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_MFR_ID_CODE_LSB, R>(iv_target, iv_data, l_mfgid_lsb)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_MFR_ID_CODE_MSB, R>(iv_target, iv_data, l_mfgid_msb)) );
- ///
- /// @brief Decodes Rank Mix
- /// @param[out] o_value rank mix value from SPD
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 12 (bit 6)
- /// @note Item JC-45-2220.01x
- /// @note Page 23
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const override;
+ {
+ fapi2::buffer<uint16_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_mfgid_msb, l_mfgid_lsb);
- ///
- /// @brief Decode CAS Latencies Supported
- /// @param[out] o_value bitmap of supported CAS latencies
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Bytes 20-23
- /// @note Item JC-45-2220.01x
- /// @note Page 33-34
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value) const override;
+ o_value = l_buffer;
- ///
- /// @brief Decodes Minimum Write Recovery Time
- /// @param[out] o_value tWRmin in MTB units
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 40
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const override;
+ FAPI_INF("%s.DRAM Manufacturer ID Code: %x",
+ spd::c_str(iv_target),
+ o_value);
+ }
- ///
- /// @brief Decodes Minimum Write to Read Time - Different Bank Group
- /// @param[out] o_value tWRT_Smin in MTB units
- /// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 40
- /// @note DDR4 SPD Document Release 3
- ///
- virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
- /// @brief Decodes Minimum Write to Read Time - Same Bank Group
- /// @param[out] o_value tWRT_Lmin in MTB units
+ /// @brief Decodes DRAM Stepping
+ /// @param[out] o_value uint8_t DRAM Stepping val
/// @return FAPI2_RC_SUCCESS iff okay
- /// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 46
- /// @note DDR4 SPD Document Release 3
///
- virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const override;
+ virtual fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_STEPPING, R>(iv_target, iv_data, o_value)) );
- ///
- /// @brief Returns Logical ranks per DIMM
- /// @param[out] o_logical_ranks number of logical ranks
- /// @return fapi2::FAPI2_RC_SUCCESS iff okay
- ///
- virtual fapi2::ReturnCode logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
-};// spd_decoder_v1_1
+};// decoder
-}// ddr4
}// spd
}// mss
diff --git a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C
deleted file mode 100644
index fa47e5384..000000000
--- a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C
+++ /dev/null
@@ -1,3021 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_0.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-///
-/// @file spd_decoder.C
-/// @brief SPD decoder definitions
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-// std lib
-#include <map>
-#include <vector>
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
-#include <generic/memory/lib/spd/common/rcw_settings.H>
-#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-#include <generic/memory/lib/utils/mss_math.H>
-
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-namespace mss
-{
-namespace spd
-{
-namespace ddr4
-{
-
-/////////////////////////
-// Member Method implementation
-/////////////////////////
-
-///
-/// @brief ctor
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data vector
-/// @param[in] i_module_decoder shared_ptr to dimm module decoder
-/// @param[in] i_raw_card raw card data structure
-///
-decoder_v1_0::decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- const std::shared_ptr<dimm_module_decoder>& i_module_decoder,
- const rcw_settings& i_raw_card)
- : decoder(i_target, i_spd_data, i_module_decoder, i_raw_card)
-{}
-
-///
-/// @brief Decodes number of used SPD bytes
-/// @param[out] o_value number of SPD bytes used
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note Decodes SPD Byte 0 bits(0~3)
-/// @note Item JC-45-2220.01x
-/// @note Page 14
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::number_of_used_bytes( uint16_t& o_value ) const
-{
- // =========================================================
- // Byte 0 maps
- // Item JC-45-2220.01x
- // Page 14
- // DDR4 SPD Document Release 3
- // Byte 0 (0x000): Number of Bytes Used / Number of Bytes in SPD Device
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint16_t> > BYTES_USED_MAP =
- {
- //{key byte, number of used bytes}
- {1, 128},
- {2, 256},
- {3, 384},
- {4, 512}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< BYTES_USED >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(BYTES_USED_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- BYTES_USED.iv_byte,
- l_field_bits,
- "Failed check on SPD used bytes") );
-
- FAPI_INF("%s. Bytes Used: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes total number of SPD bytes
-/// @param[out] o_value number of total SPD bytes
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note Decodes SPD Byte 0 (bits 4~6)
-/// @note Item JC-45-2220.01x
-/// @note Page 14
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::number_of_total_bytes( uint16_t& o_value ) const
-{
-
- // =========================================================
- // Byte 0 maps
- // Item JC-45-2220.01x
- // Page 14
- // DDR4 SPD Document Release 3
- // Byte 0 (0x000): Number of Bytes Used / Number of Bytes in SPD Device
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint16_t> > BYTES_TOTAL_MAP =
- {
- //{key byte, number of total bytes}
- {1, 256},
- {2, 512}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< TOTAL_BYTES_USED >(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(BYTES_TOTAL_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- TOTAL_BYTES_USED.iv_byte,
- l_field_bits,
- "Failed check on SPD total bytes") );
-
- FAPI_INF("%s. Total Bytes: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM density from SPD
-/// @param[out] o_value SDRAM density in GBs
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 4 (bits 0~3)
-/// @note Item JC-45-2220.01x
-/// @note Page 18
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::sdram_density( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 4 maps
- // Item JC-45-2220.01x
- // Page 18
- // DDR4 SPD Document Release 3
- // Byte 4 (0x004): SDRAM Density and Banks
- // =========================================================
- static const std::vector< std::pair<uint8_t, uint8_t> > SDRAM_DENSITY_MAP =
- {
- // {key byte, capacity in GBs}
- {2, 1},
- {3, 2},
- {4, 4},
- {5, 8},
- {6, 16},
- {7, 32},
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SDRAM_CAPACITY >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check to assure SPD DRAM capacity (map) wont be at invalid values
- const bool l_is_val_found = mss::find_value_from_key(SDRAM_DENSITY_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- SDRAM_CAPACITY.iv_byte,
- l_field_bits,
- "Failed check for SPD DRAM capacity") );
-
- FAPI_INF("%s. SDRAM density: %d Gb",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes number of SDRAM bank_bits from SPD
-/// @param[out] o_value Number of SDRAM bank bits
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 4 (bits 5~4)
-/// @note Item JC-45-2220.01x
-/// @note Page 18
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::bank_bits( uint8_t& o_value) const
-
-{
- // =========================================================
- // Byte 4 maps
- // Item JC-45-2220.01x
- // Page 18
- // DDR4 SPD Document Release 3
- // Byte 4 (0x004): SDRAM Density and Banks
- // =========================================================
- static const std::vector< std::pair<uint8_t, uint8_t> > BANK_ADDR_BITS_MAP =
- {
- // {key byte, number of bank address bits}
- {0, 2},
- {1, 3}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SDRAM_BANKS >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check to assure SPD DRAM capacity (map) wont be at invalid values
- const bool l_is_val_found = mss::find_value_from_key(BANK_ADDR_BITS_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- SDRAM_BANKS.iv_byte,
- l_field_bits,
- "Failed check for SPD DRAM banks") );
-
- FAPI_INF("%s. Number of banks address bits: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes number of SDRAM bank group bits from SPD
-/// @param[out] o_value Number of SDRAM bank group bits
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 4 (bits 6~7)
-/// @note Item JC-45-2220.01x
-/// @note Page 18
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::bank_group_bits( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 4 maps
- // Item JC-45-2220.01x
- // Page 18
- // DDR4 SPD Document Release 3
- // Byte 4 (0x004): SDRAM Density and Banks
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > BANK_GROUP_BITS_MAP =
- {
- // {key byte, number of bank groups bits}
- {0, 0},
- {1, 1},
- {2, 2}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< BANK_GROUP >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check to assure SPD DRAM capacity (map) wont be at invalid values
- const bool l_is_val_found = mss::find_value_from_key(BANK_GROUP_BITS_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- BANK_GROUP.iv_byte,
- l_field_bits,
- "Failed check for SPD DRAM bank groups") );
-
- FAPI_INF("%s. Number of bank group bits: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes number of SDRAM column address bits
-/// @param[out] o_value number of column address bits
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 5 (bits 2~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 18
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::column_address_bits( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 5 maps
- // Item JC-45-2220.01x
- // Page 18
- // DDR4 SPD Document Release 3
- // Byte 5 (0x005): SDRAM Addressing
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > COLUMN_ADDRESS_BITS_MAP =
- {
- //{key byte,col address bits}
- {0, 9},
- {1, 10},
- {2, 11},
- {3, 12}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< COL_ADDRESS >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check to assure SPD DRAM capacity (map) wont be at invalid values
- const bool l_is_val_found = mss::find_value_from_key(COLUMN_ADDRESS_BITS_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- COL_ADDRESS.iv_byte,
- l_field_bits,
- "Failed check for SDRAM Column Address Bits") );
-
- FAPI_INF("%s. Number of Column Address Bits: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes number of SDRAM row address bits
-/// @param[out] o_value number of row address bits
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 5 (bits 5~3)
-/// @note Item JC-45-2220.01x
-/// @note Page 18
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::row_address_bits( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 5 maps
- // Item JC-45-2220.01x
- // Page 18
- // DDR4 SPD Document Release 3
- // Byte 5 (0x005): SDRAM Addressing
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > ROW_ADDRESS_BITS_MAP =
- {
- //{key byte,row address bits}
- {0, 12},
- {1, 13},
- {2, 14},
- {3, 15},
- {4, 16},
- {5, 17},
- {6, 18}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< ROW_ADDRESS >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check to assure SPD DRAM capacity (map) wont be at invalid values
- const bool l_is_val_found = mss::find_value_from_key(ROW_ADDRESS_BITS_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target,
- l_is_val_found,
- ROW_ADDRESS.iv_byte,
- l_field_bits,
- "Failed check for SDRAM Row Address Bits") );
-
- FAPI_INF("%s. Number of Row Address Bits: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes Primary SDRAM signal loading
-/// @param[out] o_value enum representing signal loading type
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 6 (bits 1~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 19
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::prim_sdram_signal_loading( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 6 maps
- // Item JC-45-2220.01x
- // Page 19
- // DDR4 SPD Document Release 3
- // Byte 6 (0x006): Primary SDRAM Package Type
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_SIGNAL_LOADING_MAP =
- {
- // {key byte, signal loading}
- {0, fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP},
- {1, fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_DDP_QDP},
- {2, fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_3DS}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< PRIM_SIGNAL_LOADING >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(PRIM_SIGNAL_LOADING_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target,
- l_is_val_found,
- PRIM_SIGNAL_LOADING.iv_byte,
- l_field_bits,
- "Failed check for Primary SDRAM Signal Loading") );
-
- FAPI_INF("%s. Primary SDRAM Signal Loading: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Primary SDRAM die count
-/// @param[out] o_value die count
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 6 (bits 6~4)
-/// @note Item JC-45-2220.01x
-/// @note Page 19
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::prim_sdram_die_count( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 6 maps
- // Item JC-45-2220.01x
- // Page 19
- // DDR4 SPD Document Release 3
- // Byte 6 (0x006): Primary SDRAM Package Type
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_DIE_COUNT_MAP =
- {
- // {key byte, number of die}
- {0, 1},
- {1, 2},
- {2, 3},
- {3, 4},
- {4, 5},
- {5, 6},
- {6, 7},
- {7, 8}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< PRIM_DIE_COUNT >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(PRIM_DIE_COUNT_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target,
- l_is_val_found,
- PRIM_DIE_COUNT.iv_byte,
- l_field_bits,
- "Failed check for SDRAM Row Address Bits") );
-
- FAPI_INF("%s. Number of Row Address Bits: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Primary SDRAM package type
-/// @param[out] o_value enum representing package type
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 6 (bit 7)
-/// @note Item JC-45-2220.01x
-/// @note Page 19
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::prim_sdram_package_type( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 6 maps
- // Item JC-45-2220.01x
- // Page 19
- // DDR4 SPD Document Release 3
- // Byte 6 (0x006): Primary SDRAM Package Type
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > PRIM_PACKAGE_TYPE_MAP =
- {
- // {key byte, value}
- {0, MONOLITHIC},
- {1, NON_MONOLITHIC}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< PRIM_PACKAGE_TYPE >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(PRIM_PACKAGE_TYPE_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- PRIM_PACKAGE_TYPE.iv_byte,
- l_field_bits,
- "Failed check for Primary SDRAM package type") );
-
- FAPI_INF("%s. Primary SDRAM package type: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decode SDRAM Maximum activate count
-/// @param[out] o_value enum representing max activate count
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 7 (bits 3~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 20
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::maximum_activate_count( uint32_t& o_value ) const
-{
- // =========================================================
- // Byte 7 maps
- // Item JC-45-2220.01x
- // Page 20
- // DDR4 SPD Document Release 3
- // Byte 7 (0x007): SDRAM Optional Features
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint32_t> > MAC_MAP =
- {
- // {key byte, maximum activate count}
- {0, fapi2::ENUM_ATTR_EFF_DRAM_MAC_UNTESTED},
- {1, fapi2::ENUM_ATTR_EFF_DRAM_MAC_700K},
- {2, fapi2::ENUM_ATTR_EFF_DRAM_MAC_600K},
- {3, fapi2::ENUM_ATTR_EFF_DRAM_MAC_500K},
- {4, fapi2::ENUM_ATTR_EFF_DRAM_MAC_400K},
- {5, fapi2::ENUM_ATTR_EFF_DRAM_MAC_300K},
- {6, fapi2::ENUM_ATTR_EFF_DRAM_MAC_200K},
- {8, fapi2::ENUM_ATTR_EFF_DRAM_MAC_UNLIMITED}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< MAC >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(MAC_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- MAC.iv_byte,
- l_field_bits,
- "Failed check for SDRAM Maximum Active Count (MAC)") );
-
- FAPI_INF("%s. Maximum Active Count (MAC): %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point
-/// @param[out] o_value max activate window multiplier
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 7 (bits 3~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 20
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::maximum_activate_window_multiplier( uint32_t& o_value ) const
-{
- // =========================================================
- // Byte 7 maps
- // Item JC-45-2220.01x
- // Page 20
- // DDR4 SPD Document Release 3
- // Byte 7 (0x007): SDRAM Optional Features
- // =========================================================
- // Multiplier with tREFI is not taken into account here
- static const std::vector<std::pair<uint8_t, uint32_t> > TMAW_MAP =
- {
- // {key byte, tMAW multiplier}
- {0, 8192},
- {1, 4096},
- {2, 2048}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< TMAW >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(TMAW_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- TMAW.iv_byte,
- l_field_bits,
- "Failed check for Maximum Active Window (tMAW)") );
-
- FAPI_INF("%s. Maximum Active Window multiplier: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode Post package repair (PPR)
-/// @param[out] o_value enum representing if (hard) PPR is supported
-/// @return fapi2::ReturnCode
-/// @note SPD Byte 9 (bits 7~6)
-/// @note Item JC-45-2220.01x
-/// @note Page 21
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::post_package_repair( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 9 maps
- // Item JC-45-2220.01x
- // Page 21
- // DDR4 SPD Document Release 3
- // Byte 9 (0x009): Other SDRAM Optional Features
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > PPR_MAP =
- {
- // {key byte, value }
- {0, fapi2::ENUM_ATTR_EFF_DRAM_PPR_NOT_SUPPORTED},
- {1, fapi2::ENUM_ATTR_EFF_DRAM_PPR_SUPPORTED}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< PPR >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(PPR_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- PPR.iv_byte,
- l_field_bits,
- "Failed check for PPR") );
-
- FAPI_INF("%s. Post Package Repair (PPR): %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Secondary SDRAM signal loading
-/// @param[out] o_value enum representing signal loading type
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 10 (bits 1~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::sec_sdram_signal_loading( uint8_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 10 (bits 1~0) were reserved
- // and coded as zeros. There was no concept of
- // secondary SDRAM signal loading so this
- // is thus hard-wired to zero.
- o_value = 0x00;
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decode Soft post package repair (soft PPR)
-/// @param[out] o_value enum representing if soft PPR is supported
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 9 (bit 5)
-/// @note Item JC-45-2220.01x
-/// @note Page 21
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::soft_post_package_repair( uint8_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 9 (bit 5) was reserved
- // and coded as zeros. There was no concept of soft PPR so this
- // is thus hard-wired to zero.
- o_value = 0x00;
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes Secondary DRAM Density Ratio
-/// @param[out] o_value raw bits from SPD
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 10 (bits 3~2)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::sec_dram_density_ratio( uint8_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 10 (bits 3~2) were reserved
- // and coded as zeros. There was no concept of
- // secondary SDRAM density ratio so this
- // is thus hard-wired to zero.
- o_value = 0x00;
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes Secondary SDRAM die count
-/// @param[out] o_value die count
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 10 (bits 6~4)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::sec_sdram_die_count( uint8_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 10 (bits 6~4) were reserved
- // and coded as zeros. There was no concept of
- // secondary SDRAM hybrid media so this
- // is thus hard-wired to zero.
- o_value = 0x00;
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes Secondary SDRAM package type
-/// @param[out] o_value enum representing package type
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 10 (bit 7)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::sec_sdram_package_type( uint8_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 10 (bit 7) was reserved
- // and coded as zeros. There was no concept of
- // secondary SDRAM package type so this
- // is thus hard-wired to zero.
- o_value = 0x00;
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decode Module Nominal Voltage, VDD
-/// @param[out] o_value enum representing if 1.2V is operable
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 11 (bit 0)
-/// @note Item JC-45-2220.01x
-/// @note Page 23
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::operable_nominal_voltage( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 11 maps
- // Item JC-45-2220.01x
- // Page 22-23
- // DDR4 SPD Document Release 3
- // Byte 11 (0x00B): Modle Nominal Voltage
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > OPERABLE_MAP =
- {
- // {key byte, value }
- {0, NOT_OPERABLE },
- {1, OPERABLE}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< OPERABLE_FLD >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(OPERABLE_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- OPERABLE_FLD.iv_byte,
- l_field_bits,
- "Failed check for Operable nominal voltage") );
-
- FAPI_INF("%s. Operable: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode Module Nominal Voltage, VDD
-/// @param[out] o_value enum representing if 1.2V is endurant
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 11 (bit 1)
-/// @note Item JC-45-2220.01x
-/// @note Page 23
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::endurant_nominal_voltage( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 11 maps
- // Item JC-45-2220.01x
- // Page 22-23
- // DDR4 SPD Document Release 3
- // Byte 11 (0x00B): Modle Nominal Voltage
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > ENDURANT_MAP =
- {
- // {key byte, value }
- {0, NOT_ENDURANT},
- {1, ENDURANT}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< ENDURANT_FLD >(iv_target, iv_spd_data);
-
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(ENDURANT_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- ENDURANT_FLD.iv_byte,
- l_field_bits,
- "Failed check for Endurant nominal voltage") );
-
- FAPI_INF("%s. Endurant: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM device width
-/// @param[out] o_value device width in bits
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 12 (bits 2~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 23
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::device_width( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 12 maps
- // Item JC-45-2220.01x
- // Page 23
- // DDR4 SPD Document Release 3
- // Byte 12 (0x00C): Module Organization
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > DEVICE_WIDTH_MAP =
- {
- // {key byte, device width (bits)}
- {0, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4},
- {1, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X8},
- {2, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X16},
- {3, fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X32},
- // All others reserved
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SDRAM_WIDTH >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(DEVICE_WIDTH_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- SDRAM_WIDTH.iv_byte,
- l_field_bits,
- "Failed check for Device Width") );
-
- FAPI_INF("%s. Device Width: %d bits",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes number of package ranks per DIMM
-/// @param[out] o_value number of package ranks per DIMM
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 12 (bits 5~3)
-/// @note Item JC-45-2220.01x
-/// @note Page 23
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::num_package_ranks_per_dimm( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 12 maps
- // Item JC-45-2220.01x
- // Page 23
- // DDR4 SPD Document Release 3
- // Byte 12 (0x00C): Module Organization
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP =
- {
- // {key byte, num of package ranks per DIMM (package ranks)}
- {0, 1},
- {1, 2},
- {2, 3},
- {3, 4},
- {4, 5},
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< PACKAGE_RANKS >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(NUM_PACKAGE_RANKS_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- PACKAGE_RANKS.iv_byte,
- l_field_bits,
- "Failed check for Num Package Ranks Per DIMM") );
-
- FAPI_INF("%s. Num Package Ranks per DIMM: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Rank Mix
-/// @param[out] o_value rank mix value from SPD
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 12 (bit 6)
-/// @note Item JC-45-2220.01x
-/// @note Page 23
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::rank_mix( uint8_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // Decodes SPD Byte 3 (bits 4~6) were reserved
- // and coded as zeros. There was no concept of rank_mix so this
- // is thus hard-wired to zero.
- o_value = 0x00;
- return fapi2::FAPI2_RC_SUCCESS;
-
-}
-
-///
-/// @brief Decodes primary bus width
-/// @param[out] o_value primary bus width in bits
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 13 (bits 2~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 27
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::prim_bus_width( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 13 maps
- // Item JC-45-2220.01x
- // Page 27
- // DDR4 SPD Document Release 3
- // Byte 13 (0x00D): Module Memory Bus Width
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > BUS_WIDTH_MAP =
- {
- // {key byte, bus width (in bits)
- {0, 8},
- {1, 16},
- {2, 32},
- {3, 64}
- // All others reserved
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< BUS_WIDTH >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(BUS_WIDTH_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- BUS_WIDTH.iv_byte,
- l_field_bits,
- "Failed check for Primary Bus Width") );
-
- FAPI_INF("%s. Primary Bus Width: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes bus width extension
-/// @param[out] o_value bus width extension in bits
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 13 (bits 2~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 28
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::bus_width_extension( uint8_t& o_value) const
-{
- // =========================================================
- // Byte 13 maps
- // Item JC-45-2220.01x
- // Page 27
- // DDR4 SPD Document Release 3
- // Byte 13 (0x00D): Module Memory Bus Width
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > BUS_WIDTH_EXT_MAP =
- {
- {0, 0},
- {1, 8}
- // All others reserved
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< BUS_EXT_WIDTH >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(BUS_WIDTH_EXT_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- BUS_EXT_WIDTH.iv_byte,
- l_field_bits,
- "Failed check for Bus Width Extension") );
-
- FAPI_INF("%s. Bus Width Extension (bits): %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decode Module Thermal Sensor
-/// @param[out] o_value thermal sensor value from SPD
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 14 (bit 7)
-/// @note Item JC-45-2220.01x
-/// @note Page 28
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::thermal_sensor( uint8_t& o_value) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< THERM_SENSOR >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check for valid value
- constexpr size_t INVALID_VALUE = 2; // single bit value 0 or 1
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < INVALID_VALUE,
- THERM_SENSOR.iv_byte,
- l_field_bits,
- "Failed check for Thermal Sensor") );
-
- // Update output after check passes
- o_value = l_field_bits;
-
- FAPI_INF("%s. Thermal Sensor: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode Extended Base Module Type
-/// @param[out] o_value raw data from SPD
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 15 (bits 3~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 28
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::extended_base_module_type( uint8_t& o_value) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< EXTENDED_MODULE_TYPE >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check for valid value
- // Currently reserved to 0b000
- constexpr size_t RESERVED = 0;
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits == RESERVED,
- EXTENDED_MODULE_TYPE.iv_byte,
- l_field_bits,
- "Failed check for Extended Base Module Type") );
-
- // Update output for check passes
- o_value = l_field_bits;
-
- FAPI_INF("%s. Extended Base Module Type: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decode Fine Timebase
-/// @param[out] o_value fine_timebase from SPD in picoseconds
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 17 (bits 1~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 29
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_timebase( int64_t& o_value) const
-{
- // =========================================================
- // Byte 17 maps
- // Item JC-45-2220.01x
- // Page 29
- // DDR4 SPD Document Release 3
- // Byte 17 (0x011): Timebases
- // =========================================================
- // Created a maps of a single value in case mapping expands to more values
- static const std::vector<std::pair<uint8_t, int64_t> > FINE_TIMEBASE_MAP =
- {
- // {key byte, fine timebase (in picoseconds)
- {0, 1}
- // All others reserved
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< FINE_TIMEBASE >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(FINE_TIMEBASE_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- FINE_TIMEBASE.iv_byte,
- l_field_bits,
- "Failed check for Fine Timebase") );
-
- FAPI_INF("%s. Fine Timebase: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode Medium Timebase
-/// @param[out] o_value medium timebase from SPD in picoseconds
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 17 (bits 3~2)
-/// @note Item JC-45-2220.01x
-/// @note Page 29
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::medium_timebase( int64_t& o_value) const
-{
- // =========================================================
- // Byte 17 maps
- // Item JC-45-2220.01x
- // Page 29
- // DDR4 SPD Document Release 3
- // Byte 17 (0x011): Timebases
- // =========================================================
- // Created a maps of a single value in case mapping expands to more values
- static const std::vector<std::pair<uint8_t, int64_t> > MEDIUM_TIMEBASE_MAP =
- {
- // {key byte, medium timebase (in picoseconds)
- {0, 125}
- // All others reserved
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< MEDIUM_TIMEBASE >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- const bool l_is_val_found = mss::find_value_from_key(MEDIUM_TIMEBASE_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- MEDIUM_TIMEBASE.iv_byte,
- l_field_bits,
- "Failed check for Medium Timebase") );
-
- FAPI_INF("%s. Medium Timebase: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes SDRAM Minimum Cycle Time in MTB
-/// @param[out] o_value tCKmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 18
-/// @note Item JC-45-2220.01x
-/// @note Page 31-32
-/// @note DDR4 SPD Document Release 3
-/// @warning If tCKmin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tCKmin (SPD byte 125)
-/// used for correction to get the actual value.
-///
-fapi2::ReturnCode decoder_v1_0::min_tck( int64_t& o_value ) const
-{
- // Explicit conversion
- constexpr size_t BYTE_INDEX = 18;
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: %d.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_timing_val);
-
- // Check if value is valid
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the min cycle time (tckmin) in MTB") );
-
- // Update output after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Cycle Time (tCKmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM Maximum Cycle Time in MTB
-/// @param[out] o_value tCKmax in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 19
-/// @note Item JC-45-2220.01x
-/// @note Page 32
-/// @note DDR4 SPD Document Release 3
-/// @warning If tCKmax cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tCKmax (SPD byte 124)
-/// used for correction to get the actual value.
-///
-fapi2::ReturnCode decoder_v1_0::max_tck( int64_t& o_value ) const
-{
- // Explicit conversion
- constexpr size_t BYTE_INDEX = 19;
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: %d.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_timing_val);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the max cycle time (tckmax) in MTB") );
-
- // Update output after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Maximum Cycle Time (tCKmax) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decode CAS Latencies Supported
-/// @param[out] o_value bitmap of supported CAS latencies
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Bytes 20-23
-/// @note Item JC-45-2220.01x
-/// @note Page 33-34
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::supported_cas_latencies( uint64_t& o_value ) const
-{
- // Trace print in the front assists w/ debug
- constexpr size_t FIRST_BYTE = 20;
- uint8_t first_raw_byte = iv_spd_data[FIRST_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- FIRST_BYTE,
- first_raw_byte);
-
- constexpr size_t SEC_BYTE = 21;
- uint8_t sec_raw_byte = iv_spd_data[SEC_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- SEC_BYTE,
- sec_raw_byte);
-
- constexpr size_t THIRD_BYTE = 22;
- uint8_t third_raw_byte = iv_spd_data[THIRD_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- THIRD_BYTE,
- third_raw_byte);
-
- constexpr size_t FOURTH_BYTE = 23;
- uint8_t fourth_raw_byte = iv_spd_data[FOURTH_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- FOURTH_BYTE,
- fourth_raw_byte);
-
- // Buffers used for bit manipulation
- // Combine Bytes to create bitmap - right aligned
- fapi2::buffer<uint64_t> l_buffer;
-
- l_buffer.insertFromRight<CAS_BYTE_1_START, CAS_BYTE_1_LEN>(first_raw_byte)
- .insertFromRight<CAS_BYTE_2_START, CAS_BYTE_2_LEN>(sec_raw_byte)
- .insertFromRight<CAS_BYTE_3_START, CAS_BYTE_3_LEN>(third_raw_byte)
- .insertFromRight<CAS_BYTE_4_START, CAS_BYTE_4_LEN>(fourth_raw_byte);
-
- // According to the JEDEC spec:
- // Byte 22 (Bits 7~0) and Byte 23 are reserved and thus not supported
- constexpr size_t MAX_VALID_VAL = 0x3FFFF;
-
- // Check for a valid value
- uint64_t l_supported_cl = l_buffer;
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_supported_cl <= MAX_VALID_VAL,
- FOURTH_BYTE,
- fourth_raw_byte,
- "Failed check on CAS latencies supported") );
-
- // Update output value only if range check passes
- o_value = l_supported_cl;
-
- FAPI_INF("%s. CAS latencies supported (bitmap): 0x%llX",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes SDRAM Minimum CAS Latency Time in MTB
-/// @param[out] o_value tAAmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 24
-/// @note Item JC-45-2220.01x
-/// @note Page 34
-/// @note DDR4 SPD Document Release 3
-/// @warning If tAAmin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tAAmin (SPD byte 123)
-/// used for correction to get the actual value.
-///
-fapi2::ReturnCode decoder_v1_0::min_taa( int64_t& o_value ) const
-{
- // Explicit conversion
- constexpr size_t BYTE_INDEX = 24;
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_timing_val);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum CAS Latency Time (tAAmin) in MTB") );
-
- // Only update output if it passes check
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum CAS Latency Time (tAAmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB
-/// @param[out] o_value tRCDmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 25
-/// @note Item JC-45-2220.01x
-/// @note Page 35
-/// @note DDR4 SPD Document Release 3
-/// @warning If tRCDmin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tRCDmin (SPD byte 122)
-/// used for correction to get the actual value
-///
-fapi2::ReturnCode decoder_v1_0::min_trcd( int64_t& o_value ) const
-{
- // Explicit conversion
- constexpr size_t BYTE_INDEX = 25;
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_timing_val);
-
- // Find valid value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum RAS to CAS Delay Time (tRCDmin) in MTB") );
-
- // Only update output if it passes check
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum RAS to CAS Delay Time (tRCDmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB
-/// @param[out] o_value tRPmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 26
-/// @note Item JC-45-2220.01x
-/// @note Page 36-37
-/// @note DDR4 SPD Document Release 3
-/// @warning If tRPmin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tRPmin (SPD byte 121)
-/// used for correction to get the actual value
-///
-fapi2::ReturnCode decoder_v1_0::min_trp( int64_t& o_value ) const
-{
- // Explicit conversion
- constexpr size_t BYTE_INDEX = 26;
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_timing_val);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Row Precharge Delay Time (tRPmin) in MTB") );
-
- // Only update output if it passes check
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Row Precharge Delay Time (tRPmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB
-/// @param[out] o_value tRASmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 27 (bits 3~0) & Byte 28 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 38
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_tras( int64_t& o_value) const
-{
- uint8_t tRASmin_MSN = extract_spd_field< TRASMIN_MSN >(iv_target, iv_spd_data);
- FAPI_INF("MSN Field Bits value: %lu", tRASmin_MSN);
-
- uint8_t tRASmin_LSB = extract_spd_field< TRASMIN_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tRASmin_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSN_START = 52;
- constexpr size_t MSN_LEN = 4;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
-
- l_buffer.insertFromRight<MSN_START, MSN_LEN>( tRASmin_MSN )
- .insertFromRight<LSB_START, LSB_LEN>( tRASmin_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // But byte 28 of the JEDEC spec explains how to piece this together - AAM
- constexpr size_t ERROR_BYTE_INDEX = 28;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Active to Precharge Delay Time (tRASmin) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Active to Precharge Delay Time (tRASmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB
-/// @param[out] o_value tRCmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 27 (bits 7~4) & SPD Byte 29 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 38
-/// @note DDR4 SPD Document Release 3
-/// @warning If tRCmin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tRCmin (SPD byte 120)
-/// used for correction to get the actual value.
-///
-fapi2::ReturnCode decoder_v1_0::min_trc( int64_t& o_value) const
-{
- uint8_t tRCmin_MSN = extract_spd_field< TRCMIN_MSN >(iv_target, iv_spd_data);
- FAPI_INF("MSN Field Bits value: %lu", tRCmin_MSN);
-
- uint8_t tRCmin_LSB = extract_spd_field< TRCMIN_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tRCmin_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSN_START = 52;
- constexpr size_t MSN_LEN = 4;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
- l_buffer.insertFromRight<MSN_START, MSN_LEN>( tRCmin_MSN )
- .insertFromRight<LSB_START, LSB_LEN>( tRCmin_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // But byte 29 of the JEDEC spec explains how to piece this together - AAM
- constexpr size_t ERROR_BYTE_INDEX = 29;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Active to Active/Refresh Delay Time (tRCmin) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Active to Active/Refresh Delay Time (tRCmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1
-/// @param[out] o_value tRFC1min in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 30 & Byte 31
-/// @note Item JC-45-2220.01x
-/// @note Page 39-40
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_trfc1( int64_t& o_value) const
-{
- uint8_t tRFC1min_MSB = extract_spd_field< TRFC1MIN_MSB >(iv_target, iv_spd_data);
- FAPI_INF("MSB Field Bits value: %lu", tRFC1min_MSB);
-
- uint8_t tRFC1min_LSB = extract_spd_field< TRFC1MIN_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tRFC1min_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSB_START = 48;
- constexpr size_t MSB_LEN = 8;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
-
- l_buffer.insertFromRight<MSB_START, MSB_LEN>( tRFC1min_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( tRFC1min_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // Chose one of them (byte 30) to for error printout of this decode
- constexpr size_t ERROR_BYTE_INDEX = 30;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Refresh Recovery Delay Time 1 (tRFC1min) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Refresh Recovery Delay Time 1 (tRFC1min) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2
-/// @param[out] o_value tRFC2min in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 32 & Byte 33
-/// @note Item JC-45-2220.01x
-/// @note Page 40
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_trfc2( int64_t& o_value) const
-{
- uint8_t tRFC2min_MSB = extract_spd_field< TRFC2MIN_MSB >(iv_target, iv_spd_data);
- FAPI_INF("MSB Field Bits value: %lu", tRFC2min_MSB);
-
- uint8_t tRFC2min_LSB = extract_spd_field< TRFC2MIN_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tRFC2min_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSB_START = 48;
- constexpr size_t MSB_LEN = 8;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
-
- l_buffer.insertFromRight<MSB_START, MSB_LEN>( tRFC2min_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( tRFC2min_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // Chose one of them (byte 33) to for error printout of this decode
- constexpr size_t ERROR_BYTE_INDEX = 33;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Refresh Recovery Delay Time 2 (tRFC2min) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Refresh Recovery Delay Time 2 (tRFC2min) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4
-/// @param[out] o_value tRFC4min in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 34 & Byte 35
-/// @note Item JC-45-2220.01x
-/// @note Page 40
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_trfc4( int64_t& o_value) const
-{
- uint8_t tRFC4min_MSB = extract_spd_field< TRFC4MIN_MSB >(iv_target, iv_spd_data);
- FAPI_INF("MSB Field Bits value: %lu", tRFC4min_MSB);
-
- uint8_t tRFC4min_LSB = extract_spd_field< TRFC4MIN_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tRFC4min_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSB_START = 48;
- constexpr size_t MSB_LEN = 8;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
-
- l_buffer.insertFromRight<MSB_START, MSB_LEN>( tRFC4min_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( tRFC4min_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // Chose one of them (byte 34) for error printout of this decode
- constexpr size_t ERROR_BYTE_INDEX = 34;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Refresh Recovery Delay Time 4 (tRFC4min) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Refresh Recovery Delay Time 4 (tRFC4min) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes SDRAM Minimum Four Activate Window Delay Time
-/// @param[out] o_value tFAWmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 36 (bits 3~0) & Byte 37 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 42
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_tfaw( int64_t& o_value) const
-{
- uint8_t tFAWmin_MSN = extract_spd_field< TFAWMIN_MSN >(iv_target, iv_spd_data);
- FAPI_INF("MSN Field Bits value: %lu", tFAWmin_MSN);
-
- uint8_t tFAWmin_LSB = extract_spd_field< TFAWMIN_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tFAWmin_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSN_START = 52;
- constexpr size_t MSN_LEN = 4;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
-
- l_buffer.insertFromRight<MSN_START, MSN_LEN>( tFAWmin_MSN ).
- insertFromRight<LSB_START, LSB_LEN>( tFAWmin_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 65535; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // Chose one of them (byte 37) to for error printout of this decode
- constexpr size_t ERROR_BYTE_INDEX = 37;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Four Activate Window Delay Time (tFAWmin) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Four Activate Window Delay Time (tFAWmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group
-/// @param[out] o_value tRRD_Smin MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 38
-/// @note Item JC-45-2220.01x
-/// @note Page 43
-/// @note DDR4 SPD Document Release 3
-/// @warning If tRRD_Smin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tRRD_Smin (SPD byte 119)
-/// used for correction to get the actual value.
-///
-fapi2::ReturnCode decoder_v1_0::min_trrd_s( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 38;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Minimum Activate to Activate Delay Time - Different Bank Group
- // explicit conversion to int64_t
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Find valid value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin) in MTB") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group
-/// @param[out] o_value tRRD_Lmin MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 39
-/// @note Item JC-45-2220.01x
-/// @note Page 43-44
-/// @note DDR4 SPD Document Release 3
-/// @warning If tRRD_Lmin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tRRD_Lmin (SPD byte 118)
-/// used for correction to get the actual value.
-///
-fapi2::ReturnCode decoder_v1_0::min_trrd_l( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 39;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Minimum Activate to Activate Delay Time - Same Bank Group
- // explicit conversion to int64_t
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Find valid value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on Minimum Activate to Activate Delay Time - Same Bank Group (tRRD_Lmin) in MTB") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Activate to Activate Delay Time - Same Bank Group (tRRD_Lmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group
-/// @param[out] o_value tCCD_Lmin MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 40
-/// @note Item JC-45-2220.01x
-/// @note Page 44-45
-/// @note DDR4 SPD Document Release 3
-/// @warning If tCCD_Lmin cannot be divided evenly by the MTB,
-/// this byte must be rounded up to the next larger
-/// integer and the Fine Offset for tCCD_Lmin (SPD byte 117)
-/// used for correction to get the actual value.
-///
-fapi2::ReturnCode decoder_v1_0::min_tccd_l( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 40;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Minimum CAS to CAS Delay Time - Same Bank Group
- // explicit conversion to int64_t
- int64_t l_timing_val = int64_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 255; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on Minimum CAS to CAS Delay Time - Same Bank Group (tCCD_Lmin) in MTB") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum CAS to CAS Delay Time - Same Bank Group (tCCD_Lmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Minimum Write Recovery Time
-/// @param[out] o_value tWRmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 40
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_twr( int64_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0) were reserved
- // and coded as zeros.
- // Default as 0x78 for all DDR4 bins for rev 1.0
- // No value given in 1.0 JEDEC spec and no value in SPD - JLH
- // 1.1 Has valid values defined and in SPD, this is taken from there
- o_value = 0x78;
- return fapi2::FAPI2_RC_SUCCESS;
-
-}
-
-///
-/// @brief Decodes Minimum Write to Read Time - Different Bank Group
-/// @param[out] o_value tWRT_Smin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 40
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_twtr_s( int64_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0) were reserved
- // and coded as zeros.
- // Default as 0x14 for all DDR4 bins for rev 1.0
- // No value given in 1.0 JEDEC spec and no value in SPD - JLH
- // 1.1 Has valid values defined and in SPD, this is taken from there
- o_value = 0x14;
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes Minimum Write to Read Time - Same Bank Group
-/// @param[out] o_value tWRT_Lmin in MTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 46
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::min_twtr_l( int64_t& o_value) const
-{
- // For General Section rev 1.0 of the SPD,
- // SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0) were reserved
- // and coded as zeros.
- // Default as 0x3C for all DDR4 bins for rev 1.0
- // No value given in 1.0 JEDEC spec and no value in SPD - JLH
- // 1.1 Has valid values defined and in SPD, this is taken from there
- o_value = 0x3C;
- return fapi2::FAPI2_RC_SUCCESS;
-
-}
-
-///
-/// @brief Decodes Package Rank Map
-/// @param[out] o_value vector of package rank maps for SPD bytes 60 - 77
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 60 - 77
-/// @note JEDEC Standard No. 21-C
-/// @note Page 45
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::package_rank_map( std::vector<uint8_t>& o_value ) const
-{
- o_value.clear();
-
- FAPI_TRY( (sdram_connector_helper<DQ0_31, PKG_RANK_MAP>(o_value)),
- "%s Failed to sdram_connector_helper for DQ0_31, PKG_RANK_MAP", iv_target_str_storage );
-
- FAPI_TRY( (sdram_connector_helper<DQ32_63, PKG_RANK_MAP>(o_value)),
- "%s Failed to sdram_connector_helper for DQ32_63, PKG_RANK_MAP", iv_target_str_storage );
-
- FAPI_TRY( (sdram_connector_helper<CB0_7, PKG_RANK_MAP>(o_value)),
- "%s Failed to sdram_connector_helper for CB0_7, PKG_RANK_MAP", iv_target_str_storage );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Nibble map
-/// @param[out] o_value vector of bit order encoding for SPD bytes 60 - 77
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 60 - 77
-/// @note JEDEC Standard No. 21-C
-/// @note Page 45
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::nibble_map( std::vector<uint8_t>& o_value ) const
-{
- o_value.clear();
-
- FAPI_TRY( (sdram_connector_helper<DQ0_31, NIBBLE_MAP>(o_value)),
- "%s Failed to sdram_connector_helper for DQ0_31, NIBBLE_MAP", iv_target_str_storage );
-
- FAPI_TRY( (sdram_connector_helper<DQ32_63, NIBBLE_MAP>(o_value)),
- "%s Failed to sdram_connector_helper for DQ32_63, NIBBLE_MAP", iv_target_str_storage );
-
- FAPI_TRY( (sdram_connector_helper<CB0_7, NIBBLE_MAP>(o_value)),
- "%s Failed to sdram_connector_helper for CB0_7, NIBBLE_MAP", iv_target_str_storage );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Fine Offset for Minimum CAS to CAS Delay Time - Same Bank Group
-/// @param[out] o_value tCCD_Lmin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 117
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_tccd_l( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 117;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for Minimum CAS to CAS Delay Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the fine offset for min RAS to CAS Delay Time (tCCD_Lmin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum RAS to CAS Delay Time (tCCD_Lmin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group
-/// @param[out] o_value tRRD_Lmin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 118
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_trrd_l( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 118;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for Minimum Activate to Activate Delay Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the fine offset for Minimum Activate to Activate Delay Time (tRRD_Lmin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum Activate to Activate Delay Time (tRRD_Lmin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group
-/// @param[out] o_value tRRD_Smin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 119
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_trrd_s( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 119;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the fine offset for Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum Activate to Activate Delay Time - Different Bank Group (tRRD_Smin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time
-/// @param[out] o_value tRCmin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 120
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_trc( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 120;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for Minimum Active to Active/Refresh Delay Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for vali value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the fine offset for Minimum Active to Active/Refresh Delay Time (tRCmin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum Active to Active/Refresh Delay Time (tRCmin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time
-/// @param[out] o_value tRPmin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 121
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_trp( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 121;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for Minimum Row Precharge Delay Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the fine offset for Minimum Row Precharge Delay Time (tRPmin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum Row Precharge Delay Time (tRPmin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-///
-/// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time
-/// @param[out] o_value tRCDmin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 122
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_trcd( int64_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 122;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for SDRAM Minimum RAS to CAS Delay Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the fine offset for min RAS to CAS Delay Time (tRCDmin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum RAS to CAS Delay Time (tRCDmin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time
-/// @param[out] o_value tAAmin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 123
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_taa( int64_t& o_value ) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 123;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for SDRAM Minimum CAS Latency Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the Fine offset for Minimum CAS Latency Time (tAAmin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum CAS Latency Time (tAAmin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time
-/// @param[out] o_value tCKmax offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 124
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_max_tck( int64_t& o_value ) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 124;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for SDRAM Maximum Cycle Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the fine offset for max cycle time (tckmax)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Maximum Cycle Time (tCKmax) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time
-/// @param[out] o_value tCKmin offset in FTB units
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 125
-/// @note Item JC-45-2220.01x
-/// @note Page 52
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::fine_offset_min_tck( int64_t& o_value ) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 125;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- // Retrieve Fine Offset for SDRAM Minimum Cycle Time
- // int8_t conversion - allows me to get a negative offset
- // then implicit conversion to int64_t
- int64_t l_timing_val = int8_t(iv_spd_data[BYTE_INDEX]);
-
- // Check for valid value
- constexpr int64_t TIMING_LOWER_BOUND = -128; // from JEDEC
- constexpr int64_t TIMING_UPPER_BOUND = 127; // from JEDEC
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- BYTE_INDEX,
- l_timing_val,
- "Failed check on the Fine offset for Minimum Cycle Time (tCKmin)") );
-
- // Update output value only if range check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Fine offset for Minimum Cycle Time (tCKmin) in FTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section
-/// @param[out] o_value crc value from SPD
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 127 & Byte 126
-/// @note Item JC-45-2220.01x
-/// @note Page 53
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::cyclical_redundancy_code( uint16_t& o_value ) const
-{
- uint8_t crc_MSB = extract_spd_field< CRC_MSB >(iv_target, iv_spd_data);
- FAPI_INF("MSB Field Bits value: %lu", crc_MSB);
-
- uint8_t crc_LSB = extract_spd_field< CRC_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", crc_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSN_START = 0;
- constexpr size_t MSN_LEN = 8;
- constexpr size_t LSB_START = 8;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<uint16_t> l_buffer;
- l_buffer.insertFromRight<MSN_START, MSN_LEN>( crc_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( crc_LSB );
-
- // This value isn't bounded in the SPD document
- o_value = l_buffer;
-
- FAPI_INF("%s. Cyclical Redundancy Code (CRC): %d",
- iv_target_str_storage,
- o_value);
-
- // Returns "happy" until we can figure out a way to test this - AAM
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes module manufacturer ID code
-/// @param[out] o_value module manufacturing id code
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 320 (bit 7~0), 321 (6~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12 - 54
-///
-fapi2::ReturnCode decoder_v1_0::module_manufacturer_id_code( uint16_t& o_value ) const
-{
-
- constexpr size_t BYTE_INDEX_MSB = 320;
- uint8_t mfgid_MSB = iv_spd_data[BYTE_INDEX_MSB];
-
- constexpr size_t BYTE_INDEX_LSB = 321;
- uint8_t mfgid_LSB = iv_spd_data[BYTE_INDEX_LSB];
-
- constexpr size_t MSB_START = 0;
- constexpr size_t MSB_LEN = 8;
- constexpr size_t LSB_START = 8;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<uint16_t> l_buffer;
- l_buffer.insertFromRight<MSB_START, MSB_LEN>( mfgid_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( mfgid_LSB );
-
- o_value = l_buffer;
-
- FAPI_INF("%s.Module Manufacturer ID Code: %x",
- iv_target_str_storage,
- o_value);
-
- // Returns "happy" until we can figure out a way to test this - AAM
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes Module Manufacturing Location
-/// @param[out] o_value uint8_t identifier for manufacturing location of memory module
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 322
-/// @note Item JC-45-2220.01x
-/// @note Page 55
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::module_manufacturing_location( uint8_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 322;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- o_value = iv_spd_data[BYTE_INDEX];
-
- FAPI_INF("%s. Module Manufacturing Location: %x",
- iv_target_str_storage,
- o_value);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodesmodule manufacturing date
-/// @param[out] o_value the 2 byte date of manufacturing in BCD format
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 323-324
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 54
-/// @note in Binary Coded Decimal (BCD)
-/// @note MSB = year, LSB = week
-///
-fapi2::ReturnCode decoder_v1_0::module_manufacturing_date( uint16_t& o_value ) const
-{
-
- constexpr size_t BYTE_INDEX_MSB = 323;
- uint8_t date_MSB = iv_spd_data[BYTE_INDEX_MSB];
-
- constexpr size_t BYTE_INDEX_LSB = 324;
- uint8_t date_LSB = iv_spd_data[BYTE_INDEX_LSB];
-
- constexpr size_t MSB_START = 0;
- constexpr size_t MSB_LEN = 8;
- constexpr size_t LSB_START = 8;
- constexpr size_t LSB_LEN = 8;
-
- //Using insertFromRight because IBM is backwards
- fapi2::buffer<uint16_t> l_buffer;
- l_buffer.insertFromRight<MSB_START, MSB_LEN>( date_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( date_LSB );
-
- o_value = l_buffer;
-
- FAPI_INF("%s.Module Manufacturer ID date: %x",
- iv_target_str_storage,
- o_value);
-
- // Returns "happy" until we can figure out a way to test this - AAM
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes module's unique serial number
-/// @param[out] o_value
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 325-328
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 54
-/// @note in Binary Coded Decimal (BCD)
-///
-fapi2::ReturnCode decoder_v1_0::module_serial_number( uint32_t& o_value ) const
-{
- constexpr size_t BYTE_INDEX_0 = 325;
- uint8_t sn_byte_0 = iv_spd_data[BYTE_INDEX_0];
-
- constexpr size_t BYTE_INDEX_1 = 326;
- uint8_t sn_byte_1 = iv_spd_data[BYTE_INDEX_1];
-
- constexpr size_t BYTE_INDEX_2 = 327;
- uint8_t sn_byte_2 = iv_spd_data[BYTE_INDEX_2];
-
- constexpr size_t BYTE_INDEX_3 = 328;
- uint8_t sn_byte_3 = iv_spd_data[BYTE_INDEX_3];
-
- constexpr size_t START_BYTE_0 = 0;
- constexpr size_t LEN_BYTE_0 = 8;
- constexpr size_t START_BYTE_1 = 8;
- constexpr size_t LEN_BYTE_1 = 8;
- constexpr size_t START_BYTE_2 = 16;
- constexpr size_t LEN_BYTE_2 = 8;
- constexpr size_t START_BYTE_3 = 24;
- constexpr size_t LEN_BYTE_3 = 8;
-
- //Goes down the batting order, Inserts from left side because IBM
- fapi2::buffer<uint32_t> l_buffer;
- l_buffer.insertFromRight<START_BYTE_0, LEN_BYTE_0>( sn_byte_0 )
- .insertFromRight<START_BYTE_1, LEN_BYTE_1>( sn_byte_1 )
- .insertFromRight<START_BYTE_2, LEN_BYTE_2>( sn_byte_2 )
- .insertFromRight<START_BYTE_3, LEN_BYTE_3>( sn_byte_3 );
-
- o_value = l_buffer;
-
- FAPI_INF("%s.Module Serial Number : %x",
- iv_target_str_storage,
- o_value);
-
- // Returns "happy" until we can figure out a way to test this - AAM
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes Module Revision Code
-/// @param[out] o_value uint8_t identifier for revision code
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 349
-/// @note Item JC-45-2220.01x
-/// @note Page 55
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_0::module_revision_code( uint8_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 349;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- o_value = iv_spd_data[BYTE_INDEX];
-
- FAPI_INF("%s. Module Revision Code: %x",
- iv_target_str_storage,
- o_value);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes DRAM Manufacturer ID code
-/// @param[out] o_value dram manufacturing id code
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 350 351
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 54
-///
-fapi2::ReturnCode decoder_v1_0::dram_manufacturer_id_code( uint16_t& o_value ) const
-{
- constexpr size_t BYTE_INDEX_MSB = 350;
- uint8_t mfgid_MSB = iv_spd_data[BYTE_INDEX_MSB];
-
- constexpr size_t BYTE_INDEX_LSB = 351;
- uint8_t mfgid_LSB = iv_spd_data[BYTE_INDEX_LSB];
-
- constexpr size_t MSB_START = 0;
- constexpr size_t MSB_LEN = 8;
- constexpr size_t LSB_START = 8;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<uint16_t> l_buffer;
- l_buffer.insertFromRight<MSB_START, MSB_LEN>( mfgid_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( mfgid_LSB );
-
- o_value = l_buffer;
-
- FAPI_INF("%s.DRAM Manufacturer ID Code (dram_mfg_id): %x",
- iv_target_str_storage,
- o_value);
-
- // Returns "happy" until we can figure out a way to test this - AAM
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes REGISTER Manufacturer ID code
-/// @param[out] o_value rcd manufacturing id code
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 133-134
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 54
-///
-fapi2::ReturnCode decoder_v1_0::reg_manufacturer_id_code( uint16_t& o_value ) const
-{
- constexpr size_t BYTE_INDEX_LSB = 133;
- uint8_t mfgid_LSB = iv_spd_data[BYTE_INDEX_LSB];
-
- constexpr size_t BYTE_INDEX_MSB = 134;
- uint8_t mfgid_MSB = iv_spd_data[BYTE_INDEX_MSB];
-
- constexpr size_t MSB_START = 0;
- constexpr size_t MSB_LEN = 8;
- constexpr size_t LSB_START = 8;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<uint16_t> l_buffer;
- l_buffer.insertFromRight<MSB_START, MSB_LEN>( mfgid_MSB )
- .insertFromRight<LSB_START, LSB_LEN>( mfgid_LSB );
-
- o_value = l_buffer;
-
- FAPI_INF("%s.RCD Manufacturer ID Code (rcd_mfg_id): %x",
- iv_target_str_storage,
- o_value);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes Register Revision Number
-/// @param[out] o_value register revision number
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 135
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 54
-///
-fapi2::ReturnCode decoder_v1_0::register_rev_num( uint8_t& o_value ) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 135;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%01X.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- o_value = iv_spd_data[BYTE_INDEX];
-
- FAPI_INF("%s. Register Revision Number: %x",
- iv_target_str_storage,
- o_value);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes DRAM Stepping
-/// @param[out] o_value uint8_t DRAM Stepping val
-/// @return FAPI2_RC_SUCCESS iff okay
-/// @note SPD Byte 353
-/// @note Item JC-45-2220.01x
-/// @note Page 56
-/// @note DDR4 SPD Document Release 3
-/// @note also called die revision level
-///
-fapi2::ReturnCode decoder_v1_0::dram_stepping( uint8_t& o_value) const
-{
- // Trace in the front assists w/ debug
- constexpr size_t BYTE_INDEX = 352;
-
- FAPI_INF("%s SPD data at Byte %d: 0x%01X.",
- iv_target_str_storage,
- BYTE_INDEX,
- iv_spd_data[BYTE_INDEX]);
-
- o_value = iv_spd_data[BYTE_INDEX];
-
- FAPI_INF("%s. DRAM stepping: %x",
- iv_target_str_storage,
- o_value);
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Returns Logicalranks in Primary SDRAM type
-/// @param[out] o_logical_ranks number of logical ranks
-/// @return fapi2::FAPI2_RC_SUCCESS iff okay
-///
-fapi2::ReturnCode decoder_v1_0::prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const
-{
- uint8_t l_signal_loading = 0;
- uint8_t l_ranks_per_dimm = 0;
-
- FAPI_TRY( prim_sdram_signal_loading(l_signal_loading) );
- FAPI_TRY( num_package_ranks_per_dimm(l_ranks_per_dimm) );
-
- if(l_signal_loading == spd::SINGLE_LOAD_STACK)
- {
- // For single-load-stack(3DS) the logical ranks per package ends up being the same as the die count.
- uint8_t l_die_count = 0;
- FAPI_TRY( prim_sdram_die_count(l_die_count) );
-
- o_logical_ranks = l_ranks_per_dimm * l_die_count;
- }
- else
- {
- // Covers case for MONOLITHIC & MULTI_LOAD_STACK
- // The die count isn't guaranteed to be 1 (e.g. SDP - 1 die package, DDP - 2 die package).
- // Value of 1 is used for calculation purposes as defined by the SPD spec.
- o_logical_ranks = l_ranks_per_dimm;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Returns Logical ranks per DIMM
-/// @param[in] i_pDecoder shared pointer to the SPD decoder
-/// @param[out] o_logical_ranks number of logical ranks
-/// @return fapi2::FAPI2_RC_SUCCESS iff okay
-///
-fapi2::ReturnCode decoder_v1_0::logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const
-{
- FAPI_TRY( prim_sdram_logical_ranks(o_logical_rank_per_dimm) );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}// ddr4
-}//spd
-}// mss
diff --git a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C b/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C
deleted file mode 100644
index ca08de944..000000000
--- a/src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C
+++ /dev/null
@@ -1,760 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4_v1_1.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-///
-/// @file spd_decoder_v1_1.C
-/// @brief SPD decoder definitions
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/spd/spd_checker.H>
-#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-namespace mss
-{
-namespace spd
-{
-namespace ddr4
-{
-
-/////////////////////////
-// Member method definitions
-/////////////////////////
-
-///
-/// @brief ctor
-/// @param[in] i_target dimm target
-/// @param[in] i_spd_data SPD data vector
-/// @param[in] i_module_decoder shared_ptr to dimm module decoder
-/// @param[in] i_raw_card raw card data structure
-///
-decoder_v1_1::decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- const std::shared_ptr<dimm_module_decoder>& i_module_decoder,
- const rcw_settings& i_raw_card)
- : decoder_v1_0(i_target, i_spd_data, i_module_decoder, i_raw_card)
-{}
-
-///
-/// @brief Decodes SDRAM density from SPD
-/// @param[out] o_value SDRAM density in GBs
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 4 (bits 0~3)
-/// @note Item JC-45-2220.01x
-/// @note Page 18
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::sdram_density( uint8_t& o_value ) const
-{
- // =========================================================
- // Byte 4 maps
- // Item JC-45-2220.01x
- // Page 18
- // DDR4 SPD Document Release 3
- // Byte 4 (0x004): SDRAM Density and Banks
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > SDRAM_DENSITY_MAP =
- {
- // {key byte, capacity in GBs}
- {2, 1},
- {3, 2},
- {4, 4},
- {5, 8},
- {6, 16},
- {7, 32},
- {8, 12},
- {12, 24}
- };
-
- // Extracting desired biits
- const uint8_t l_field_bits = extract_spd_field< SDRAM_CAPACITY >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Check to assure SPD DRAM capacity (map) wont be at invalid values
- bool l_is_val_found = mss::find_value_from_key(SDRAM_DENSITY_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- SDRAM_CAPACITY.iv_byte,
- l_field_bits,
- "Failed check for SPD DRAM capacity") );
-
- FAPI_INF("%s. SDRAM density: %d Gb",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Secondary SDRAM signal loading
-/// @param[out] o_value enum representing signal loading type
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 10 (bits 1~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::sec_sdram_signal_loading( uint8_t& o_value ) const
-{
- // =========================================================
- // Byte 10 maps
- // Item JC-45-2220.01x
- // Page 21-22
- // DDR4 SPD Document Release 3
- // Byte 10 (0x00A): Secondary SDRAM Package Type
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > SEC_SIGNAL_LOADING_MAP =
- {
- // {key byte, signal loading}
- {0, UNSPECIFIED},
- {1, MULTI_LOAD_STACK},
- {2, SINGLE_LOAD_STACK}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SEC_SIGNAL_LOADING >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- bool l_is_val_found = mss::find_value_from_key(SEC_SIGNAL_LOADING_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- SEC_SIGNAL_LOADING.iv_byte,
- l_field_bits,
- "Failed check for Secondary SDRAM Signal Loading") );
-
- FAPI_INF("%s. Secondary SDRAM Signal Loading: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode Soft post package repair (soft PPR)
-/// @param[out] o_value enum representing if soft PPR is supported
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 9 (bit 5)
-/// @note Item JC-45-2220.01x
-/// @note Page 21
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::soft_post_package_repair( uint8_t& o_value ) const
-{
- // =========================================================
- // Byte 9 maps
- // Item JC-45-2220.01x
- // Page 21
- // DDR4 SPD Document Release 3
- // Byte 9 (0x009): Other SDRAM Optional Features
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > SOFT_PPR_MAP =
- {
- // {key byte, value }
- {0, fapi2::ENUM_ATTR_EFF_DRAM_SOFT_PPR_NOT_SUPPORTED},
- {1, fapi2::ENUM_ATTR_EFF_DRAM_SOFT_PPR_SUPPORTED}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SOFT_PPR >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- bool l_is_val_found = mss::find_value_from_key(SOFT_PPR_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target,
- l_is_val_found,
- SOFT_PPR.iv_byte,
- l_field_bits,
- "Failed check for Soft PPR") );
-
- FAPI_INF("%s. Soft Post Package Repair (Soft PPR): %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Secondary DRAM Density Ratio
-/// @param[out] o_value raw bits from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 10 (bits 3~2)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::sec_dram_density_ratio( uint8_t& o_value ) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SEC_DENSITY_RATIO >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- constexpr size_t UNDEFINED = 3; // JEDEC map doesn't go beyond 3
-
- FAPI_TRY( mss::check::spd:: fail_for_invalid_value(iv_target,
- l_field_bits < UNDEFINED,
- SEC_DENSITY_RATIO.iv_byte,
- l_field_bits,
- "Failed check for DRAM Density Ratio") );
-
- FAPI_INF("%s. DRAM Density Ratio: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes Secondary SDRAM die count
-/// @param[out] o_value die count
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 10 (bits 6~4)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::sec_sdram_die_count( uint8_t& o_value ) const
-{
- // =========================================================
- // Byte 10 maps
- // Item JC-45-2220.01x
- // Page 21-22
- // DDR4 SPD Document Release 3
- // Byte 10 (0x00A): Secondary SDRAM Package Type
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > SEC_DIE_COUNT_MAP =
- {
- // {key byte, number of die}
- {0, 1},
- {1, 2},
- {2, 3},
- {3, 4},
- {4, 5},
- {5, 6},
- {6, 7},
- {7, 8}
-
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SEC_DIE_COUNT >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- bool l_is_val_found = mss::find_value_from_key(SEC_DIE_COUNT_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- SEC_DIE_COUNT.iv_byte,
- l_field_bits,
- "Failed check for Secondary Die Count") );
-
- FAPI_INF("%s. Secondary Die Count: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Secondary SDRAM package type
-/// @param[out] o_value enum representing package type
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 10 (bit 7)
-/// @note Item JC-45-2220.01x
-/// @note Page 22
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::sec_sdram_package_type( uint8_t& o_value ) const
-{
- // =========================================================
- // Byte 10 maps
- // Item JC-45-2220.01x
- // Page 21-22
- // DDR4 SPD Document Release 3
- // Byte 10 (0x00A): Secondary SDRAM Package Type
- // =========================================================
-
- static const std::vector<std::pair<uint8_t, uint8_t> > SEC_PACKAGE_TYPE_MAP =
- {
- // {key byte, value }
- {0, MONOLITHIC},
- {1, NON_MONOLITHIC}
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< SEC_PACKAGE_TYPE >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- bool l_is_val_found = mss::find_value_from_key(SEC_PACKAGE_TYPE_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- SEC_PACKAGE_TYPE.iv_byte,
- l_field_bits,
- "Failed check for Secondary Package Type") );
-
- FAPI_INF("%s. Secondary Package Type: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes number of package ranks per DIMM
-/// @param[out] o_value number of package ranks per DIMM
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 12 (bits 5~3)
-/// @note Item JC-45-2220.01x
-/// @note Page 23
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::num_package_ranks_per_dimm( uint8_t& o_value ) const
-{
- // =========================================================
- // Byte 12 maps
- // Item JC-45-2220.01x
- // Page 23
- // DDR4 SPD Document Release 3
- // Byte 12 (0x00C): Module Organization
- // =========================================================
- static const std::vector<std::pair<uint8_t, uint8_t> > NUM_PACKAGE_RANKS_MAP =
- {
- // {key byte, num of package ranks per DIMM (package ranks)}
- {0, 1},
- {1, 2},
- {2, 3},
- {3, 4},
- {4, 5},
- {5, 6},
- {6, 7},
- {7, 8},
- };
-
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< PACKAGE_RANKS >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- bool l_is_val_found = mss::find_value_from_key(NUM_PACKAGE_RANKS_MAP, l_field_bits, o_value);
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_is_val_found,
- PACKAGE_RANKS.iv_byte,
- l_field_bits,
- "Failed check for Num Package Ranks Per DIMM") );
-
- FAPI_INF("%s. Num Package Ranks per DIMM: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Rank Mix
-/// @param[out] o_value rank mix value from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 12 (bit 6)
-/// @note Item JC-45-2220.01x
-/// @note Page 23
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::rank_mix( uint8_t& o_value ) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< RANK_MIX >(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // Find map value
- constexpr size_t INVALID_VALUE = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits < INVALID_VALUE),
- RANK_MIX.iv_byte,
- l_field_bits,
- "Failed check for Rank Mix") );
-
- // Update output after check passes
- o_value = l_field_bits;
-
- FAPI_INF("%s. Rank Mix: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decode CAS Latencies Supported
-/// @param[out] o_value bitmap of supported CAS latencies
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Bytes 20-23
-/// @note Item JC-45-2220.01x
-/// @note Page 33-34
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::supported_cas_latencies( uint64_t& o_value ) const
-{
- // Trace print in the front assists w/ debug
- constexpr size_t FIRST_BYTE = 20;
- uint8_t first_raw_byte = iv_spd_data[FIRST_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- FIRST_BYTE,
- first_raw_byte);
-
- constexpr size_t SEC_BYTE = 21;
- uint8_t sec_raw_byte = iv_spd_data[SEC_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- SEC_BYTE,
- sec_raw_byte);
-
- constexpr size_t THIRD_BYTE = 22;
- uint8_t third_raw_byte = iv_spd_data[THIRD_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- THIRD_BYTE,
- third_raw_byte);
-
- constexpr size_t FOURTH_BYTE = 23;
- uint8_t fourth_raw_byte = iv_spd_data[FOURTH_BYTE];
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- FOURTH_BYTE,
- fourth_raw_byte);
-
- // Buffers used for bit manipulation
- // Combine Bytes to create bitmap - right aligned
- fapi2::buffer<uint64_t> l_buffer;
-
- l_buffer.insertFromRight<CAS_BYTE_1_START, CAS_BYTE_1_LEN>(first_raw_byte)
- .insertFromRight<CAS_BYTE_2_START, CAS_BYTE_2_LEN>(sec_raw_byte)
- .insertFromRight<CAS_BYTE_3_START, CAS_BYTE_3_LEN>(third_raw_byte)
- .insertFromRight<CAS_BYTE_4_START, CAS_BYTE_4_LEN>(fourth_raw_byte);
-
- // According to the JEDEC spec:
- // Byte 23 bit 6 is reserved and must be coded as 0.
- // Should we warn instead of fail because in last revision this was a reserved byte coded as 0x00
- constexpr size_t BIT_START = 33; // relative position of bit 6 in byte 23 relative to uint64_t
- constexpr size_t BIT_LEN = 1;
-
- // Check for a valid value
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- !(l_buffer.getBit<BIT_START, BIT_LEN>()),
- FOURTH_BYTE,
- fourth_raw_byte,
- "Failed check on CAS latencies supported") );
-
- // Update output value only if range check passes
- o_value = l_buffer;
-
- FAPI_INF("%s. CAS latencies supported (bitmap): 0x%llX",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Minimum Write Recovery Time
-/// @param[out] o_value tWRmin in MTB units
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 41 (bits 3~0) & Byte 42 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 40
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::min_twr( int64_t& o_value ) const
-{
- uint8_t tWRmin_MSN = extract_spd_field< TWRMIN_MSN >(iv_target, iv_spd_data);
- FAPI_INF("MSN Field Bits value: %lu", tWRmin_MSN);
-
- uint8_t tWRmin_LSB = extract_spd_field< TWRMIN_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tWRmin_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSN_START = 52;
- constexpr size_t MSN_LEN = 4;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
- l_buffer.insertFromRight<MSN_START, MSN_LEN>( tWRmin_MSN ).
- insertFromRight<LSB_START, LSB_LEN>( tWRmin_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- // This value used to be reserved to 0 - before spec update
- // constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
-
- constexpr int64_t TIMING_LOWER_BOUND = 0;
- constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // Chose one of them (byte 42) to for error printout of this decode
- constexpr size_t ERROR_BYTE_INDEX = 42;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Write Recovery Time (tWRmin) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Write Recovery Time (tWRmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes Minimum Write to Read Time - Different Bank Group
-/// @param[out] o_value tWTR_Smin in MTB units
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 43 (bits 3~0) & Byte 44 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 40
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::min_twtr_s( int64_t& o_value ) const
-{
- uint8_t tWTR_Smin_MSN = extract_spd_field< TWTRMIN_S_MSN >(iv_target, iv_spd_data);
- FAPI_INF("MSN Field Bits value: %lu", tWTR_Smin_MSN);
-
- uint8_t tWTR_Smin_LSB = extract_spd_field< TWTRMIN_S_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tWTR_Smin_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSN_START = 52;
- constexpr size_t MSN_LEN = 4;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
-
- l_buffer.insertFromRight<MSN_START, MSN_LEN>( tWTR_Smin_MSN )
- .insertFromRight<LSB_START, LSB_LEN>( tWTR_Smin_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
-
- // This value used to be reserved to 0 - before spec update - AAM
- // constexpr int64_t TIMING_LOWER_BOUND = 1; // from JEDEC
- constexpr int64_t TIMING_LOWER_BOUND = 0;
- constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // Chose one of them (byte 44) to for error printout of this decode
- constexpr size_t ERROR_BYTE_INDEX = 44;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Write to Read Time - Different Bank Group (tWTR_Smin) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Write to Read Time - Different Bank Group (tWTR_Smin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes Minimum Write to Read Time - Same Bank Group
-/// @param[out] o_value tWTR_Lmin in MTB units
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 43 (bits 7~4) & Byte 45 (bits 7~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 46
-/// @note DDR4 SPD Document Release 3
-///
-fapi2::ReturnCode decoder_v1_1::min_twtr_l( int64_t& o_value ) const
-{
- // Extracting desired bits
- uint8_t tWTR_Lmin_MSN = extract_spd_field< TWTRMIN_L_MSN >(iv_target, iv_spd_data);
- FAPI_INF("MSN Field Bits value: %lu", tWTR_Lmin_MSN);
-
- uint8_t tWTR_Lmin_LSB = extract_spd_field< TWTRMIN_L_LSB >(iv_target, iv_spd_data);
- FAPI_INF("LSB Field Bits value: %lu", tWTR_Lmin_LSB);
-
- // Combining bits to create timing value (in a buffer)
- constexpr size_t MSN_START = 52;
- constexpr size_t MSN_LEN = 4;
- constexpr size_t LSB_START = 56;
- constexpr size_t LSB_LEN = 8;
-
- fapi2::buffer<int64_t> l_buffer;
-
- l_buffer.insertFromRight<MSN_START, MSN_LEN>( tWTR_Lmin_MSN )
- .insertFromRight<LSB_START, LSB_LEN>( tWTR_Lmin_LSB );
-
- // Extract timing value from the buffer into an integral type
- int64_t l_timing_val = l_buffer;
-
- // JEDEC spec limits for this timing value
- // This value used to be reserved to 0 - before spec update
- //constexpr int64_t TIMING_LOWER_BOUND = 1 // from JEDEC
- constexpr int64_t TIMING_LOWER_BOUND = 0;
- constexpr int64_t TIMING_UPPER_BOUND = 4095; // from JEDEC
-
- // best we can do?
- // I had to combine parts from two different bytes.
- // Chose one of them (byte 45) to for error printout of this decode
- constexpr size_t ERROR_BYTE_INDEX = 45;
-
- FAPI_TRY(mss::check::spd::fail_for_invalid_value(iv_target,
- (l_timing_val <= TIMING_UPPER_BOUND) &&
- (l_timing_val >= TIMING_LOWER_BOUND),
- ERROR_BYTE_INDEX,
- l_timing_val,
- "Failed check on the Minimum Write to Read Time - Same Bank Group (tWTR_Lmin) in MTB") );
-
- // Update output only after check passes
- o_value = l_timing_val;
-
- FAPI_INF("%s. Minimum Write to Read Time - Same Bank Group (tWTR_Lmin) in MTB units: %d",
- iv_target_str_storage,
- o_value);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Helper function that returns Logical ranks in SDRAM type
-/// @param[out] o_logical_ranks number of logical ranks
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode decoder_v1_1::sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const
-{
- uint8_t l_signal_loading = 0;
- uint8_t l_ranks_per_dimm = 0;
-
- FAPI_TRY( sec_sdram_signal_loading(l_signal_loading) );
- FAPI_TRY( num_package_ranks_per_dimm(l_ranks_per_dimm) );
-
- if(l_signal_loading == spd::SINGLE_LOAD_STACK)
- {
- // For single-load-stack(3DS) the logical ranks per package ends up being the same as the die count.
- uint8_t l_die_count = 0;
- FAPI_TRY( sec_sdram_die_count(l_die_count) );
-
- o_logical_ranks = l_ranks_per_dimm * l_die_count;
- }
- else
- {
- // Covers case for MONOLITHIC & MULTI_LOAD_STACK
- // The die count isn't guaranteed to be 1 (e.g. SDP - 1 die package, DDP - 2 die package).
- // Value of 1 is used for calculation purposes as defined by the SPD spec.
- o_logical_ranks = l_ranks_per_dimm;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Returns Logical ranks per DIMM
-/// @param[out] o_logical_ranks number of logical ranks
-/// @return fapi2::FAPI2_RC_SUCCESS if okay
-///
-fapi2::ReturnCode decoder_v1_1::logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const
-{
- uint8_t l_rank_mix = 0;
-
- FAPI_TRY( rank_mix(l_rank_mix) );
-
- if(l_rank_mix == fapi2::ENUM_ATTR_EFF_DRAM_RANK_MIX_SYMMETRICAL)
- {
- FAPI_TRY( prim_sdram_logical_ranks(o_logical_rank_per_dimm) );
- }
- else
- {
- // Rank mix is ASYMMETRICAL
- uint8_t l_prim_logical_rank_per_dimm = 0;
- uint8_t l_sec_logical_rank_per_dimm = 0;
-
- FAPI_TRY( prim_sdram_logical_ranks(l_prim_logical_rank_per_dimm) );
- FAPI_TRY( sec_sdram_logical_ranks(l_sec_logical_rank_per_dimm) );
-
- o_logical_rank_per_dimm = l_prim_logical_rank_per_dimm + l_sec_logical_rank_per_dimm;
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}// ddr4
-}// spd
-}// mss
diff --git a/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H b/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H
index da24f3155..ec7916df4 100644
--- a/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H
+++ b/src/import/generic/memory/lib/spd/common/dimm_module_decoder.H
@@ -52,11 +52,12 @@ namespace spd
///
class dimm_module_decoder
{
- public:
+ private:
+
const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ std::vector<uint8_t> iv_data;
- //
- std::vector<uint8_t> iv_spd_data;
+ public:
///
/// @brief default ctor
@@ -67,9 +68,10 @@ class dimm_module_decoder
/// @brief ctor
///
dimm_module_decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data): iv_target(i_target), iv_spd_data(i_spd_data)
+ const std::vector<uint8_t>& i_spd_data):
+ iv_target(i_target),
+ iv_data(i_spd_data)
{
- fapi2::toString(iv_target, iv_target_str_storage, fapi2::MAX_ECMD_STRING_LEN);
}
///
@@ -78,6 +80,33 @@ class dimm_module_decoder
virtual ~dimm_module_decoder() = default;
///
+ /// @brief Gets decoder target
+ /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ ///
+ virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_target;
+ }
+
+ ///
+ /// @brief Gets decoder SPD data
+ /// @return std::vector<uint8_t>
+ ///
+ virtual std::vector<uint8_t> get_data() const
+ {
+ return iv_data;
+ }
+
+ ///
+ /// @brief Sets decoder SPD data
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ virtual void set_data(const std::vector<uint8_t>& i_spd_data)
+ {
+ iv_data = i_spd_data;
+ }
+
+ ///
/// @brief Decodes module nominal height max
/// @param[out] o_output height range encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
@@ -122,8 +151,23 @@ class dimm_module_decoder
}
///
+ /// @brief Decodes reference raw card used
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 130 (Bits 7~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12 - 48
+ ///
+ virtual fapi2::ReturnCode reference_raw_card(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Decodes number of registers used on RDIMM
- /// @param[out] o_output encoding from SPD
+ /// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const
@@ -145,7 +189,7 @@ class dimm_module_decoder
///
/// @brief Decodes register and buffer type for LRDIMMs
- /// @param[out] o_output encoding from SPD
+ /// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const
@@ -178,22 +222,11 @@ class dimm_module_decoder
}
///
- /// @brief Decodes number of continuation codes
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- ///
- virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output) const
- {
- o_output = 0;
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- ///
/// @brief Decodes register manufacturer ID code
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
///
- virtual fapi2::ReturnCode reg_manufacturer_id_code(uint8_t& o_output) const
+ virtual fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_output) const
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
@@ -312,7 +345,7 @@ class dimm_module_decoder
///
/// @brief Decodes RCD output slew rate control
- /// @param[out] o_output encoded drive strength
+ /// @param[out] o_output encoded slew rate
/// @return FAPI2_RC_SUCCESS if okay
///
virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output) const
@@ -521,45 +554,8 @@ class dimm_module_decoder
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
-
- protected:
-
- char iv_target_str_storage[fapi2::MAX_ECMD_STRING_LEN];
-
};
-///
-/// @brief data structure for byte fields
-/// @note holds byte index, start bit and length of decoded field
-///
-struct field_t
-{
- const uint64_t iv_byte;
- const uint64_t iv_start;
- const uint64_t iv_length;
-
- // default ctor deleted
- constexpr field_t() = delete;
-
- ///
- /// @brief ctor
- /// @param[in] i_byte_index
- /// @param[in] i_start_bit
- /// @param[in] i_bit_length
- ///
- constexpr field_t(const uint64_t i_byte_index,
- const uint64_t i_start_bit,
- const uint64_t i_bit_length)
- : iv_byte(i_byte_index), iv_start(i_start_bit), iv_length(i_bit_length)
- {}
-
- ///
- /// @brief default dtor
- ///
- ~field_t() = default;
-
-};// field_t
-
}// spd
}// mss
diff --git a/src/import/generic/memory/lib/spd/common/spd_decoder_base.H b/src/import/generic/memory/lib/spd/common/spd_decoder_base.H
index 53b931b40..878d2f27e 100644
--- a/src/import/generic/memory/lib/spd/common/spd_decoder_base.H
+++ b/src/import/generic/memory/lib/spd/common/spd_decoder_base.H
@@ -40,157 +40,140 @@
#include <memory>
#include <fapi2.H>
-#include <generic/memory/lib/spd/common/dimm_module_decoder.H>
-#include <generic/memory/lib/spd/common/rcw_settings.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/spd/spd_reader.H>
namespace mss
{
+
namespace spd
{
-///
-/// @brief Helper function to extract byte information
-/// @tparam F the SPD field to extract
-/// @param[in] i_target the dimm target
-/// @param[in] i_spd_data the SPD data
-/// @return extracted byte (right aligned)
-///
-template< const field_t& F >
-inline uint8_t extract_spd_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data)
+class base_cnfg_decoder
{
- char l_target_str_storage[fapi2::MAX_ECMD_STRING_LEN];
- fapi2::toString(i_target, l_target_str_storage, fapi2::MAX_ECMD_STRING_LEN);
-
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- l_target_str_storage,
- F.iv_byte,
- i_spd_data[F.iv_byte]);
-
- fapi2::buffer<uint8_t> l_buffer(i_spd_data[F.iv_byte]);
+ private:
- // Extracting desired bits
- uint8_t l_field_bits = 0;
- l_buffer.extractToRight<F.iv_start, F.iv_length>(l_field_bits);
-
- return l_field_bits;
-}
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ std::vector<uint8_t> iv_data;
-///
-/// @brief Helper function to extract byte information
-/// @param[in] i_target the dimm target
-/// @param[in] i_field the SPD field
-/// @param[in] i_spd_data the SPD data
-/// @return extracted byte (right aligned)
-///
-inline uint8_t extract_spd_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const field_t& i_field,
- const std::vector<uint8_t>& i_spd_data)
-{
- char l_target_str_storage[fapi2::MAX_ECMD_STRING_LEN];
- fapi2::toString(i_target, l_target_str_storage, fapi2::MAX_ECMD_STRING_LEN);
+ public:
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- l_target_str_storage,
- i_field.iv_byte,
- i_spd_data[i_field.iv_byte]);
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data SPD data vector
+ ///
+ base_cnfg_decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data)
+ : iv_target(i_target),
+ iv_data(i_spd_data)
+ {
+ }
- fapi2::buffer<uint8_t> l_buffer(i_spd_data[i_field.iv_byte]);
+ ///
+ /// @brief dtor
+ ///
+ virtual ~base_cnfg_decoder() = default;
- // Extracting desired bits
- uint8_t l_field_bits = 0;
- l_buffer.extractToRight( l_field_bits, i_field.iv_start, i_field.iv_length );
+ ///
+ /// @brief Gets decoder target
+ /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ ///
+ virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_target;
+ }
- return l_field_bits;
-}
+ ///
+ /// @brief Gets decoder SPD data
+ /// @return std::vector<uint8_t>
+ ///
+ virtual std::vector<uint8_t> get_data() const
+ {
+ return iv_data;
+ }
-///
-/// @class decoder
-/// @brief Base SPD DRAM decoder
-///
-class decoder
-{
- protected:
- char iv_target_str_storage[fapi2::MAX_ECMD_STRING_LEN];
+ ///
+ /// @brief Sets decoder SPD data
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ virtual void set_data(const std::vector<uint8_t>& i_spd_data)
+ {
+ iv_data = i_spd_data;
+ }
///
- /// @brief Helper function that turns Logical ranks in Primary SDRAM type
- /// @param[out] o_logical_ranks number of logical ranks
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @brief Decodes number of used SPD bytes
+ /// @param[out] o_value number of SPD bytes used
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode prim_sdram_logical_ranks( uint8_t& o_logical_ranks ) const
+ virtual fapi2::ReturnCode number_of_used_bytes( uint8_t& o_value ) const
{
- o_logical_ranks = 0;
+ o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Helper functions that returns Logical ranks in Secondary SDRAM type
- /// @param[out] o_logical_ranks number of logical ranks
- /// @return fapi2::FAPI2_RC_SUCCESS if okay
+ /// @brief Decodes SDP revision
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode sec_sdram_logical_ranks( uint8_t& o_logical_ranks ) const
+ virtual fapi2::ReturnCode revision( uint8_t& o_value ) const
{
- o_logical_ranks = 0;
+ o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
- public:
- const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
- std::shared_ptr<dimm_module_decoder> iv_module_decoder;
- std::vector<uint8_t> iv_spd_data;
- rcw_settings iv_raw_card;
-
///
- /// @brief default ctor
+ /// @brief Decodes total number of SPD bytes
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- decoder() = default;
+ virtual fapi2::ReturnCode number_of_total_bytes( uint8_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
///
- /// @brief ctor
- /// @param[in] i_target dimm target
- /// @param[in] i_spd_data SPD data vector
- /// @param[in] i_module_decoder shared_ptr to dimm module decoder
- /// @param[in] i_raw_card raw pointer to rcd data
+ /// @brief Decodes DRAM device type
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data,
- const std::shared_ptr<dimm_module_decoder>& i_module_decoder,
- const rcw_settings& i_raw_card)
- : iv_target(i_target),
- iv_module_decoder(i_module_decoder),
- iv_spd_data(i_spd_data),
- iv_raw_card(i_raw_card)
+ virtual fapi2::ReturnCode device_type( uint8_t& o_value ) const
{
- fapi2::toString(iv_target, iv_target_str_storage, fapi2::MAX_ECMD_STRING_LEN);
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Default dtor
+ /// @brief Decodes base module type
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual ~decoder() = default;
-
- /////////////////////////
- // Member Methods
- /////////////////////////
+ virtual fapi2::ReturnCode base_module( uint8_t& o_value ) const
+ {
+ o_value = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
///
- /// @brief Decodes number of used SPD bytes
- /// @param[out] o_value number of SPD bytes used
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @brief Decodes hybrid media
+ /// @param[out] o_value number of total SPD bytes
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode number_of_used_bytes( uint16_t& o_value ) const
+ virtual fapi2::ReturnCode hybrid_media( uint8_t& o_value ) const
{
o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
///
- /// @brief Decodes total number of SPD bytes
+ /// @brief Decodes hybrid
/// @param[out] o_value number of total SPD bytes
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode number_of_total_bytes( uint16_t& o_value ) const
+ virtual fapi2::ReturnCode hybrid( uint8_t& o_value ) const
{
o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
@@ -199,7 +182,7 @@ class decoder
///
/// @brief Decodes SDRAM density from SPD
/// @param[out] o_value SDRAM density in GBs
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode sdram_density( uint8_t& o_value ) const
{
@@ -210,7 +193,7 @@ class decoder
///
/// @brief Decodes number of SDRAM banks bits from SPD
/// @param[out] o_value Number of SDRAM bank bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode bank_bits( uint8_t& o_value ) const
{
@@ -221,7 +204,7 @@ class decoder
///
/// @brief Decodes number of SDRAM bank groups bits from SPD
/// @param[out] o_value Number of SDRAM bank groups bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const
{
@@ -232,7 +215,7 @@ class decoder
///
/// @brief Decodes number of SDRAM column address bits
/// @param[out] o_value Number of SDRAM bank bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const
{
@@ -243,7 +226,7 @@ class decoder
///
/// @brief Decodes number of SDRAM row address bits
/// @param[out] o_value Number of SDRAM bank bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const
{
@@ -254,7 +237,7 @@ class decoder
///
/// @brief Decodes Primary SDRAM signal loading
/// @param[out] o_value Number of SDRAM bank bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const
{
@@ -265,7 +248,7 @@ class decoder
///
/// @brief Decodes Primary SDRAM die count
/// @param[out] o_value Number of SDRAM bank bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const
{
@@ -275,7 +258,7 @@ class decoder
///
/// @brief Decodes Primary SDRAM package type
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const
{
@@ -285,9 +268,9 @@ class decoder
///
/// @brief Decode SDRAM Maximum activate count
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode maximum_activate_count( uint32_t& o_value ) const
+ virtual fapi2::ReturnCode maximum_activate_count( uint8_t& o_value ) const
{
o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
@@ -295,9 +278,9 @@ class decoder
///
/// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
- virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint32_t& o_value ) const
+ virtual fapi2::ReturnCode maximum_activate_window_multiplier( uint8_t& o_value ) const
{
o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
@@ -305,7 +288,7 @@ class decoder
///
/// @brief Decode Post package repair (PPR)
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const
{
@@ -315,7 +298,7 @@ class decoder
///
/// @brief Decode Soft post package repair (soft PPR)
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const
{
@@ -325,7 +308,7 @@ class decoder
///
/// @brief Decodes Secondary SDRAM signal loading
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const
{
@@ -335,7 +318,7 @@ class decoder
///
/// @brief Decodes Secondary DRAM Density Ratio
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const
{
@@ -345,7 +328,7 @@ class decoder
///
/// @brief Decodes Secondary SDRAM die count
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const
{
@@ -355,7 +338,7 @@ class decoder
///
/// @brief Decodes Secondary SDRAM package type
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const
{
@@ -366,7 +349,7 @@ class decoder
///
/// @brief Decode Module Nominal Voltage, VDD
/// @param[out] o_value enum representing if 1.2V is operable
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const
{
@@ -377,17 +360,18 @@ class decoder
///
/// @brief Decode Module Nominal Voltage, VDD
/// @param[out] o_value enum representing if 1.2V is endurant
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const
{
o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
+
///
/// @brief Decodes SDRAM device width
/// @param[out] o_value device width in bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode device_width( uint8_t& o_value ) const
{
@@ -398,7 +382,7 @@ class decoder
///
/// @brief Decodes number of package ranks per DIMM
/// @param[out] o_value number of package ranks per DIMM
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const
{
@@ -409,7 +393,7 @@ class decoder
///
/// @brief Decodes Rank Mix
/// @param[out] o_value rank mix value from SPD
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode rank_mix( uint8_t& o_value ) const
{
@@ -420,7 +404,7 @@ class decoder
///
/// @brief Decodes primary bus width
/// @param[out] o_value primary bus width in bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const
{
@@ -431,7 +415,7 @@ class decoder
///
/// @brief Decodes bus width extension
/// @param[out] o_value bus width extension in bits
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const
{
@@ -442,7 +426,7 @@ class decoder
///
/// @brief Decode Module Thermal Sensor
/// @param[out] o_value thermal sensor value from SPD
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const
{
@@ -453,7 +437,7 @@ class decoder
///
/// @brief Decode Extended Base Module Type
/// @param[out] o_value extended base module type value from SPD
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const
{
@@ -464,7 +448,7 @@ class decoder
///
/// @brief Decode Fine Timebase
/// @param[out] o_value fine_timebase from SPD in picoseconds
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_timebase( int64_t& o_value ) const
{
@@ -475,7 +459,7 @@ class decoder
///
/// @brief Decode Medium Timebase
/// @param[out] o_value fine_timebase from SPD in picoseconds
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode medium_timebase( int64_t& o_value ) const
{
@@ -487,7 +471,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Cycle Time in MTB
/// @param[out] o_value tCKmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_tck( int64_t& o_value ) const
{
@@ -498,7 +482,7 @@ class decoder
///
/// @brief Decodes SDRAM Maximum Cycle Time in MTB
/// @param[out] o_value tCKmax in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode max_tck( int64_t& o_value ) const
{
@@ -509,7 +493,7 @@ class decoder
///
/// @brief Decode CAS Latencies Supported
/// @param[out] o_value bitmap of supported CAS latencies
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const
{
@@ -520,7 +504,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum CAS Latency Time in MTB
/// @param[out] o_value tAAmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_taa( int64_t& o_value ) const
{
@@ -531,7 +515,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB
/// @param[out] o_value tRCDmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trcd( int64_t& o_value ) const
{
@@ -542,7 +526,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB
/// @param[out] o_value tRPmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trp( int64_t& o_value ) const
{
@@ -553,7 +537,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB
/// @param[out] o_value tRASmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_tras( int64_t& o_value ) const
{
@@ -564,7 +548,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB
/// @param[out] o_value tRCmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trc( int64_t& o_value ) const
{
@@ -575,7 +559,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1
/// @param[out] o_value tRFC1min in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trfc1( int64_t& o_value ) const
{
@@ -586,7 +570,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2
/// @param[out] o_value tRFC2min in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trfc2( int64_t& o_value ) const
{
@@ -597,7 +581,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4
/// @param[out] o_value tRFC4min in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trfc4( int64_t& o_value ) const
{
@@ -608,7 +592,7 @@ class decoder
///
/// @brief Decodes SDRAM Minimum Four Activate Window Delay Time
/// @param[out] o_value tFAWmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_tfaw( int64_t& o_value ) const
{
@@ -619,7 +603,7 @@ class decoder
///
/// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group
/// @param[out] o_value tRRD_Smin MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const
{
@@ -630,7 +614,7 @@ class decoder
///
/// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group
/// @param[out] o_value tRRD_Lmin MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const
{
@@ -641,7 +625,7 @@ class decoder
///
/// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group
/// @param[out] o_value tCCD_Lmin MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const
{
@@ -652,7 +636,7 @@ class decoder
///
/// @brief Decodes Minimum Write Recovery Time
/// @param[out] o_value tWRmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_twr( int64_t& o_value ) const
{
@@ -663,7 +647,7 @@ class decoder
///
/// @brief Decodes Minimum Write to Read Time - Different Bank Group
/// @param[out] o_value tWRT_Smin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const
{
@@ -674,7 +658,7 @@ class decoder
///
/// @brief Decodes Minimum Write to Read Time - Same Bank Group
/// @param[out] o_value tWRT_Lmin in MTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const
{
@@ -707,7 +691,7 @@ class decoder
///
/// @brief Decodes Fine Offset for Minimum CAS to CAS Delay Time - Same Bank Group
/// @param[out] o_value tCCD_Lmin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const
{
@@ -718,7 +702,7 @@ class decoder
///
/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group
/// @param[out] o_value tRRD_Lmin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const
{
@@ -729,7 +713,7 @@ class decoder
///
/// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group
/// @param[out] o_value tRRD_Smin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const
{
@@ -740,7 +724,7 @@ class decoder
///
/// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time
/// @param[out] o_value tRCmin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const
{
@@ -751,7 +735,7 @@ class decoder
///
/// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time
/// @param[out] o_value tRPmin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const
{
@@ -762,7 +746,7 @@ class decoder
///
/// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time
/// @param[out] o_value tRCDmin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const
{
@@ -773,7 +757,7 @@ class decoder
///
/// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time
/// @param[out] o_value tAAmin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const
{
@@ -784,7 +768,7 @@ class decoder
///
/// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time
/// @param[out] o_value tCKmax offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const
{
@@ -795,7 +779,7 @@ class decoder
///
/// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time
/// @param[out] o_value tCKmin offset in FTB units
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const
{
@@ -806,7 +790,7 @@ class decoder
///
/// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section
/// @param[out] o_value crc value from SPD
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const
{
@@ -817,7 +801,7 @@ class decoder
///
/// @brief Decodes module manufacturer ID code
/// @param[out] o_output module manufacturing id code
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const
{
@@ -828,7 +812,7 @@ class decoder
///
/// @brief Decodes Module Manufacturing Location
/// @param[out] o_value uint8_t identifier for manufacturing location of memory module
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const
{
@@ -839,7 +823,7 @@ class decoder
///
/// @brief Decodesmodule manufacturing date
/// @param[out] o_value the 2 byte date of manufacturing in BCD format
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
virtual fapi2::ReturnCode module_manufacturing_date( uint16_t& o_value ) const
{
o_value = 0;
@@ -849,7 +833,7 @@ class decoder
///
/// @brief Decodes module's unique serial number
/// @param[out] o_value module's serial number
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode module_serial_number( uint32_t& o_value ) const
{
@@ -860,7 +844,7 @@ class decoder
///
/// @brief Decodes Module Revision Code
/// @param[out] o_value uint8_t identifier for revision code
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const
{
@@ -871,7 +855,7 @@ class decoder
///
/// @brief Decodes DRAM Manufacturer ID code
/// @param[out] o_value dram manufacturing id code
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const
{
@@ -880,50 +864,16 @@ class decoder
}
///
- /// @brief Decodes RCD Manufacturer ID code
- /// @param[out] o_value rcd manufacturing id code
- /// @return FAPI2_RC_SUCCESS if okay
- ///
- virtual fapi2::ReturnCode reg_manufacturer_id_code( uint16_t& o_value ) const
- {
- o_value = 0;
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- ///
- /// @brief Decodes Register Revision Number
- /// @param[out] o_value register revision number
- /// @return FAPI2_RC_SUCCESS if okay
- ///
- virtual fapi2::ReturnCode register_rev_num( uint8_t& o_value ) const
- {
- o_value = 0;
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
- ///
/// @brief Decodes DRAM Stepping
/// @param[out] o_value uint8_t DRAM Stepping val
- /// @return FAPI2_RC_SUCCESS if okay
+ /// @return FAPI2_RC_SUCCESS iff okay
///
virtual fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const
{
o_value = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
-
- ///
- /// @brief Returns Logical ranks per DIMM
- /// @param[out] o_logical_ranks number of logical ranks
- /// @return FAPI2_RC_SUCCESS if okay
- ///
- virtual fapi2::ReturnCode logical_ranks_per_dimm( uint8_t& o_logical_rank_per_dimm ) const
- {
- o_logical_rank_per_dimm = 0;
- return fapi2::FAPI2_RC_SUCCESS;
- }
-
-};// decoder
+};
}// spd
}// mss
diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H
index f8031274e..49220680c 100644
--- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H
+++ b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H
@@ -39,84 +39,107 @@
#include <fapi2.H>
#include <vector>
+#include <generic/memory/lib/spd/spd_decoder_def.H>
#include <generic/memory/lib/spd/common/dimm_module_decoder.H>
+#include <generic/memory/lib/spd/spd_reader.H>
namespace mss
{
namespace spd
{
-namespace ddr4
-{
-namespace lrdimm
-{
///
-/// @brief LRDIMM module decoder for revision 1.0
+/// @brief LRDIMM module decoder
+/// @tparam R SPD revision - partial specialization
///
-class decoder_v1_0 : public dimm_module_decoder
+template < rev R >
+class decoder<DDR4, LRDIMM_MODULE, R > : public dimm_module_decoder
{
- public:
-
- // First field - SPD byte
- // Second field - start bit
- // Third field - bit length
- constexpr static field_t MODULE_NOMINAL_HEIGHT{128, 3, 5};
- constexpr static field_t RAW_CARD_EXTENSION{128, 0, 3};
-
- constexpr static field_t FRONT_MODULE_THICKNESS{129, 4, 4};
- constexpr static field_t BACK_MODULE_THICKNESS{129, 0, 4};
-
- constexpr static field_t NUM_REGISTERS_USED{131, 6, 2};
- constexpr static field_t NUM_ROWS_OF_DRAMS{131, 4, 2};
- constexpr static field_t REGISTER_TYPE{131, 0, 4};
-
- constexpr static field_t HEAT_SPREADER_THERM_CHAR{132, 1, 7};
- constexpr static field_t HEAT_SPREADER_SOLUTION{132, 0, 1};
-
- constexpr static field_t CONTINUATION_CODES{133, 1, 7};
- constexpr static field_t ADDR_MAPPING{136, 7, 1};
-
- constexpr static field_t CKE_DRIVE_STRENGTH{137, 6, 2};
- constexpr static field_t ODT_DRIVE_STRENGTH{137, 4, 2};
- constexpr static field_t CA_DRIVE_STRENGTH{137, 2, 2};
- constexpr static field_t CS_DRIVE_STRENGTH{137, 0, 2};
+ private:
- constexpr static field_t B_SIDE_DRIVE_STRENGTH{138, 6, 2};
- constexpr static field_t A_SIDE_DRIVE_STRENGTH{138, 4, 2};
- constexpr static field_t BCOM_BODT_BCKE_DRIVE_STRENGTH{138, 3, 1};
- constexpr static field_t BCK_DRIVE_STRENGTH{138, 2, 1};
- constexpr static field_t RCD_SLEW_CNTRL{138, 1, 1 };
+ using fields_t = fields<DDR4, LRDIMM_MODULE>;
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ std::vector<uint8_t> iv_data;
- constexpr static field_t VREF_DQ_RANK0{140, 2, 6};
- constexpr static field_t VREF_DQ_RANK1{141, 2, 6};
- constexpr static field_t VREF_DQ_RANK2{142, 2, 6};
- constexpr static field_t VREF_DQ_RANK3{143, 2, 6};
-
- constexpr static field_t DATA_BUFFER_MDQ{145, 1, 3};
-
- constexpr static field_t DRAM_VREF_DQ_RANGE{155, 4, 4};
- constexpr static field_t DATA_BUFFER_VREF_DQ{155, 3, 1};
+ ///
+ /// @brief Helper function to check for reserved values for DRAM interface MDQ Drive Strenth
+ /// @tparam T SPD revision
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[in] i_input value to check reserved bits against
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ template < rev T >
+ fapi2::ReturnCode check_for_reserved_values(const uint64_t i_dimm_speed,
+ const uint8_t i_input) const
+ {
+ static_assert(T <= LRDIMM_MAX, "Invalid SPD revision");
+ const std::vector<size_t> l_reserved_bits{0b011, 0b100, 0b110, 0b111};
+
+ // Lets make an additinal check that we aren't being set to a reserved field
+ FAPI_ASSERT( !std::binary_search(l_reserved_bits.begin(), l_reserved_bits.end(), i_input),
+ fapi2::MSS_INVALID_DB_MDQ_DRIVE_STRENGTH()
+ .set_DATA_RATE(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Reserved settings for data buffer MDQ drive strength received for dimm speed %d on %s",
+ i_dimm_speed,
+ spd::c_str(iv_target) );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
- constexpr static field_t DATA_BUFFER_GAIN_ADJUST{156, 7, 1};
- constexpr static field_t DATA_BUFFER_DFE{156, 6, 1};
+ public:
// deleted default ctor
- decoder_v1_0() = delete;
+ decoder() = delete;
///
/// @brief ctor
/// @param[in] i_target dimm target
/// @param[in] i_spd_data vector DIMM SPD data
///
- decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data)
- : dimm_module_decoder(i_target, i_spd_data)
- {}
+ decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data):
+ dimm_module_decoder(i_target, i_spd_data),
+ iv_target(i_target),
+ iv_data(i_spd_data)
+ {
+ static_assert( R <= rev::LRDIMM_MAX, " R > rev::LRDIMM_MAX");
+ }
///
/// @brief default dtor
///
- virtual ~decoder_v1_0() = default;
+ virtual ~decoder() = default;
+
+ ///
+ /// @brief Gets decoder target
+ /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ ///
+ virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_target;
+ }
+
+ ///
+ /// @brief Gets decoder SPD data
+ /// @return std::vector<uint8_t>
+ ///
+ virtual std::vector<uint8_t> get_data() const
+ {
+ return iv_data;
+ }
+
+ ///
+ /// @brief Sets decoder SPD data
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ virtual void set_data(const std::vector<uint8_t>& i_spd_data)
+ {
+ iv_data = i_spd_data;
+ }
///
/// @brief Decodes module nominal height max
@@ -127,7 +150,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 55
///
- virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_NOMINAL_HEIGHT, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes raw card extension
@@ -138,7 +167,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 55
///
- virtual fapi2::ReturnCode raw_card_extension(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode raw_card_extension(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::RAW_CARD_EXT, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes front module maximum thickness max
@@ -149,7 +184,14 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 55
///
- virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::FRONT_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+
+ }
///
/// @brief Decodes back module maximum thickness max
@@ -160,7 +202,31 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 55
///
- virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BACK_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+
+ }
+
+ ///
+ /// @brief Decodes reference raw card used
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 130 (Bits 7~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12 - 48
+ ///
+ virtual fapi2::ReturnCode reference_raw_card(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::REF_RAW_CARD, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of registers used on LRDIMM
@@ -171,7 +237,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 57
///
- virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::NUM_REGS_USED, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of rows of DRAMs on LRDIMM
@@ -182,29 +254,49 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 57
///
- virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ROWS_OF_DRAMS, rev::V1_0>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+
+ }
///
- /// @brief Decodes heat spreader solution
- /// @param[out] o_output drive strength encoding from SPD
+ /// @brief Decodes register and data buffer types
+ /// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 132 (Bit 7)
+ /// @note SPD Byte 131 (Bits 7~4)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12.2 - 58
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 63
///
- virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_TYPE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+
+ }
///
- /// @brief Decodes number of continuation codes
+ /// @brief Decodes heat spreader solution
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 133 (Bits 6~0)
+ /// @note SPD Byte 132 (Bit 7)
/// @note Item JEDEC Standard No. 21-C
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 58
///
- virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::HEAT_SPREADER_SOL, rev::V1_0>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register manufacturer ID code
@@ -215,7 +307,28 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 58
///
- virtual fapi2::ReturnCode reg_manufacturer_id_code(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_output) const override
+ {
+ uint8_t l_cont_codes = 0;
+ uint8_t l_last_nonzero_byte = 0;
+
+ FAPI_TRY( (mss::spd::reader<fields_t::CONTINUATION_CODES, R>(iv_target, iv_data, l_cont_codes)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::LAST_NON_ZERO_BYTE, R>(iv_target, iv_data, l_last_nonzero_byte)) );
+
+ {
+ fapi2::buffer<uint16_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_last_nonzero_byte, l_cont_codes);
+
+ o_output = l_buffer;
+
+ FAPI_INF("%s.Module Manufacturer ID Code: 0x%04x",
+ spd::c_str(iv_target),
+ o_output);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register revision number
@@ -226,7 +339,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 58
///
- virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_REV, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes address mapping from register to dram
@@ -237,7 +356,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 59
///
- virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ADDR_MAP_REG_TO_DRAM, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for CKE signal
@@ -247,7 +372,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 60
///
- virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::CKE_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for ODT signal
@@ -258,7 +389,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 60
///
- virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ODT_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for command/address (CA) signal
@@ -269,7 +406,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 60
///
- virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::CA_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for control signal (CS) signal
@@ -280,7 +423,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 60
///
- virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::CS_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for clock (B side)
@@ -291,7 +440,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 60
///
- virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::YO_Y2_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for clock (A side)
@@ -302,7 +457,65 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 60
///
- virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::Y1_Y3_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE)
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 66
+ ///
+ virtual fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BCOM_BODT_BCKE_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCK)
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 5)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 66
+ ///
+ virtual fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BCK_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes RCD output slew rate control
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 6)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 4
+ /// @note Page 4.1.2.L-4 - 70
+ ///
+ virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::RCD_SLEW_CNTRL, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes data buffer revision number
@@ -313,7 +526,14 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 60
///
- virtual fapi2::ReturnCode data_buffer_rev(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode data_buffer_rev(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_REV, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes DRAM VrefDQ for Package Rank 0
@@ -324,7 +544,14 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 61
///
- virtual fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes DRAM VrefDQ for Package Rank 1
@@ -335,7 +562,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 61
///
- virtual fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes DRAM VrefDQ for Package Rank 2
@@ -346,7 +579,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 61
///
- virtual fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes DRAM VrefDQ for Package Rank 3
@@ -357,7 +596,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 61
///
- virtual fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::VREF_DQ_RANK3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes data buffer VrefDQ for DRAM interface
@@ -368,7 +613,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 61
///
- virtual fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_VREF_DQ, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes DRAM interface MDQ Drive Strenth
@@ -382,7 +633,49 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note Page 4.1.2.12.2 - 62
///
virtual fapi2::ReturnCode data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed,
- uint8_t& o_output) const override;
+ uint8_t& o_output) const override
+ {
+ switch(i_dimm_speed)
+ {
+ case mss::DIMM_SPEED_1600:
+ case mss::DIMM_SPEED_1866:
+ FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_LTE_1866, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2133:
+ case mss::DIMM_SPEED_2400:
+ FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_LTE_2400, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2666:
+ case mss::DIMM_SPEED_2933:
+ case mss::DIMM_SPEED_3200:
+ FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_LTE_3200, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_SPEED()
+ .set_DIMM_SPEED(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target));
+ break;
+ }
+
+ // Lets make an additinal check that we aren't being set to a reserved field
+ FAPI_TRY((check_for_reserved_values<R>(i_dimm_speed, o_output)),
+ "Failed reserved bit check for %s", spd::c_str(iv_target));
+
+ // If we are here we have a valid output, exit
+ // to avoid error path of fapi_try_exit
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ // A little output clean up if we fail out
+ o_output = 0;
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes DRAM interface MDQ read termination strength
@@ -395,7 +688,41 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 62
///
- virtual fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output) const override
+ {
+ switch(i_dimm_speed)
+ {
+ case mss::DIMM_SPEED_1600:
+ case mss::DIMM_SPEED_1866:
+ FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_RTT_LTE_1866, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2133:
+ case mss::DIMM_SPEED_2400:
+ FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_RTT_LTE_2400, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2666:
+ case mss::DIMM_SPEED_2933:
+ case mss::DIMM_SPEED_3200:
+ FAPI_TRY( (mss::spd::reader<fields_t::DB_MDQ_RTT_LTE_3200, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_SPEED()
+ .set_DIMM_SPEED(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target));
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes DRAM drive strenth
@@ -408,7 +735,41 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 63
///
- virtual fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const override
+ {
+ switch(i_dimm_speed)
+ {
+ case mss::DIMM_SPEED_1600:
+ case mss::DIMM_SPEED_1866:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_DRIVE_STRENGTH_LTE_1866, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2133:
+ case mss::DIMM_SPEED_2400:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_DRIVE_STRENGTH_LTE_2400, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2666:
+ case mss::DIMM_SPEED_2933:
+ case mss::DIMM_SPEED_3200:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_DRIVE_STRENGTH_LTE_3200, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_SPEED()
+ .set_DIMM_SPEED(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target));
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes DRAM ODT for RTT_NOM
@@ -421,7 +782,42 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - (64 - 65)
///
- virtual fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output) const override
+ {
+ switch(i_dimm_speed)
+ {
+ case mss::DIMM_SPEED_1600:
+ case mss::DIMM_SPEED_1866:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_NOM_LTE_1866, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2133:
+ case mss::DIMM_SPEED_2400:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_NOM_LTE_2400, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2666:
+ case mss::DIMM_SPEED_2933:
+ case mss::DIMM_SPEED_3200:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_NOM_LTE_3200, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_SPEED()
+ .set_DIMM_SPEED(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target));
+
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes DRAM ODT for RTT_WR
@@ -434,7 +830,41 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - (64 - 65)
///
- virtual fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output) const override
+ {
+ switch(i_dimm_speed)
+ {
+ case mss::DIMM_SPEED_1600:
+ case mss::DIMM_SPEED_1866:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_WR_LTE_1866, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2133:
+ case mss::DIMM_SPEED_2400:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_WR_LTE_2400, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2666:
+ case mss::DIMM_SPEED_2933:
+ case mss::DIMM_SPEED_3200:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_WR_LTE_3200, R>(iv_target, iv_data, o_output)) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_SPEED()
+ .set_DIMM_SPEED(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target));
+
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1
@@ -447,172 +877,95 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12.2 - 65
///
- virtual fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output) const override
+ {
+ switch(i_dimm_speed)
+ {
+ case mss::DIMM_SPEED_1600:
+ case mss::DIMM_SPEED_1866:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R01_LTE_1866, R>(iv_target, iv_data,
+ o_output)) );
+ break;
- ///
- /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3
- /// for a particular dimm speed
- /// @param[in] i_dimm_speed the dimm speed in MT/s
- /// @param[out] o_output ODT termination strength (in ohms)
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 152 - 154 (Bits 5~3)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12.2 - 65
- ///
- virtual fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output) const override;
-
-};//decoder
-
-///
-/// @brief LRDIMM module decoder for revision 1.1
-///
-class decoder_v1_1 : public decoder_v1_0
-{
- public:
-
- // deleted default ctor
- decoder_v1_1() = delete;
-
- ///
- /// @brief ctor
- /// @param[in] i_target dimm target
- /// @param[in] i_spd_data vector DIMM SPD data
- ///
- decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data)
- : decoder_v1_0(i_target, i_spd_data)
- {}
-
- ///
- /// @brief default dtor
- ///
- virtual ~decoder_v1_1() = default;
-
- ///
- /// @brief Decodes register and data buffer types
- /// @param[out] o_output encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 131 (Bits 7~4)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 63
- ///
- virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for CKE signal
- /// @param[out] o_output encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (Bits 1~0)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 65
- ///
- virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for ODT signal
- /// @param[out] o_output encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (Bits 3~2)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 65
- ///
- virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for control signal (CS) signal
- /// @param[out] o_output encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (Bits 6~7)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 65
- ///
- virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for clock (B side)
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (Bits 1~0)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 66
- ///
- virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for clock (A side)
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (Bits 3~2)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 66
- ///
- virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override;
-};
+ case mss::DIMM_SPEED_2133:
+ case mss::DIMM_SPEED_2400:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R01_LTE_2400, R>(iv_target, iv_data,
+ o_output)) );
+ break;
-///
-/// @brief LRDIMM module decoder for revision 1.2
-///
-class decoder_v1_2 : public decoder_v1_1
-{
- public:
+ case mss::DIMM_SPEED_2666:
+ case mss::DIMM_SPEED_2933:
+ case mss::DIMM_SPEED_3200:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R01_LTE_3200, R>(iv_target, iv_data,
+ o_output)) );
+ break;
- // deleted default ctor
- decoder_v1_2() = delete;
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_SPEED()
+ .set_DIMM_SPEED(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target));
- ///
- /// @brief ctor
- /// @param[in] i_target dimm target
- /// @param[in] i_spd_data vector DIMM SPD data
- ///
- decoder_v1_2(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data)
- : decoder_v1_1(i_target, i_spd_data)
- {}
+ break;
+ }
- ///
- /// @brief default dtor
- ///
- virtual ~decoder_v1_2() = default;
+ return fapi2::FAPI2_RC_SUCCESS;
- ///
- /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE)
- /// @param[out] o_output encoded drive strength
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (Bit 4)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 66
- ///
- virtual fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_output) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
- ///
- /// @brief Decodes register output drive strength for data buffer control (BCK)
- /// @param[out] o_output encoded drive strength
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (Bit 5)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 66
- ///
- virtual fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_output) const override;
///
- /// @brief Decodes RCD output slew rate control
- /// @param[out] o_output encoded drive strength
+ /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (Bit 6)
+ /// @note SPD Byte 152 - 154 (Bits 5~3)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 4
- /// @note Page 4.1.2.L-4 - 70
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 65
///
- virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output) const override
+ {
+ switch(i_dimm_speed)
+ {
+ case mss::DIMM_SPEED_1600:
+ case mss::DIMM_SPEED_1866:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R23_LTE_1866, R>(iv_target, iv_data,
+ o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2133:
+ case mss::DIMM_SPEED_2400:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R23_LTE_2400, R>(iv_target, iv_data,
+ o_output)) );
+ break;
+
+ case mss::DIMM_SPEED_2666:
+ case mss::DIMM_SPEED_2933:
+ case mss::DIMM_SPEED_3200:
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_ODT_RTT_PARK_R23_LTE_3200, R>(iv_target, iv_data,
+ o_output)) );
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_SPEED()
+ .set_DIMM_SPEED(i_dimm_speed)
+ .set_TARGET(iv_target),
+ "Invalid dimm speed received: %d for %s", i_dimm_speed, spd::c_str(iv_target));
+
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes VrefDQ range for DRAM interface range
@@ -623,7 +976,14 @@ class decoder_v1_2 : public decoder_v1_1
/// @note DDR4 SPD Document Release 4
/// @note Page 4.1.2.L-4 - 76
///
- virtual fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::DRAM_VREF_DQ_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
///
/// @brief Decodes data buffer VrefDQ range for DRAM interface range
@@ -634,7 +994,13 @@ class decoder_v1_2 : public decoder_v1_1
/// @note DDR4 SPD Document Release 4
/// @note Page 4.1.2.L-4 - 76
///
- virtual fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_VREF_DQ_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes data buffer gain adjustment
@@ -645,7 +1011,13 @@ class decoder_v1_2 : public decoder_v1_1
/// @note DDR4 SPD Document Release 4
/// @note Page 4.1.2.L-4 - 77
///
- virtual fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_GAIN_ADJUST, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes data buffer Decision Feedback Equalization (DFE)
@@ -656,11 +1028,16 @@ class decoder_v1_2 : public decoder_v1_1
/// @note DDR4 SPD Document Release 4
/// @note Page 4.1.2.L-4 - 77
///
- virtual fapi2::ReturnCode data_buffer_dfe(uint8_t& o_output) const override;
-};
+ virtual fapi2::ReturnCode data_buffer_dfe(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::DATA_BUFFER_DFE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+};//decoder
-}// lrdimm
-}// ddr4
}// spd
}// mss
diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C
deleted file mode 100644
index dc3ef9cad..000000000
--- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C
+++ /dev/null
@@ -1,1368 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_0.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file lrdimm_decoder_v1_0.C
-/// @brief LRDIMM module SPD decoder definitions for revision 1.0
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-// std lib
-#include <vector>
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/spd/spd_checker.H>
-#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-
-namespace mss
-{
-namespace spd
-{
-namespace ddr4
-{
-namespace lrdimm
-{
-
-/////////////////////////
-// Non-member helper functions
-// For LRDIMM module rev 1.0
-/////////////////////////
-
-///
-/// @brief Helper function to find SPD byte based on freq
-/// @param[in] i_dimm_speed DIMM speed in MT/s
-/// @param[out] o_byte byte to extract spd from
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
-///
-static fapi2::ReturnCode mdq_helper(const uint64_t i_dimm_speed, uint8_t& o_byte)
-{
- switch(i_dimm_speed)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_byte = 145;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- o_byte = 146;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_byte = 147;
- break;
-
- default:
- FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- break;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-};
-
-///
-/// @brief Helper function to find start bit based on freq
-/// @param[in] i_dimm_speed DIMM speed in MT/s
-/// @param[out] o_start_bit start bit to extract SPD from
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
-///
-static fapi2::ReturnCode drive_strength_start_bit_finder(const uint64_t i_dimm_speed, size_t& o_start_bit)
-{
- switch(i_dimm_speed)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_start_bit = 6;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- o_start_bit = 4;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_start_bit = 2;
- break;
-
- default:
- FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- break;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Helper function to find SPD byte based on freq
-/// @param[in] i_dimm_speed DIMM speed in MT/s
-/// @param[out] o_byte byte to extract spd from
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
-///
-static fapi2::ReturnCode rtt_wr_and_nom_byte_finder(const uint64_t i_dimm_speed, size_t& o_byte)
-{
- switch(i_dimm_speed)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_byte = 149;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- o_byte = 150;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_byte = 151;
- break;
-
- default:
- FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- break;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Helper function to find SPD byte based on freq
-/// @param[in] i_dimm_speed DIMM speed in MT/s
-/// @param[out] o_byte byte to extract spd from
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
-///
-static fapi2::ReturnCode rtt_park_byte_finder(const uint64_t i_dimm_speed, size_t& o_byte)
-{
- switch(i_dimm_speed)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_byte = 152;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- o_byte = 153;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_byte = 154;
- break;
-
- default:
- FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- break;
- }
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-/////////////////////////
-// Member Method implementation
-// For LRDIMM module rev 1.0
-/////////////////////////
-
-///
-/// @brief Decodes module nominal height max
-/// @param[out] o_output height range encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 128 (Bits 4~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 55
-///
-fapi2::ReturnCode decoder_v1_0::max_module_nominal_height(uint8_t& o_output) const
-{
- const uint8_t l_field_bits = extract_spd_field< MODULE_NOMINAL_HEIGHT >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b11111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- MODULE_NOMINAL_HEIGHT.iv_byte,
- l_field_bits,
- "Failed bound check for module nominal height max") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Max module nominal height: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes raw card extension
-/// @param[out] o_output raw card rev. encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 128 (Bits 7~5)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 55
-///
-fapi2::ReturnCode decoder_v1_0::raw_card_extension(uint8_t& o_output) const
-{
- const uint8_t l_field_bits = extract_spd_field< RAW_CARD_EXTENSION >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- RAW_CARD_EXTENSION.iv_byte,
- l_field_bits,
- "Failed bound check for raw card extension") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Raw card extension: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes front module maximum thickness max
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 129 (Bits 3~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 55
-///
-fapi2::ReturnCode decoder_v1_0::front_module_max_thickness(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< FRONT_MODULE_THICKNESS >(iv_target, iv_spd_data);
-
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b1111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- FRONT_MODULE_THICKNESS.iv_byte,
- l_field_bits,
- "Failed bound check for front module max thickness") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Front module max thickness: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes back module maximum thickness max
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 129 (Bits 7~4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 55
-///
-fapi2::ReturnCode decoder_v1_0::back_module_max_thickness(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< BACK_MODULE_THICKNESS >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b1111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- BACK_MODULE_THICKNESS.iv_byte,
- l_field_bits,
- "Failed bound check for back module max thickness") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Back module max thickness: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes number of registers used on LRDIMM
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 131 (Bits 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 57
-///
-fapi2::ReturnCode decoder_v1_0::num_registers_used(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< NUM_REGISTERS_USED >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 0b10;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- NUM_REGISTERS_USED.iv_byte,
- l_field_bits,
- "Failed bound check for number of registers used on RDIMM ") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Number of registers used on LRDIMM : %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes number of rows of DRAMs on LRDIMM
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 131 (Bits 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 57
-///
-fapi2::ReturnCode decoder_v1_0::num_rows_of_drams(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< NUM_ROWS_OF_DRAMS >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- NUM_REGISTERS_USED.iv_byte,
- l_field_bits,
- "Failed bound check for number of rows of DRAMs on LRDIMM ") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Number of rows of DRAMs on LRDIMM : %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes heat spreader solution
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 132 (Bit 7)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 58
-///
-fapi2::ReturnCode decoder_v1_0::heat_spreader_solution(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< HEAT_SPREADER_SOLUTION >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- HEAT_SPREADER_SOLUTION.iv_byte,
- l_field_bits,
- "Failed bound check for heat spreader solution") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Heat spreader solution: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes number of continuation codes
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 133 (bit 6~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 58
-///
-fapi2::ReturnCode decoder_v1_0::num_continuation_codes(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< CONTINUATION_CODES >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 10; // JEP106AS spec
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- CONTINUATION_CODES.iv_byte,
- l_field_bits,
- "Failed bound check for number of continuation codes") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Number of continuation codes: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register manufacturer ID code
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 134 (bit 7~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 58
-///
-fapi2::ReturnCode decoder_v1_0::reg_manufacturer_id_code(uint8_t& o_output) const
-{
- constexpr size_t BYTE_INDEX = 134;
- uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_raw_byte);
-
- // All bits used for encoding, no bounds to check
- o_output = l_raw_byte;
-
- FAPI_INF("%s. Register revision number: %d",
- iv_target_str_storage,
- o_output);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes register revision number
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 135 (bit 7~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 58
-///
-fapi2::ReturnCode decoder_v1_0::register_rev_num(uint8_t& o_output) const
-{
- constexpr size_t BYTE_INDEX = 135;
- uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_raw_byte);
-
- // All bits used for encoding, no bounds to check
- o_output = l_raw_byte;
-
- FAPI_INF("%s. Register revision number: %d",
- iv_target_str_storage,
- o_output);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes address mapping from register to dram
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 136 (bit 0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 59
-///
-fapi2::ReturnCode decoder_v1_0::register_to_dram_addr_mapping(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< ADDR_MAPPING >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- ADDR_MAPPING.iv_byte,
- l_field_bits,
- "Failed bound check for to register to dram addr mapping") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Address mapping from register to dram: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for CKE signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 60
-///
-fapi2::ReturnCode decoder_v1_0::cke_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< CKE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- CKE_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CKE") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CKE: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for ODT signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 60
-///
-fapi2::ReturnCode decoder_v1_0::odt_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< ODT_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- ODT_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for ODT") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for ODT: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for command/address (CA) signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 5~4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 60
-///
-fapi2::ReturnCode decoder_v1_0::ca_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< CA_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t INVALID_VAL = 4;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < INVALID_VAL, // extract sanity check
- CA_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CA") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CA: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for control signal (CS) signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 6~7)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 60
-///
-fapi2::ReturnCode decoder_v1_0::cs_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< CS_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- CS_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CS") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CS: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (B side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (bit 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 60
-///
-fapi2::ReturnCode decoder_v1_0::b_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< B_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- B_SIDE_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (A side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (bit 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 60
-///
-fapi2::ReturnCode decoder_v1_0::a_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< A_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- A_SIDE_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes data buffer revision number
-/// @param[out] o_output revision number
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 139 (Bits 7~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 60
-///
-fapi2::ReturnCode decoder_v1_0::data_buffer_rev(uint8_t& o_output) const
-{
- // Extracting desired bits
- constexpr size_t BYTE_INDEX = 139;
- const uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_raw_byte);
-
- // This checks JEDEC range is met
- constexpr size_t UNDEFINED = 0xFF;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_raw_byte != UNDEFINED,
- BYTE_INDEX,
- l_raw_byte,
- "Failed bounds check for data buffer revision number") );
-
- // Update output only if check passes
- o_output = l_raw_byte;
-
- FAPI_INF("%s. Data buffer rev: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes DRAM VrefDQ for Package Rank 0
-/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 140 (Bits 5~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 61
-///
-fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank0(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK0 >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // JESD79-4 specification
- constexpr size_t RESERVED = 0b110011;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- VREF_DQ_RANK0.iv_byte,
- l_field_bits,
- "Failed bounds check for DRAM VrefDQ for Package Rank 0") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM VrefDQ for Package Rank 0: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM VrefDQ for Package Rank 1
-/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 141 (Bits 5~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 61
-///
-fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank1(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK1 >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // JESD79-4 specification
- constexpr size_t RESERVED = 0b110011;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- VREF_DQ_RANK1.iv_byte,
- l_field_bits,
- "Failed bounds check for DRAM VrefDQ for Package Rank 1") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM VrefDQ for Package Rank 1: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM VrefDQ for Package Rank 2
-/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 142 (Bits 5~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 61
-///
-fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank2(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK2 >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // JESD79-4 specification
- constexpr size_t RESERVED = 0b110011;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- VREF_DQ_RANK2.iv_byte,
- l_field_bits,
- "Failed bounds check for DRAM VrefDQ for Package Rank 2") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM VrefDQ for Package Rank 2: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM VrefDQ for Package Rank 3
-/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 143 (Bits 5~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.12.2 - 61
-///
-fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank3(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK3 >(iv_target, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // JESD79-4 specification
- constexpr size_t RESERVED = 0b110011;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- VREF_DQ_RANK3.iv_byte,
- l_field_bits,
- "Failed bounds check for DRAM VrefDQ for Package Rank 3") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM VrefDQ for Package Rank 3: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes data buffer VrefDQ for DRAM interface
-/// @param[out] o_output encoding of F5BC6x in DDR4DB01 spec
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 144 (Bits 5~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 61
-///
-fapi2::ReturnCode decoder_v1_0::data_buffer_vref_dq(uint8_t& o_output) const
-{
- constexpr size_t BYTE_INDEX = 144;
- uint8_t l_raw_data = iv_spd_data[BYTE_INDEX];
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_raw_data);
-
- // DDR4DB01 spec
- constexpr size_t RESERVED = 0b00110011;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_raw_data < RESERVED,
- BYTE_INDEX,
- l_raw_data,
- "Failed bounds check for data buffer VrefDQ for DRAM interface") );
-
- // Update output only if check passes
- o_output = l_raw_data;
-
- FAPI_INF("%s. Data buffer VrefDQ for DRAM interface: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM interface MDQ Drive Strenth
-/// of the data buffer component for a particular dimm speed
-/// @param[in] i_dimm_speed the dimm speed in MT/s
-/// @param[out] o_output encoding of F5BC6x in
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 145 - 147 (Bits 6~4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 62
-///
-fapi2::ReturnCode decoder_v1_0::data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const
-{
- uint8_t l_byte = 0;
-
- FAPI_TRY( mdq_helper(i_dimm_speed, l_byte) );
-
- {
- constexpr size_t START = 1;
- constexpr size_t LEN = 3;
- const field_t MDQ_DRIVE_STRENGTH(l_byte, START, LEN);
-
- const uint8_t l_field_bits = extract_spd_field( iv_target, MDQ_DRIVE_STRENGTH, iv_spd_data );
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // Lets make sure we aren't being set to a reserved field
- bool is_reserved_bit = false;
-
- switch(l_field_bits)
- {
- case 0b011:
- case 0b100:
- case 0b110:
- case 0b111:
- is_reserved_bit = true;
- break;
-
- default:
- is_reserved_bit = false;
- break;
- }
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 7;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits <= MAX_VALID_VALUE) &&
- (is_reserved_bit != true),
- l_byte,
- l_field_bits,
- "Failed bounds check for DRAM interface MDQ Drive Strenth") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM interface MDQ Drive Strenth: %d",
- iv_target_str_storage,
- o_output);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM interface MDQ read termination strength
-/// of the data buffer component for a particular dimm speed
-/// @param[in] i_dimm_speed the dimm speed in MT/s
-/// @param[out] o_output encoding of F5BC6x in
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 145 - 147 (Bits 2~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 62
-///
-fapi2::ReturnCode decoder_v1_0::data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output) const
-{
- uint8_t l_byte = 0;
-
- FAPI_TRY( mdq_helper(i_dimm_speed, l_byte) );
-
- {
- constexpr size_t START = 1;
- constexpr size_t LEN = 3;
- const field_t DATA_BUFFER_MDQ_RTT(l_byte, START, LEN);
-
- const uint8_t l_field_bits = extract_spd_field( iv_target, DATA_BUFFER_MDQ_RTT, iv_spd_data );
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 7;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- l_byte,
- l_field_bits,
- "Failed bounds check for DRAM interface MDQ RTT:") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM interface MDQ RTT: %d",
- iv_target_str_storage,
- o_output);
- }
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM drive strenth
-/// for a particular dimm speed
-/// @param[in] i_dimm_speed the dimm speed in MT/s
-/// @param[out] o_output DRAM drive strength (encoding)
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 148 (Bits 5~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 63
-///
-fapi2::ReturnCode decoder_v1_0::dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) const
-{
- size_t l_start = 0;
- FAPI_TRY( drive_strength_start_bit_finder(i_dimm_speed, l_start) );
-
- {
- constexpr size_t BYTE_INDEX = 148;
- constexpr size_t LEN = 2;
- const field_t DRAM_DRIVE_STRENGTH(BYTE_INDEX, l_start, LEN);
-
- const uint8_t l_field_bits = extract_spd_field( iv_target, DRAM_DRIVE_STRENGTH, iv_spd_data );
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // SPD JEDEC specification
- constexpr size_t RESERVED = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- BYTE_INDEX,
- l_field_bits,
- "Failed bounds check for DRAM VrefDQ for Package Rank 3") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM drive strenth: %d",
- iv_target_str_storage,
- o_output);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM ODT for RTT_NOM
-/// for a particular dimm speed
-/// @param[in] i_dimm_speed the dimm speed in MT/s
-/// @param[out] o_output ODT termination strength (encoding)
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 149 - 151 (Bits 2~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - (64 - 65)
-///
-fapi2::ReturnCode decoder_v1_0::dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output) const
-{
- size_t l_byte = 0;
- FAPI_TRY( rtt_wr_and_nom_byte_finder(i_dimm_speed, l_byte) );
-
- {
- constexpr size_t START = 5;
- constexpr size_t LEN = 3;
- const field_t DRAM_RTT_NOM(l_byte, START, LEN);
-
- const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_NOM, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 7;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- l_byte,
- l_field_bits,
- "Failed bounds check for DRAM RTT_NOM") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM RTT_NOM: %d",
- iv_target_str_storage,
- o_output);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM ODT for RTT_WR
-/// for a particular dimm speed
-/// @param[in] i_dimm_speed the dimm speed in MT/s
-/// @param[out] o_output ODT termination strength (encoding)
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 149 - 151 (Bits 5~3)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - (64 - 65)
-///
-fapi2::ReturnCode decoder_v1_0::dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output) const
-{
- size_t l_byte = 0;
- FAPI_TRY( rtt_wr_and_nom_byte_finder(i_dimm_speed, l_byte) );
-
- {
- constexpr size_t START = 2;
- constexpr size_t LEN = 3;
- const field_t DRAM_RTT_WR(l_byte, START, LEN);
-
- const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_WR, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // Lets make sure we aren't being set to a reserved field
- bool is_reserved_bit = false;
-
- switch(l_field_bits)
- {
- case 0b101:
- case 0b110:
- case 0b111:
- is_reserved_bit = true;
- break;
-
- default:
- is_reserved_bit = false;
- break;
- }
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 7;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits <= MAX_VALID_VALUE) &&
- (is_reserved_bit != true),
- l_byte,
- l_field_bits,
- "Failed bounds check for DRAM RTT_WR") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM_RTT_WR: %d",
- iv_target_str_storage,
- o_output);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1
-/// for a particular dimm speed
-/// @param[in] i_dimm_speed the dimm speed in MT/s
-/// @param[out] o_output ODT termination strength (encoding)
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 152 - 154 (Bits 2~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 65
-///
-fapi2::ReturnCode decoder_v1_0::dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output) const
-{
- size_t l_byte = 0;
- FAPI_TRY( rtt_park_byte_finder(i_dimm_speed, l_byte) );
-
- {
- constexpr size_t START = 5;
- constexpr size_t LEN = 3;
- const field_t DRAM_RTT_PARK(l_byte, START, LEN);
-
- const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_PARK, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 7;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- l_byte,
- l_field_bits,
- "Failed bounds check for DRAM RTT_PARK (package ranks 0,1)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM RTT_PARK (package ranks 0,1): %d",
- iv_target_str_storage,
- o_output);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3
-/// for a particular dimm speed
-/// @param[in] i_dimm_speed the dimm speed in MT/s
-/// @param[out] o_output ODT termination strength (encoding)
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 152 - 154 (Bits 5~3)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12.2 - 65
-///
-fapi2::ReturnCode decoder_v1_0::dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output) const
-{
- size_t l_byte = 0;
- FAPI_TRY( rtt_park_byte_finder(i_dimm_speed, l_byte) );
-
- {
- constexpr size_t START = 2;
- constexpr size_t LEN = 3;
- const field_t DRAM_RTT_PARK(l_byte, START, LEN);
-
- const uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_PARK, iv_spd_data);
- FAPI_INF("%s Field Bits value: %d", iv_target_str_storage, l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 7;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- l_byte,
- l_field_bits,
- "Failed bounds check for DRAM RTT_PARK (package ranks 2,3)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. DRAM RTT_PARK (package ranks 2,3): %d",
- iv_target_str_storage,
- o_output);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}// lrdimm
-}// ddr4
-}// spd
-}// mss
diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C
deleted file mode 100644
index 3cccbb654..000000000
--- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C
+++ /dev/null
@@ -1,276 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_1.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file lrdimm_decoder_v1_1.C
-/// @brief LRDIMM module SPD decoder definitions for revision 1.1
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-// std lib
-#include <vector>
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/spd/spd_checker.H>
-#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-namespace mss
-{
-namespace spd
-{
-namespace ddr4
-{
-namespace lrdimm
-{
-
-///
-/// @brief Decodes register and data buffer types
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 131 (Bits 7~4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12.3 - 63
-///
-fapi2::ReturnCode decoder_v1_1::register_and_buffer_type(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< REGISTER_TYPE >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- REGISTER_TYPE.iv_byte,
- l_field_bits,
- "Failed bounds check for Register and Data Buffer Types") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register and Data Buffer Types: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes register output drive strength for CKE signal
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (Bits 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12.3 - 65
-///
-fapi2::ReturnCode decoder_v1_1::cke_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< CKE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- CKE_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CKE") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CKE: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for ODT signal
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (Bits 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12.3 - 65
-///
-fapi2::ReturnCode decoder_v1_1::odt_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< ODT_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- ODT_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for ODT") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for ODT: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for control signal (CS) signal
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (Bits 6~7)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12.3 - 65
-///
-fapi2::ReturnCode decoder_v1_1::cs_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< CS_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- CS_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CS") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CS: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (B side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (Bits 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12.3 - 66
-///
-fapi2::ReturnCode decoder_v1_1::b_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< B_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- B_SIDE_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (A side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (Bits 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12.3 - 66
-///
-fapi2::ReturnCode decoder_v1_1::a_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< A_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL,
- A_SIDE_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}// lrdimm
-}// ddr4
-}// spd
-}// mss
diff --git a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C b/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C
deleted file mode 100644
index 029ad635e..000000000
--- a/src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C
+++ /dev/null
@@ -1,310 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4_v1_2.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-///
-/// @file lrdimm_decoder_v1_2.C
-/// @brief LRDIMM module SPD decoder definitions for revision 1.2
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-// std lib
-#include <vector>
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/spd/spd_checker.H>
-#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-namespace mss
-{
-namespace spd
-{
-namespace ddr4
-{
-namespace lrdimm
-{
-
-///
-/// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE)
-/// @param[out] o_output encoded drive strength
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (Bit 4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.12.3 - 76
-///
-fapi2::ReturnCode decoder_v1_2::bcom_bcke_bodt_drive_strength(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< BCOM_BODT_BCKE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL,
- BCOM_BODT_BCKE_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for data buffer control (BCOM, BODT, BCKE)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for data buffer control (BCOM, BODT, BCKE): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for data buffer control (BCK)
-/// @param[out] o_output encoded drive strength
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (Bit 5)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.12.3 - 76
-///
-fapi2::ReturnCode decoder_v1_2::bck_output_drive_strength(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< BCK_DRIVE_STRENGTH >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL,
- BCK_DRIVE_STRENGTH.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for data buffer control (BCK)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for data buffer control (BCK): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes RCD output slew rate control
-/// @param[out] o_output encoded drive strength
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (Bit 6)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.L-4 - 76
-///
-fapi2::ReturnCode decoder_v1_2::slew_rate_control(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< RCD_SLEW_CNTRL >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 0b1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- RCD_SLEW_CNTRL.iv_byte,
- l_field_bits,
- "Failed bound check for RCD output slew rate control") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. RCD output slew rate control: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes VrefDQ range for DRAM interface range
-/// @param[out] o_output spd encoding
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 155 (Bits 3~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.L-4 - 76
-///
-fapi2::ReturnCode decoder_v1_2::dram_vref_dq_range(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< DRAM_VREF_DQ_RANGE >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 0b1111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- DRAM_VREF_DQ_RANGE.iv_byte,
- l_field_bits,
- "Failed bound check for VrefDQ range for DRAM interface range ") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. VrefDQ range for DRAM interface range: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes data buffer VrefDQ range for DRAM interface range
-/// @param[out] o_output spd encoding
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 155 (Bit 4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.L-4 - 76
-///
-fapi2::ReturnCode decoder_v1_2::data_buffer_vref_dq_range(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_VREF_DQ >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- DATA_BUFFER_VREF_DQ.iv_byte,
- l_field_bits,
- "Failed bound check for data buffer VrefDQ range for DRAM interface range") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Data buffer VrefDQ range for DRAM interface range: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes data buffer gain adjustment
-/// @param[out] o_output spd encoding
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 156 (Bit 0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.L-4 - 77
-///
-fapi2::ReturnCode decoder_v1_2::data_buffer_gain_adjustment(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_GAIN_ADJUST >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- DATA_BUFFER_GAIN_ADJUST.iv_byte,
- l_field_bits,
- "Failed bound check for data buffer gain adjustment") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Data buffer gain adjustment: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes data buffer Decision Feedback Equalization (DFE)
-/// @param[out] o_output spd encoding
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 156 (Bit 1)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 4
-/// @note Page 4.1.2.L-4 - 77
-///
-fapi2::ReturnCode decoder_v1_2::data_buffer_dfe(uint8_t& o_output) const
-{
- // Extracting desired bits
- uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_DFE >(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VAL = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VAL, // extract sanity check
- DATA_BUFFER_DFE.iv_byte,
- l_field_bits,
- "Failed bound check for data buffer Decision Feedback Equalization (DFE)") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Data buffer Decision Feedback Equalization (DFE): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}// lrdimm
-}// ddr4
-}// spd
-}// mss
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H
index 0ec15c90e..96290460b 100644
--- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H
@@ -38,137 +38,79 @@
#include <fapi2.H>
#include <generic/memory/lib/spd/common/dimm_module_decoder.H>
+#include <generic/memory/lib/spd/spd_decoder_def.H>
+#include <generic/memory/lib/spd/spd_traits_ddr4.H>
+#include <generic/memory/lib/spd/spd_reader.H>
namespace mss
{
namespace spd
{
-namespace ddr4
-{
-namespace rdimm
-{
///
/// @class decoder
-/// @brief RDIMM module SPD DRAM decoder for rev 1.0
+/// @tparam R SPD revision - partial specialization
+/// @brief RDIMM module SPD DRAM decoder
///
-class decoder_v1_0 : public dimm_module_decoder
+template < rev R >
+class decoder<DDR4, RDIMM_MODULE, R > : public dimm_module_decoder
{
- protected:
+ private:
- enum
- {
- // Byte 128
- MODULE_NOM_HEIGHT_START = 3,
- MODULE_NOM_HEIGHT_LEN = 5,
- RAW_CARD_EXT_START = 0,
- RAW_CARD_EXT_LEN = 3,
-
- // Byte 129
- FRONT_MODULE_THICKNESS_START = 4,
- FRONT_MODULE_THICKNESS_LEN = 4,
- BACK_MODULE_THICKNESS_START = 0,
- BACK_MODULE_THICKNESS_LEN = 4,
-
- // Byte 130
- REF_RAW_CARD_START = 3,
- REF_RAW_CARD_LEN = 5,
- REF_RAW_CARD_REV_START = 1,
- REF_RAW_CARD_REV_LEN = 2,
- REF_RAW_CARD_EXT_START = 0,
- REF_RAW_CARD_EXT_LEN = 1,
-
- // Byte 131
- REGS_USED_START = 6,
- REGS_USED_LEN = 2,
- ROWS_OF_DRAMS_START = 4,
- ROWS_OF_DRAMS_LEN = 2,
- REGISTER_TYPE_START = 0,
- REGISTER_TYPE_LEN = 4,
-
- // Byte 132
- HEAT_SPREADER_CHAR_START = 1,
- HEAT_SPREADER_CHAR_LEN = 7,
- HEAT_SPREADER_SOL_START = 0,
- HEAT_SPREADER_SOL_LEN = 1,
-
- // Byte 133
- CONTINUATION_CODES_START = 1,
- CONTINUATION_CODES_LEN = 7,
-
- // Byte 134 - whole byte taken
- // Byte 135 - whole byte taken
-
- // Byte 136
- ADDR_MAPPING_START = 7,
- ADDR_MAPPING_LEN = 1,
-
- // Byte 137
- CKE_DRIVER_START = 6,
- CKE_DRIVER_LEN = 2,
- ODT_DRIVER_START = 4,
- ODT_DRIVER_LEN = 2,
- CA_DRIVER_START = 2,
- CA_DRIVER_LEN = 2,
- CS_DRIVER_START = 0,
- CS_DRIVER_LEN = 2,
-
- // Byte 138
- YO_Y2_DRIVER_START = 6,
- YO_Y2_DRIVER_LEN = 2,
- Y1_Y3_DRIVER_START = 4,
- Y1_Y3_DRIVER_LEN = 2,
- };
-
- enum addr_mapping
- {
- STANDARD = 0,
- MIRRORED = 1,
- };
+ using fields_t = fields<DDR4, RDIMM_MODULE>;
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ std::vector<uint8_t> iv_data;
public:
- // First field - SPD byte
- // Second field - start bit
- // Third field - bit length
- static constexpr field_t MODULE_NOMINAL_HEIGHT{128, MODULE_NOM_HEIGHT_START, MODULE_NOM_HEIGHT_LEN};
- static constexpr field_t RAW_CARD_EXTENSION{128, RAW_CARD_EXT_START, RAW_CARD_EXT_LEN};
- static constexpr field_t FRONT_MODULE_THICKNESS{129, FRONT_MODULE_THICKNESS_START, FRONT_MODULE_THICKNESS_LEN};
- static constexpr field_t BACK_MODULE_THICKNESS{129, BACK_MODULE_THICKNESS_START, BACK_MODULE_THICKNESS_LEN};
- static constexpr field_t REF_RAW_CARD{130, REF_RAW_CARD_START, REF_RAW_CARD_LEN};
- static constexpr field_t REF_RAW_CARD_REV{130, REF_RAW_CARD_REV_START, REF_RAW_CARD_REV_LEN};
- static constexpr field_t REF_RAW_CARD_EXT{130, REF_RAW_CARD_EXT_START, REF_RAW_CARD_EXT_LEN};
- static constexpr field_t NUM_REGS_USED{131, REGS_USED_START, REGS_USED_LEN};
- static constexpr field_t ROWS_OF_DRAMS{131, ROWS_OF_DRAMS_START, ROWS_OF_DRAMS_LEN};
- static constexpr field_t REGISTER_TYPE{131, REGISTER_TYPE_START, REGISTER_TYPE_LEN};
- static constexpr field_t HEAT_SPREADER_CHAR{132, HEAT_SPREADER_CHAR_START, HEAT_SPREADER_CHAR_LEN};
- static constexpr field_t HEAT_SPREADER_SOL{132, HEAT_SPREADER_SOL_START, HEAT_SPREADER_SOL_LEN};
- static constexpr field_t CONTINUATION_CODES{133, CONTINUATION_CODES_START, CONTINUATION_CODES_LEN};
- static constexpr field_t ADDR_MAPPING{136, ADDR_MAPPING_START, ADDR_MAPPING_LEN};
- static constexpr field_t CKE_DRIVER{137, CKE_DRIVER_START, CKE_DRIVER_LEN};
- static constexpr field_t ODT_DRIVER{137, ODT_DRIVER_START, ODT_DRIVER_LEN};
- static constexpr field_t CA_DRIVER{137, CA_DRIVER_START, CA_DRIVER_LEN};
- static constexpr field_t CS_DRIVER{137, CS_DRIVER_START, CS_DRIVER_LEN};
- static constexpr field_t YO_Y2_DRIVER{138, YO_Y2_DRIVER_START, YO_Y2_DRIVER_LEN};
- static constexpr field_t Y1_Y3_DRIVER{138, Y1_Y3_DRIVER_START, Y1_Y3_DRIVER_LEN};
-
// deleted default ctor
- decoder_v1_0() = delete;
+ decoder() = delete;
///
/// @brief ctor
/// @param[in] i_target dimm target
/// @param[in] i_spd_data vector DIMM SPD data
///
- decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data):
- dimm_module_decoder(i_target, i_spd_data)
- {}
+ decoder(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data):
+ dimm_module_decoder(i_target, i_spd_data),
+ iv_target(i_target),
+ iv_data(i_spd_data)
+ {
+ static_assert( R <= rev::RDIMM_MAX, " R > rev::RDIMM_MAX");
+ }
///
/// @brief default dtor
///
- virtual ~decoder_v1_0() = default;
+ virtual ~decoder() = default;
+
+ ///
+ /// @brief Gets decoder target
+ /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ ///
+ virtual fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_target;
+ }
+
+ ///
+ /// @brief Gets decoder SPD data
+ /// @return std::vector<uint8_t>
+ ///
+ virtual std::vector<uint8_t> get_data() const
+ {
+ return iv_data;
+ }
+
+ ///
+ /// @brief Sets decoder SPD data
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ virtual void set_data(const std::vector<uint8_t>& i_spd_data)
+ {
+ iv_data = i_spd_data;
+ }
///
/// @brief Decodes module nominal height max, in mm
@@ -179,7 +121,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 48
///
- virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::MODULE_NOMINAL_HEIGHT, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes front module maximum thickness max, in mm
@@ -190,7 +138,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 48
///
- virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::FRONT_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes back module maximum thickness max, in mm
@@ -201,7 +155,30 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 48
///
- virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::BACK_MODULE_THICKNESS, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes reference raw card used
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 130 (Bits 7~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12 - 48
+ ///
+ virtual fapi2::ReturnCode reference_raw_card(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::REF_RAW_CARD, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of registers used on RDIMM
@@ -212,7 +189,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 50
///
- virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::NUM_REGS_USED, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes number of rows of DRAMs on RDIMM
@@ -223,7 +206,31 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 50
///
- virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ROWS_OF_DRAMS, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+
+ }
+
+ ///
+ /// @brief Decodes register types
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 131 (Bits 7~4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 63
+ ///
+ virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_TYPE, R>(iv_target, iv_data, o_output)) );
+ fapi_try_exit:
+ return fapi2::current_err;
+
+ }
///
/// @brief Decodes heat spreader thermal characteristics
@@ -234,7 +241,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 51
///
- virtual fapi2::ReturnCode heat_spreader_thermal_char(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode heat_spreader_thermal_char(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::HEAT_SPREADER_CHAR, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes heat spreader solution
@@ -245,18 +258,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 51
///
- virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::HEAT_SPREADER_SOL, R>(iv_target, iv_data, o_output)) );
- ///
- /// @brief Decodes number of continuation codes
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 133 (bit 6~0)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 51
- ///
- virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register manufacturer ID code
@@ -267,7 +275,28 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 51
///
- virtual fapi2::ReturnCode reg_manufacturer_id_code(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_output) const override
+ {
+ uint8_t l_cont_codes = 0;
+ uint8_t l_last_nonzero_byte = 0;
+
+ FAPI_TRY( (mss::spd::reader<fields_t::CONTINUATION_CODES, R>(iv_target, iv_data, l_cont_codes)) );
+ FAPI_TRY( (mss::spd::reader<fields_t::LAST_NON_ZERO_BYTE, R>(iv_target, iv_data, l_last_nonzero_byte)) );
+
+ {
+ fapi2::buffer<uint16_t> l_buffer;
+ rightAlignedInsert(l_buffer, l_last_nonzero_byte, l_cont_codes);
+
+ o_output = l_buffer;
+
+ FAPI_INF("%s. Register Manufacturer ID Code: 0x%04x",
+ spd::c_str(iv_target),
+ o_output);
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register revision number
@@ -278,7 +307,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 51
///
- virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::REGISTER_REV, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes address mapping from register to dram
@@ -289,7 +324,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 52
///
- virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ADDR_MAP_REG_TO_DRAM, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for CKE signal
@@ -300,7 +341,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 53
///
- virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::CKE_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for ODT signal
@@ -311,7 +358,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 53
///
- virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::ODT_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for command/address (CA) signal
@@ -322,7 +375,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 53
///
- virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::CA_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for control signal (CS) signal
@@ -333,7 +392,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 53
///
- virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::CS_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for clock (B side)
@@ -344,7 +409,13 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 53
///
- virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::YO_Y2_DRIVER, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
///
/// @brief Decodes register output drive strength for clock (A side)
@@ -355,106 +426,17 @@ class decoder_v1_0 : public dimm_module_decoder
/// @note DDR4 SPD Document Release 2
/// @note Page 4.1.2.12 - 53
///
- virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override;
-
-};// decoder_v1_0
-
-///
-/// @class decoder
-/// @brief RDIMM module SPD DRAM decoder for rev 1.1
-///
-class decoder_v1_1 : public decoder_v1_0
-{
- public:
-
- // deleted default ctor
- decoder_v1_1() = delete;
-
- ///
- /// @brief ctor
- /// @param[in] i_target dimm target
- /// @param[in] i_spd_data vector DIMM SPD data
- ///
- decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const std::vector<uint8_t>& i_spd_data):
- decoder_v1_0(i_target, i_spd_data)
- {}
-
- ///
- /// @brief default dtor
- ///
- virtual ~decoder_v1_1() = default;
-
- ///
- /// @brief Decodes register types
- /// @param[out] o_output encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 131 (Bits 7~4)
- /// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 3
- /// @note Page 4.1.2.12.3 - 63
- ///
- virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for CKE signal
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (bit 1~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
- ///
- virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for ODT signal
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (bit 3~2)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
- ///
- virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) const override;
-
- ///
- /// @brief Decodes register output drive strength for control signal (CS) signal
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (bit 6~7)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
- ///
- virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) const override;
+ virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (mss::spd::reader<fields_t::Y1_Y3_DRIVER, R>(iv_target, iv_data, o_output)) );
- ///
- /// @brief Decodes register output drive strength for clock (B side)
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (bit 1~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
- ///
- virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) const override;
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
- ///
- /// @brief Decodes register output drive strength for clock (A side)
- /// @param[out] o_output drive strength encoding from SPD
- /// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (bit 3~2)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
- ///
- virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) const override;
-};//decoder_v1_1
+};// decoder
-}// rdimm
-}// ddr4
}// spd
}// mss
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C
deleted file mode 100644
index 021130412..000000000
--- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C
+++ /dev/null
@@ -1,644 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-///
-/// @file rdimm_decoder.C
-/// @brief RDIMM module specific SPD decoder definitions
-///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
-// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 3
-// *HWP Consumed by: HB:FSP
-
-// std lib
-#include <vector>
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/spd/spd_checker.H>
-#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-
-namespace mss
-{
-namespace spd
-{
-namespace ddr4
-{
-namespace rdimm
-{
-
-/////////////////////////
-// Member Method implementation
-// For RDIMM module rev 1.0
-/////////////////////////
-
-///
-/// @brief Decodes module nominal height max, in mm
-/// @param[out] o_output height range encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 128 (Bits 4~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 48
-///
-fapi2::ReturnCode decoder_v1_0::max_module_nominal_height(uint8_t& o_output) const
-{
- const uint8_t l_field_bits = extract_spd_field<MODULE_NOMINAL_HEIGHT>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b11111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- MODULE_NOMINAL_HEIGHT.iv_byte,
- l_field_bits,
- "Failed bound check for module nominal height max") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Max module nominal height: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes front module maximum thickness max, in mm
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 129 (Bits 3~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 48
-///
-fapi2::ReturnCode decoder_v1_0::front_module_max_thickness(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<FRONT_MODULE_THICKNESS>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b1111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- FRONT_MODULE_THICKNESS.iv_byte,
- l_field_bits,
- "Failed bound check for front module max thickness") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Front module max thickness: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes back module maximum thickness max, in mm
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 129 (Bits 7~4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 48
-///
-fapi2::ReturnCode decoder_v1_0::back_module_max_thickness(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<BACK_MODULE_THICKNESS>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b1111;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- BACK_MODULE_THICKNESS.iv_byte,
- l_field_bits,
- "Failed bound check for back module max thickness") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Back module max thickness: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes number of registers used on RDIMM
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 131 (Bits 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 50
-///
-fapi2::ReturnCode decoder_v1_0::num_registers_used(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<NUM_REGS_USED>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- NUM_REGS_USED.iv_byte,
- l_field_bits,
- "Failed bound check for number of registers used on RDIMM ") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Number of registers used on RDIMM : %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes number of rows of DRAMs on RDIMM
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 131 (Bits 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 50
-///
-fapi2::ReturnCode decoder_v1_0::num_rows_of_drams(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<ROWS_OF_DRAMS>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- ROWS_OF_DRAMS.iv_byte,
- l_field_bits,
- "Failed bound check for number of rows of DRAMs on RDIMM ") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Number of rows of DRAMs on RDIMM : %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes heat spreader thermal characteristics
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCEawSS if okay
-/// @note SPD Byte 132 (Bits 6~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 51
-///
-fapi2::ReturnCode decoder_v1_0::heat_spreader_thermal_char(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<HEAT_SPREADER_CHAR>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- HEAT_SPREADER_CHAR.iv_byte,
- l_field_bits,
- "Failed bound check for heat spreader thermal characteristics") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Heat spreader thermal characteristics: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes heat spreader solution
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 132 (Bit 7)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 51
-///
-fapi2::ReturnCode decoder_v1_0::heat_spreader_solution(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<HEAT_SPREADER_SOL>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 1;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- HEAT_SPREADER_SOL.iv_byte,
- l_field_bits,
- "Failed bound check for heat spreader solution") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Heat spreader solution: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-///
-/// @brief Decodes number of continuation codes
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 133 (bit 6~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 51
-///
-fapi2::ReturnCode decoder_v1_0::num_continuation_codes(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<CONTINUATION_CODES>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t MAX_VALID_VALUE = 10; // JEP106AS
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits <= MAX_VALID_VALUE,
- CONTINUATION_CODES.iv_byte,
- l_field_bits,
- "Failed bound check for number of continuation codes") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Number of continuation codes: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes register manufacturer ID code
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 134 (bit 7~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 51
-///
-fapi2::ReturnCode decoder_v1_0::reg_manufacturer_id_code(uint8_t& o_output) const
-{
- constexpr size_t BYTE_INDEX = 134;
- uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_raw_byte);
-
- o_output = l_raw_byte;
-
- FAPI_INF("%s. Manufacturer ID code: %d",
- iv_target_str_storage,
- o_output);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes register revision number
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 135 (bit 7~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 51
-///
-fapi2::ReturnCode decoder_v1_0::register_rev_num(uint8_t& o_output) const
-{
- constexpr size_t BYTE_INDEX = 135;
- uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
-
- // Trace in the front assists w/ debug
- FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
- iv_target_str_storage,
- BYTE_INDEX,
- l_raw_byte);
-
- o_output = l_raw_byte;
-
- FAPI_INF("%s. Register revision number: %d",
- iv_target_str_storage,
- o_output);
-
- return fapi2::FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Decodes address mapping from register to dram
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 136 (bit 0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 52
-///
-fapi2::ReturnCode decoder_v1_0::register_to_dram_addr_mapping(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<ADDR_MAPPING>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- ADDR_MAPPING.iv_byte,
- l_field_bits,
- "Failed bound check for to register to dram addr mapping") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Address mapping from register to dram: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for CKE signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 53
-///
-fapi2::ReturnCode decoder_v1_0::cke_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<CKE_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- CKE_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CKE") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CKE: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for ODT signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 53
-///
-fapi2::ReturnCode decoder_v1_0::odt_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<ODT_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- ODT_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for ODT") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for ODT: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for command/address (CA) signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 5~4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 53
-///
-fapi2::ReturnCode decoder_v1_0::ca_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<CA_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t INVALID_VAL = 3;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < INVALID_VAL, // extract sanity check
- CA_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CA") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CA: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for control signal (CS) signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 6~7)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 53
-///
-fapi2::ReturnCode decoder_v1_0::cs_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<CS_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- CS_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CS") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CS: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (B side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (bit 1~0)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 53
-///
-fapi2::ReturnCode decoder_v1_0::b_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<YO_Y2_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED, // extract sanity check
- YO_Y2_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (A side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (bit 3~2)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 2
-/// @note Page 4.1.2.12 - 53
-///
-fapi2::ReturnCode decoder_v1_0::a_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<Y1_Y3_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field_Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- l_field_bits < RESERVED,
- Y1_Y3_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}// rdimm
-}// ddr4
-}// spd
-}// mss
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C
deleted file mode 100644
index 9a6aa5446..000000000
--- a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C
+++ /dev/null
@@ -1,268 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
-/* [+] International Business Machines Corp. */
-/* */
-/* */
-/* Licensed under the Apache License, Version 2.0 (the "License"); */
-/* you may not use this file except in compliance with the License. */
-/* You may obtain a copy of the License at */
-/* */
-/* http://www.apache.org/licenses/LICENSE-2.0 */
-/* */
-/* Unless required by applicable law or agreed to in writing, software */
-/* distributed under the License is distributed on an "AS IS" BASIS, */
-/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
-/* implied. See the License for the specific language governing */
-/* permissions and limitations under the License. */
-/* */
-/* IBM_PROLOG_END_TAG */
-
-// std lib
-#include <vector>
-
-// fapi2
-#include <fapi2.H>
-
-// mss lib
-#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
-#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
-#include <generic/memory/lib/spd/spd_checker.H>
-#include <generic/memory/lib/utils/c_str.H>
-#include <generic/memory/lib/utils/find.H>
-
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_MCA;
-using fapi2::TARGET_TYPE_MCS;
-using fapi2::TARGET_TYPE_DIMM;
-
-
-namespace mss
-{
-namespace spd
-{
-namespace ddr4
-{
-namespace rdimm
-{
-
-/////////////////////////
-// Member Method implementation
-// For RDIMM module rev 1.1
-/////////////////////////
-
-///
-/// @brief Decodes register type
-/// @param[out] o_output encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 131 (Bits 7~4)
-/// @note Item JEDEC Standard No. 21-C
-/// @note DDR4 SPD Document Release 3
-/// @note Page 4.1.2.12.3 - 63
-///
-fapi2::ReturnCode decoder_v1_1::register_and_buffer_type(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<REGISTER_TYPE>(iv_target, iv_spd_data);
- FAPI_INF("Field Bits value: %d", l_field_bits);
-
- // This checks my extracting params returns a value within bound
- constexpr size_t RESERVED = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits < RESERVED), // extract sanity check
- REGISTER_TYPE.iv_byte,
- l_field_bits,
- "Failed bounds check for Register and Data Buffer Types") );
-
- // Update output only if check passes
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Types: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-
-}
-
-///
-/// @brief Decodes register output drive strength for CKE signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 1~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 76
-/// @note DDR4 SPD Document Release 4
-///
-fapi2::ReturnCode decoder_v1_1::cke_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<CKE_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // This really just checks my extract gives me a valid value
- constexpr size_t MAX_VALID_VALUE = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits <= MAX_VALID_VALUE), // extract sanity check
- CKE_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for CKE") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CKE: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for ODT signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 3~2)
-/// @note Item JC-45-2220.01x
-/// @note Page 76
-/// @note DDR4 SPD Document Release 4
-///
-fapi2::ReturnCode decoder_v1_1::odt_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<ODT_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // This really just checks my extract gives me a valid value
- constexpr size_t MAX_VALID_VALUE = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits <= MAX_VALID_VALUE), // extract sanity check
- ODT_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for ODT") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for ODT: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for control signal (CS) signal
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 137 (bit 6~7)
-/// @note Item JC-45-2220.01x
-/// @note Page 76
-/// @note DDR4 SPD Document Release 4
-///
-fapi2::ReturnCode decoder_v1_1::cs_signal_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<CS_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // This really just checks my extract gives me a valid value
- constexpr size_t MAX_VALID_VALUE = 0b11;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits <= MAX_VALID_VALUE), // extract sanity check
- CS_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for chip select") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for CS: %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (B side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (bit 1~0)
-/// @note Item JC-45-2220.01x
-/// @note Page 76
-/// @note DDR4 SPD Document Release 4
-///
-fapi2::ReturnCode decoder_v1_1::b_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<YO_Y2_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // This really just checks my extract gives me a valid value
- constexpr size_t MAX_VALID_VAL = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits <= MAX_VALID_VAL), // extract sanity check
- YO_Y2_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Decodes register output drive strength for clock (A side)
-/// @param[out] o_output drive strength encoding from SPD
-/// @return FAPI2_RC_SUCCESS if okay
-/// @note SPD Byte 138 (bit 3~2)
-/// @note Item JC-45-2220.01x
-/// @note Page 76
-/// @note DDR4 SPD Document Release 4
-///
-fapi2::ReturnCode decoder_v1_1::a_side_clk_output_driver(uint8_t& o_output) const
-{
- // Extracting desired bits
- const uint8_t l_field_bits = extract_spd_field<Y1_Y3_DRIVER>(iv_target, iv_spd_data);
- FAPI_DBG("Field Bits value: %d", l_field_bits);
-
- // This really just checks my extract gives me a valid value
- constexpr size_t MAX_VALID_VAL = 2;
-
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
- (l_field_bits <= MAX_VALID_VAL), // extract sanity check
- Y1_Y3_DRIVER.iv_byte,
- l_field_bits,
- "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
-
- o_output = l_field_bits;
-
- FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d",
- iv_target_str_storage,
- o_output);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-}// rdimm
-}// ddr4
-}// spd
-}// mss
diff --git a/src/import/generic/memory/lib/spd/spd_checker.H b/src/import/generic/memory/lib/spd/spd_checker.H
index d3a85aaa4..a26ac4741 100644
--- a/src/import/generic/memory/lib/spd/spd_checker.H
+++ b/src/import/generic/memory/lib/spd/spd_checker.H
@@ -23,42 +23,130 @@
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file spd_checker.H
+/// @brief SPD functions to check boundaries
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
#ifndef _SPD_CHECKER_H_
#define _SPD_CHECKER_H_
#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
namespace mss
{
-namespace check
+
+///
+/// @brief Selectors for timing limits
+/// @note BITS12 stands for a 12 bit range
+/// @note BITS16 stands for a 16 bit range
+///
+enum bit_len
+{
+ BITS12 = 12,
+ BITS16 = 16,
+};
+
+///
+/// @class bitRangeTraits
+/// @brief Traits class to select
+/// @tparam T bit_len selector
+///
+template <bit_len T>
+struct bitRangeTraits;
+
+///
+/// @class bitRangeTraits
+/// @brief Traits class to select - BITS12 specialization
+///
+template<>
+struct bitRangeTraits<BITS12>
+{
+ enum
+ {
+ LOWER_BOUND = 0x1,
+ UPPER_BOUND = 0xfff,
+ };
+};
+
+///
+/// @class bitRangeTraits
+/// @brief Traits class to select - BITS16 specialization
+///
+template<>
+struct bitRangeTraits<BITS16>
{
+ enum
+ {
+ LOWER_BOUND = 0x1,
+ UPPER_BOUND = 0xffff,
+ };
+};
+
namespace spd
{
+namespace check
+{
+
+///
+/// @brief SPD timing boundary check
+/// @tparam BL bit_len selector
+/// @tparam T the TargetType
+/// @tparam TT defaulted to bitRangeTraits<TB>
+/// @param[in] i_target fapi2 target
+/// @param[in] i_timing the timing value
+/// @param[in] i_ffdc ffdc function code
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template < bit_len BL, fapi2::TargetType T, typename TT = bitRangeTraits<BL> >
+fapi2::ReturnCode max_timing_range(const fapi2::Target<T>& i_target,
+ const int64_t i_timing,
+ const generic_ffdc_codes i_ffdc)
+{
+ FAPI_ASSERT( (i_timing <= TT::UPPER_BOUND) &&
+ (i_timing >= TT::LOWER_BOUND),
+ fapi2::MSS_SPD_TIMING_FAIL()
+ .set_FUNCTION_CODE(i_ffdc)
+ .set_TARGET(i_target),
+ "Failed timing parameter check for %s",
+ spd::c_str(i_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
-/// @brief Checks conditional passes and implements traces & exits if it fails
-/// @tparam T input data of any size
-/// @param[in] i_target fapi2 dimm target
-/// @param[in] i_conditional conditional that we are testing against
-/// @param[in] i_spd_byte_index current SPD byte
-/// @param[in] i_spd_data debug data
-/// @param[in] i_err_str error string to print out when conditional fails
-/// @return ReturnCode
+/// @brief Checks conditional passes and implements traces & exits if it fails
+/// @tparam T input data of any size
+/// @param[in] i_target fapi2 dimm target
+/// @param[in] i_conditional conditional that we are testing against
+/// @param[in] i_spd_byte_index current SPD byte
+/// @param[in] i_spd_data debug data
+/// @param[in] i_err_str error string to print out when conditional fails
+/// @return FAPI2_RC_SUCCESS iff okay
///
template< typename T >
inline fapi2::ReturnCode fail_for_invalid_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const bool i_conditional,
const size_t i_spd_byte_index,
const T i_spd_data,
- const char* i_err_str)
+ const char* i_err_str = "")
{
FAPI_ASSERT(i_conditional,
fapi2::MSS_BAD_SPD().
set_VALUE(i_spd_data).
set_BYTE(i_spd_byte_index).
set_DIMM_TARGET(i_target),
- "%s %s Byte %d, Data returned: %d.",
- c_str(i_target),
+ "%s %s Byte %d, data 0x%02x, extracted value: 0x%02x.",
+ spd::c_str(i_target),
i_err_str,
i_spd_byte_index,
i_spd_data);
@@ -67,70 +155,136 @@ inline fapi2::ReturnCode fail_for_invalid_value(const fapi2::Target<fapi2::TARGE
fapi_try_exit:
return fapi2::current_err;
-} // fail_for_invalid_value()
+} // fail_for_invalid_value
///
-/// @brief Checks conditional passes and implements traces if it fails. No FFDC collected.
-/// @tparam T input data of any size
-/// @param[in] i_target fapi2 dimm target
-/// @param[in] i_conditional that we are testing against
-/// @param[in] i_spd_byte_index
-/// @param[in] i_spd_data debug data
-/// @param[in] i_err_str string to print out when conditional fails
-/// @return void
+/// @brief Helper function to test if a DRAM generation is valid
+/// @param[in] i_dram_gen the DRAM gen from SPD
+/// @return true if this DRAM gen is valid, else false
///
-template< typename T >
-inline void warn_for_invalid_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const bool i_conditional,
- const size_t i_spd_byte_index,
- const T i_spd_data,
- const char* i_err_str)
+static inline bool is_dram_gen_valid(const uint8_t i_dram_gen)
+{
+ bool l_result = false;
+
+ switch(i_dram_gen)
+ {
+ case DDR4:
+ l_result = true;
+ break;
+
+ default:
+ l_result = false;
+ break;
+ }
+
+ return l_result;
+}
+
+///
+/// @brief Checks for valid DRAM generation
+/// @param[in] i_target the DIMM target
+/// @param[in] i_dram_gen the DRAM gen from SPD
+/// @param[in] i_func_code mss ffdc code
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode dram_gen(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_dram_gen,
+ const generic_ffdc_codes i_func_code)
+{
+ FAPI_ASSERT(is_dram_gen_valid(i_dram_gen),
+ fapi2::MSS_INVALID_DRAM_GEN()
+ .set_DRAM_GEN(i_dram_gen)
+ .set_FUNCTION(i_func_code)
+ .set_DIMM_TARGET(i_target),
+ "Invalid DRAM gen recieved (%d) for %s",
+ i_dram_gen, spd::c_str(i_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to test if a DIMM type is valid
+/// @param[in] i_dimm_type the DIMM type from SPD
+/// @return true if this DIMM type is valid, else false
+///
+static inline bool is_dimm_type_valid(const uint8_t i_dimm_type)
{
- // Don't print warning conditional if true
- if(!i_conditional)
+ bool l_result = false;
+
+ switch(i_dimm_type)
{
- FAPI_IMP("%s. %s. Byte %d, Data returned: %d.",
- c_str(i_target),
- i_err_str,
- i_spd_byte_index,
- i_spd_data );
+ case RDIMM:
+ case LRDIMM:
+ l_result = true;
+ break;
+
+ default:
+ l_result = false;
+ break;
}
-}// warn_for_invalid_value
-
-///
-/// @brief Checks if valid factory parameters are given
-/// @param[in] i_target fapi2 dimm target
-/// @param[in] i_dimm_type DIMM type enumeration
-/// @param[in] i_encoding_rev SPD encoding level rev number
-/// @param[in] i_additions_rev SPD additions level rev number
-/// @param[in] i_err_str string to print out when conditional fails
-/// @return fapi2::ReturnCode
-///
-inline fapi2::ReturnCode invalid_factory_sel(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint8_t i_dimm_type,
- const uint8_t i_encoding_rev,
- const uint8_t i_additions_rev,
- const char* i_err_str)
+
+ return l_result;
+}
+
+///
+/// @brief Checks for valid DIMM type
+/// @param[in] i_target the DIMM target
+/// @param[in] i_dram_gen the DIMM type from SPD
+/// @param[in] i_func_code mss ffdc code
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode dimm_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint8_t i_dimm_type,
+ const generic_ffdc_codes i_func_code)
{
- FAPI_ASSERT(false,
- fapi2::MSS_INVALID_DIMM_REV_COMBO().
- set_DIMM_TYPE(i_dimm_type).
- set_ENCODING_REV(i_encoding_rev).
- set_ADDITIONS_REV(i_additions_rev).
- set_DIMM_TARGET(i_target),
- "%s. %s. Invalid combination for dimm type: %d, rev: %d.%d",
- c_str(i_target),
- i_err_str,
- i_dimm_type,
- i_encoding_rev,
- i_additions_rev);
+ FAPI_ASSERT(is_dimm_type_valid(i_dimm_type),
+ fapi2::MSS_INVALID_DIMM_TYPE()
+ .set_DIMM_TYPE(i_dimm_type)
+ .set_FUNCTION(i_func_code)
+ .set_DIMM_TARGET(i_target),
+ "Invalid DIMM type recieved (%d) for %s",
+ i_dimm_type, spd::c_str(i_target));
+
return fapi2::FAPI2_RC_SUCCESS;
+
fapi_try_exit:
return fapi2::current_err;
-}// invalid_factory_sel
+}
+
+///
+/// @brief Helper function to check for reserved values
+/// @tparam TT FAPI2 target type
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_reserved_bits vector of SORTED reserved bits to sort through
+/// @param[in] i_ffdc ffdc function code
+/// @param[in] i_input value to check
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template < fapi2::TargetType TT >
+inline fapi2::ReturnCode reserved_values(const fapi2::Target<TT>& i_target,
+ const std::vector<uint8_t>& i_reserved_bits,
+ const generic_ffdc_codes i_ffdc,
+ const uint8_t i_input)
+{
+ // Lets make an additional check that we aren't being set to a reserved field
+ FAPI_ASSERT( !std::binary_search(i_reserved_bits.begin(), i_reserved_bits.end(), i_input),
+ fapi2::MSS_INVALID_SPD_RESERVED_BITS()
+ .set_FUNCTION_CODE(i_ffdc)
+ .set_TARGET(i_target),
+ "Reserved bits seen on %s",
+ spd::c_str(i_target) );
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
-}// spd
}// check
+}// spd
}// mss
#endif
diff --git a/src/import/generic/memory/lib/spd/spd_decoder_def.H b/src/import/generic/memory/lib/spd/spd_decoder_def.H
index fe2ecc46b..9d8378145 100644
--- a/src/import/generic/memory/lib/spd/spd_decoder_def.H
+++ b/src/import/generic/memory/lib/spd/spd_decoder_def.H
@@ -22,3 +22,38 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file spd_decoder_def.H
+/// @brief SPD decoder definition
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_SPD_DECODER_DEF_H_
+#define _MSS_SPD_DECODER_DEF_H_
+
+#include <generic/memory/lib/spd/spd_field.H>
+
+namespace mss
+{
+namespace spd
+{
+
+///
+/// @class decoder
+/// @tparam D device type (DDR4, etc.)
+/// @tparam S JEDEC SPD parameters (LRDIMM_MODULE, GEN_SEC, etc.)
+/// @tparam R SPD revision (e.g. rev 1.1, 1.2, etc.)
+/// @brief Base SPD DRAM decoder
+///
+template < device_type D, parameters S, rev R >
+class decoder;
+
+}// spd
+}// mss
+
+#endif //_MSS_SPD_DECODER_DEF_H_
diff --git a/src/import/generic/memory/lib/spd/spd_facade.H b/src/import/generic/memory/lib/spd/spd_facade.H
index 440d9498a..5c86d7895 100644
--- a/src/import/generic/memory/lib/spd/spd_facade.H
+++ b/src/import/generic/memory/lib/spd/spd_facade.H
@@ -22,3 +22,1637 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+#ifndef _MSS_SPD_FACADE_H_
+#define _MSS_SPD_FACADE_H_
+
+#include <generic/memory/lib/spd/spd_factory_pattern.H>
+#include <generic/memory/lib/utils/find.H>
+#include <fapi2_spd_access.H>
+
+namespace mss
+{
+namespace spd
+{
+
+///
+/// @brief Retrieve SPD data
+/// @param[in] i_target the DIMM target
+/// @param[out] o_spd reference to std::vector
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+inline fapi2::ReturnCode get_raw_data(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ std::vector<uint8_t>& o_spd)
+{
+ // Get SPD blob size
+ size_t l_size = 0;
+ FAPI_TRY( fapi2::getSPD(i_target, nullptr, l_size),
+ "%s. Failed to retrieve SPD blob size", spd::c_str(i_target) );
+
+ // Reassign container size with the retrieved size
+ // Arbitrarily set the data to zero since it will be overwritten
+ o_spd.assign(l_size, 0);
+
+ // Retrieve SPD data content
+ FAPI_TRY( fapi2::getSPD(i_target, o_spd.data(), l_size),
+ "%s. Failed to retrieve SPD data", spd::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @class facade
+/// @brief SDP facade to simplify decoder interface
+/// @note the facade should be a pass through class,
+/// shouldn't be subclassed. Factories should be the work horse.
+///
+class facade final
+{
+ private:
+
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ std::vector<uint8_t> iv_data;
+ std::shared_ptr<dimm_module_decoder> iv_dimm_module_decoder;
+ std::shared_ptr<base_cnfg_decoder> iv_base_cnfg_decoder;
+
+ public:
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_spd_data SPD data in a vector reference
+ /// @param[out] o_rc FAPI2_RC_SUCCESS iff okay
+ ///
+ facade( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data,
+ fapi2::ReturnCode& o_rc):
+ iv_target(i_target),
+ iv_data(i_spd_data)
+ {
+ factories l_factories(i_target, i_spd_data, o_rc);
+ FAPI_TRY(o_rc, "Failed to instantiate factories object for %s", spd::c_str(i_target));
+
+ FAPI_TRY(l_factories.create_decoder(iv_dimm_module_decoder));
+ FAPI_TRY(l_factories.create_decoder(iv_base_cnfg_decoder));
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+ fapi_try_exit:
+ o_rc = fapi2::current_err;
+ }
+
+ ///
+ /// @brief dtor
+ ///
+ ~facade() = default;
+
+ ///
+ /// @brief Gets facade target
+ /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ ///
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_target;
+ }
+
+ ///
+ /// @brief Gets facade SPD data
+ /// @return std::vector<uint8_t>
+ ///
+ std::vector<uint8_t> get_data() const
+ {
+ return iv_data;
+ }
+
+ ///
+ /// @brief Sets facade SPD data
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ void set_data(const std::vector<uint8_t>& i_spd_data)
+ {
+ // Keep SPD data changes consistent through decoders
+ iv_data = i_spd_data;
+ iv_base_cnfg_decoder->set_data(i_spd_data);
+ iv_dimm_module_decoder->set_data(i_spd_data);
+ }
+
+ ///
+ /// @brief Decodes number of used SPD bytes
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode number_of_used_bytes( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->number_of_used_bytes(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes total SPD encoding for total bytes
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode number_of_total_bytes( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->number_of_total_bytes(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDP revision
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode revision( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->revision(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM device type
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode device_type( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->device_type(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes base module type
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode base_module( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->base_module(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM density from SPD
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode sdram_density( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->sdram_density(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes hybrid media
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode hybrid_media( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->hybrid_media(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes hybrid
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode hybrid( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->hybrid(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes number of SDRAM banks bits from SPD
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode bank_bits( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->bank_bits(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes number of SDRAM bank groups bits from SPD
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode bank_group_bits( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->bank_group_bits(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes number of SDRAM column address bits
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode column_address_bits( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->column_address_bits(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes number of SDRAM row address bits
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode row_address_bits( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->row_address_bits(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Primary SDRAM signal loading
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode prim_sdram_signal_loading( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->prim_sdram_signal_loading(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Primary SDRAM die count
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode prim_sdram_die_count( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->prim_sdram_die_count(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Primary SDRAM package type
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode prim_sdram_package_type( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->prim_sdram_package_type(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode SDRAM Maximum activate count
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode maximum_activate_count( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->maximum_activate_count(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode SDRAM Maximum activate window (multiplier), tREFI uknown at this point
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode maximum_activate_window_multiplier( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->maximum_activate_window_multiplier(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Post package repair (PPR)
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode post_package_repair( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->post_package_repair(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Soft post package repair (soft PPR)
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode soft_post_package_repair( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->soft_post_package_repair(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Secondary SDRAM signal loading
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode sec_sdram_signal_loading( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->sec_sdram_signal_loading(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Secondary DRAM Density Ratio
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode sec_dram_density_ratio( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->sec_dram_density_ratio(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Secondary SDRAM die count
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode sec_sdram_die_count( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->sec_sdram_die_count(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Secondary SDRAM package type
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode sec_sdram_package_type( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->sec_sdram_package_type(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Module Nominal Voltage, VDD
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode operable_nominal_voltage( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->operable_nominal_voltage(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Module Nominal Voltage, VDD
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode endurant_nominal_voltage( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->endurant_nominal_voltage(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM device width
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode device_width( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->device_width(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes number of package ranks per DIMM
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode num_package_ranks_per_dimm( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->num_package_ranks_per_dimm(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Rank Mix
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode rank_mix( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->rank_mix(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes primary bus width
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode prim_bus_width( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->prim_bus_width(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes bus width extension
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode bus_width_extension( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->bus_width_extension(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Module Thermal Sensor
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode thermal_sensor( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->thermal_sensor(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Extended Base Module Type
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode extended_base_module_type( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->extended_base_module_type(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Fine Timebase
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_timebase( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_timebase(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode Medium Timebase
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode medium_timebase( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->medium_timebase(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ ///
+ /// @brief Decodes SDRAM Minimum Cycle Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_tck( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_tck(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Maximum Cycle Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode max_tck( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->max_tck(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decode CAS Latencies Supported
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode supported_cas_latencies( uint64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->supported_cas_latencies(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum CAS Latency Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_taa( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_taa(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum RAS to CAS Delay Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trcd( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trcd(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum Row Precharge Delay Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trp( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trp(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum Active to Precharge Delay Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_tras( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_tras(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum Active to Active/Refresh Delay Time in MTB
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trc( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trc(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 1
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trfc1( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trfc1(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 2
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trfc2( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trfc2(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum Refresh Recovery Delay Time 4
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trfc4( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trfc4(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes SDRAM Minimum Four Activate Window Delay Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_tfaw( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_tfaw(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Minimum Activate to Activate Delay Time - Different Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trrd_s( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trrd_s(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Minimum Activate to Activate Delay Time - Same Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_trrd_l( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_trrd_l(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Minimum CAS to CAS Delay Time - Same Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_tccd_l( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_tccd_l(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Minimum Write Recovery Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_twr( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_twr(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Minimum Write to Read Time - Different Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_twtr_s( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_twtr_s(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Minimum Write to Read Time - Same Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode min_twtr_l( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->min_twtr_l(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Package Rank Map
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode package_rank_map( std::vector<uint8_t>& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->package_rank_map(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Nibble Map
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode nibble_map( std::vector<uint8_t>& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->nibble_map(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_tccd_l( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_tccd_l(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Same Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_trrd_l( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trrd_l(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for Minimum Activate to Activate Delay Time - Different Bank Group
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_trrd_s( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trrd_s(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for Minimum Active to Active/Refresh Delay Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_trc( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trc(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for Minimum Row Precharge Delay Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_trp( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trp(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for SDRAM Minimum RAS to CAS Delay Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_trcd( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_trcd(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for SDRAM Minimum CAS Latency Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_taa( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_taa(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for SDRAM Maximum Cycle Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_max_tck( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_max_tck(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Fine Offset for SDRAM Minimum Cycle Time
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode fine_offset_min_tck( int64_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->fine_offset_min_tck(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Cyclical Redundancy Code (CRC) for Base Configuration Section
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode cyclical_redundancy_code( uint16_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->cyclical_redundancy_code(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes module manufacturer ID code
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode module_manufacturer_id_code( uint16_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->module_manufacturer_id_code(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Module Manufacturing Location
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode module_manufacturing_location( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->module_manufacturing_location(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodesmodule manufacturing date
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ fapi2::ReturnCode module_manufacturing_date( uint16_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->module_manufacturing_date(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes module's unique serial number
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode module_serial_number( uint32_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->module_serial_number(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Module Revision Code
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode module_revision_code( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->module_revision_code(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM Manufacturer ID code
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode dram_manufacturer_id_code( uint16_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->dram_manufacturer_id_code(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM Stepping
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode dram_stepping( uint8_t& o_value ) const
+ {
+ FAPI_TRY( iv_base_cnfg_decoder->dram_stepping(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+ ///
+ /// @brief Decodes module nominal height max
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode max_module_nominal_height(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->max_module_nominal_height(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes raw card extension
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode raw_card_extension(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->raw_card_extension(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes front module maximum thickness max
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode front_module_max_thickness(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->front_module_max_thickness(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes back module maximum thickness max
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode back_module_max_thickness(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->back_module_max_thickness(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes reference raw card used
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode reference_raw_card(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->reference_raw_card(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes number of registers used on RDIMM
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode num_registers_used(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->num_registers_used(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes number of rows of DRAMs on RDIMM
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode num_rows_of_drams(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->num_rows_of_drams(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register and buffer type for LRDIMMs
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode register_and_buffer_type(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->register_and_buffer_type(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes heat spreader thermal characteristics
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCEawSS if okay
+ ///
+ fapi2::ReturnCode heat_spreader_thermal_char(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->heat_spreader_thermal_char(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes heat spreader solution
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode heat_spreader_solution(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->heat_spreader_solution(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register manufacturer ID code
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode reg_manufacturer_id_code(uint16_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->reg_manufacturer_id_code(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register revision number
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode register_rev_num(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->register_rev_num(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes address mapping from register to dram
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->register_to_dram_addr_mapping(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for CKE signal
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->cke_signal_output_driver(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for ODT signal
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->odt_signal_output_driver(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for command/address (CA) signal
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->ca_signal_output_driver(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for control signal (CS) signal
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->cs_signal_output_driver(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for clock (B side)
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->b_side_clk_output_driver(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for clock (A side)
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->a_side_clk_output_driver(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE)
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->bcom_bcke_bodt_drive_strength(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCK)
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->bck_output_drive_strength(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes RCD output slew rate control
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode slew_rate_control(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->slew_rate_control(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes data buffer revision number
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_buffer_rev(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->data_buffer_rev(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 0
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank0(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 1
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank1(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 2
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank2(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 3
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_rank3(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes data buffer VrefDQ for DRAM interface
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->data_buffer_vref_dq(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM interface MDQ Drive Strenth
+ /// of the data buffer component for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->data_buffer_mdq_drive_strength(i_dimm_speed, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM interface MDQ read termination strength
+ /// of the data buffer component for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->data_buffer_mdq_rtt(i_dimm_speed, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM drive strenth
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_drive_strength(i_dimm_speed, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_NOM
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_rtt_nom(i_dimm_speed, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_WR
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_rtt_wr(i_dimm_speed, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_rtt_park_ranks0_1(i_dimm_speed, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_rtt_park_ranks2_3(i_dimm_speed, o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes VrefDQ range for DRAM interface range
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->dram_vref_dq_range(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes data buffer VrefDQ range for DRAM interface range
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->data_buffer_vref_dq_range(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes data buffer gain adjustment
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->data_buffer_gain_adjustment(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes data buffer Decision Feedback Equalization (DFE)
+ /// @param[out] o_value SPD encoded value
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ fapi2::ReturnCode data_buffer_dfe(uint8_t& o_value) const
+ {
+ FAPI_TRY( iv_dimm_module_decoder->data_buffer_dfe(o_value) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @brief Helper function to append SPD decoder to the end of a vector
+/// @param[in] i_target the DIMM target
+/// @param[in] i_spd_data SPD data in a vector reference
+/// @param[in,out] io_spd_decoder reference to std::vector of SPD facades
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+static fapi2::ReturnCode add_decoder_to_list( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data,
+ std::vector< facade >& io_spd_decoder )
+{
+ fapi2::ReturnCode l_rc;
+ facade l_spd_decoder(i_target, i_spd_data, l_rc);
+ FAPI_TRY(l_rc, "Failed to instantiate SPD facade for %s", spd::c_str(i_target));
+
+ io_spd_decoder.push_back(l_spd_decoder);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Creates a list of SPD decoder from target
+/// @tparam T the fapi2 target
+/// @param[in] i_target the DIMM target
+/// @param[out] o_spd_decoder reference to std::vector of SPD facades
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template < fapi2::TargetType T >
+fapi2::ReturnCode get_spd_decoder_list( const fapi2::Target<T>& i_target,
+ std::vector< facade >& o_spd_decoder )
+{
+ o_spd_decoder.clear();
+
+ for( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
+ {
+ std::vector<uint8_t> l_spd;
+ FAPI_TRY( get_raw_data(l_dimm, l_spd) );
+
+ FAPI_TRY( add_decoder_to_list(l_dimm, l_spd, o_spd_decoder) );
+ }// dimms
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Creates a list of SPD decoder of SPD data to target
+/// @tparam T the fapi2 target
+/// @param[in] i_target the DIMM target
+/// @param[in] i_spd_data SPD data
+/// @param[out] o_spd_decoder reference to std::vector of SPD facades
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template < fapi2::TargetType T >
+fapi2::ReturnCode get_spd_decoder_list( const fapi2::Target<T>& i_target,
+ const std::vector<uint8_t>& i_spd_data,
+ std::vector< facade >& o_spd_decoder )
+{
+ o_spd_decoder.clear();
+
+ for( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
+ {
+ FAPI_TRY( add_decoder_to_list(l_dimm, i_spd_data, o_spd_decoder) );
+ }// dimms
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// spd
+}// mss
+
+#endif //_MSS_SPD_FACADE_H_
diff --git a/src/import/generic/memory/lib/spd/spd_factory_pattern.C b/src/import/generic/memory/lib/spd/spd_factory_pattern.C
index bc58ff24f..dceb944fa 100644
--- a/src/import/generic/memory/lib/spd/spd_factory_pattern.C
+++ b/src/import/generic/memory/lib/spd/spd_factory_pattern.C
@@ -22,3 +22,334 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file spd_factory_pattern.C
+/// @brief SPD factory pattern implementation
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#include <generic/memory/lib/spd/spd_factory_pattern.H>
+
+namespace mss
+{
+namespace spd
+{
+
+///
+/// @brief constexpr ctor
+/// @param[in] i_dram_gen DRAM generation
+/// @param[in] i_spd_param DIMM type
+/// @param[in] i_rev SPD revision
+///
+module_key::module_key(const uint8_t i_dram_gen,
+ const parameters i_spd_param,
+ const uint8_t i_rev):
+ iv_rev(i_rev),
+ iv_dram_gen(i_dram_gen),
+ iv_param(i_spd_param)
+{}
+
+///
+/// @brief less-than operator
+/// @param[in] i_rhs the module_key
+/// @return true or false
+///
+bool module_key::operator<(const module_key& i_rhs) const
+{
+ // Impose weak strict ordering for dram_gen
+ // by dram gen, dimm type, and then revision
+ if(iv_dram_gen != i_rhs.iv_dram_gen)
+ {
+ return iv_dram_gen < i_rhs.iv_dram_gen;
+ }
+
+ // If we are here than iv_param == i_key.iv_param
+ // Impose weak strict ordering for encoding_level
+ if( iv_param != i_rhs.iv_param)
+ {
+ return iv_param < i_rhs.iv_param;
+ }
+
+ // If we are here than iv_encoding_level == i_key.iv_encoding_leve
+ // Impose weak strict ordering for additions_level
+ if( iv_rev != i_rhs.iv_rev)
+ {
+ return iv_rev < i_rhs.iv_rev;
+ }
+
+ return false;
+}
+
+///
+/// @brief ctor
+/// @param[in] i_target the DIMM target
+/// @param[in] i_key the module_key
+///
+rev_fallback::rev_fallback(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const module_key& i_key):
+ iv_target(i_target),
+ iv_key(i_key),
+ iv_encoding_level(0),
+ iv_additions_level(0),
+ LRDIMM_DDR4_V1_0{DDR4, LRDIMM_MODULE, rev::V1_0},
+ LRDIMM_DDR4_V1_1{DDR4, LRDIMM_MODULE, rev::V1_1},
+ LRDIMM_DDR4_V1_2{DDR4, LRDIMM_MODULE, rev::V1_2},
+ RDIMM_DDR4_V1_0{DDR4, RDIMM_MODULE, rev::V1_0},
+ RDIMM_DDR4_V1_1{DDR4, RDIMM_MODULE, rev::V1_1},
+ NVDIMM_DDR4_V1_0{DDR4, NVDIMM_MODULE, rev::V1_0},
+ NVDIMM_DDR4_V1_1{DDR4, NVDIMM_MODULE, rev::V1_1}
+{
+ // Member variable initialization
+ fapi2::buffer<uint8_t> l_buffer(i_key.iv_rev);
+ l_buffer.extractToRight<ENCODINGS_REV_START, LEN>(iv_encoding_level);
+ l_buffer.extractToRight<ADDITIONS_REV_START, LEN>(iv_additions_level);
+
+ // Setup pre-defined maps available to search through
+ // 3 diff mappings because each map has an independently
+ // managed revision.
+ iv_rdimm_rev_map[RDIMM_DDR4_V1_0] = rev::V1_0;
+ iv_rdimm_rev_map[RDIMM_DDR4_V1_1] = rev::V1_1;
+
+ iv_lrdimm_rev_map[LRDIMM_DDR4_V1_0] = rev::V1_0;
+ iv_lrdimm_rev_map[LRDIMM_DDR4_V1_1] = rev::V1_1;
+ iv_lrdimm_rev_map[LRDIMM_DDR4_V1_2] = rev::V1_2;
+
+ iv_nvdimm_rev_map[NVDIMM_DDR4_V1_0] = rev::V1_1;
+ iv_nvdimm_rev_map[NVDIMM_DDR4_V1_1] = rev::V1_1;
+
+ // Another small map to select the right map based on module
+ iv_spd_param_map[RDIMM_MODULE] = iv_rdimm_rev_map;
+ iv_spd_param_map[LRDIMM_MODULE] = iv_lrdimm_rev_map;
+ iv_spd_param_map[NVDIMM_MODULE] = iv_nvdimm_rev_map;
+}
+
+///
+/// @brief Retrieves highest supported SPD revision
+/// @param[out] o_rev SPD revision
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode rev_fallback::get_supported_rev(uint8_t& o_rev) const
+{
+ std::map<module_key, uint8_t> l_map;
+
+ auto it = iv_spd_param_map.find(iv_key.iv_param);
+ FAPI_ASSERT(it != iv_spd_param_map.end(),
+ fapi2::MSS_INVALID_SPD_PARAMETER_RECEIVED()
+ .set_SPD_PARAM(iv_key.iv_param)
+ .set_FUNCTION_CODE(GET_SUPPORTED_REV)
+ .set_TARGET(iv_target),
+ "Invalid SPD parameter received %d for %s",
+ iv_key.iv_param, spd::c_str(iv_target));
+
+ l_map = it->second;
+ FAPI_TRY( check_encoding_level(l_map) );
+
+ // The logic is easier to handle only additions level changes.
+ // This source will need to be updated to handle encodings level changes
+ // (rare occurance that hasn't happened yet...) and will be caught with the conditional above.
+ select_highest_rev(l_map, o_rev);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to select the largest SPD revision
+/// @param[in] i_map a map of supported SPD revisions for a certain SPD param
+/// @param[out] o_rev the SPD Revision
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+void rev_fallback::select_highest_rev( const std::map<module_key, uint8_t>& i_map,
+ uint8_t& o_rev) const
+{
+ // When encoding revisions are the same and only
+ // addition revisions differ, setting are backward
+ // compatible. This means if we hit a case where
+ // the additions level is not in our existing list of
+ // decoders we can default to the highest decoded revision.
+ // (e.g. If the DRAM is rev 1.3 but we have only decoded up
+ // to rev 1.1, we can safely default to rev 1.1 accepting
+ // that we lose features that may exist in higher revisions).
+ auto it = i_map.end();
+ o_rev = (--it)->second;
+}
+
+///
+/// @brief Helper function to check non-backward compatible encoding level changes
+/// @param[in] i_map Map of supported SPD revisions for a certain SPD param
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode rev_fallback::check_encoding_level(const std::map<module_key, uint8_t>& i_map) const
+{
+ // A change in encoding revision breaks backward compatability,
+ // (e.g. revision 2.# is not backwards compatible with revision 1.#,
+ // for some integer #).
+ auto it = --(i_map.end());
+ const uint8_t l_highest_possible_rev = it->second;
+ const fapi2::buffer<uint8_t> l_buffer(l_highest_possible_rev);
+
+ uint8_t l_last_valid_encoding_lvl = 0;
+ l_buffer.extractToRight<ENCODINGS_REV_START, LEN>(l_last_valid_encoding_lvl);
+
+ FAPI_INF("Highest valid rev 0x%02x, Highest valid encoding level %d, encoding level received %d for %s",
+ l_highest_possible_rev, l_last_valid_encoding_lvl, iv_encoding_level, spd::c_str(iv_target));
+
+ FAPI_ASSERT( iv_encoding_level <= l_last_valid_encoding_lvl,
+ fapi2::MSS_SPD_REV_ENCODING_LEVEL_NOT_SUPPORTED()
+ .set_ENCODING_LEVEL(iv_encoding_level)
+ .set_TARGET(iv_target),
+ "SPD revision encoding level (%d) is greater than largest decode (%d) for %s",
+ iv_encoding_level, l_last_valid_encoding_lvl, spd::c_str(iv_target));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief ctor
+/// @param[in] i_target the DIMM target
+/// @param[in] i_spd_data SPD data in a vector reference
+/// @param[out] o_rc FAPI2_RC_SUCCESS iff okay
+///
+factories::factories(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data,
+ fapi2::ReturnCode& o_rc):
+ iv_target(i_target),
+ iv_spd_data(i_spd_data)
+{
+ FAPI_TRY( (reader<init_fields::REVISION, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_rev)),
+ "Failed to read REVISION field for %s", spd::c_str(i_target) );
+ FAPI_TRY( (reader<init_fields::BASE_MODULE, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_dimm_type)),
+ "Failed to read BASE_MODULE field for %s", spd::c_str(i_target) );
+ FAPI_TRY( (reader<init_fields::DEVICE_TYPE, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_dram_gen)),
+ "Failed to read DEVICE_TYPE field for %s", spd::c_str(i_target) );
+ FAPI_TRY( (reader<init_fields::HYBRID, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_hybrid)),
+ "Failed to read HYBRID field for %s", spd::c_str(i_target) );
+ FAPI_TRY( (reader<init_fields::HYBRID_MEDIA, spd::rev::GEN_SEC_MAX>(i_target, i_spd_data, iv_hybrid_media)),
+ "Failed to read HYBRID_MEDIA field for %s", spd::c_str(i_target) );
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+}
+
+///
+/// @brief creates base_cnfg_decoder object
+/// @param[out] o_decoder_ptr the base_cnfg_decoder object ptr
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode factories::create_decoder( std::shared_ptr<base_cnfg_decoder>& o_decoder_ptr ) const
+{
+ parameters l_param = UNINITIALIZED;
+ FAPI_TRY(base_cfg_select_param(l_param));
+
+ {
+ auto l_factory_key = module_key(iv_dram_gen, l_param, iv_rev);
+
+ const module_factory<base_cnfg_decoder> l_decoder(iv_target, iv_spd_data);
+ FAPI_TRY( l_decoder.make_object(l_factory_key, o_decoder_ptr) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief creates dimm_module_decoder object
+/// @param[out] o_decoder_ptr the dimm_module_decoder object ptr
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode factories::create_decoder( std::shared_ptr<dimm_module_decoder>& o_decoder_ptr ) const
+{
+ parameters l_param = UNINITIALIZED;
+ FAPI_TRY(dimm_module_select_param(l_param));
+
+ {
+ auto l_factory_key = module_key(iv_dram_gen, l_param, iv_rev);
+
+ const module_factory<dimm_module_decoder> l_decoder(iv_target, iv_spd_data);
+ FAPI_TRY( l_decoder.make_object(l_factory_key, o_decoder_ptr) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper to select SPD parameter for the dimm module
+/// @param[out] o_param SPD parameter
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode factories::dimm_module_select_param(parameters& o_param) const
+{
+ switch(iv_dimm_type)
+ {
+ case RDIMM:
+ o_param = RDIMM_MODULE;
+ break;
+
+ case LRDIMM:
+ o_param = LRDIMM_MODULE;
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::MSS_INVALID_DIMM_TYPE()
+ .set_DIMM_TYPE(iv_dimm_type)
+ .set_FUNCTION(DIMM_MODULE_PARAM_SELECT)
+ .set_DIMM_TARGET(iv_target),
+ "Invalid DIMM type recieved (%d) for %s",
+ iv_dimm_type, spd::c_str(iv_target));
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper to select SPD parameter for the base cfg
+/// @param[out] o_param SPD parameter
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode factories::base_cfg_select_param(parameters& o_param) const
+{
+ if(iv_hybrid == HYBRID && iv_hybrid_media == NVDIMM_HYBRID)
+ {
+ // The general section used for NVDIMMs is different than
+ // those for LRDIMM and RDIMM modules.
+ o_param = NVDIMM_MODULE;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // If we are here let's make sure we are not hybrid, sanity
+ // check to assure we don't have invalid hybrid combination
+ FAPI_ASSERT(iv_hybrid == NOT_HYBRID &&
+ iv_hybrid_media == NOT_HYBRID,
+ fapi2::MSS_INVALID_HYBRID_MODULE().
+ set_HYBRID(iv_hybrid).
+ set_HYBRID_MEDIA(iv_hybrid_media).
+ set_FUNCTION(BASE_CFG_PARAM_SELECT).
+ set_TARGET(iv_target),
+ "Invalid hybrid (%d) or hybrid_media (%d) for %s",
+ iv_hybrid, iv_hybrid_media, spd::c_str(iv_target));
+
+ FAPI_TRY(dimm_module_select_param(o_param));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// spd
+}// mss
diff --git a/src/import/generic/memory/lib/spd/spd_factory_pattern.H b/src/import/generic/memory/lib/spd/spd_factory_pattern.H
index c0629c5c9..9d36738d4 100644
--- a/src/import/generic/memory/lib/spd/spd_factory_pattern.H
+++ b/src/import/generic/memory/lib/spd/spd_factory_pattern.H
@@ -22,3 +22,487 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file spd_factory_pattern.H
+/// @brief SPD factory pattern declaration
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_SPD_FACTORY_PATTERN_H_
+#define _MSS_SPD_FACTORY_PATTERN_H_
+
+#include <fapi2.H>
+#include <cstdint>
+#include <map>
+#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
+#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
+#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_decoder_ddr4.H>
+#include <generic/memory/lib/spd/spd_checker.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+///
+/// @class moduleFactoryTraits
+/// @brief class that holds module factory traits
+/// @tparam T the decoder type we want the factory to generate
+///
+template < typename T >
+struct moduleFactoryTraits;
+
+///
+/// @class moduleFactoryTraits - base_cnfg_decoder specialization
+/// @brief class that holds module factory traits
+///
+template< >
+struct moduleFactoryTraits<spd::base_cnfg_decoder>
+{
+ static constexpr generic_ffdc_codes MODULE_FACTORY_FFDC_CODE = BASE_CFG_FACTORY;
+};
+
+///
+/// @class moduleFactoryTraits - dimm_module_decoder specialization
+/// @brief class that holds module factory traits
+///
+template< >
+struct moduleFactoryTraits<spd::dimm_module_decoder>
+{
+ static constexpr generic_ffdc_codes MODULE_FACTORY_FFDC_CODE = DIMM_MODULE_FACTORY;
+};
+
+namespace spd
+{
+
+///
+/// @class module_key
+/// @brief SPD module key for factory
+///
+struct module_key
+{
+ uint8_t iv_rev;
+ uint8_t iv_dram_gen;
+ parameters iv_param;
+
+ ///
+ /// @brief default ctor
+ ///
+ module_key() = default;
+
+ ///
+ /// @brief constexpr ctor
+ /// @param[in] i_dram_gen DRAM generation
+ /// @param[in] i_spd_param DIMM type
+ /// @param[in] i_rev SPD revision
+ ///
+ module_key(const uint8_t i_dram_gen,
+ const parameters i_spd_param,
+ const uint8_t i_rev);
+
+ ///
+ /// @brief default dtor
+ ///
+ ~module_key() = default;
+
+ ///
+ /// @brief less-than operator
+ /// @param[in] i_rhs the module_key
+ /// @return true or false
+ ///
+ bool operator<(const module_key& i_rhs) const;
+
+};// module_key
+
+///
+/// @brief Class that performs revision fallback
+/// @class rev_fallback
+///
+class rev_fallback
+{
+ public:
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_key the module_key
+ ///
+ rev_fallback(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const module_key& i_key);
+
+ ///
+ /// @brief dtor
+ ///
+ ~rev_fallback() = default;
+
+ ///
+ /// @brief Retrieves highest supported SPD revision
+ /// @param[out] o_rev SPD revision
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode get_supported_rev(uint8_t& o_rev) const;
+
+ private:
+
+ enum
+ {
+ LEN = 4,
+ ENCODINGS_REV_START = 0,
+ ADDITIONS_REV_START = 4,
+ };
+
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ module_key iv_key;
+ uint8_t iv_encoding_level;
+ uint8_t iv_additions_level;
+
+ // Constants convenient for map indexing
+ const module_key LRDIMM_DDR4_V1_0;
+ const module_key LRDIMM_DDR4_V1_1;
+ const module_key LRDIMM_DDR4_V1_2;
+
+ const module_key RDIMM_DDR4_V1_0;
+ const module_key RDIMM_DDR4_V1_1;
+
+ const module_key NVDIMM_DDR4_V1_0;
+ const module_key NVDIMM_DDR4_V1_1;
+
+ std::map<module_key, uint8_t> iv_lrdimm_rev_map;
+ std::map<module_key, uint8_t> iv_rdimm_rev_map;
+ std::map<module_key, uint8_t> iv_nvdimm_rev_map;
+ std::map< parameters, std::map<module_key, uint8_t> > iv_spd_param_map;
+
+ ///
+ /// @brief Helper function to select the largest SPD revision
+ /// @param[in] i_map a map of supported SPD revisions for a certain SPD param
+ /// @param[out] o_rev the SPD Revision
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ void select_highest_rev( const std::map<module_key, uint8_t>& i_map,
+ uint8_t& o_rev) const;
+
+ ///
+ /// @brief Helper function to check non-backward compatible encoding level changes
+ /// @param[in] i_map Map of supported SPD revisions for a certain SPD param
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode check_encoding_level(const std::map<module_key, uint8_t>& i_map) const;
+};
+
+///
+/// @class module_factory
+/// @tparam T module decoder type (e.g. base_cnfg_decoder, dimm_module_decoder)
+/// @tparam TT defaulted to moduleFactoryTraits<T>
+/// @brief Factory method for SPD module parameters
+///
+template < typename T, typename TT = moduleFactoryTraits<T> >
+class module_factory
+{
+ public:
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ module_factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data):
+ iv_target(i_target),
+ LRDIMM_DDR4_REV_1_0{DDR4, LRDIMM_MODULE, rev::V1_0},
+ LRDIMM_DDR4_REV_1_1{DDR4, LRDIMM_MODULE, rev::V1_1},
+ LRDIMM_DDR4_REV_1_2{DDR4, LRDIMM_MODULE, rev::V1_2},
+ RDIMM_DDR4_REV_1_0{DDR4, RDIMM_MODULE, rev::V1_0},
+ RDIMM_DDR4_REV_1_1{DDR4, RDIMM_MODULE, rev::V1_1},
+ NVDIMM_DDR4_REV_1_0{DDR4, NVDIMM_MODULE, rev::V1_0},
+ NVDIMM_DDR4_REV_1_1{DDR4, NVDIMM_MODULE, rev::V1_1}
+ {
+ // Setup pre-defined maps available to search through
+ init_map_vars(i_spd_data, iv_decoder_map);
+ }
+
+ ///
+ /// @brief default dtor
+ ///
+ ~module_factory() = default;
+
+ ///
+ /// @brief creates module_decoder object from key
+ /// @param[in,out] io_key the module key
+ /// @param[out] o_decoder_ptr the dimm_module_decoder object ptr
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode make_object(module_key& io_key,
+ std::shared_ptr<T>& o_decoder_ptr) const
+ {
+ auto it = iv_decoder_map.find(io_key);
+
+ // If we found matching key, return that associated decoder
+ if(it != iv_decoder_map.end())
+ {
+ o_decoder_ptr = it->second;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // If we are here that means we didn't find a matching key-value pair.
+ // So we will dig deeper to evaluate the issue and try to fallback to
+ // a supported (backward compatible) SPD revision.
+ FAPI_TRY( try_fallback(io_key, o_decoder_ptr) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ private:
+
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+
+ // Indexing member vars for convenient map indexing
+ const module_key LRDIMM_DDR4_REV_1_0;
+ const module_key LRDIMM_DDR4_REV_1_1;
+ const module_key LRDIMM_DDR4_REV_1_2;
+ const module_key RDIMM_DDR4_REV_1_0;
+ const module_key RDIMM_DDR4_REV_1_1;
+ const module_key NVDIMM_DDR4_REV_1_0;
+ const module_key NVDIMM_DDR4_REV_1_1;
+
+ std::map< module_key, std::shared_ptr<T> > iv_decoder_map;
+
+ ///
+ /// @brief Helper function to initialize base_cnfg_decoder map
+ /// @param[out] o_map base_cnfg_decoder map
+ ///
+ void init_map_vars(const std::vector<uint8_t>& i_spd_data,
+ std::map< module_key, std::shared_ptr<base_cnfg_decoder> >& o_map)
+ {
+ //
+ // RDIMMs
+ //
+
+ // Rev 1.0
+ // Life starts out at base revision level
+ o_map[RDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_0> >(iv_target, i_spd_data);
+
+ // Rev 1.1
+ // Changes to both the general section & rdimm section occured
+ o_map[RDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data);
+
+ //
+ // LRDIMMs
+ //
+
+ // Rev 1.0
+ // Life starts out at base revision level
+ o_map[LRDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_0> >(iv_target, i_spd_data);
+
+ // Rev 1.1
+ // Changes to both the general section & lrdimm section occured
+ o_map[LRDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data);
+
+ // Rev 1.2
+ // Changes lrdimm section occured
+ // General section remained the same
+ o_map[LRDIMM_DDR4_REV_1_2] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data);
+
+ //
+ // NVDIMMs
+ //
+
+ // Rev 1.0
+ // NVDIMMs start out life w/the updated general section.
+ o_map[NVDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data);
+
+ // Rev 1.1
+ // Changes to the NVDIMM module occured, general section remains the same
+ o_map[NVDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, BASE_CNFG, rev::V1_1> >(iv_target, i_spd_data);
+ }
+
+ ///
+ /// @brief Helper function to initialize dimm_module_decoder map
+ /// @param[out] o_map dimm_module_decoder map
+ ///
+ void init_map_vars(const std::vector<uint8_t>& i_spd_data,
+ std::map< module_key, std::shared_ptr<dimm_module_decoder> >& o_map)
+ {
+ //
+ // RDIMMs
+ //
+
+ // Rev 1.0
+ // Life starts out at base revision level
+ o_map[RDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, RDIMM_MODULE, rev::V1_0> >(iv_target, i_spd_data);
+
+ // Rev 1.1
+ // Changes to both the general section & rdimm section occured
+ o_map[RDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, RDIMM_MODULE, rev::V1_1> >(iv_target, i_spd_data);
+
+ //
+ // LRDIMMs
+ //
+
+ // Rev 1.0
+ // Life starts out at base revision level
+ o_map[LRDIMM_DDR4_REV_1_0] = std::make_shared< decoder<DDR4, LRDIMM_MODULE, rev::V1_0> >(iv_target, i_spd_data);
+
+ // Rev 1.1
+ // Changes to both the general section & lrdimm section occured
+ o_map[LRDIMM_DDR4_REV_1_1] = std::make_shared< decoder<DDR4, LRDIMM_MODULE, rev::V1_1> >(iv_target, i_spd_data);
+
+ // Rev 1.2
+ // Changes lrdimm section occured
+ // General section remained the same
+ o_map[LRDIMM_DDR4_REV_1_2] = std::make_shared< decoder<DDR4, LRDIMM_MODULE, rev::V1_2> >(iv_target, i_spd_data);
+ }
+
+ ///
+ /// @brief Try to fallback to a supported backward compatible decoder
+ /// @param[in,out] io_key the module key
+ /// @param[out] o_rev SPD revision we are falling back to
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode find_backward_compatible_rev(module_key& io_key) const
+ {
+ const rev_fallback l_rev_fallback(iv_target, io_key);
+
+ // Overwrite io_key.iv_rev with a supported revision
+ FAPI_TRY(l_rev_fallback.get_supported_rev(io_key.iv_rev));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Create a decoder with the fallback module_key
+ /// @param[in] i_key the module key
+ /// @param[out] o_decoder_ptr decoder ptr
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode create_fallback_decoder(const module_key& i_key,
+ std::shared_ptr<T>& o_decoder_ptr) const
+ {
+ auto it = iv_decoder_map.find(i_key);
+
+ // Sanity check, should never fail unless it's a programming error...
+ constexpr generic_ffdc_codes FFDC_CODE = TT::MODULE_FACTORY_FFDC_CODE;
+
+ FAPI_ASSERT( it != iv_decoder_map.end(),
+ fapi2::MSS_FAILED_SPD_REVISION_FALLBACK()
+ .set_FAILED_REVISION(i_key.iv_rev)
+ .set_FUNCTION_CODE(FFDC_CODE)
+ .set_TARGET(iv_target),
+ "Failed to find a map value for the key (rev 0x%02, param %d, dram gen: %d",
+ i_key.iv_rev, i_key.iv_param, i_key.iv_dram_gen);
+
+ // Update SPD rev to fallback rev
+ {
+ constexpr size_t REV_BYTE = 1;
+ o_decoder_ptr = it->second;
+ std::vector<uint8_t> l_spd_data = o_decoder_ptr->get_data();
+ l_spd_data[REV_BYTE] = i_key.iv_rev;
+ o_decoder_ptr->set_data(l_spd_data);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Try to fallback to a supported backward compatible decoder
+ /// @param[in,out] io_key the module key
+ /// @param[out] o_decoder_ptr the o_decoder_ptr object ptr
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode try_fallback(module_key& io_key,
+ std::shared_ptr<T>& o_decoder_ptr) const
+ {
+ const uint8_t l_dimm_type = io_key.iv_param == RDIMM_MODULE ? RDIMM : LRDIMM;
+
+ // Invalid DRAM gen is a hard fail
+ FAPI_TRY(check::dram_gen(iv_target, io_key.iv_dram_gen, TT::MODULE_FACTORY_FFDC_CODE));
+
+ // Invalid DIMM type is a hard fail
+ FAPI_TRY(check::dimm_type(iv_target, l_dimm_type, TT::MODULE_FACTORY_FFDC_CODE));
+
+ // We can circumvent SPD revision fails by using backward compatible revisions
+ FAPI_TRY(find_backward_compatible_rev(io_key));
+
+ // Let's create a new decoder that we can fall back to
+ FAPI_TRY(create_fallback_decoder(io_key, o_decoder_ptr));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+///
+/// @class factories
+/// @brief Factory method that creates the right decoder based on SPD data
+///
+class factories
+{
+ public:
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target the DIMM target
+ /// @param[in] i_spd_data SPD data in a vector reference
+ /// @param[out] o_rc FAPI2_RC_SUCCESS iff okay
+ ///
+ factories(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data,
+ fapi2::ReturnCode& o_rc);
+
+ ///
+ /// @brief default dtor
+ ///
+ ~factories() = default;
+
+
+ ///
+ /// @brief creates base_cnfg_decoder object
+ /// @param[out] o_decoder_ptr the base_cnfg_decoder object ptr
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode create_decoder( std::shared_ptr<base_cnfg_decoder>& o_decoder_ptr ) const;
+
+ ///
+ /// @brief creates dimm_module_decoder object
+ /// @param[out] o_decoder_ptr the dimm_module_decoder object ptr
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode create_decoder( std::shared_ptr<dimm_module_decoder>& o_decoder_ptr ) const;
+
+ private:
+
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ std::vector<uint8_t> iv_spd_data;
+ uint8_t iv_rev;
+ uint8_t iv_dram_gen;
+ uint8_t iv_dimm_type;
+ uint8_t iv_hybrid;
+ uint8_t iv_hybrid_media;
+
+ ///
+ /// @brief Helper to select SPD parameter for the dimm module
+ /// @param[out] o_param SPD parameter
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode dimm_module_select_param(parameters& o_param) const;
+
+ ///
+ /// @brief Helper to select SPD parameter for the base cfg
+ /// @param[out] o_param SPD parameter
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode base_cfg_select_param(parameters& o_param) const;
+
+};
+
+}// spd
+}// mss
+
+#endif //_MSS_SPD_FACTORY_PATTERN_H_
diff --git a/src/import/generic/memory/lib/spd/spd_fields_ddr4.H b/src/import/generic/memory/lib/spd/spd_fields_ddr4.H
index 97413367d..15c95ff77 100644
--- a/src/import/generic/memory/lib/spd/spd_fields_ddr4.H
+++ b/src/import/generic/memory/lib/spd/spd_fields_ddr4.H
@@ -460,7 +460,6 @@ class fields<DDR4, BASE_CNFG>
static constexpr field_t OFFSET_TCK_MIN{125, OFFSET_TCK_MIN_START, OFFSET_TCK_MIN_LEN};
static constexpr field_t CRC_LSB{126, CRC_LSB_START, CRC_LSB_LEN};
static constexpr field_t CRC_MSB{127, CRC_MSB_START, CRC_MSB_LEN};
- static constexpr field_t REF_RAW_CARD{130, REF_RAW_CARD_START, REF_RAW_CARD_LEN};
static constexpr field_t CONTINUATION_CODES{320, CONTINUATION_CODES_START, CONTINUATION_CODES_LEN};
static constexpr field_t LAST_NON_ZERO_BYTE{321, LAST_NON_ZERO_BYTE_START, LAST_NON_ZERO_BYTE_LEN};
static constexpr field_t MODULE_MFG_LOCATION{322, MODULE_MFG_LOC_START, MODULE_MFG_LOC_LEN};
diff --git a/src/import/generic/memory/lib/spd/spd_reader.H b/src/import/generic/memory/lib/spd/spd_reader.H
index 90b9df1da..c67db544b 100644
--- a/src/import/generic/memory/lib/spd/spd_reader.H
+++ b/src/import/generic/memory/lib/spd/spd_reader.H
@@ -51,6 +51,94 @@ namespace spd
{
///
+/// @brief Helper function to find bit length of an integral type
+/// @tparam T integral type
+/// @return bit length for given integral type
+///
+template < typename T >
+constexpr size_t get_bit_length()
+{
+ return sizeof(T) * BITS_PER_BYTE;
+}
+
+///
+/// @brief Helper function to find bit length of an input param
+/// @tparam T input type
+/// @param[in] i_input argument we want to get bit length of
+/// @return bit length for given input
+///
+template < typename T >
+constexpr size_t get_bit_length(const T& i_input)
+{
+ return sizeof(T) * BITS_PER_BYTE;
+}
+
+///
+/// @brief Variadic helper function to find bit length of integral types
+/// @tparam T input type
+/// @tparam Types input type for a list in input params
+/// @param[in] i_first first argument we want to get bit length of
+/// @param[in] i_args list of arguments we want to get the total bit length of
+/// @return total bit length for given input
+//
+template < typename T, typename... Types >
+constexpr size_t get_bit_length (const T& i_first, const Types& ... i_args)
+{
+ // Recursive-ish pattern to add up bit length of passed in params
+ return get_bit_length(i_first) + get_bit_length(i_args...);
+}
+
+///
+/// @tparam T input type
+/// @tparam T
+/// @param[in] i_data data to insert
+/// @param[in,out] io_out buffer we wish to insert values to
+///
+template <size_t INPUT_BIT_LEN, typename T, typename OT>
+static void set_buffer_helper(const T i_data, fapi2::buffer<OT>& io_out)
+{
+ constexpr size_t l_output_bit_length = get_bit_length<OT>();
+
+ constexpr size_t l_start_bit = l_output_bit_length - INPUT_BIT_LEN;
+ constexpr size_t l_len = get_bit_length<T>();
+
+ FAPI_DBG("Total input bit length %d, output bit length %d, insert start bit %d, insert length %d, data %d",
+ INPUT_BIT_LEN, l_output_bit_length, l_start_bit, l_len, i_data);
+
+ io_out.template insertFromRight<l_start_bit, l_len >(i_data);
+}
+
+///
+/// @brief Helper function to insert entire values of any integral value into a buffer
+/// @tparam T input type
+/// @tparam OT output type of fapi2::buffer
+/// @param[in,out] io_out buffer we wish to insert values to
+/// @param[in] i_input argument we want to get bit length of
+///
+template <typename T, typename OT>
+void rightAlignedInsert(fapi2::buffer<OT>& io_out, const T& i_input)
+{
+ constexpr size_t l_input_total_args_bit_length = get_bit_length(i_input);
+ set_buffer_helper<l_input_total_args_bit_length>(i_input, io_out);
+}
+
+///
+/// @tparam T input type
+/// @tparam Types input type for a list in input params
+/// @param[in,out] io_out buffer we wish to insert values to
+/// @param[in] i_first first argument we want to get bit length of
+/// @param[in] i_args list of arguments we want to get the total bit length of
+///
+template <typename T, typename OT, typename... Types>
+void rightAlignedInsert(fapi2::buffer<OT>& io_out, const T& first, const Types& ... args)
+{
+ constexpr size_t l_input_total_args_bit_length = get_bit_length(first, args...);
+ set_buffer_helper<l_input_total_args_bit_length>(first, io_out);
+
+ rightAlignedInsert(io_out, args...);
+}
+
+///
/// @brief Helper function to extract byte information
/// @tparam F the SPD field to extract
/// @param[in] i_target the dimm target
@@ -85,6 +173,8 @@ fapi2::ReturnCode extract_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_
o_value);
}
+ return fapi2::FAPI2_RC_SUCCESS;
+
fapi_try_exit:
return fapi2::current_err;
}
@@ -107,18 +197,20 @@ fapi2::ReturnCode reader( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target
OT& o_value)
{
T l_temp = 0;
- FAPI_TRY(extract_field<F>(i_target, i_spd_data, l_temp));
+ FAPI_TRY( extract_field<F>(i_target, i_spd_data, l_temp),
+ "Failed extract_field() for %s", spd::c_str(i_target) );
FAPI_DBG("extracted %s value: 0x%02x for %s",
TT::FIELD_STR, l_temp, spd::c_str(i_target));
// Test if retrieved data seems valid
- FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target,
- conditional( l_temp,
- TT::COMPARISON_VAL,
- typename TT::template COMPARISON_OP<T>() ),
- F.get_byte(),
- l_temp) );
+ FAPI_TRY( check::fail_for_invalid_value(i_target,
+ conditional( l_temp,
+ TT::COMPARISON_VAL,
+ typename TT::template COMPARISON_OP<T>() ),
+ F.get_byte(),
+ l_temp),
+ "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );
// Output should only change if data check passes
o_value = static_cast<OT>(l_temp);
diff --git a/src/import/generic/memory/lib/spd/spd_traits.H b/src/import/generic/memory/lib/spd/spd_traits.H
index 9eb546302..b05f2c447 100644
--- a/src/import/generic/memory/lib/spd/spd_traits.H
+++ b/src/import/generic/memory/lib/spd/spd_traits.H
@@ -67,9 +67,8 @@ bool conditional(const T i_spd_field,
/// @brief trait structure to hold static SPD information
/// @tparam F holds SPD field info
/// @tparam R the revision of the SPD field
-/// @tparam B boolean required to activate trait class - defaulted to true_type
///
-template< const field_t& F, rev R, typename B = std::true_type >
+template< const field_t& F, rev R >
class readerTraits;
///
diff --git a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H
index 5d2323bba..e9bda39ea 100644
--- a/src/import/generic/memory/lib/spd/spd_traits_ddr4.H
+++ b/src/import/generic/memory/lib/spd/spd_traits_ddr4.H
@@ -46,19 +46,15 @@ namespace mss
namespace spd
{
-// Note: The 3rd template parameter is a compile-time conditional
-// to activate trait class based on a valid SPD revision.
-
///
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note BYTES_USED field partial specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template<rev R>
-class readerTraits < fields<DDR4, BASE_CNFG>::BYTES_USED, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::BYTES_USED, R>
{
public:
@@ -74,11 +70,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BYTES_USED, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TOTAL_BYTES field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template<rev R>
-class readerTraits < fields<DDR4, BASE_CNFG>::TOTAL_BYTES, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TOTAL_BYTES, R >
{
public:
@@ -94,11 +89,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TOTAL_BYTES, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note REVISION field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::REVISION, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::REVISION, R >
{
public:
@@ -136,8 +130,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, R >
{
public:
@@ -153,11 +146,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::DEVICE_TYPE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note BASE_MODULE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::BASE_MODULE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::BASE_MODULE, R >
{
public:
@@ -193,8 +185,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID, rev::V1_0 >
/// @note valid for rev >= 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID, R >
{
public:
@@ -227,11 +218,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, rev::V1_0 >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note HYBRID_MEDIA field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, R >
{
public:
@@ -247,11 +237,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::HYBRID_MEDIA, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note BANK_GROUP_BITS field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::BANK_GROUP_BITS, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::BANK_GROUP_BITS, R >
{
public:
@@ -270,8 +259,7 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BANK_GROUP_BITS, R,
/// @note rev 1.0 specialization
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::BANKS_ADDR_BITS, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::BANKS_ADDR_BITS, R >
{
public:
@@ -304,11 +292,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, rev::V1_0 >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note SDRAM_CAPACITY, field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, R >
{
public:
@@ -324,11 +311,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SDRAM_CAPACITY, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note COL_ADDR_BITS field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::COL_ADDR_BITS, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::COL_ADDR_BITS, R >
{
public:
@@ -344,11 +330,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::COL_ADDR_BITS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note ROW_ADDR_BITS field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::ROW_ADDR_BITS, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::ROW_ADDR_BITS, R >
{
public:
@@ -364,11 +349,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::ROW_ADDR_BITS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note PRIM_SIGNAL_LOADING field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_SIGNAL_LOADING, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_SIGNAL_LOADING, R >
{
public:
@@ -384,11 +368,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_SIGNAL_LOADING, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note PRIM_DIE_COUNT field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_DIE_COUNT, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_DIE_COUNT, R >
{
public:
@@ -404,11 +387,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::PRIM_DIE_COUNT, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note PRIM_PACKAGE_TYPE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::PRIM_PACKAGE_TYPE, R,
- std::integral_constant<bool, (R >= rev::V1_0)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::PRIM_PACKAGE_TYPE, R >
{
public:
@@ -424,11 +406,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::PRIM_PACKAGE_TYPE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MAC field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MAC, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MAC, R >
{
public:
@@ -447,8 +428,7 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MAC, R,
/// @note rev 1.0 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::TMAW, R,
- std::integral_constant<bool, (R >= rev::V1_0)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::TMAW, R >
{
public:
@@ -464,11 +444,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::TMAW, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note PPR field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::PPR, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::PPR, R >
{
public:
@@ -483,32 +462,15 @@ class readerTraits < fields<DDR4, BASE_CNFG>::PPR, R,
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note SOFT_PPR field specialization
-/// @note rev 1.0 specialization
-///
-template<>
-class readerTraits< fields<DDR4, BASE_CNFG>::SOFT_PPR, rev::V1_0 >
-{
- public:
-
- static constexpr size_t COMPARISON_VAL = 0;
- static constexpr const char* FIELD_STR = "Soft post package repair (SPPR)";
-
- template <typename T>
- using COMPARISON_OP = std::equal_to<T>;
-};
-
-///
-/// @class readerTraits
-/// @brief trait structure to hold static SPD information
-/// @note SOFT_PPR field specialization
-/// @note valid for rev >= 1.1
+/// @note valid for revs
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::SOFT_PPR, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::SOFT_PPR, R >
{
public:
+ // Some existing HW has a soft PPR value of 0b01 despite being rev 1.0
+ // So we'll allow even thought it doesn't match the SPD spec....
static constexpr size_t COMPARISON_VAL = 0b01;
static constexpr const char* FIELD_STR = "Soft post package repair (SPPR)";
@@ -541,8 +503,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_SIGNAL_LOADING, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::SEC_SIGNAL_LOADING, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::SEC_SIGNAL_LOADING, R >
{
public:
@@ -578,8 +539,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DENSITY_RATIO, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DENSITY_RATIO, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DENSITY_RATIO, R >
{
public:
@@ -615,8 +575,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DIE_COUNT, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DIE_COUNT, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::SEC_DIE_COUNT, R >
{
public:
@@ -652,8 +611,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, R >
{
public:
@@ -669,11 +627,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::SEC_PACKAGE_TYPE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OPERABLE_FLD field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OPERABLE_FLD, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OPERABLE_FLD, R >
{
public:
@@ -689,11 +646,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OPERABLE_FLD, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note ENDURANT_FLD field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::ENDURANT_FLD, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::ENDURANT_FLD, R >
{
public:
@@ -709,11 +665,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::ENDURANT_FLD, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note SDRAM_WIDTH field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::SDRAM_WIDTH, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::SDRAM_WIDTH, R >
{
public:
@@ -749,8 +704,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::PACKAGE_RANKS, rev::V1_0 >
/// @note valid for rev >= 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::PACKAGE_RANKS, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::PACKAGE_RANKS, R >
{
public:
@@ -786,8 +740,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, rev::V1_0 >
/// @note rev 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, R >
{
public:
@@ -803,11 +756,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::RANK_MIX, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note BUS_WIDTH field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::BUS_WIDTH, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::BUS_WIDTH, R >
{
public:
@@ -823,11 +775,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BUS_WIDTH, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note BUS_EXT_WIDTH field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::BUS_EXT_WIDTH, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::BUS_EXT_WIDTH, R >
{
public:
@@ -843,11 +794,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::BUS_EXT_WIDTH, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note THERM_SENSOR field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::THERM_SENSOR, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::THERM_SENSOR, R >
{
public:
@@ -863,11 +813,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::THERM_SENSOR, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note EXTENDED_MODULE_TYPE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::EXTENDED_MODULE_TYPE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::EXTENDED_MODULE_TYPE, R >
{
public:
@@ -883,11 +832,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::EXTENDED_MODULE_TYPE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MED_TIMEBASE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MEDIUM_TIMEBASE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MEDIUM_TIMEBASE, R >
{
public:
@@ -903,11 +851,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MEDIUM_TIMEBASE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note FINE_TIMEBASE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::FINE_TIMEBASE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::FINE_TIMEBASE, R >
{
public:
@@ -923,11 +870,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::FINE_TIMEBASE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TCK_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MIN, R >
{
public:
@@ -943,11 +889,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TCK_MAX field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MAX, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MAX, R >
{
public:
@@ -963,11 +908,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TCK_MAX, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CL_FIRST_BYTE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::CL_FIRST_BYTE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::CL_FIRST_BYTE, R >
{
public:
@@ -984,11 +928,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CL_FIRST_BYTE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CL_SECOND_BYTE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::CL_SECOND_BYTE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::CL_SECOND_BYTE, R >
{
public:
@@ -1024,8 +967,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::CL_THIRD_BYTE, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::CL_THIRD_BYTE, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::CL_THIRD_BYTE, R >
{
public:
@@ -1061,8 +1003,7 @@ class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, R >
{
public:
@@ -1078,11 +1019,10 @@ class readerTraits< fields<DDR4, BASE_CNFG>::CL_FOURTH_BYTE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TAA_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TAA_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TAA_MIN, R >
{
public:
@@ -1098,11 +1038,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TAA_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRCD_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRCD_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRCD_MIN, R >
{
public:
@@ -1118,11 +1057,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRCD_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRP_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRP_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRP_MIN, R >
{
public:
@@ -1138,11 +1076,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRP_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRASMIN_MSN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_MSN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_MSN, R >
{
public:
@@ -1158,11 +1095,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_MSN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRASMIN_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_LSB, R >
{
public:
@@ -1178,11 +1114,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRASMIN_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRCMIN_MSN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_MSN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_MSN, R >
{
public:
@@ -1197,11 +1132,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_MSN, R,
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_LSB, R >
{
public:
@@ -1217,11 +1151,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRCMIN_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRFC1MIN_MSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_MSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_MSB, R >
{
public:
@@ -1237,11 +1170,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_MSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRFC1MIN_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_LSB, R >
{
public:
@@ -1257,11 +1189,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC1MIN_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRFC2MIN_MSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_MSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_MSB, R >
{
public:
@@ -1277,11 +1208,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_MSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRFC2MIN_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_LSB, R >
{
public:
@@ -1297,11 +1227,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC2MIN_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRFC4MIN_MSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_MSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_MSB, R >
{
public:
@@ -1318,11 +1247,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_MSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRFC4MIN_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_LSB, R >
{
public:
@@ -1338,11 +1266,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRFC4MIN_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TFAWMIN_MSN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_MSN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_MSN, R >
{
public:
@@ -1358,11 +1285,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_MSN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TFAWMIN_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_LSB, R >
{
public:
@@ -1378,11 +1304,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TFAWMIN_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRRD_S_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_S_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_S_MIN, R >
{
public:
@@ -1398,11 +1323,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_S_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TRRD_L_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_L_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_L_MIN, R >
{
public:
@@ -1418,11 +1342,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TRRD_L_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TCCD_L_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TCCD_L_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TCCD_L_MIN, R >
{
public:
@@ -1439,11 +1362,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TCCD_L_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TWRMIN_MSN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_MSN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_MSN, R >
{
public:
@@ -1459,11 +1381,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_MSN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TWRMIN_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_LSB, R >
{
public:
@@ -1480,11 +1401,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWRMIN_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TWTRMIN_S_MSN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_MSN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_MSN, R >
{
public:
@@ -1500,11 +1420,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_MSN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TWTRMIN_S_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_LSB, R >
{
public:
@@ -1520,11 +1439,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_S_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TWTRMIN_L_MSN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_MSN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_MSN, R >
{
public:
@@ -1541,11 +1459,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_MSN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note TWTRMIN_L_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_LSB, R >
{
public:
@@ -1562,11 +1479,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::TWTRMIN_L_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TCCD_L_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCCD_L_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCCD_L_MIN, R >
{
public:
@@ -1584,11 +1500,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCCD_L_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TRRD_L_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_L_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_L_MIN, R >
{
public:
@@ -1605,11 +1520,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_L_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TRRD_S_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_S_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_S_MIN, R >
{
public:
@@ -1626,11 +1540,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRRD_S_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TRC_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRC_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRC_MIN, R >
{
public:
@@ -1646,11 +1559,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRC_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TRP_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRP_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRP_MIN, R >
{
public:
@@ -1667,11 +1579,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRP_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TAA_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TAA_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TAA_MIN, R >
{
public:
@@ -1687,11 +1598,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TAA_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TRCD_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRCD_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRCD_MIN, R >
{
public:
@@ -1707,11 +1617,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TRCD_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TCK_MIN field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MIN, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MIN, R >
{
public:
@@ -1727,11 +1636,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MIN, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note OFFSET_TCK_MAX field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MAX, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MAX, R >
{
public:
@@ -1747,11 +1655,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::OFFSET_TCK_MAX, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CRC_MSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::CRC_MSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::CRC_MSB, R >
{
public:
@@ -1767,11 +1674,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CRC_MSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CRC_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::CRC_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::CRC_LSB, R >
{
public:
@@ -1787,11 +1693,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CRC_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CONTINUATION_CODES field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::CONTINUATION_CODES, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::CONTINUATION_CODES, R >
{
public:
@@ -1807,11 +1712,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::CONTINUATION_CODES, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note LAST_NON_ZERO_BYTE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::LAST_NON_ZERO_BYTE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::LAST_NON_ZERO_BYTE, R >
{
public:
@@ -1827,11 +1731,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::LAST_NON_ZERO_BYTE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_MFG_LOCATION field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_LOCATION, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_LOCATION, R >
{
public:
@@ -1847,11 +1750,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_LOCATION, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_MFG_DATE_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_LSB, R >
{
public:
@@ -1867,11 +1769,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_MFG_DATE_MSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_MSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_MSB, R >
{
public:
@@ -1887,11 +1788,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_MFG_DATE_MSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_SERIAL_NUM_BYTE1 field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE1, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE1, R >
{
public:
@@ -1907,11 +1807,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE1, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_SERIAL_NUM_BYTE2 field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE2, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE2, R >
{
public:
@@ -1927,11 +1826,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE2, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_SERIAL_NUM_BYTE3 field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE3, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE3, R >
{
public:
@@ -1947,11 +1845,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE3, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_SERIAL_NUM_BYTE4 field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE4, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE4, R >
{
public:
@@ -1967,11 +1864,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_SERIAL_NUM_BYTE4, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_REV_CODE field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_REV_CODE, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_REV_CODE, R >
{
public:
@@ -1987,11 +1883,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::MODULE_REV_CODE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_MFR_ID_CODE_LSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_LSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_LSB, R >
{
public:
@@ -2007,11 +1902,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_LSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_MFR_ID_CODE_MSB field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_MSB, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_MSB, R >
{
public:
@@ -2027,11 +1921,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_MFR_ID_CODE_MSB, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_STEPPING field specialization
-/// @note valid for revisions up to rev::GEN_SEC_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_STEPPING, R,
- std::integral_constant<bool, (R <= rev::GEN_SEC_MAX)> >
+class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_STEPPING, R >
{
public:
@@ -2047,11 +1940,10 @@ class readerTraits < fields<DDR4, BASE_CNFG>::DRAM_STEPPING, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_NOMINAL_HEIGHT field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R >
{
public:
@@ -2068,11 +1960,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note FRONT_MODULE_THICKNESS field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::FRONT_MODULE_THICKNESS, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::FRONT_MODULE_THICKNESS, R >
{
public:
@@ -2089,11 +1980,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::FRONT_MODULE_THICKNESS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note BACK_MODULE_THICKNESS field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::BACK_MODULE_THICKNESS, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::BACK_MODULE_THICKNESS, R >
{
public:
@@ -2109,11 +1999,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::BACK_MODULE_THICKNESS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note REF_RAW_CARD field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::REF_RAW_CARD, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::REF_RAW_CARD, R >
{
public:
@@ -2129,11 +2018,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::REF_RAW_CARD, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note NUM_REGS_USED field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::NUM_REGS_USED, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::NUM_REGS_USED, R >
{
public:
@@ -2149,11 +2037,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::NUM_REGS_USED, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note ROWS_OF_DRAMS field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::ROWS_OF_DRAMS, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::ROWS_OF_DRAMS, R >
{
public:
@@ -2169,11 +2056,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::ROWS_OF_DRAMS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note REGISTER_TYPE field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_TYPE, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_TYPE, R >
{
public:
@@ -2189,11 +2075,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_TYPE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note HEAT_SPREADER_CHAR field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_CHAR, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_CHAR, R >
{
public:
@@ -2209,11 +2094,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_CHAR, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note HEAT_SPREADER_SOL field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_SOL, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_SOL, R >
{
public:
@@ -2229,11 +2113,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::HEAT_SPREADER_SOL, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CONTINUATION_CODES field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::CONTINUATION_CODES, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::CONTINUATION_CODES, R >
{
public:
@@ -2249,11 +2132,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::CONTINUATION_CODES, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note LAST_NON_ZERO_BYTE field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::LAST_NON_ZERO_BYTE, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::LAST_NON_ZERO_BYTE, R >
{
public:
@@ -2269,11 +2151,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::LAST_NON_ZERO_BYTE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note REGISTER_REV field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_REV, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_REV, R >
{
public:
@@ -2289,12 +2170,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::REGISTER_REV, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note ADDR_MAP_REG_TO_DRAM field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R,
-
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R >
{
public:
@@ -2309,7 +2188,7 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R,
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note CKE_DRIVER field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template<>
class readerTraits< fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, rev::V1_0 >
@@ -2327,11 +2206,10 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, rev::V1_0 >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note CKE_DRIVER field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, R >
{
public:
@@ -2346,7 +2224,7 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::CKE_DRIVER, R,
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note ODT_DRIVER field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template<>
class readerTraits< fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, rev::V1_0 >
@@ -2364,11 +2242,10 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, rev::V1_0 >
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note ODT_DRIVER field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, R >
{
public:
@@ -2384,11 +2261,10 @@ class readerTraits < fields<DDR4, RDIMM_MODULE>::ODT_DRIVER, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CA_DRIVER field specialization
-/// @note valid for revisions up to rev::RDIMM_MAX (largest decoded rev)
+/// @note valid for all revisionsRDIMM_MAX (largest decoded rev)
///
template< rev R >
-class readerTraits < fields<DDR4, RDIMM_MODULE>::CA_DRIVER, R,
- std::integral_constant<bool, (R <= rev::RDIMM_MAX)> >
+class readerTraits < fields<DDR4, RDIMM_MODULE>::CA_DRIVER, R >
{
public:
@@ -2424,8 +2300,7 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::CS_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, RDIMM_MODULE>::CS_DRIVER, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, RDIMM_MODULE>::CS_DRIVER, R >
{
public:
@@ -2461,8 +2336,7 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::YO_Y2_DRIVER, rev::V1_0 >
/// @note rev 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, RDIMM_MODULE>::YO_Y2_DRIVER, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, RDIMM_MODULE>::YO_Y2_DRIVER, R >
{
public:
@@ -2498,8 +2372,7 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, R >
{
public:
@@ -2515,11 +2388,10 @@ class readerTraits< fields<DDR4, RDIMM_MODULE>::Y1_Y3_DRIVER, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note MODULE_NOMINAL_HEIGHT field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R >
{
public:
@@ -2535,11 +2407,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::MODULE_NOMINAL_HEIGHT, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note RAW_CARD_EXT field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::RAW_CARD_EXT, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::RAW_CARD_EXT, R >
{
public:
@@ -2555,11 +2426,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::RAW_CARD_EXT, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note FRONT_MODULE_THICKNESS field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::FRONT_MODULE_THICKNESS, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::FRONT_MODULE_THICKNESS, R >
{
public:
@@ -2575,11 +2445,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::FRONT_MODULE_THICKNESS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note BACK_MODULE_THICKNESS field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::BACK_MODULE_THICKNESS, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::BACK_MODULE_THICKNESS, R >
{
public:
@@ -2595,11 +2464,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::BACK_MODULE_THICKNESS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note REF_RAW_CARD field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::REF_RAW_CARD, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::REF_RAW_CARD, R >
{
public:
@@ -2615,11 +2483,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::REF_RAW_CARD, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note NUM_REGS_USED field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::NUM_REGS_USED, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::NUM_REGS_USED, R >
{
public:
@@ -2635,11 +2502,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::NUM_REGS_USED, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note ROWS_OF_DRAMS field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::ROWS_OF_DRAMS, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::ROWS_OF_DRAMS, R >
{
public:
@@ -2655,11 +2521,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::ROWS_OF_DRAMS, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note REGISTER_TYPE field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_TYPE, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_TYPE, R >
{
public:
@@ -2675,11 +2540,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_TYPE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note HEAT_SPREADER_SOL field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::HEAT_SPREADER_SOL, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::HEAT_SPREADER_SOL, R >
{
public:
@@ -2695,11 +2559,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::HEAT_SPREADER_SOL, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CONTINUATION_CODES field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::CONTINUATION_CODES, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::CONTINUATION_CODES, R >
{
public:
@@ -2715,11 +2578,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::CONTINUATION_CODES, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note LAST_NON_ZERO_BYTE field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::LAST_NON_ZERO_BYTE, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::LAST_NON_ZERO_BYTE, R >
{
public:
@@ -2735,11 +2597,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::LAST_NON_ZERO_BYTE, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note REGISTER_REV field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_REV, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_REV, R >
{
public:
@@ -2755,11 +2616,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::REGISTER_REV, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note ADDR_MAP_REG_TO_DRAM field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::ADDR_MAP_REG_TO_DRAM, R >
{
public:
@@ -2796,8 +2656,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::CKE_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::CKE_DRIVER, R,
- std::integral_constant<bool, R >= rev::V1_1 > >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::CKE_DRIVER, R >
{
public:
@@ -2833,8 +2692,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, R,
- std::integral_constant<bool, R >= rev::V1_1 > >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, R >
{
public:
@@ -2850,11 +2708,10 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::ODT_DRIVER, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note CA_DRIVER field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::CA_DRIVER, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::CA_DRIVER, R >
{
public:
@@ -2890,8 +2747,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::CS_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::CS_DRIVER, R,
- std::integral_constant<bool, R >= rev::V1_1 > >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::CS_DRIVER, R >
{
public:
@@ -2928,8 +2784,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::YO_Y2_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::YO_Y2_DRIVER, R,
- std::integral_constant<bool, R >= rev::V1_1> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::YO_Y2_DRIVER, R >
{
public:
@@ -2965,8 +2820,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::Y1_Y3_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::Y1_Y3_DRIVER, R,
- std::integral_constant<bool, R >= rev::V1_1> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::Y1_Y3_DRIVER, R >
{
public:
@@ -3002,8 +2856,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCOM_BODT_BCKE_DRIVER, rev::V1_
/// @note valid for rev >= 1.1 specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCOM_BODT_BCKE_DRIVER, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCOM_BODT_BCKE_DRIVER, R >
{
public:
@@ -3039,8 +2892,7 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, rev::V1_0 >
/// @note valid for rev >= 1.1
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, R,
- std::integral_constant<bool, (R >= rev::V1_1)> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, R >
{
public:
@@ -3055,11 +2907,28 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::BCK_DRIVER, R,
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note RCD_SLEW_CNTRL field specialization
-/// @note rev 1.0 & 1.1 specialization
+/// @note rev 1.0 specialization
///
-template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R,
- std::integral_constant<bool, (R <= rev::V1_1)> >
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, rev::V1_0 >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0;
+ static constexpr const char* FIELD_STR = "RCD output slew rate control";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @note RCD_SLEW_CNTRL field specialization
+/// @note rev 1.1 specialization
+///
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, rev::V1_1 >
{
public:
@@ -3077,8 +2946,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R,
/// @note valid for rev >= 1.2
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R,
- std::integral_constant<bool, (R >= rev::V1_2)> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R >
{
public:
@@ -3094,11 +2962,10 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::RCD_SLEW_CNTRL, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DATA_BUFFER_REV field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_REV, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_REV, R >
{
public:
@@ -3106,18 +2973,17 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_REV, R,
static constexpr const char* FIELD_STR = "Data buffer revision";
template <typename T>
- using COMPARISON_OP = std::less_equal<T>;
+ using COMPARISON_OP = std::less<T>;
};
///
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note VREF_DQ_RANK0 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK0, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK0, R >
{
public:
@@ -3133,11 +2999,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK0, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note VREF_DQ_RANK1 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK1, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK1, R >
{
public:
@@ -3153,11 +3018,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK1, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note VREF_DQ_RANK2 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK2, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK2, R >
{
public:
@@ -3173,11 +3037,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK2, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note VREF_DQ_RANK3 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK3, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK3, R >
{
public:
@@ -3194,12 +3057,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::VREF_DQ_RANK3, R,
/// @tparam R the revision of the SPD field
/// @note DATA_BUFFER_VREF_DQ field specialization
/// @note rev 1.0 specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ, R,
-
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ, R >
{
public:
@@ -3215,11 +3076,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DB_MDQ_LTE_1866 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_1866, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_1866, R >
{
public:
@@ -3235,11 +3095,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_1866, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DB_MDQ_LTE_2400 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_2400, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_2400, R >
{
public:
@@ -3255,11 +3114,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_2400, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DB_MDQ_LTE_3200 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_3200, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_3200, R >
{
public:
@@ -3275,11 +3133,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_LTE_3200, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DB_MDQ_RTT_LTE_1866 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_1866, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_1866, R >
{
public:
@@ -3295,11 +3152,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_1866, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DB_MDQ_RTT_LTE_2400 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_2400, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_2400, R >
{
public:
@@ -3315,11 +3171,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_2400, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DB_MDQ_RTT_LTE_3200 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_3200, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_3200, R >
{
public:
@@ -3335,11 +3190,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DB_MDQ_RTT_LTE_3200, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_DRIVE_STRENGTH_LTE_1866 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_1866, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_1866, R >
{
public:
@@ -3355,11 +3209,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_1866,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_DRIVE_STRENGTH_LTE_2400 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_2400, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_2400, R >
{
public:
@@ -3375,11 +3228,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_2400,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_DRIVE_STRENGTH_LTE_3200 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_3200, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_3200, R >
{
public:
@@ -3395,11 +3247,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_DRIVE_STRENGTH_LTE_3200,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_NOM_LTE_1866 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_1866, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_1866, R >
{
public:
@@ -3415,11 +3266,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_1866, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_NOM_LTE_2400 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_2400, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_2400, R >
{
public:
@@ -3435,11 +3285,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_2400, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_NOM_LTE_3200 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_3200, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_3200, R >
{
public:
@@ -3455,11 +3304,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_NOM_LTE_3200, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_WR_LTE_1866 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_1866, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_1866, R >
{
public:
@@ -3475,11 +3323,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_1866, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_WR_LTE_2400 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_2400, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_2400, R >
{
public:
@@ -3495,11 +3342,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_2400, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_WR_LTE_3200 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_3200, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_3200, R >
{
public:
@@ -3515,11 +3361,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_WR_LTE_3200, R,
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_PARK_R01_LTE_1866 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_1866, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_1866, R >
{
public:
@@ -3535,11 +3380,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_1866
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_PARK_R01_LTE_2400 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_2400, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_2400, R >
{
public:
@@ -3555,11 +3399,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_2400
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_PARK_R01_LTE_3200 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_3200, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_3200, R >
{
public:
@@ -3575,11 +3418,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R01_LTE_3200
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_PARK_R23_LTE_1866 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_1866, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_1866, R >
{
public:
@@ -3595,11 +3437,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_1866
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_PARK_R23_LTE_2400 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_2400, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_2400, R >
{
public:
@@ -3615,11 +3456,10 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_2400
/// @brief trait structure to hold static SPD information
/// @tparam R the revision of the SPD field
/// @note DRAM_ODT_RTT_PARK_R23_LTE_3200 field specialization
-/// @note valid for revisions up to rev::LRDIMM_MAX (largest decoded rev)
+/// @note valid for all revisions
///
template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_3200, R,
- std::integral_constant<bool, (R <= rev::LRDIMM_MAX)> >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_3200, R >
{
public:
@@ -3634,11 +3474,28 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_ODT_RTT_PARK_R23_LTE_3200
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note DRAM_VREF_DQ_RANGE field specialization
-/// @note rev 1.0 & 1.1 specialization
+/// @note rev 1.0 specialization
///
-template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R,
- std::integral_constant<bool, (R <= rev::V1_1)> >
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, rev::V1_0 >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0b1111;
+ static constexpr const char* FIELD_STR = "VrefDQ range for DRAM interface range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @note DRAM_VREF_DQ_RANGE field specialization
+/// @note rev 1.1 specialization
+///
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, rev::V1_1 >
{
public:
@@ -3656,8 +3513,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R,
/// @note rev 1.2+ specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R,
- std::integral_constant<bool, (R >= rev::V1_2)> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R >
{
public:
@@ -3672,11 +3528,28 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::DRAM_VREF_DQ_RANGE, R,
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note DATA_BUFFER_VREF_DQ field specialization
-/// @note rev 1.0 & 1.1 specialization
+/// @note rev 1.0 specialization
///
-template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R,
- std::integral_constant<bool, (R <= rev::V1_1)> >
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, rev::V1_0 >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0;
+ static constexpr const char* FIELD_STR = "Data Buffer VrefDQ range for DRAM interface range";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @note DATA_BUFFER_VREF_DQ field specialization
+/// @note rev 1.1 specialization
+///
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, rev::V1_1 >
{
public:
@@ -3694,8 +3567,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R,
/// @note rev 1.2+ specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R,
- std::integral_constant<bool, (R >= rev::V1_2)> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R >
{
public:
@@ -3712,9 +3584,26 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_VREF_DQ_RANGE, R,
/// @note DATA_BUFFER_DFE field specialization
/// @note rev 1.0 & 1.1 specialization
///
-template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R,
- std::integral_constant<bool, (R <= rev::V1_1)> >
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, rev::V1_0 >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0;
+ static constexpr const char* FIELD_STR = "Data Buffer DFE";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @note DATA_BUFFER_DFE field specialization
+/// @note rev 1.1 specialization
+///
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, rev::V1_1 >
{
public:
@@ -3732,8 +3621,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R,
/// @note rev 1.2+ specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R,
- std::integral_constant<bool, (R >= rev::V1_2)> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R >
{
public:
@@ -3748,11 +3636,28 @@ class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_DFE, R,
/// @class readerTraits
/// @brief trait structure to hold static SPD information
/// @note DATA_BUFFER_GAIN_ADJUST field specialization
-/// @note rev 1.0 & 1.1 specialization
+/// @note rev 1.0 specialization
///
-template< rev R >
-class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R,
- std::integral_constant<bool, (R <= rev::V1_1)> >
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, rev::V1_0 >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 1;
+ static constexpr const char* FIELD_STR = "Data Buffer Gain Adjust";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @note DATA_BUFFER_GAIN_ADJUST field specialization
+/// @note rev 1.1 specialization
+///
+template< >
+class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, rev::V1_1 >
{
public:
@@ -3770,8 +3675,7 @@ class readerTraits < fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R,
/// @note rev 1.2+ specialization
///
template< rev R >
-class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R,
- std::integral_constant<bool, (R >= rev::V1_2)> >
+class readerTraits< fields<DDR4, LRDIMM_MODULE>::DATA_BUFFER_GAIN_ADJUST, R >
{
public:
diff --git a/src/import/generic/memory/lib/spd/spd_utils.C b/src/import/generic/memory/lib/spd/spd_utils.C
index 3a977ccf6..bfe380dc5 100644
--- a/src/import/generic/memory/lib/spd/spd_utils.C
+++ b/src/import/generic/memory/lib/spd/spd_utils.C
@@ -22,3 +22,204 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file spd_utls.C
+/// @brief SPD utility function implimentations
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+
+#include <generic/memory/lib/spd/spd_utils.H>
+#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+namespace spd
+{
+
+///
+/// @brief Helper function to retrieves medium and fine timebase values
+/// @param[in] i_spd_decoder the SPD decoder
+/// @param[out] o_mtb the medium timebase (MTB) from SPD
+/// @param[out] o_ftb the fine timebase (FTB) from SPD
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode get_timebases( const mss::spd::facade& i_spd_decoder,
+ int64_t& o_mtb,
+ int64_t& o_ftb )
+{
+ // =========================================================
+ // Byte 17 maps
+ // Item JC-45-2220.01x
+ // Page 29
+ // DDR4 SPD Document Release 3
+ // Byte 17 (0x011): Timebases
+ // =========================================================
+ // Created a maps of a single value in case mapping expands to more values
+ static const std::vector<std::pair<int64_t, int64_t> > FINE_TIMEBASE_MAP =
+ {
+ // {key byte, fine timebase (in picoseconds)
+ {0, 1}
+ // All others reserved
+ };
+
+ // =========================================================
+ // Byte 17 maps
+ // Item JC-45-2220.01x
+ // Page 29
+ // DDR4 SPD Document Release 3
+ // Byte 17 (0x011): Timebases
+ // =========================================================
+ // Created a maps of a single value in case mapping expands to more values
+ static const std::vector<std::pair<int64_t, int64_t> > MEDIUM_TIMEBASE_MAP =
+ {
+ // {key byte, medium timebase (in picoseconds)
+ {0, 125}
+ // All others reserved
+ };
+
+ // Retrieve timing parameters
+ const auto l_target = i_spd_decoder.get_dimm_target();
+
+ int64_t l_spd_ftb = 0;
+ int64_t l_spd_mtb = 0;
+
+ FAPI_TRY( i_spd_decoder.medium_timebase(l_spd_mtb),
+ "%s. Failed medium_timebase()", spd::c_str(l_target) );
+
+ FAPI_ASSERT( mss::find_value_from_key(MEDIUM_TIMEBASE_MAP, l_spd_mtb, o_mtb),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_spd_mtb)
+ .set_DATA(o_mtb)
+ .set_FUNCTION(GET_TIMEBASES_MTB)
+ .set_TARGET(l_target),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_spd_mtb, spd::c_str(l_target) );
+ FAPI_TRY( i_spd_decoder.fine_timebase(l_spd_ftb),
+ "%s. Failed fine_timebase()", spd::c_str(l_target) );
+
+ FAPI_ASSERT( mss::find_value_from_key(FINE_TIMEBASE_MAP, l_spd_ftb, o_ftb),
+ fapi2::MSS_LOOKUP_FAILED()
+ .set_KEY(l_spd_ftb)
+ .set_DATA(o_ftb)
+ .set_FUNCTION(GET_TIMEBASES_FTB)
+ .set_TARGET(l_target),
+ "Could not find a mapped value that matched the key (%d) for %s",
+ l_spd_ftb, spd::c_str(l_target) );
+
+ FAPI_INF("MTB: %d, FTB: %d for %s", o_mtb, o_ftb, spd::c_str(l_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD
+/// @param[in] i_spd_decoder the SPD decoder
+/// @param[out] o_value tCKmin value in ps
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode get_tckmin( const mss::spd::facade& i_spd_decoder,
+ uint64_t& o_value )
+{
+ int64_t l_timing_ftb = 0;
+ int64_t l_timing_mtb = 0;
+ int64_t l_medium_timebase = 0;
+ int64_t l_fine_timebase = 0;
+ int64_t l_temp = 0;
+
+ // Retrieve timing parameters
+ const auto l_target = i_spd_decoder.get_dimm_target();
+
+ FAPI_TRY( get_timebases(i_spd_decoder, l_medium_timebase, l_fine_timebase),
+ "%s. Failed get_timebases", spd::c_str(l_target) );
+ FAPI_TRY( i_spd_decoder.min_tck(l_timing_mtb),
+ "%s. Failed min_tck()", spd::c_str(l_target) );
+ FAPI_TRY( i_spd_decoder.fine_offset_min_tck(l_timing_ftb),
+ "%s. Failed fine_offset_min_tck()", spd::c_str(l_target) );
+
+ // Calculate timing value
+ l_temp = spd::calc_timing_from_timebase(l_timing_mtb,
+ l_medium_timebase,
+ l_timing_ftb,
+ l_fine_timebase);
+
+ // Sanity check
+ FAPI_ASSERT(l_temp > 0,
+ fapi2::MSS_INVALID_TIMING_VALUE().
+ set_VALUE(l_temp).
+ set_FUNCTION(GET_TCKMIN).
+ set_DIMM_TARGET(l_target),
+ "%s. tCKmin invalid (<= 0) : %d",
+ spd::c_str(l_target),
+ l_temp);
+
+ o_value = l_temp;
+
+ FAPI_INF("%s. tCKmin (ps): %d",
+ spd::c_str(l_target),
+ o_value );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD
+/// @param[in] i_spd_decoder SPD decoder
+/// @param[out] o_value tCKmax value in ps
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode get_tckmax( const mss::spd::facade& i_spd_decoder,
+ uint64_t& o_value )
+{
+ int64_t l_timing_ftb = 0;
+ int64_t l_timing_mtb = 0;
+ int64_t l_medium_timebase = 0;
+ int64_t l_fine_timebase = 0;
+ int64_t l_temp = 0;
+
+ // Retrieve timing parameters
+ const auto l_target = i_spd_decoder.get_dimm_target();
+
+ FAPI_TRY( get_timebases(i_spd_decoder, l_medium_timebase, l_fine_timebase),
+ "%s. Failed get_timebases", spd::c_str(l_target) );
+ FAPI_TRY( i_spd_decoder.max_tck(l_timing_mtb),
+ "%s. Failed max_tck()", spd::c_str(l_target) );
+ FAPI_TRY( i_spd_decoder.fine_offset_max_tck(l_timing_ftb),
+ "%s. Failed fine_offset_max_tck()", spd::c_str(l_target) );
+
+ // Calculate timing value
+ l_temp = spd::calc_timing_from_timebase(l_timing_mtb,
+ l_medium_timebase,
+ l_timing_ftb,
+ l_fine_timebase);
+
+ // Sanity check
+ FAPI_ASSERT(l_temp > 0,
+ fapi2::MSS_INVALID_TIMING_VALUE().
+ set_VALUE(l_temp).
+ set_FUNCTION(GET_TCKMAX).
+ set_DIMM_TARGET(l_target),
+ "%s. tCKmax invalid (<= 0) : %d",
+ spd::c_str(l_target),
+ l_temp);
+
+ o_value = l_temp;
+
+ FAPI_INF( "%s. tCKmax (ps): %d",
+ spd::c_str(l_target),
+ o_value);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// spd
+}// mss
diff --git a/src/import/generic/memory/lib/spd/spd_utils.H b/src/import/generic/memory/lib/spd/spd_utils.H
index 4674e71aa..916c41d39 100644
--- a/src/import/generic/memory/lib/spd/spd_utils.H
+++ b/src/import/generic/memory/lib/spd/spd_utils.H
@@ -22,3 +22,150 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file spd_utls.H
+/// @brief SPD utility functions definitions
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_SPD_UTILS_H_
+#define _MSS_SPD_UTILS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/spd/spd_facade.H>
+
+namespace mss
+{
+namespace spd
+{
+
+///
+/// @brief Calculates timing value
+/// @param[in] i_timing_mtb timing value in MTB units
+/// @param[in] i_mtb_multiplier SPD medium timebase
+/// @param[in] i_timing_ftb fine offset of timing value
+/// @param[in] i_ftb_multiplier SPD fine timebase
+/// @return the timing value in picoseconds
+///
+inline int64_t calc_timing_from_timebase(const int64_t i_timing_mtb,
+ const int64_t i_mtb_multiplier,
+ const int64_t i_timing_ftb,
+ const int64_t i_ftb_multiplier)
+{
+ // JEDEC algorithm
+ const int64_t l_timing_val = i_timing_mtb * i_mtb_multiplier;
+ const int64_t l_fine_offset = i_timing_ftb * i_ftb_multiplier;
+
+ return l_timing_val + l_fine_offset;
+}
+
+///
+/// @brief Helper to compute JEDEC's SPD rounding algorithm
+/// to convert ps to nCK
+/// @tparam T input type
+/// @tparam OT output type
+/// @param[in] i_timing_in_ps timing parameter in ps
+/// @param[in] i_tck_in_ps clock period in ps
+/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC)
+/// @param[out] o_value_nck the end calculation in nck
+/// @return true if overflow didn't occur, false otherwise
+/// @note DDR4 SPD Contents Rounding Algorithm
+/// @note Item 2220.46
+///
+template<typename T, typename OT>
+static inline bool jedec_spd_rounding_alg(const T& i_timing_in_ps,
+ const T& i_tck_in_ps,
+ const guard_band i_inverse_corr_factor,
+ OT& o_val_nck)
+{
+ // Preliminary nCK calculation, scaled by 1000 per JDEC algorithm
+ T l_temp_nck = (i_timing_in_ps * mss::CONVERT_PS_IN_A_NS) / (i_tck_in_ps == 0 ? 1 : i_tck_in_ps);
+ l_temp_nck += i_inverse_corr_factor;
+ l_temp_nck = l_temp_nck / mss::CONVERT_PS_IN_A_NS;
+
+ // Check for overflow
+ // static_cast needed for HB compiler that complains about
+ // comparision of two different integral types
+ o_val_nck = l_temp_nck;
+
+ FAPI_DBG("Input timing (ps) %d, tCK (ps) %d, temp output %d, output (nCK) %d",
+ i_timing_in_ps, i_tck_in_ps, l_temp_nck, o_val_nck);
+
+ return (static_cast<T>(o_val_nck) == l_temp_nck);
+}
+
+///
+/// @brief Returns clock cycles based on input application period
+/// @tparam T input type
+/// @tparam OT output type
+/// @param[in] i_timing_in_ps timing parameter in ps
+/// @param[in] i_tck_in_ps clock period in ps
+/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC)
+/// @param[out] o_value_nck the end calculation in nck
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note DDR4 SPD Contents Rounding Algorithm
+/// @note Item 2220.46
+///
+template<typename T, typename OT>
+inline fapi2::ReturnCode calc_nck(const T& i_timing_in_ps,
+ const T& i_tck_in_ps,
+ const guard_band i_inverse_corr_factor,
+ OT& o_val_nck)
+{
+ FAPI_ASSERT( jedec_spd_rounding_alg(i_timing_in_ps,
+ i_tck_in_ps,
+ i_inverse_corr_factor,
+ o_val_nck),
+ fapi2::MSS_INVALID_CAST_CALC_NCK().
+ set_TIMING_PS(i_timing_in_ps).
+ set_NCK_NS(i_tck_in_ps).
+ set_CORRECTION_FACTOR(i_inverse_corr_factor),
+ "Overflow occured. Returned data is %d", o_val_nck);
+
+ // If we don't assert, we don't know what's in current_err ...
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to retrieves medium and fine timebase values
+/// @param[in] i_spd_decoder the SPD decoder
+/// @param[out] o_mtb the medium timebase (MTB) from SPD
+/// @param[out] o_ftb the fine timebase (FTB) from SPD
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode get_timebases( const mss::spd::facade& i_spd_decoder,
+ int64_t& o_mtb,
+ int64_t& o_ftb );
+
+///
+/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD
+/// @param[in] i_spd_decoder the SPD decoder
+/// @param[out] o_value tCKmin value in ps
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode get_tckmin( const mss::spd::facade& i_spd_decoder,
+ uint64_t& o_value );
+
+///
+/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD
+/// @param[in] i_spd_decoder SPD decoder
+/// @param[out] o_value tCKmax value in ps
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode get_tckmax( const mss::spd::facade& i_spd_decoder,
+ uint64_t& o_value );
+
+}// spd
+
+}// mss
+
+#endif // _MSS_SPD_UTILS_H_
diff --git a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
index 4bdaf09b7..736827295 100644
--- a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
+++ b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
@@ -43,6 +43,20 @@ namespace mss
{
///
+/// @brief Common conversions
+///
+enum conversions
+{
+ CONVERT_PS_IN_A_NS = 1000, ///< 1000 pico in an nano
+ CONVERT_PS_IN_A_US = 1000000, ///< 1000000 picos in a micro
+ MHZ_TO_KHZ = 1000,
+ SEC_IN_HOUR = 60 * 60, ///< seconds in an hour, used for scrub times
+ NIBBLES_PER_BYTE = 2,
+ BITS_PER_NIBBLE = 4,
+ BITS_PER_BYTE = 8,
+};
+
+///
/// @brief FFDC generic codes
///
enum generic_ffdc_codes
@@ -58,22 +72,58 @@ enum generic_ffdc_codes
PRE_DATA_ENGINE_CTOR = 0x1005,
EXTRACT_SPD_FLD = 0x1006,
SPD_READER = 0x1007,
- BASE_CNFG_MAKE_OBJ = 0x1008,
- DIMM_MODULE_MAKE_OBJ = 0x1009,
- CREATE_BASE_CNFG_FACTORY = 0x100A,
- CREATE_MODULE_FACTORY = 0x100B,
+ BASE_CFG_PARAM_SELECT = 0x1008,
+ DIMM_MODULE_PARAM_SELECT = 0x1009,
+ BASE_CFG_FACTORY = 0x100A,
+ DIMM_MODULE_FACTORY = 0x100B,
+ GET_TAAMIN = 0x100C,
+ GET_TCKMIN = 0x100D,
+ GET_TCKMAX = 0x100E,
GET_TIMEBASES_FTB = 0x100F,
GET_TIMEBASES_MTB = 0x1010,
+ GET_SUPPORTED_REV = 0x1011,
+ TRASMIN = 0x1012,
+ TRCMIN = 0x1013,
+ TRFC1MIN = 0x1014,
+ TRFC2MIN = 0x1015,
+ TRFC4MIN = 0x1016,
+ TFAWMIN = 0x1017,
+ TWTR_S_MIN = 0x1018,
+ TWRMIN = 0x1019,
+ TWTR_L_MIN = 0x101A,
+ DEVICE_TYPE = 0x101B,
+ BASE_MODULE_TYPE = 0x101C,
};
///
-/// @brief DRAM generation selector
+/// @brief Supported proc types
///
-enum device_type
+enum proc_type
{
- DDR4 = 0x0c,
+ NIMBUS,
+ AXONE,
};
+///
+/// @brief JEDEC supported DDR4 speeds
+///
+enum ddr4_dimm_speeds
+{
+ DIMM_SPEED_1600 = 1600,
+ DIMM_SPEED_1866 = 1866,
+ DIMM_SPEED_2133 = 2133,
+ DIMM_SPEED_2400 = 2400,
+ DIMM_SPEED_2666 = 2666,
+ DIMM_SPEED_2933 = 2933,
+ DIMM_SPEED_3200 = 3200,
+};
+
+namespace spd
+{
+
+///
+/// @brief SPD revisions - not tied any particular module
+///
enum rev : uint8_t
{
V1_0 = 0x10, ///< represents Rev 1.0
@@ -93,11 +143,43 @@ enum rev : uint8_t
///
enum parameters
{
+ UNINITIALIZED,
BASE_CNFG,
RDIMM_MODULE,
LRDIMM_MODULE,
+ NVDIMM_MODULE,
+};
+
+///
+/// @brief DRAM generation selector
+/// @note values set to SPD settings
+///
+enum device_type
+{
+ DDR4 = 0x0c,
+};
+
+///
+/// @brief DIMM type selector
+/// @note values set to SPD settings
+///
+enum dimm_type
+{
+ RDIMM = 0b0001,
+ LRDIMM = 0b0100,
+};
+
+enum guard_band : uint16_t
+{
+ // Used for caclulating spd timing values - from JEDEC rounding algorithm
+ // Correction factor is 1% (for DDR3) or 2.5% (for DDR4)
+ // when doing integer math, we add-in the inverse correction factor
+ // Formula used for derivation:
+ // Guardband = 1000 * (1000* correction_factor) - 1
+ INVERSE_DDR4_CORRECTION_FACTOR = 974, ///< DDR4 correction factor
};
+}// spd
}// mss
#endif
OpenPOWER on IntegriCloud