summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9')
-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