diff options
author | Jacob Harvey <jlharvey@us.ibm.com> | 2017-02-28 12:59:13 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-06-11 14:39:59 -0400 |
commit | b79fd9671a34ff842b4c1d5beb6695feb5dc5b62 (patch) | |
tree | 5cce1cc047dd54903e82ca51c68741a367b59e55 /src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H | |
parent | 987752d8494c4ac2f0dac41b72c21b5cbb0d0488 (diff) | |
download | talos-hostboot-b79fd9671a34ff842b4c1d5beb6695feb5dc5b62.tar.gz talos-hostboot-b79fd9671a34ff842b4c1d5beb6695feb5dc5b62.zip |
Cleaning up error handling for mss_freq L3
Change-Id: I799ed61062720822e8225efa8d0381a4c73a879c
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37283
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37313
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H | 77 |
1 files changed, 72 insertions, 5 deletions
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 a5d8dfaff..3c3b89d7e 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 @@ -27,7 +27,7 @@ /// @brief Synchronous function implementations /// // *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> -// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com> +// *HWP HWP Backup: Jacob Harvey <jlharvey@us.ibm.com> // *HWP Team: Memory // *HWP Level: 3 // *HWP Consumed by: HB:FSP @@ -50,6 +50,24 @@ enum class speed_equality : uint8_t }; /// +/// @brief Checks to see if a passed in value could be a valid nest frequency +/// @param[in] i_proposed_freq a frequency value that is to be checked +/// @return boolean true, false whether the value is a valid nest frequency +/// +inline bool is_nest_freq_valid (const uint64_t i_proposed_freq) +{ + std::vector<uint64_t> l_nest_freqs_supported = { fapi2::ENUM_ATTR_FREQ_PB_MHZ_1600, + fapi2::ENUM_ATTR_FREQ_PB_MHZ_1866, + fapi2::ENUM_ATTR_FREQ_PB_MHZ_2000, + fapi2::ENUM_ATTR_FREQ_PB_MHZ_2133, + fapi2::ENUM_ATTR_FREQ_PB_MHZ_2400 + }; + std::sort(l_nest_freqs_supported.begin(), l_nest_freqs_supported.end()); + + return ( std::binary_search(l_nest_freqs_supported.begin(), l_nest_freqs_supported.end(), i_proposed_freq) ); +} + +/// /// @brief Retrieves a mapping of MSS frequency values per mcbist target /// @param[in] i_targets vector of controller targets /// @param[out] o_freq_map dimm speed map <key, value> = (mcbist target, frequency) @@ -94,7 +112,7 @@ fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_T /// @param[in] vector of MVPD freqs /// @param[in] vector of max allowed freqs /// @param[in] bool whether or not we're forced into sync mode -/// @param[in,out] reference to a std::vector<uint32_t> space to put the sorted vector +/// @param[out] reference to a std::vector<uint32_t> space to put the sorted vector /// @return FAPI2_RC_SUCCESS iff ok /// @note Taken from ATTR_MSS_MRW_SUPPORTED_FREQ. The result is sorted so such that the min /// supported freq is std::vector<>.begin and the max is std::vector<>.end - 1. You can @@ -104,19 +122,19 @@ fapi2::ReturnCode supported_freqs_helper(const fapi2::Target<fapi2::TARGET_TYPE_ const std::vector<uint32_t>& i_freqs, const std::vector<uint32_t>& i_max_freqs, const bool i_req_sync_mode, - std::vector<uint32_t>& io_freqs); + std::vector<uint32_t>& o_freqs); /// /// @brief Create and sort a vector of supported MT/s (freq) /// @param[in] MCA target for which to get the DIMM configs -/// @param[in,out] reference to a std::vector<uint32_t> space to put the sorted vector +/// @param[out] reference to a std::vector<uint32_t> space to put the sorted vector /// @return FAPI2_RC_SUCCESS iff ok /// @note Taken from ATTR_MSS_MRW_SUPPORTED_FREQ. The result is sorted so such that the min /// supported freq is std::vector<>.begin and the max is std::vector<>.end - 1. You can /// search the resulting vector for valid frequencies as it is sorted. /// fapi2::ReturnCode supported_freqs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, - std::vector<uint32_t>& io_freqs); + std::vector<uint32_t>& o_freqs); /// /// @brief Return whether a given freq is supported @@ -126,6 +144,55 @@ fapi2::ReturnCode supported_freqs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i /// bool is_freq_supported(const uint32_t i_freq, const std::vector<uint32_t>& i_freqs); +/// +/// @brief Selects DIMM frequency to run based on supported system frequencies +/// @tparam T the fapi2::TargetType for which the DIMM information exists. +/// @param[in] target from which to get the dimm information +/// @param[in,out] io_dimm_freq input is current dimm freq & output is next +/// lowest dimm freq between 1866 MT/s (-5% margin) - 2666 MT/s (+5% margin) +/// @return FAPI2_RC_SUCCESS iff ok +/// @note Frequency values obtained from: +/// @note From P9 User's Manual Version 0.8 - June 08, 2015 +/// @note Memory Controller Unit - page 199 of 456 +/// +template< fapi2::TargetType T > +inline fapi2::ReturnCode select_supported_freq(const fapi2::Target<T>& i_target, uint64_t& io_dimm_freq) +{ + std::vector<uint32_t> l_freqs; + + FAPI_TRY( mss::supported_freqs(i_target, l_freqs) ); + + { + // supported_freqs sorts so upper_bound is valid. + auto iterator = std::upper_bound(l_freqs.begin(), l_freqs.end(), io_dimm_freq); + + auto l_supported = l_freqs.begin(); + + // Doing this because the HB compiler freaks out if we have it within the FAPI_ASSERT. + // Outputting the value and then incrementing the iterator, that's why it's a post increment + const auto l_0 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0; + const auto l_1 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0; + const auto l_2 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0; + const auto l_3 = (l_supported != l_freqs.end()) ? *(l_supported++) : 0; + + FAPI_ASSERT( (iterator != l_freqs.begin() && l_freqs.size() != 0), + fapi2::MSS_SELECTED_FREQ_NOT_SUPPORTED() + .set_FREQ(io_dimm_freq) + .set_SUPPORTED_FREQ_0( l_0 ) + .set_SUPPORTED_FREQ_1( l_1 ) + .set_SUPPORTED_FREQ_2( l_2 ) + .set_SUPPORTED_FREQ_3( l_3 ) + .set_TARGET(i_target), + "%s Error finding selected freq (%d) from list", + mss::c_str(i_target), + io_dimm_freq ); + // Upper bound checks just greater than, not equals. Return one up + io_dimm_freq = *(--iterator); + } + +fapi_try_exit: + return fapi2::current_err; +} }// mss |