summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C34
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H11
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/cas_latency.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H1
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H25
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dcd.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H18
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H9
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H184
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/mss.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.C7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C3
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml14
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml26
-rw-r--r--src/import/generic/memory/lib/utils/conversions.H (renamed from src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H)266
-rw-r--r--src/import/generic/memory/lib/utils/find.H30
-rw-r--r--src/import/generic/memory/lib/utils/poll.H1
-rw-r--r--src/import/generic/memory/lib/utils/shared/mss_generic_consts.H66
-rw-r--r--src/import/generic/xml/error_info/generic_error.xml26
-rwxr-xr-xsrc/usr/fapi2/fapi2.mk2
32 files changed, 510 insertions, 265 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C
index 79d8434b4..d1e8edc48 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/bcw_load_ddr4.C
@@ -37,7 +37,7 @@
#include <p9_mc_scom_addresses.H>
#include <generic/memory/lib/utils/c_str.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/eff_config/timing.H>
#include <lib/ccs/ccs.H>
#include <lib/dimm/bcw_load_ddr4.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
index cd514951a..81cb6e69d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
@@ -47,7 +47,7 @@
#include <lib/mcbist/memdiags.H>
#include <lib/mcbist/mcbist.H>
#include <lib/mcbist/settings.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/mc/port.H>
#include <lib/phy/dp16.H>
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 2e2a49540..9b3243609 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
@@ -41,7 +41,7 @@
#include <lib/eff_config/timing.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
#include <lib/dimm/rank.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/dimm/eff_dimm.H>
#include <lib/dimm/mrs_load.H>
@@ -2627,21 +2627,29 @@ fapi2::ReturnCode eff_dimm::dram_cwl()
// Using an if branch because a ternary conditional wasn't working with params for find_value_from_key
if (l_preamble == 0)
{
- FAPI_TRY( mss::find_value_from_key( CWL_TABLE_1,
- iv_freq,
- l_cwl),
- "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
- iv_freq,
- l_preamble);
+ FAPI_ASSERT( mss::find_value_from_key( CWL_TABLE_1,
+ iv_freq,
+ l_cwl),
+ fapi2::MSS_DRAM_CWL_ERROR()
+ .set_TARGET(iv_mca)
+ .set_FREQ(iv_freq)
+ .set_PREAMBLE(l_preamble),
+ "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
+ iv_freq,
+ l_preamble);
}
else
{
- FAPI_TRY( mss::find_value_from_key( CWL_TABLE_2,
- iv_freq,
- l_cwl),
- "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
- iv_freq,
- l_preamble);
+ FAPI_ASSERT( mss::find_value_from_key( CWL_TABLE_2,
+ iv_freq,
+ l_cwl),
+ fapi2::MSS_DRAM_CWL_ERROR()
+ .set_TARGET(iv_mca)
+ .set_FREQ(iv_freq)
+ .set_PREAMBLE(l_preamble),
+ "Failed finding CAS Write Latency (cwl), freq: %d, preamble %d",
+ iv_freq,
+ l_preamble);
}
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 b4a715fb7..4ea2178db 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
@@ -37,9 +37,10 @@
#include <cstdint>
#include <fapi2.H>
+#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
namespace mss
{
@@ -352,7 +353,7 @@ template< fapi2::TargetType T >
inline uint64_t tmod( const fapi2::Target<T>& i_target )
{
// Per DDR4 Full spec update (79-4A) - timing requirements
- return mss::max_ck_ns( i_target, 24, 15 );
+ return mss::max_ck_ns<T>( i_target, 24, 15 );
}
///
@@ -410,7 +411,7 @@ inline uint64_t twlo_twloe(const fapi2::Target<T>& i_target)
constexpr uint64_t l_dq_ck = 1;
constexpr uint64_t l_dqs_ck = 1;
uint8_t l_wlo_ck = 0;
- uint64_t l_wloe_ck = mss::ns_to_cycles(i_target, 2);
+ uint64_t l_wloe_ck = mss::ns_to_cycles<T>(i_target, 2);
uint64_t l_twlo_twloe = 0;
uint8_t l_twldqsen = 0;
@@ -1151,7 +1152,7 @@ inline uint64_t tvrefdqe( const fapi2::Target<T>& i_target )
{
// JEDEC tVREFDQE in ns
constexpr uint64_t tVREFDQE = 150;
- return ns_to_cycles(i_target, tVREFDQE);
+ return ns_to_cycles<T>(i_target, tVREFDQE);
}
///
@@ -1165,7 +1166,7 @@ inline uint64_t tvrefdqx( const fapi2::Target<T>& i_target )
{
// JEDEC tVREFDQX in ns
constexpr uint64_t tVREFDQX = 150;
- return ns_to_cycles(i_target, tVREFDQX);
+ return ns_to_cycles<T>(i_target, tVREFDQX);
}
///
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 bd01e5dc9..9b5688756 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
@@ -46,7 +46,7 @@
// mss lib
#include <generic/memory/lib/spd/spd_facade.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/freq/sync.H>
namespace mss
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 0d9d4c0f8..1a0ee8165 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
@@ -447,7 +447,7 @@ fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TARGET_TYPE_MCBIST>& i_
// Get cached decoder
std::vector< mss::spd::facade > l_spd_facades;
- FAPI_TRY( get_spd_decoder_list(i_target, l_spd_facades) );
+ FAPI_TRY( get_spd_decoder_list(i_target, l_spd_facades), "%s get decoder - spd", mss::c_str(i_target) );
// Looking for the biggest application period on an MC.
// This will further reduce supported frequencies the system can run on.
@@ -470,7 +470,7 @@ fapi2::ReturnCode spd_supported_freq(const fapi2::Target<TARGET_TYPE_MCBIST>& i_
l_largest_tck = std::max(l_largest_tck, l_tck_min_in_ps);
l_largest_tck = std::min(l_largest_tck, l_tckmax_in_ps);
- FAPI_TRY( mss::ps_to_freq(l_largest_tck, l_dimm_freq) );
+ FAPI_TRY( mss::ps_to_freq(l_largest_tck, l_dimm_freq), "%s ps to freq %lu", mss::c_str(i_target), l_largest_tck );
FAPI_INF("Biggest freq supported from SPD %d MT/s for %s",
l_dimm_freq, mss::c_str(l_dimm));
@@ -503,9 +503,9 @@ fapi2::ReturnCode supported_freqs(const fapi2::Target<TARGET_TYPE_MCBIST>& i_tar
std::vector<uint8_t> l_deconfigured = {0};
// Retrieve system MRW, SPD, and VPD constraints
- FAPI_TRY( mss::max_allowed_dimm_freq(l_max_freqs.data()) );
- FAPI_TRY( spd_supported_freq(i_target, l_spd_supported_freq) );
- FAPI_TRY( vpd_supported_freqs(i_target, l_vpd_supported_freqs) );
+ FAPI_TRY( mss::max_allowed_dimm_freq(l_max_freqs.data()), "%s max_allowed_dimm_freq", mss::c_str(i_target) );
+ FAPI_TRY( spd_supported_freq(i_target, l_spd_supported_freq), "%s spd supported freqs", mss::c_str(i_target) );
+ FAPI_TRY( vpd_supported_freqs(i_target, l_vpd_supported_freqs), "%s vpd supported freqs", mss::c_str(i_target) );
// Limit frequency scoreboard according to MRW constraints
FAPI_TRY( limit_freq_by_mrw(i_target, l_max_freqs, l_scoreboard) );
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
index 5b2a5ce3d..4e46f0b1e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
@@ -39,6 +39,7 @@
#include <vector>
#include <fapi2.H>
+#include <lib/shared/mss_const.H>
namespace mss
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
index a72a74d8b..0a44ca640 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
@@ -41,7 +41,7 @@
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
#include <lib/mss_attribute_accessors.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/shared/mss_const.H>
#include <generic/memory/lib/utils/scom.H>
#include <lib/dimm/rank.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
index 92e66f80b..bafdc6e98 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
@@ -43,6 +43,7 @@
#include <generic/memory/lib/utils/poll.H>
#include <generic/memory/lib/utils/memory_size.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/shared/mss_const.H>
#include <lib/utils/bit_count.H>
#include <lib/utils/num.H>
@@ -418,6 +419,30 @@ class mcbistTraits<fapi2::TARGET_TYPE_MCS>
};
+///
+/// @brief Return the estimated time an MCBIST subtest will take to complete
+/// Useful for initial polling delays, probably isn't accurate for much else
+/// as it doesn't take refresh in to account (which will necessarily slow down
+/// the program.)
+/// @param[in] i_target the target from which to gather memory frequency
+/// @param[in] i_bytes number of *bytes* in the address range
+/// @param[in] i_64B_per mss::YES if the command is 64B, mss::NO if it's 128B. Defaults to mss::YES
+/// @return the initial polling delay for this program in ns
+///
+template< fapi2::TargetType T >
+inline uint64_t calculate_initial_delay(const fapi2::Target<T>& i_target,
+ const uint64_t i_bytes,
+ const bool i_64B_per = mss::YES)
+{
+ // TODO RTC: 164104 Update MCBIST delay calculator. As we learn more about what
+ // the lab really needs, we can probably make this function better.
+ const uint64_t l_bytes_per_cmd = (i_64B_per == mss::YES) ? 64 : 128;
+
+ // Best case is a command takes 4 cycles. Given the number of commands and address space size
+ // we can get some idea of how long to wait before we start polling.
+ return cycles_to_ns(i_target, (i_bytes / l_bytes_per_cmd) * mss::CYCLES_PER_CMD);
+}
+
namespace mcbist
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H
index dee63a739..f8125daf9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/cal_timers.H
@@ -62,17 +62,9 @@ inline fapi2::ReturnCode cal_timer_setup(const fapi2::Target<T>& i_target,
// i.e. DQS_ALIGN + INITIAL_PAT_WR = 3 polls, so this should be 2
constexpr uint64_t MINIMUM_POLL_COUNT = 2;
- // Sometimes when running in sim, particularly Mesa, it is helpful to not delay a bunch
- // when training starts - makes it simpler to get an AET for, say, write leveling. So
- // this is here to allow the simple removal of the initial delay for those situations.
-#ifdef THRASH_CCS_IP_IN_SIM
- io_poll.iv_initial_delay = mss::cycles_to_ns(i_target, 1);
- io_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(1);
-#else
// We don't want to wait too long for the initial check, just some hueristics here
io_poll.iv_initial_delay = mss::cycles_to_ns(i_target, i_total_cycles / 8);
io_poll.iv_initial_sim_delay = mss::cycles_to_simcycles(i_total_cycles / 8);
-#endif
// Delay 10us between polls, and setup the poll count so
// iv_initial_delay + (iv_delay * iv_poll_count) == i_total_cycles + some fudge;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dcd.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dcd.C
index b606baa3f..acd9dbae8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dcd.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dcd.C
@@ -38,7 +38,7 @@
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/pos.H>
#include <generic/memory/lib/utils/poll.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/workarounds/adr32s_workarounds.H>
using fapi2::TARGET_TYPE_MCA;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
index b4dfb6110..ae1a824df 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_training.C
@@ -321,8 +321,9 @@ uint64_t dqs_align::calculate_cycles( const fapi2::Target<fapi2::TARGET_TYPE_MCA
// This step runs for approximately 6 x 600 x 4 DRAM clocks per rank pair.
const uint64_t l_dqs_align_cycles = 6 * 600 * 4;
- FAPI_DBG("%s dqs_align_cycles: %llu(%lluns)", mss::c_str(i_target), l_dqs_align_cycles, mss::cycles_to_ns(i_target,
- l_dqs_align_cycles));
+ FAPI_DBG("%s dqs_align_cycles: %llu(%lluns)", mss::c_str(i_target), l_dqs_align_cycles,
+ mss::cycles_to_ns(i_target,
+ l_dqs_align_cycles));
return l_dqs_align_cycles;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H
index a751adb4d..06f8cc4b5 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,7 +39,7 @@
#include <fapi2.H>
#include <p9_mc_scom_addresses.H>
#include <generic/memory/lib/utils/scom.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/eff_config/timing.H>
namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
index ee432fd8d..e38696fef 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
@@ -299,10 +299,12 @@ inline fapi2::ReturnCode encode ( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
//used to hold result from vector pair lookup
OT l_encoding = 0;
- //Returns true if found, so need to negate for FAPI_TRY
//Failing out if we don't find an encoding. All suported types should be encoded above
- FAPI_TRY( !mss::find_value_from_key (i_map, i_attr, l_encoding),
- "Couldn't find encoding for power thermal encode for value: %x target: %s", i_attr, mss::c_str(i_target));
+ FAPI_ASSERT( mss::find_value_from_key (i_map, i_attr, l_encoding),
+ fapi2::MSS_POWER_THERMAL_ENCODE_ERROR()
+ .set_ATTR(i_attr)
+ .set_DIMM_TARGET(i_target),
+ "Couldn't find encoding for power thermal encode for value: %x target: %s", i_attr, mss::c_str(i_target));
o_buf.insertFromRight<S, L>(l_encoding);
fapi_try_exit:
@@ -330,9 +332,13 @@ inline fapi2::ReturnCode decode ( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
//used to hold result from vector pair lookup
OT l_encoding = 0;
i_buf.extractToRight<S, L>(l_encoding);
- //Find_key_from_value returns fapi2 error
- FAPI_TRY( mss::find_key_from_value (i_map, l_encoding, o_attr),
- "Couldn't find encoding for power thermal decode for target: %s", mss::c_str(i_target));
+
+ //Failing out if we don't find an decoding. All suported types should be encoded above
+ FAPI_ASSERT( mss::find_key_from_value (i_map, l_encoding, o_attr),
+ fapi2::MSS_POWER_THERMAL_DECODE_ERROR()
+ .set_ATTR(l_encoding)
+ .set_DIMM_TARGET(i_target),
+ "Couldn't find encoding for power thermal decode for target: %s", mss::c_str(i_target));
fapi_try_exit:
return fapi2::current_err;
}
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 d8187e549..53d058775 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
@@ -120,15 +120,6 @@ enum sizes
enum times
{
- 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
- DELAY_1US = 1000, ///< general purpose 1 usec delay for HW mode
- DELAY_10US = 10000, ///< general purpose 1 usec delay for HW mode
- DELAY_100US = 100000, ///< general purpose 100 usec delay for HW mode
- DELAY_1MS = 1000000, ///< general purpose 1 ms delay for HW mode
-
- // Not *exactly* a time but go with it.
BG_SCRUB_IN_HOURS = 12,
CMD_TIMEBASE = 8192, ///< Represents the timebase multiplier for the MCBIST inter cmd gap
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 1dd9cb759..70904130f 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
@@ -51,9 +51,10 @@
#include <generic/memory/lib/spd/lrdimm/ddr4/lrdimm_raw_cards.H>
#include <generic/memory/lib/spd/spd_checker.H>
#include <generic/memory/lib/spd/spd_utils.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/eff_config/timing.H>
+#include <lib/shared/mss_const.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H
index a81e75110..1b7f749fd 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/mss_nimbus_conversions.H
@@ -22,3 +22,187 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file mss_nimbus_conversions.H
+/// @brief Functions to convert units
+///
+// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_NIMBUS_CONVERSIONS_H_
+#define _MSS_NIMBUS_CONVERSIONS_H_
+
+#include <generic/memory/lib/utils/conversions.H>
+#include <generic/memory/lib/utils/find.H>
+#include <lib/mss_attribute_accessors.H>
+
+namespace mss
+{
+
+///
+/// @brief Return the number of cycles contained in a count of picoseconds
+/// @tparam T the target type from which to get the mt/s
+/// @tparam OT the output type, derrived from the parameters
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_ps the number of picoseconds to convert
+/// @return uint64_t, the number of cycles
+///
+template< fapi2::TargetType T, typename OT >
+inline OT ps_to_cycles(const fapi2::Target<T>& i_target, const OT i_ps)
+{
+ // The frequency in MT/s
+ uint64_t l_freq = 0;
+ uint64_t l_clock_period = 0;
+
+ // Gets the frequency attribute
+ FAPI_TRY( mss::freq( mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );
+
+ // No time if MT/s is 0 (well, infinite really but shut up)
+ if (l_freq == 0)
+ {
+ return 0;
+ }
+
+ // Hoping the compiler figures out how to do these together.
+ FAPI_TRY( freq_to_ps(l_freq, l_clock_period) );
+
+ return ps_to_cycles( l_clock_period, i_ps );
+
+fapi_try_exit:
+ // We simply can't work if we can't get the frequency or
+ // if we get an unsupported value that can't be converted to a valid tCK (clock period)
+ // ...so this should be ok
+ FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq);
+ fapi2::Assert(false);
+
+ // Keeps compiler happy
+ return 0;
+}
+
+///
+/// @brief Return the number of ps contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of picoseconds
+///
+template< fapi2::TargetType T >
+inline uint64_t cycles_to_ps(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ // The frequency in MHZ
+ uint64_t l_freq = 0;
+ uint64_t l_clock_period = 0;
+
+ // Gets the operating frequency
+ FAPI_TRY( mss::freq( mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );
+
+ FAPI_TRY( freq_to_ps(l_freq, l_clock_period) );
+ return cycles_to_ps(l_clock_period, i_cycles);
+
+fapi_try_exit:
+
+ // We simply can't work if we can't get the frequency or
+ // if we get an unsupported value that can't be converted to a valid tCK (clock period)
+ // ...so this should be ok
+ FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq);
+ fapi2::Assert(false);
+
+ // Keeps compiler happy
+ return 0;
+}
+
+///
+/// @brief Return the number of cycles contained in a count of microseconds
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_us the number of microseconds to convert
+/// @return uint64_t, the number of cycles
+///
+template< fapi2::TargetType T >
+inline uint64_t us_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_us)
+{
+ return ps_to_cycles(i_target, i_us * CONVERT_PS_IN_A_US);
+}
+
+///
+/// @brief Return the number of cycles contained in a count of nanoseconds
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_ps the number of nanoseconds to convert
+/// @return uint64_t, the number of cycles
+///
+template< fapi2::TargetType T >
+inline uint64_t ns_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ns)
+{
+ return ps_to_cycles(i_target, i_ns * CONVERT_PS_IN_A_NS);
+}
+
+///
+/// @brief Return the amount of unit time contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @tparam D the time conversion (NS_IN_PS, etc)
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of microseconds
+///
+template< uint64_t D, fapi2::TargetType T >
+inline uint64_t cycles_to_time(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ // Hoping the compiler figures out how to do these together.
+ uint64_t l_dividend = cycles_to_ps(i_target, i_cycles);
+ uint64_t l_quotient = l_dividend / ((D == 0) ? 1 : D);
+ uint64_t l_remainder = l_dividend % ((D == 0) ? 1 : D);
+
+ // Make sure we add time if there wasn't an even number of cycles
+ return l_quotient + (l_remainder == 0 ? 0 : 1);
+}
+
+///
+/// @brief Return the number of nanoseconds contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of nanoseconds
+///
+template< fapi2::TargetType T >
+inline uint64_t cycles_to_ns(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ uint64_t l_ns = cycles_to_time<CONVERT_PS_IN_A_NS>(i_target, i_cycles);
+ return l_ns;
+}
+
+///
+/// @brief Return the number of microseconds contained in a count of cycles
+/// @tparam T the target type from which to get the mt/s
+/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_cycles the number of cycles to convert
+/// @return uint64_t, the number of microseconds
+///
+template< fapi2::TargetType T >
+inline uint64_t cycles_to_us(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+{
+ uint64_t l_us = cycles_to_time<CONVERT_PS_IN_A_US>(i_target, i_cycles);
+ return l_us;
+}
+
+///
+/// @brief Return the maximum of two values *in clocks*, the first in clocks the second in ns
+/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_target
+/// @param[in] i_clocks a value in clocks
+/// @param[in] i_time a value in nanoseconds
+/// @return max( iclocks nCK, i_time ) in clocks
+///
+template< fapi2::TargetType T >
+inline uint64_t max_ck_ns(const fapi2::Target<T>& i_target, const uint64_t i_clocks, const uint64_t i_time)
+{
+ return std::max( i_clocks, ns_to_cycles(i_target, i_time) );
+}
+
+} // ns mss
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
index 4b877b47f..281079963 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/adr32s_workarounds.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,7 +42,7 @@
#include <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/pos.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/fir/fir.H>
#include <lib/workarounds/adr32s_workarounds.H>
#include <lib/phy/ddr_phy.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C
index 73c9c3516..4e73323f2 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dll_workarounds.C
@@ -39,7 +39,7 @@
#include <lib/fir/fir.H>
#include <lib/phy/phy_cntrl.H>
#include <lib/shared/mss_const.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
namespace mss
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/mss.H b/src/import/chips/p9/procedures/hwp/memory/mss.H
index 7d2cd547b..84fe9c6ca 100644
--- a/src/import/chips/p9/procedures/hwp/memory/mss.H
+++ b/src/import/chips/p9/procedures/hwp/memory/mss.H
@@ -51,7 +51,7 @@
#include <generic/memory/lib/utils/pos.H>
#include <lib/utils/swizzle.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <generic/memory/lib/utils/find.H>
#include <generic/memory/lib/utils/poll.H>
#include <lib/utils/checker.H>
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
index 0304b992a..d0362d456 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
@@ -38,7 +38,7 @@
#include <p9_mss_draminit.H>
#include <generic/memory/lib/utils/count_dimm.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
#include <lib/dimm/bcw_load.H>
#include <lib/workarounds/dqs_align_workarounds.H>
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 e01918cd7..15d956308 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
@@ -104,12 +104,13 @@ extern "C"
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));
+ FAPI_TRY(mss::set_pre_init_attrs(d, l_spd_decoder), "%s failed to set pre init attrs", mss::c_str(d) );
}
}
// Get supported freqs for this MCBIST
- FAPI_TRY( mss::supported_freqs(l_mcbist, l_supported_freqs) );
+ FAPI_TRY( mss::supported_freqs(l_mcbist, l_supported_freqs), "%s failed to get supported frequencies",
+ mss::c_str(i_target) );
for (const auto& l_mcs : mss::find_targets<TARGET_TYPE_MCS>(l_mcbist))
{
@@ -151,7 +152,7 @@ extern "C"
uint64_t l_tCKmin = 0;
// Find CAS latency using JEDEC algorithm
- FAPI_TRY( l_cas_latency.find_cl(l_desired_cl, l_tCKmin) );
+ FAPI_TRY( l_cas_latency.find_cl(l_desired_cl, l_tCKmin), "%s failed to find a cas latency", mss::c_str(i_target) );
FAPI_INF("%s. Result from CL algorithm, CL (nck): %d, tCK (ps): %d",
mss::c_str(l_mca), l_desired_cl, l_tCKmin);
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.H
index 64286aadd..3131dc541 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.H
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_freq.H
@@ -38,7 +38,7 @@
#include <utility>
#include <fapi2.H>
#include <lib/shared/mss_const.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_conversions.H>
namespace mss
{
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 487824835..1cf6a8a4a 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
@@ -46,7 +46,8 @@
#include <lib/power_thermal/throttle.H>
#include <generic/memory/lib/utils/index.H>
#include <generic/memory/lib/utils/find.H>
-#include <lib/utils/conversions.H>
+#include <lib/utils/mss_nimbus_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/xml/error_info/p9_memory_mss_eff_config.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
index b14b4923f..965e0de84 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
@@ -538,4 +538,18 @@
</callout>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_DRAM_CWL_ERROR</rc>
+ <description>
+ The DRAM's CWL could not be found based upon the inputted DIMM frequency
+ </description>
+ <ffdc>TARGET</ffdc>
+ <ffdc>FREQ</ffdc>
+ <ffdc>PREAMBLE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
</hwpErrors>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml
index be58c845b..5de51418f 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config_thermal.xml
@@ -56,6 +56,32 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_POWER_THERMAL_ENCODE_ERROR</rc>
+ <description>
+ There was no match or value found in encoding the power thermal attributes
+ </description>
+ <ffdc>DIMM_TARGET</ffdc>
+ <ffdc>ATTR</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_POWER_THERMAL_DECODE_ERROR</rc>
+ <description>
+ There was no match or value found in decoding the power thermal attributes
+ </description>
+ <ffdc>DIMM_TARGET</ffdc>
+ <ffdc>ATTR</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
+ <hwpError>
<rc>RC_MSS_POWER_INTERCEPT_NOT_SET</rc>
<description>
The attribute ATTR_MSS_TOTAL_POWER_INTERCEPT was not set and equals 0
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H b/src/import/generic/memory/lib/utils/conversions.H
index fd476fd82..efbb53a47 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H
+++ b/src/import/generic/memory/lib/utils/conversions.H
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H $ */
+/* $Source: src/import/generic/memory/lib/utils/conversions.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
@@ -38,8 +38,7 @@
#include <vector>
#include <fapi2.H>
-#include <lib/mss_attribute_accessors.H>
-#include <lib/shared/mss_const.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
#include <generic/memory/lib/utils/find.H>
///
@@ -80,6 +79,26 @@ static const uint64_t SIM_CYCLES_PER_CYCLE = 8;
namespace mss
{
+namespace dram_freq
+{
+//
+// DRAM clock and frequency information
+//
+static const std::vector<std::pair<uint64_t, uint64_t>> FREQ_TO_CLOCK_PERIOD =
+{
+ {DIMM_SPEED_1600, 1250}, // DDR4
+ {DIMM_SPEED_1866, 1071}, // DDR4
+ {DIMM_SPEED_2133, 937}, // DDR4
+ {DIMM_SPEED_2400, 833}, // DDR4
+ {DIMM_SPEED_2666, 750}, // DDR4
+ {DIMM_SPEED_2933, 682}, // DDR4
+ {DIMM_SPEED_3200, 625}, // DDR4/5
+ {DIMM_SPEED_3600, 555}, // DDR5
+ {DIMM_SPEED_4000, 500}, // DDR5
+ {DIMM_SPEED_4400, 454}, // DDR5
+ {DIMM_SPEED_4800, 416}, // DDR5
+};
+}
///
/// @brief Return the number of picoseconds
@@ -92,36 +111,27 @@ namespace mss
template<typename T, typename OT>
inline fapi2::ReturnCode freq_to_ps(const T i_speed_grade, OT& o_tCK_in_ps )
{
- switch(i_speed_grade)
- {
- case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
- o_tCK_in_ps = 1071;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
- o_tCK_in_ps = 937;
- break;
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
- o_tCK_in_ps = 833;
- break;
-
- // Default 2933 to 2666
- // TODO:RTC192461
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2933:
- FAPI_INF("2933 speed grade detected. Setting o_tCK_in_ps to match 2666");
-
- case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
- o_tCK_in_ps = 750;
- break;
-
- default:
- FAPI_ERR("Invalid dimm speed grade (MT/s) - %d - provided", i_speed_grade);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- break;
- }
+ // We need to have at least two bytes of data, due to the sizes of the frequencies and clock periods
+ constexpr size_t MIN_BYTE_SIZE = 2;
+ static_assert(sizeof(T) >= MIN_BYTE_SIZE && sizeof(OT) >= MIN_BYTE_SIZE,
+ "Input and output must be at least 2 bytes in length");
+
+ // Temporary variables to help with the conversion
+ const uint64_t l_input = static_cast<uint64_t>(i_speed_grade);
+ uint64_t l_output = 0;
+
+ FAPI_ASSERT(find_value_from_key(dram_freq::FREQ_TO_CLOCK_PERIOD, l_input, l_output),
+ fapi2::MSS_INVALID_FREQUENCY()
+ .set_FREQ(l_input),
+ "Frequency %u does not have an associated clock period", l_input);
+
+ // Cast the output type
+ o_tCK_in_ps = static_cast<OT>(l_output);
return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
}
///
@@ -135,37 +145,28 @@ inline fapi2::ReturnCode freq_to_ps(const T i_speed_grade, OT& o_tCK_in_ps )
template<typename T, typename OT>
fapi2::ReturnCode ps_to_freq(const T i_time_in_ps, OT& o_speed_grade)
{
- switch(i_time_in_ps)
- {
- // Default 682ps (2933MT/s) to 750ps (2666MT/s)
- // TODO:RTC192461
- case 682:
- FAPI_INF("682ps detected (2933 speed bin). Setting o_speed_grade to match 2666.");
-
- case 750:
- o_speed_grade = fapi2::ENUM_ATTR_MSS_FREQ_MT2666;
- break;
-
- case 833:
- o_speed_grade = fapi2::ENUM_ATTR_MSS_FREQ_MT2400;
- break;
-
- case 937:
- o_speed_grade = fapi2::ENUM_ATTR_MSS_FREQ_MT2133;
- break;
-
- case 1071:
- o_speed_grade = fapi2::ENUM_ATTR_MSS_FREQ_MT1866;
- break;
-
- default:
- FAPI_ERR("Invalid clock period (tCK) - %d - provided", i_time_in_ps);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- break;
- }
+ // We need to have at least two bytes of data, due to the sizes of the frequencies and clock periods
+ constexpr size_t MIN_BYTE_SIZE = 2;
+ static_assert(sizeof(T) >= MIN_BYTE_SIZE && sizeof(OT) >= MIN_BYTE_SIZE,
+ "Input and output must be at least 2 bytes in length");
+
+ // Temporary variables to help with the conversion
+ const uint64_t l_input = static_cast<uint64_t>(i_time_in_ps);
+ uint64_t l_output = 0;
+
+ FAPI_ASSERT(find_key_from_value(dram_freq::FREQ_TO_CLOCK_PERIOD, l_input, l_output),
+ fapi2::MSS_INVALID_CLOCK_PERIOD()
+ .set_CLOCK_PERIOD(l_input),
+ "Clock period %u does not have an associated frequency", l_input);
+
+ // Cast the output type
+ o_speed_grade = static_cast<OT>(l_output);
return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+
}
///
@@ -181,120 +182,80 @@ inline uint64_t cycles_to_simcycles( const uint64_t i_cycles )
///
/// @brief Return the number of cycles contained in a count of picoseconds
-/// @tparam T the target type from which to get the mt/s
+/// @tparam T clock period input type
/// @tparam OT the output type, derrived from the parameters
-/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_clock_period clock period in PS
/// @param[in] i_ps the number of picoseconds to convert
-/// @return uint64_t, the number of cycles
+/// @return the number of cycles
///
-template< fapi2::TargetType T, typename OT >
-inline OT ps_to_cycles(const fapi2::Target<T>& i_target, const OT i_ps)
+template< typename T, typename OT >
+inline OT ps_to_cycles(const T i_clock_period, const OT i_ps)
{
- // The frequency in MT/s
- uint64_t l_freq = 0;
- OT l_divisor = 0;
- OT l_quotient = 0;
- OT l_remainder = 0;
- OT l_rounder = (i_ps < 0) ? -1 : 1;
+ // Casts the clock period to be in OT type to avoid any weird math issues
+ const auto l_divisor = static_cast<OT>(i_clock_period);
- FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );
+ const OT l_rounder = (i_ps < 0) ? -1 : 1;
- // No time if MT/s is 0 (well, infinite really but shut up)
- if (l_freq == 0)
- {
- return 0;
- }
-
- // Hoping the compiler figures out how to do these together.
- FAPI_TRY( freq_to_ps(l_freq, l_divisor) );
- l_quotient = i_ps / ((l_divisor == 0) ? l_rounder : l_divisor);
- l_remainder = i_ps % l_divisor;
+ // Ensure we don't divide by 0
+ const OT l_quotient = i_ps / ((i_clock_period == 0) ? l_rounder : l_divisor);
+ const OT l_remainder = i_ps % ((i_clock_period == 0) ? 1 : l_divisor);
// Make sure we add a cycle if there wasn't an even number of cycles in the input
FAPI_INF("converting %llups to %llu cycles", i_ps, l_quotient + (l_remainder == 0 ? 0 : l_rounder));
return l_quotient + (l_remainder == 0 ? 0 : l_rounder);
-
-fapi_try_exit:
- // We simply can't work if we can't get the frequency or
- // if we get an unsupported value that can't be converted to a valid tCK (clock period)
- // ...so this should be ok
- FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq);
- fapi2::Assert(false);
-
- // Keeps compiler happy
- return 0;
}
///
/// @brief Return the number of ps contained in a count of cycles
-/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_clock_period
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of picoseconds
///
-template< fapi2::TargetType T >
-inline uint64_t cycles_to_ps(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+inline uint64_t cycles_to_ps(const uint64_t i_clock_period, const uint64_t i_cycles)
{
- // The frequency in mHZ
- uint64_t l_freq = 0;
- uint64_t l_clock_period = 0;
-
- FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );
- FAPI_TRY( freq_to_ps(l_freq, l_clock_period) );
- FAPI_INF("converting %llu cycles to %llups", i_cycles, i_cycles * l_clock_period );
- return i_cycles * l_clock_period;
-
-fapi_try_exit:
-
- // We simply can't work if we can't get the frequency or
- // if we get an unsupported value that can't be converted to a valid tCK (clock period)
- // ...so this should be ok
- FAPI_ERR("Can't get MSS_FREQ or obtained an invalid MSS_FREQ (%d) - stopping", l_freq);
- fapi2::Assert(false);
-
- // Keeps compiler happy
- return 0;
+ const auto l_ps = i_cycles * i_clock_period;
+ FAPI_INF("converting %llu cycles to %llups", i_cycles, l_ps );
+ return l_ps;
}
///
/// @brief Return the number of cycles contained in a count of microseconds
-/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_clock_period the clock period in PS
/// @param[in] i_us the number of microseconds to convert
/// @return uint64_t, the number of cycles
///
-template< fapi2::TargetType T >
-inline uint64_t us_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_us)
+inline uint64_t us_to_cycles(const uint64_t i_clock_period, const uint64_t i_us)
{
- return ps_to_cycles(i_target, i_us * CONVERT_PS_IN_A_US);
+ return ps_to_cycles(i_clock_period, i_us * CONVERT_PS_IN_A_US);
}
///
/// @brief Return the number of cycles contained in a count of nanoseconds
-/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_clock_period the clock period in PS
/// @param[in] i_ps the number of nanoseconds to convert
/// @return uint64_t, the number of cycles
///
-template< fapi2::TargetType T >
-inline uint64_t ns_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ns)
+inline uint64_t ns_to_cycles(const uint64_t i_clock_period, const uint64_t i_ns)
{
- return ps_to_cycles(i_target, i_ns * CONVERT_PS_IN_A_NS);
+ return ps_to_cycles(i_clock_period, i_ns * CONVERT_PS_IN_A_NS);
}
///
/// @brief Return the number of microseconds contained in a count of cycles
-/// @tparam T the target type
/// @tparam D the time conversion (NS_IN_PS, etc)
-/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_clock_period the clock period in PS
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of microseconds
///
-template< fapi2::TargetType T, uint64_t D >
-inline uint64_t cycles_to_time(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+template< uint64_t D >
+inline uint64_t cycles_to_time(const uint64_t i_clock_period, const uint64_t i_cycles)
{
// Hoping the compiler figures out how to do these together.
- uint64_t l_dividend = cycles_to_ps(i_target, i_cycles);
- uint64_t l_quotient = l_dividend / ((D == 0) ? 1 : D);
- uint64_t l_remainder = l_dividend % D;
+ const auto l_dividend = cycles_to_ps(i_clock_period, i_cycles);
+ constexpr uint64_t DIVISOR = ((D == 0) ? 1 : D);
+ const uint64_t l_quotient = l_dividend / DIVISOR;
+ const uint64_t l_remainder = l_dividend % DIVISOR;
// Make sure we add time if there wasn't an even number of cycles
return l_quotient + (l_remainder == 0 ? 0 : 1);
@@ -302,14 +263,15 @@ inline uint64_t cycles_to_time(const fapi2::Target<T>& i_target, const uint64_t
///
/// @brief Return the number of nanoseconds contained in a count of cycles
-/// @param[in] i_target target for the frequency attribute
+/// @tparam T the target type
+/// @tparam MC memory controller type
+/// @param[in] i_clock_period the clock period in PS
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of nanoseconds
///
-template< fapi2::TargetType T >
-inline uint64_t cycles_to_ns(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+inline uint64_t cycles_to_ns(const uint64_t i_clock_period, const uint64_t i_cycles)
{
- uint64_t l_ns = cycles_to_time<T, CONVERT_PS_IN_A_NS>(i_target, i_cycles);
+ const uint64_t l_ns = cycles_to_time<CONVERT_PS_IN_A_NS>(i_clock_period, i_cycles);
FAPI_INF("converting %llu cycles to %lluns", i_cycles, l_ns);
return l_ns;
@@ -317,14 +279,13 @@ inline uint64_t cycles_to_ns(const fapi2::Target<T>& i_target, const uint64_t i_
///
/// @brief Return the number of microseconds contained in a count of cycles
-/// @param[in] i_target target for the frequency attribute
+/// @param[in] i_clock_period the clock period in PS
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of microseconds
///
-template< fapi2::TargetType T >
-inline uint64_t cycles_to_us(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
+inline uint64_t cycles_to_us(const uint64_t i_clock_period, const uint64_t i_cycles)
{
- uint64_t l_us = cycles_to_time<T, CONVERT_PS_IN_A_US>(i_target, i_cycles);
+ const uint64_t l_us = cycles_to_time<CONVERT_PS_IN_A_US>(i_clock_period, i_cycles);
FAPI_INF("converting %llu cycles to %lluus", i_cycles, l_us);
return l_us;
@@ -361,41 +322,16 @@ inline T ps_to_ns(const T i_time_in_ps)
///
/// @brief Return the maximum of two values *in clocks*, the first in clocks the second in ns
-/// @tparam T the fapi2::TargetType of a type from which we can get MT/s
+/// @param[in] i_clock_period the clock period in PS
/// @param[in] i_clocks a value in clocks
/// @param[in] i_time a value in nanoseconds
/// @return max( iclocks nCK, i_time ) in clocks
///
-template< fapi2::TargetType T >
-inline uint64_t max_ck_ns(const fapi2::Target<T>& i_target, const uint64_t i_clocks, const uint64_t i_time)
+inline uint64_t max_ck_ns(const uint64_t i_clock_period, const uint64_t i_clocks, const uint64_t i_time)
{
- return std::max( i_clocks, ns_to_cycles(i_target, i_time) );
-}
-
-///
-/// @brief Return and estimated time an MCBIST subtest will take to complete
-/// Useful for initial polling delays, probably isn't accurate for much else
-/// as it doesn't take refresh in to account (which will necessarily slow down
-/// the program.)
-/// @param[in] i_target the target from which to gather memory frequency
-/// @param[in] i_bytes number of *bytes* in the address range
-/// @param[in] i_64B_per mss::YES if the command is 64B, mss::NO if it's 128B. Defaults to mss::YES
-/// @return the initial polling delay for this program in ns
-///
-template< fapi2::TargetType T >
-inline uint64_t calculate_initial_delay(const fapi2::Target<T>& i_target,
- const uint64_t i_bytes,
- const bool i_64B_per = mss::YES)
-{
- // TODO RTC: 164104 Update MCBIST delay calculator. As we learn more about what
- // the lab really needs, we can probably make this function better.
- const uint64_t l_bytes_per_cmd = (i_64B_per == mss::YES) ? 64 : 128;
-
- // Best case is a command takes 4 cycles. Given the number of commands and address space size
- // we can get some idea of how long to wait before we start polling.
- return cycles_to_ns(i_target, (i_bytes / l_bytes_per_cmd) * mss::CYCLES_PER_CMD);
+ return std::max( i_clocks, ns_to_cycles(i_clock_period, i_time) );
}
-};// mss namespace
+} // mss namespace
#endif
diff --git a/src/import/generic/memory/lib/utils/find.H b/src/import/generic/memory/lib/utils/find.H
index b8d6c7976..cb0ffab15 100644
--- a/src/import/generic/memory/lib/utils/find.H
+++ b/src/import/generic/memory/lib/utils/find.H
@@ -535,7 +535,8 @@ bool find_value_from_key(const std::vector<std::pair<T, OT> >& i_vector_of_pairs
// Did you find it? Let me know.
if( (l_value_iterator == i_vector_of_pairs.end()) || (i_key != l_value_iterator->first) )
{
- FAPI_INF("Did not find a mapping value to key: %d", i_key);
+ // Static cast ensures that the below print will not fail at compile time
+ FAPI_INF("Did not find a mapping value to key: %d", static_cast<uint64_t>(i_key));
return false;
}
@@ -551,12 +552,12 @@ bool find_value_from_key(const std::vector<std::pair<T, OT> >& i_vector_of_pairs
/// @param[in] i_vector_of_pairs the input vector of pairs
/// @param[in] i_value the "map" value, the second entry in the pairs
/// @param[out] o_key the first entry in the pair
-/// @return fapi2 ReturnCode fapi2::RC_SUCCESS if value found
+/// @return true if value is found, false otherwise
///
template<typename T, typename OT>
-fapi2::ReturnCode find_key_from_value(const std::vector<std::pair<T, OT> >& i_vector_of_pairs,
- const OT& i_value,
- T& o_key)
+bool find_key_from_value(const std::vector<std::pair<T, OT> >& i_vector_of_pairs,
+ const OT& i_value,
+ T& o_key)
{
// Comparator lambda expression
const auto compare = [&i_value](const std::pair<T, OT>& i_lhs)
@@ -572,12 +573,13 @@ fapi2::ReturnCode find_key_from_value(const std::vector<std::pair<T, OT> >& i_ve
// Did you find it? Let me know.
if( (l_value_iterator == i_vector_of_pairs.end()) || (i_value != l_value_iterator->second) )
{
- FAPI_ERR("Did not find a mapping key to value: %d", i_value);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ // Static cast ensures that the below print will not fail at compile time
+ FAPI_INF("Did not find a mapping key to value: %d", static_cast<uint64_t>(i_value));
+ return false;
}
o_key = l_value_iterator->first;
- return fapi2::FAPI2_RC_SUCCESS;
+ return true;
}// find_value_from_key
@@ -589,13 +591,13 @@ fapi2::ReturnCode find_key_from_value(const std::vector<std::pair<T, OT> >& i_ve
/// @param[in] i_array the input array of pairs
/// @param[in] i_key the "map" key
/// @param[in] o_value the value found from given key
-/// @return fapi2 ReturnCode fapi2::RC_SUCCESS if key found
+/// @return true if value is found, false otherwise
/// @note To use on short arrays. O(N), simple search
///
template<typename T, typename OT, size_t N>
-fapi2::ReturnCode find_value_from_key( const std::pair<T, OT> (&i_array)[N],
- const T& i_key,
- OT& o_value)
+bool find_value_from_key( const std::pair<T, OT> (&i_array)[N],
+ const T& i_key,
+ OT& o_value)
{
// TK Use sort and binary search for larger arrays
for (size_t i = 0; i < N; i++)
@@ -603,12 +605,12 @@ fapi2::ReturnCode find_value_from_key( const std::pair<T, OT> (&i_array)[N],
if (i_array[i].first == i_key)
{
o_value = i_array[i].second;
- return fapi2::FAPI2_RC_SUCCESS;
+ return true;
}
}
FAPI_ERR ("No match found for find_value_from_key");
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ return false;
}
///
diff --git a/src/import/generic/memory/lib/utils/poll.H b/src/import/generic/memory/lib/utils/poll.H
index 60322724e..061e462ae 100644
--- a/src/import/generic/memory/lib/utils/poll.H
+++ b/src/import/generic/memory/lib/utils/poll.H
@@ -40,7 +40,6 @@
#include <generic/memory/lib/utils/scom.H>
#include <lib/shared/mss_const.H>
-#include <lib/utils/conversions.H>
namespace mss
{
diff --git a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
index 9952519c8..ac7b104bd 100644
--- a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
+++ b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
@@ -43,20 +43,6 @@ namespace mss
{
///
-/// @brief Common conversions
-///
-enum conversions
-{
- CONVERT_PS_IN_A_NS = 1000, ///< 1000 pico in an nano
- CONVERT_PS_IN_A_US = 1000000, ///< 1000000 picos in a micro
- MHZ_TO_KHZ = 1000,
- SEC_IN_HOUR = 60 * 60, ///< seconds in an hour, used for scrub times
- NIBBLES_PER_BYTE = 2,
- BITS_PER_NIBBLE = 4,
- BITS_PER_BYTE = 8,
-};
-
-///
/// @brief FFDC generic codes
///
enum generic_ffdc_codes
@@ -93,8 +79,8 @@ enum generic_ffdc_codes
TWTR_L_MIN = 0x101A,
DEVICE_TYPE = 0x101B,
BASE_MODULE_TYPE = 0x101C,
- BAD_SPD_DATA = 0x101C,
- SET_FIELD = 0x101D,
+ BAD_SPD_DATA = 0x101D,
+ SET_FIELD = 0x101E,
};
///
@@ -107,10 +93,22 @@ enum proc_type
};
///
-/// @brief JEDEC supported DDR4 speeds
+/// @brief Supported memory controller types
+///
+enum class mc_type
+{
+ NIMBUS,
+ CENTAUR,
+ EXPLORER,
+};
+
+///
+/// @brief JEDEC supported DDR speeds
+/// @note Includes DDR4 and DDR5 only
///
-enum ddr4_dimm_speeds
+enum ddr_dimm_speeds
{
+ // Supported frequencies
DIMM_SPEED_1600 = 1600,
DIMM_SPEED_1866 = 1866,
DIMM_SPEED_2133 = 2133,
@@ -118,6 +116,16 @@ enum ddr4_dimm_speeds
DIMM_SPEED_2666 = 2666,
DIMM_SPEED_2933 = 2933,
DIMM_SPEED_3200 = 3200,
+ DIMM_SPEED_3600 = 3600,
+ DIMM_SPEED_4000 = 4000,
+ DIMM_SPEED_4400 = 4400,
+ DIMM_SPEED_4800 = 4800,
+
+ // Max/Mins for specific generations here
+ DDR4_MIN_SPEED = 1600,
+ DDR4_MAX_SPEED = 3200,
+ DDR5_MIN_SPEED = 3200,
+ DDR5_MAX_SPEED = 4800,
};
namespace spd
@@ -182,6 +190,28 @@ enum guard_band : uint16_t
};
}// spd
+
+enum conversions
+{
+ NIBBLES_PER_BYTE = 2,
+ BITS_PER_NIBBLE = 4,
+ BITS_PER_BYTE = 8,
+
+ 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
+ DELAY_1US = 1000, ///< general purpose 1 usec delay for HW mode
+ DELAY_10US = 10000, ///< general purpose 1 usec delay for HW mode
+ DELAY_100US = 100000, ///< general purpose 100 usec delay for HW mode
+ DELAY_1MS = 1000000, ///< general purpose 1 ms delay for HW mode
+
+ MHZ_TO_KHZ = 1000,
+ SEC_IN_HOUR = 60 * 60, ///< seconds in an hour, used for scrub times
+};
+
}// mss
#endif
diff --git a/src/import/generic/xml/error_info/generic_error.xml b/src/import/generic/xml/error_info/generic_error.xml
index 21ee53fab..821c5047d 100644
--- a/src/import/generic/xml/error_info/generic_error.xml
+++ b/src/import/generic/xml/error_info/generic_error.xml
@@ -30,11 +30,35 @@
<!-- *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -->
<!-- *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com> -->
-<!-- *HWP FW Owner: Bill Hoffa <wghoffa@us.ibm.com> -->
<!-- *HWP Team: Memory -->
<!-- *HWP Level: 3 -->
<!-- *HWP Consumed by: HB:FSP -->
<!-- -->
<hwpErrors>
+
+<hwpError>
+ <rc>RC_MSS_INVALID_FREQUENCY</rc>
+ <description>
+ An invalid frequency was passed to frequency to clock period
+ </description>
+ <ffdc>FREQ</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+</hwpError>
+
+<hwpError>
+ <rc>RC_MSS_INVALID_CLOCK_PERIOD</rc>
+ <description>
+ An invalid clock period was passed to clock period to frequency
+ </description>
+ <ffdc>CLOCK_PERIOD</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+</hwpError>
+
</hwpErrors>
diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk
index cfb411ff5..b49f515a1 100755
--- a/src/usr/fapi2/fapi2.mk
+++ b/src/usr/fapi2/fapi2.mk
@@ -116,6 +116,8 @@ FAPI2_ERROR_XML += $(wildcard \
$(ROOTPATH)/src/import/hwpf/fapi2/xml/error_info/*.xml)
FAPI2_ERROR_XML += $(wildcard \
$(ROOTPATH)/src/import/chips/centaur/procedures/xml/error_info/*.xml)
+FAPI2_ERROR_XML += $(wildcard \
+ $(ROOTPATH)/src/import/generic/xml/error_info/*.xml)
# Attribute XML files.
FAPI2_ATTR_XML += $(wildcard \
OpenPOWER on IntegriCloud