diff options
Diffstat (limited to 'src')
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 \ |