summaryrefslogtreecommitdiffstats
path: root/src/import/chips
diff options
context:
space:
mode:
authorAndre Marin <aamarin@us.ibm.com>2018-05-29 08:37:46 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-07-31 15:34:02 -0500
commit77a99242f79dbe5aaf47b950f070ccaeaa58d240 (patch)
treed892c4a8b69d77769a38d8dc77d6bd64d4aca468 /src/import/chips
parent73f196ac8f86bbe898733721db58e143b0a42d6c (diff)
downloadtalos-hostboot-77a99242f79dbe5aaf47b950f070ccaeaa58d240.tar.gz
talos-hostboot-77a99242f79dbe5aaf47b950f070ccaeaa58d240.zip
Remove Nimbus dependencies from the SPD decoder
Created a new pre_data_engine to set preliminary data needed before eff_config. Moved SPD to attribute mapping to eff_dimm structure and away from the SPD decoder to make it reusable for future memory controllers. Updated bugs in unit tests. Added SPD factory classes. This is only needed for Axone. Change-Id: Ief0a479ee1c7a4dab852ffb18b595564c0125e35 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/58611 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Dev-Ready: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/59470 Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Tested-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips')
-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
23 files changed, 1302 insertions, 1679 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>
OpenPOWER on IntegriCloud