diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/utils')
3 files changed, 170 insertions, 98 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/checker.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/checker.H index a91715876..f71578e82 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/checker.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/checker.H @@ -48,7 +48,7 @@ inline fapi2::ReturnCode dram_type(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& uint8_t l_dram_gen[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {0}; // Retrieve DDR4 dimm attributes - FAPI_TRY(spd_dram_device_type(i_target_mcs, &(l_dram_gen[0][0]))); + FAPI_TRY(eff_dram_gen(i_target_mcs, &(l_dram_gen[0][0]))); // Make sure all DRAMs are DDR4 or throw an error // Iterate through MCA's/ports @@ -66,7 +66,7 @@ inline fapi2::ReturnCode dram_type(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& l_dram_gen[port_num][dimm_num]); // Nimbus supports only DDR4 - FAPI_ASSERT(l_dram_gen[port_num][dimm_num] == fapi2::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR4, + FAPI_ASSERT(l_dram_gen[port_num][dimm_num] == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4, fapi2::MSS_UNSUPPORTED_DEV_TYPE(). set_DEV_TYPE(l_dram_gen[port_num][dimm_num]), "%s Incorrect DRAM device generation, DRAM generation is %llx", @@ -82,17 +82,14 @@ fapi_try_exit: /// -/// @brief Check if there is DIMM mixing (and deconfigures unsupported mixing <shrug> ?? - AAM) -/// @param[in] i_target_mcs const fapi2::Target<fapi2::TARGET_TYPE_MCS>& -/// @param[out] o_module_type uint64_t (returns something ?? - AAM ) +/// @brief Check if there is DIMM mixing (and deconfigures unsupported mixing ?? - AAM) /// @return FAPI2_RC_SUCCESS iff ok /// @note Functionality currently unknown /// -inline fapi2::ReturnCode dimm_mixing(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs, - uint64_t& o_module_type) +inline fapi2::ReturnCode dimm_mixing(void) { - //TODO - //Need to complete - AAM + //FIX p8 ported code + //Need to complete and figure out how to implement for p9 - AAM // Anuwat pushed Warren to say IBM systems will not support DIMM mixing // Now DIMM deconfig rules? - AAM @@ -137,12 +134,13 @@ inline fapi2::ReturnCode dimm_mixing(const fapi2::Target<fapi2::TARGET_TYPE_MCS> }// dimm_mixing /// -/// @brief Checks what type of system is configured (i.e., single drop, dual drop) -/// @note Functionality currently unknown +/// @brief Checks what type of system is configured (i.e., single drop, dual drop) +/// @return FAPI2_RC_SUCCESS iff ok +/// @warning Functionality currently unknown. Used in mss_freq /// inline fapi2::ReturnCode system_drop_type(void) { - //TODO + //Update for P9, how will we check if a system is single/dual drop?? - AAM #if 0 @@ -190,12 +188,12 @@ fapi_try_exit: /// /// @brief Checks nominal voltage is correct for all DIMMs -/// @param[in] i_target_mcsi const fapi2::Target<fapi2::TARGET_TYPE_MCS>&, -/// dimm_state i fapi2::TargetState -/// @return ReturnCode +/// @param[in] i_target_mcs the fapi2 target +/// @param[in] i_dimm_state (i.e. functional or non-functional) +/// @return ReturnCode /// inline fapi2::ReturnCode module_nominal_voltage(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs, - fapi2::TargetState dimm_state) + fapi2::TargetState i_dimm_state) { uint64_t l_module_nom_voltage[mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {0}; @@ -207,7 +205,7 @@ inline fapi2::ReturnCode module_nominal_voltage(const fapi2::Target<fapi2::TARGE auto port_num = mss::index(p); // Iterate through DIMM targets - for (auto d : p.getChildren<fapi2::TARGET_TYPE_DIMM>(dimm_state)) + for (auto d : p.getChildren<fapi2::TARGET_TYPE_DIMM>(i_dimm_state)) { auto dimm_num = mss::index(d); @@ -231,66 +229,98 @@ fapi_try_exit: namespace spd { + /// /// @brief Checks conditional passes and implements traces & exits if it fails -/// @tparam T spd_data of any size -/// @param[in] i_target const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& , -/// conditional bool, -/// spd_byte_index size_t, -// spd_data T, -/// err_str const char* +/// @tparam T input data of any size +/// @param[in] i_target fapi2 dimm target +/// @param[in] i_conditional conditional that we are testing against +/// @param[in] i_spd_byte_index current SPD byte +/// @param[in] i_spd_data debug data +/// @param[in] i_err_str error string to print out when conditional fails /// @return ReturnCode /// template< typename T > -inline fapi2::ReturnCode valid_value_fail(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - bool conditional, - size_t spd_byte_index, - T spd_data, - const char* err_str) +inline fapi2::ReturnCode fail_for_invalid_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + bool i_conditional, + size_t i_spd_byte_index, + T i_spd_data, + const char* i_err_str) { - FAPI_ASSERT(conditional, - fapi2::MSS_SPD_DECODE_INVALID_VALUE(). - set_VALUE(spd_data). - set_BYTE(spd_byte_index). + FAPI_ASSERT(i_conditional, + fapi2::MSS_BAD_SPD(). + set_VALUE(i_spd_data). + set_BYTE(i_spd_byte_index). set_DIMM_TARGET(i_target), "%s %s Byte %d, Data returned: %d.", c_str(i_target), - err_str, - spd_byte_index, - spd_data); + i_err_str, + i_spd_byte_index, + i_spd_data); fapi_try_exit: return fapi2::current_err; -} // invalid_value_fail() +} // fail_for_invalid_value() /// -/// @brief Checks conditional passes and implements traces if it fails -/// @tparam T spd_data of any size -/// @param[in] i_targeti const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& , -/// conditional bool, -/// spd_byte_index size_t, -// spd_data T, -/// err_str const char* +/// @brief Checks conditional passes and implements traces if it fails. No FFDC collected. +/// @tparam T input data of any size +/// @param[in] i_target fapi2 dimm target +/// @param[in] i_conditional that we are testing against +/// @param[in] i_spd_byte_index +/// @param[in] i_spd_data debug data +/// @param[in] i_err_str string to print out when conditional fails /// @return void /// template< typename T > -inline void valid_value_warn(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - bool conditional, - size_t spd_byte_index, - T spd_data, - const char* err_str) +inline void warn_for_invalid_value(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + bool i_conditional, + size_t i_spd_byte_index, + T i_spd_data, + const char* i_err_str) { // Don't print warning conditional is true - if(!conditional) + if(!i_conditional) { FAPI_IMP("%s. %s. Byte %d, Data returned: %d.", c_str(i_target), - err_str, - spd_byte_index, - spd_data ); + i_err_str, + i_spd_byte_index, + i_spd_data ); } -}// valid_value_warn +}// warn_for_invalid_value + +/// +/// @brief Checks if valid factory parameters are given +/// @param[in] i_target fapi2 dimm target +/// @param[in] i_dimm_type DIMM type enumeration +/// @param[in] i_encoding_rev SPD encoding level rev number +/// @param[in] i_additions_rev SPD additions level rev number +/// @param[in] i_err_str string to print out when conditional fails +/// @return fapi2::ReturnCode +/// +inline fapi2::ReturnCode invalid_factory_sel(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + uint8_t i_dimm_type, + uint8_t i_encoding_rev, + uint8_t i_additions_rev, + const char* i_err_str) +{ + FAPI_ASSERT(false, + fapi2::MSS_INVALID_DIMM_REV_COMBO(). + set_DIMM_TYPE(i_dimm_type). + set_ENCODING_REV(i_encoding_rev). + set_ADDITIONS_REV(i_additions_rev). + set_DIMM_TARGET(i_target), + "%s. %s. Invalid combination for dimm type: %d, rev: %d.%d", + c_str(i_target), + i_err_str, + i_dimm_type, + i_encoding_rev, + i_additions_rev); +fapi_try_exit: + return fapi2::current_err; +}// invalid_factory_sel }// spd }// check diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H index c39ebf057..70c58289d 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/conversions.H @@ -42,36 +42,40 @@ static const uint64_t SIM_CYCLES_PER_CYCLE = 8; namespace mss { + +/// +/// @brief Return the number of picoseconds +/// @tparam T input and output type +/// @param[in] i_transfer_rate input in MegaTransfers per second (MT/s) +/// @return timing in picoseconds +/// @note clock periods are defined to 1 ps of accuracy, so +/// so 1.0714 ns is defined as 1071 ps as defined by JEDEC's +/// SPD rounding algorithm. This concept is used for this calculation. +/// +template<typename T> +inline T freq_to_ps(const T i_transfer_rate) +{ + // ATTR_MSS_FREQ is in MT/s, and we know microsecond per clock is 1/(freq/2) + // actual dimm_freq is 1/2 of the speed bin + T l_dimm_freq = i_transfer_rate / 2; + + // ps per clock (note value is rounded down) + return CONVERT_PS_IN_A_US / l_dimm_freq; +} + /// -/// @brief Return the number of picoseconds taken by a certain mhz -/// @param[in] i_mhz the mhz of interest -/// @return the picoseconds +/// @brief Return the number in MT/s +/// @tparam T input and output type +/// @param[in] i_time_in_ps time in picoseconds +/// @return speed in MT/s /// -inline uint64_t mhz_to_ps(const uint64_t i_mhz) +template<typename T> +inline T ps_to_freq(const T i_time_in_ps) { - // Just used for indexs into the array below - enum freqs { FREQ_2400 = 0, }; - - // ATTR_MSS_FREQ is in mHZ, and we know us per clock is 1/(freq/2) - // We don't have many frequencies, so lets just make a little table. - static const uint64_t FREQ_TO_PS[MAX_SUPPORTED_FREQUENCIES] = - { - // 2400 is 833 picoseconds per clock - 833 - }; - - switch(i_mhz) - { - case 2400: - return FREQ_TO_PS[FREQ_2400]; - - default: - FAPI_ERR("unsupported frequency %llu", i_mhz); - fapi2::Assert(false); - - // Keeps compiler happy - return 0; - } + // reverse of freq_to_ps function, solving for freq + // since running at DDR, data is transferred on both rising & falling edges + // hence the 2X factor + return (2 * CONVERT_PS_IN_A_US) / i_time_in_ps; } /// @@ -95,7 +99,7 @@ template< fapi2::TargetType T > inline uint64_t ps_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ps) { // The frequency in mHZ - uint64_t l_freq; + uint64_t l_freq = 0; uint64_t l_divisor = 0; uint64_t l_quotient = 0; uint64_t l_remainder = 0; @@ -103,7 +107,7 @@ inline uint64_t ps_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) ); // Hoping the compiler figures out how to do these together. - l_divisor = mhz_to_ps(l_freq); + l_divisor = freq_to_ps(l_freq); l_quotient = i_ps / l_divisor; l_remainder = i_ps % l_divisor; @@ -132,12 +136,12 @@ 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; + uint64_t l_freq = 0; FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) ); - FAPI_DBG("converting %llu cycles to %llups", i_cycles, i_cycles * mhz_to_ps(l_freq)); - return i_cycles * mhz_to_ps(l_freq); + FAPI_DBG("converting %llu cycles to %llups", i_cycles, i_cycles * freq_to_ps(l_freq)); + return i_cycles * freq_to_ps(l_freq); fapi_try_exit: @@ -236,28 +240,33 @@ inline uint64_t twlo_twloe(const fapi2::Target<T>& i_target) } /// -/// @brief Convert nanoseconds to picoseconds -/// @param[in] i_time_in_ns int64_t time in nanoseconds -/// @return int64_t, time in picoseconds +/// @brief Convert nanoseconds to picoseconds +/// @tparam T input and output type +/// @param[in] i_time_in_ns time in nanoseconds +/// @return time in picoseconds /// -inline int64_t ns_to_ps(const int64_t& i_time_in_ns) +template<typename T> +inline T ns_to_ps(const T i_time_in_ns) { return i_time_in_ns * CONVERT_PS_IN_A_NS; } /// -/// @brief Convert nanoseconds to picoseconds -/// @param[in] i_time_in_ps int64_t time in picoseconds -/// @return int64_t, time in nanoseconds +/// @brief Convert nanoseconds to picoseconds +/// @tparam T input and output type +/// @param[in] i_time_in_ps time in picoseconds +/// @return time in nanoseconds /// -inline int64_t ps_to_ns(const int64_t& i_time_in_ps) +template<typename T> +inline T ps_to_ns(const T i_time_in_ps) { - int64_t remainder = i_time_in_ps % CONVERT_PS_IN_A_NS; - int64_t l_time_in_ns = i_time_in_ps / CONVERT_PS_IN_A_NS; + T remainder = i_time_in_ps % CONVERT_PS_IN_A_NS; + T l_time_in_ns = i_time_in_ps / CONVERT_PS_IN_A_NS; // Round up if remainder isn't even return l_time_in_ns + ( remainder == 0 ? 0 : 1 ); } };// mss namespace + #endif diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H index a13c1cd62..e15563970 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H @@ -43,17 +43,17 @@ namespace mss /// @return a vector of M targets. /// template< fapi2::TargetType M, fapi2::TargetType T > -inline std::vector< fapi2::Target<M> > find_targets( const fapi2::Target<T>& ); +inline std::vector< fapi2::Target<M> > find_targets( const fapi2::Target<T>& i_target); /// /// @brief find an element based on a fapi2 target /// @tparam M the target type to be returned /// @tparam T the fapi2 target type of the argument -/// @param[in] the fapi2 target T +/// @param[in] i_target the fapi2 target T /// @return an M target. /// template< fapi2::TargetType M, fapi2::TargetType T > -inline fapi2::Target<M> find_target( const fapi2::Target<T>& ); +inline fapi2::Target<M> find_target( const fapi2::Target<T>& i_target ); /// /// @brief find the McBIST given a McBIST @@ -182,6 +182,39 @@ inline fapi2::Target<fapi2::TARGET_TYPE_MCA> find_target( const fapi2::Target<fa return i_target.getParent<fapi2::TARGET_TYPE_MCA>(); } +/// +/// @brief find a key value from a vector of STL pairs +/// @tparam T input type +/// @tparam OT the output type to be returned +/// @param[in] i_vector_of_pairs the input vector of pairs +/// @param[in] i_key the "map" key +/// @param[in] o_value the value found from given key +/// @return the value corresponding to the key +/// +template<typename T, typename OT> +bool find_value_from_key(const std::vector<std::pair<T, OT> >& i_vector_of_pairs, const T& i_key, OT& o_value) +{ + // Comparator lambda expression + auto compare = [](const std::pair<T, OT>& i_lhs, const T & i_value) + { + return (i_lhs.first < i_value); + }; + + // Find iterator to matching key (if it exists) + auto l_value_iterator = std::lower_bound(i_vector_of_pairs.begin(), i_vector_of_pairs.end(), i_key, compare); + + // Did you find it? Let me know. + if( (l_value_iterator == i_vector_of_pairs.end()) || (i_key != l_value_iterator->first) ) + { + return false; + } + + o_value = l_value_iterator->second; + return true; + +} + + }// mss #endif |