diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/eff_config')
4 files changed, 302 insertions, 125 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C index ef49471e9..aeb61f126 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -25,9 +25,8 @@ /// @file attr_setters.C /// @brief Create setter functions for mss attributes /// -// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com> +// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com> // *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com> -// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com> // *HWP Team: Memory // *HWP Level: 3 // *HWP Consumed by: HB:FSP @@ -35,27 +34,62 @@ #include <fapi2.H> #include <generic/memory/lib/utils/find.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> +#include <generic/memory/lib/data_engine/pre_data_init.H> namespace mss { + /// /// @brief Set ATTR_MSS_VOLT_VDDR and ATTR_MSS_VOLT_VPP /// @param[in] i_target_mcs the MCS target -/// @param[in] l_selected_dram_voltage the voltage in millivolts for nominal voltage -/// @param[in] l_selected_dram_voltage_vpp voltage in millivolts for the VPP +/// @param[in] i_selected_dram_voltage the voltage in millivolts for nominal voltage +/// @param[in] i_selected_dram_voltage_vpp voltage in millivolts for the VPP +/// @note dram_voltage and dram_voltage_vpp are not const due to FAPI_ATTR_SET template deduction /// @return FAPI2_RC_SUCCESS iff ok /// - fapi2::ReturnCode set_voltage_attributes(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs, - uint32_t l_selected_dram_voltage, - uint32_t l_selected_dram_voltage_vpp) + uint32_t i_selected_dram_voltage, + uint32_t i_selected_dram_voltage_vpp) { const auto l_target_mcbist = find_target<fapi2::TARGET_TYPE_MCBIST>(i_target_mcs); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VDDR, l_target_mcbist, l_selected_dram_voltage) ); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VPP, l_target_mcbist, l_selected_dram_voltage_vpp) ); + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VDDR, l_target_mcbist, i_selected_dram_voltage) ); + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VPP, l_target_mcbist, i_selected_dram_voltage_vpp) ); fapi_try_exit: return fapi2::current_err; } + +/// +/// @brief Sets pre_eff_config attributes +/// @param[in] i_target the DIMM target +/// @param[in] i_spd_decoder SPD decoder +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode set_pre_init_attrs( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const spd::facade& i_spd_decoder ) +{ + fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS); + mss::pre_data_engine<mss::NIMBUS> l_data_engine(i_target, i_spd_decoder, l_rc); + FAPI_TRY(l_rc, "Failed to instantiate pre_data_engine object for %s", spd::c_str(i_target)); + + // Set attributes needed before eff_config + // DIMM type and DRAM gen are needed for c_str to aid debugging + FAPI_TRY(l_data_engine.set_dimm_type(), "Failed to set DIMM type %s", spd::c_str(i_target) ); + FAPI_TRY(l_data_engine.set_dram_gen(), "Failed to set DRAM gen %s", spd::c_str(i_target) ); + + // Hybrid and hybrid media help detect hybrid modules, specifically NVDIMMs for Nimbus + FAPI_TRY(l_data_engine.set_hybrid(), "Failed to set Hybrid %s", spd::c_str(i_target) ); + FAPI_TRY(l_data_engine.set_hybrid_media(), "Failed to set Hybrid Media %s", spd::c_str(i_target) ); + + // Number of master ranks needed for VPD decoding + // and dimm_ranks_configured is a PRD attr... + FAPI_TRY(l_data_engine.set_master_ranks(), "Failed to set Master ranks %s", spd::c_str(i_target) ); + FAPI_TRY(l_data_engine.set_dimm_ranks_configured(), "Failed to set DIMM ranks configured %s", spd::c_str(i_target) ); + +fapi_try_exit: + return fapi2::current_err; +} + } // mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H index 793d92fc9..976c1077d 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/attr_setters.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -27,37 +27,41 @@ /// @file attr_setters.H /// @brief Create setter functions for mss attributes /// -// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com> +// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com> // *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com> -// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com> // *HWP Team: Memory // *HWP Level: 3 // *HWP Consumed by: HB:FSP - - - #ifndef _MSS_ATTR_SETTERS_H_ #define _MSS_ATTR_SETTERS_H_ #include <fapi2.H> - - +#include <generic/memory/lib/spd/spd_facade.H> namespace mss { + /// /// @brief Set ATTR_MSS_VOLT_VDDR and ATTR_MSS_VOLT_VPP /// @param[in] i_target_mcs the MCS target -/// @param[in] l_selected_dram_voltage the voltage in millivolts for nominal voltage -/// @param[in] l_selected_dram_voltage_vpp voltage in millivolts for the VPP +/// @param[in] i_selected_dram_voltage the voltage in millivolts for nominal voltage +/// @param[in] i_selected_dram_voltage_vpp voltage in millivolts for the VPP +/// @note dram_voltage and dram_voltage_vpp are not const due to FAPI_ATTR_SET template deduction /// @return FAPI2_RC_SUCCESS iff ok /// - fapi2::ReturnCode set_voltage_attributes(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs, - uint32_t l_selected_dram_voltage, - uint32_t l_selected_dram_voltage_vpp); + uint32_t i_selected_dram_voltage, + uint32_t i_selected_dram_voltage_vpp); +/// +/// @brief Sets pre_eff_config attributes +/// @param[in] i_target the DIMM target +/// @param[in] i_spd_decoder SPD decoder +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode set_pre_init_attrs( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const spd::facade& i_spd_decoder ); } // mss #endif diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C new file mode 100644 index 000000000..7cf3b7b3d --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C @@ -0,0 +1,239 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/nimbus_pre_data_engine.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file nimbus_pre_data_engine.C +/// @brief pre_data_engine implimentation for Nimbus +/// +// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com> +// *HWP FW Owner: Stephen Glancy <sglancy@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: CI + +#include <generic/memory/lib/utils/index.H> +#include <lib/mss_attribute_accessors.H> +#include <lib/eff_config/attr_setters.H> +#include <generic/memory/lib/data_engine/pre_data_init.H> +#include <generic/memory/lib/utils/find.H> + +namespace mss +{ + +// ========================================================= +// DDR4 SPD Document Release 4 +// Byte 2 (0x002): Key Byte / DRAM Device Type +// ========================================================= +const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::DRAM_GEN_MAP = +{ + //{key value, dram gen} + {0x0C, fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4} + // Other key bytes reserved or not supported +}; + +// ========================================================= +// DDR4 SPD Document Release 4 +// Byte 3 (0x003): Key Byte / Module Type - Hybrid +// ========================================================= +const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::HYBRID_MAP = +{ + //{key byte, dimm type} + {0, fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID}, + {1, fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID}, + // All others reserved or not supported +}; + + +// ========================================================= +// DDR4 SPD Document Release 4 +// Byte 3 (0x003): Key Byte / Module Type - Hybrid +// ========================================================= +const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::HYBRID_MEMORY_TYPE_MAP = +{ + + //{key byte, dimm type} + {0, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE}, + {1, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM}, + // All others reserved or not supported +}; + +// ========================================================= +// DDR4 SPD Document Release 4 +// Byte 3 (0x003): Key Byte / Module Type +// ========================================================= +const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::BASE_MODULE_TYPE_MAP = +{ + //{key byte, dimm type} + {1, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM}, + {2, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM}, + {4, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM}, + // All others reserved or not supported +}; + +// ========================================================= +// DDR4 SPD Document Release 4 +// Byte 12 (0x00C): Module Organization +// ========================================================= +const std::vector< std::pair<uint8_t, uint8_t> > pre_data_engine<NIMBUS>::NUM_PACKAGE_RANKS_MAP = +{ + // {key byte, num of package ranks per DIMM (package ranks)} + {0, 1}, + {1, 2}, + {2, 3}, + {3, 4}, + {4, 5}, + {5, 6}, + {6, 7}, + {7, 8}, +}; + +/// +/// @brief ctor +/// @param[in] i_target the DIMM target +/// @param[in] i_spd_data SPD data +/// @param[out] o_rc ReturnCode for failure to init object +/// +pre_data_engine<NIMBUS>::pre_data_engine(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const spd::facade& i_spd_data, + fapi2::ReturnCode& o_rc): + iv_dimm(i_target), + iv_spd_data(i_spd_data) +{ + // Sets up commonly used member variables + uint8_t l_master_ranks = 0; + FAPI_TRY(iv_spd_data.num_package_ranks_per_dimm(l_master_ranks)); + FAPI_TRY(lookup_table_check(i_target, NUM_PACKAGE_RANKS_MAP, PRE_DATA_ENGINE_CTOR, l_master_ranks, iv_master_ranks)); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; + return; +} + +/// +/// @brief Set ATTR_EFF_DIMM_TYPE +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dimm_type() +{ + uint8_t l_base_module_type = 0; + uint8_t l_dimm_type = 0; + + FAPI_TRY(iv_spd_data.base_module(l_base_module_type)); + FAPI_TRY(lookup_table_check(iv_dimm, BASE_MODULE_TYPE_MAP, SET_ATTR_DIMM_TYPE, l_base_module_type, l_dimm_type)); + FAPI_TRY( (set_field<NIMBUS, DIMM_TYPE>(iv_dimm, l_dimm_type)) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Set ATTR_EFF_DRAM_GEN +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dram_gen() +{ + uint8_t l_device_type = 0; + uint8_t l_dram_gen = 0; + + FAPI_TRY(iv_spd_data.device_type(l_device_type)); + FAPI_TRY(lookup_table_check(iv_dimm, DRAM_GEN_MAP, SET_ATTR_DRAM_GEN, l_device_type, l_dram_gen)); + + FAPI_TRY( (set_field<NIMBUS, DRAM_GEN>(iv_dimm, l_dram_gen)) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Set ATTR_EFF_HYBRID +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode pre_data_engine<NIMBUS>::set_hybrid() +{ + uint8_t l_spd_hybrid_type = 0; + uint8_t l_hybrid = 0; + + FAPI_TRY(iv_spd_data.hybrid(l_spd_hybrid_type)); + FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_type, l_hybrid)); + + FAPI_TRY( (set_field<NIMBUS, HYBRID>(iv_dimm, l_hybrid)) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Set ATTR_EFF_HYBRID_MEMORY_TYPE +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode pre_data_engine<NIMBUS>::set_hybrid_media() +{ + uint8_t l_hybrid_media = 0; + uint8_t l_spd_hybrid_media = 0; + + FAPI_TRY(iv_spd_data.hybrid_media(l_spd_hybrid_media)); + FAPI_TRY(lookup_table_check(iv_dimm, HYBRID_MAP, SET_ATTR_HYBRID, l_spd_hybrid_media, l_hybrid_media)); + + FAPI_TRY( (set_field<NIMBUS, HYBRID_MEDIA>(iv_dimm, l_hybrid_media)) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Set ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM +/// @return FAPI2_RC_SUCCESS iff ok +/// +fapi2::ReturnCode pre_data_engine<NIMBUS>::set_master_ranks() +{ + FAPI_TRY( (set_field<NIMBUS, MRANKS>(iv_dimm, iv_master_ranks)) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Sets ATTR_EFF_DIMM_RANKS_CONFIGED +/// @return FAPI2_RC_SUCCESS iff okay +/// +fapi2::ReturnCode pre_data_engine<NIMBUS>::set_dimm_ranks_configured() +{ + // Set configed ranks. Set the bit representing the master rank configured (0 being left most.) So, + // a 4R DIMM would be 0b11110000 (0xF0). This is used by PRD. + fapi2::buffer<uint8_t> l_ranks_configed; + + FAPI_TRY( l_ranks_configed.setBit(0, iv_master_ranks), + "%s. Failed to setBit", spd::c_str(iv_dimm) ); + + FAPI_TRY( (set_field<NIMBUS, DIMM_RANKS_CNFG>(iv_dimm, uint8_t(l_ranks_configed))) ); + +fapi_try_exit: + return fapi2::current_err; +} + +}//mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H index cb500c798..b4a715fb7 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H @@ -38,6 +38,7 @@ #include <cstdint> #include <fapi2.H> #include <generic/memory/lib/utils/find.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> #include <lib/utils/conversions.H> namespace mss @@ -62,17 +63,6 @@ enum functions TDLLK = 11, }; -enum guard_band : uint16_t -{ - // Used for caclulating spd timing values - from JEDEC rounding algorithm - // Correction factor is 1% (for DDR3) or 2.5% (for DDR4) - // when doing integer math, we add-in the inverse correction factor - // Formula used for derivation: - // Guardband = 1000 * (1000* correction_factor) - 1 - INVERSE_DDR3_CORRECTION_FACTOR = 989, ///< DDR3 correction factor - INVERSE_DDR4_CORRECTION_FACTOR = 974, ///< DDR4 correction factor -}; - enum refresh_rate : uint8_t { REF1X = 1, ///< Refresh rate 1X @@ -84,96 +74,6 @@ namespace spd { /// -/// @brief Calculates timing value -/// @param[in] i_timing_mtb timing value in MTB units -/// @param[in] i_mtb_multiplier SPD medium timebase -/// @param[in] i_timing_ftb fine offset of timing value -/// @param[in] i_ftb_multiplier SPD fine timebase -/// @return the timing value in picoseconds -/// -inline int64_t calc_timing_from_timebase(const int64_t i_timing_mtb, - const int64_t i_mtb_multiplier, - const int64_t i_timing_ftb, - const int64_t i_ftb_multiplier) -{ - // JEDEC algorithm - const int64_t l_timing_val = i_timing_mtb * i_mtb_multiplier; - const int64_t l_fine_offset = i_timing_ftb * i_ftb_multiplier; - - return l_timing_val + l_fine_offset; -} - -/// -/// @brief Helper to compute JEDEC's SPD rounding algorithm -/// to convert ps to nCK -/// @tparam T input type -/// @tparam OT output type -/// @param[in] i_timing_in_ps timing parameter in ps -/// @param[in] i_tck_in_ps clock period in ps -/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC) -/// @param[out] o_value_nck the end calculation in nck -/// @return true if overflow didn't occur, false otherwise -/// @note DDR4 SPD Contents Rounding Algorithm -/// @note Item 2220.46 -/// -template<typename T, typename OT> -static inline bool jedec_spd_rounding_alg(const T& i_timing_in_ps, - const T& i_tck_in_ps, - const guard_band i_inverse_corr_factor, - OT& o_val_nck) -{ - // Preliminary nCK calculation, scaled by 1000 per JDEC algorithm - T l_temp_nck = (i_timing_in_ps * CONVERT_PS_IN_A_NS) / (i_tck_in_ps == 0 ? 1 : i_tck_in_ps); - l_temp_nck += i_inverse_corr_factor; - l_temp_nck = l_temp_nck / CONVERT_PS_IN_A_NS; - - // Check for overflow - // static_cast needed for HB compiler that complains about - // comparision of two different integral types - o_val_nck = l_temp_nck; - - FAPI_DBG("Input timing (ps) %d, tCK (ps) %d, temp output %d, output (nCK) %d", - i_timing_in_ps, i_tck_in_ps, l_temp_nck, o_val_nck); - - return (static_cast<T>(o_val_nck) == l_temp_nck); -} - -/// -/// @brief Returns clock cycles based on input application period -/// @tparam T input type -/// @tparam OT output type -/// @param[in] i_timing_in_ps timing parameter in ps -/// @param[in] i_tck_in_ps clock period in ps -/// @param[in] i_inverse_corr_factor inverse correction factor (defined by JEDEC) -/// @param[out] o_value_nck the end calculation in nck -/// @return FAPI2_RC_SUCCESS iff okay -/// @note DDR4 SPD Contents Rounding Algorithm -/// @note Item 2220.46 -/// -template<typename T, typename OT> -inline fapi2::ReturnCode calc_nck(const T& i_timing_in_ps, - const T& i_tck_in_ps, - const guard_band i_inverse_corr_factor, - OT& o_val_nck) -{ - FAPI_ASSERT( jedec_spd_rounding_alg(i_timing_in_ps, - i_tck_in_ps, - i_inverse_corr_factor, - o_val_nck), - fapi2::MSS_INVALID_CAST_CALC_NCK(). - set_TIMING_PS(i_timing_in_ps). - set_NCK_NS(i_tck_in_ps). - set_CORRECTION_FACTOR(i_inverse_corr_factor), - "Overflow occured. Returned data is %d", o_val_nck); - - // If we don't assert, we don't know what's in current_err ... - return fapi2::FAPI2_RC_SUCCESS; - -fapi_try_exit: - return fapi2::current_err; -} - -/// /// @brief Returns clock cycles form picoseconds based on speed bin /// Uses SPD rounding algorithm for DDR4 /// @tparam T the target type from which to get the mt/s @@ -201,7 +101,7 @@ inline OT ps_to_nck( const fapi2::Target<T>& i_target, const OT& i_timing_in_ps) FAPI_TRY( freq_to_ps(l_freq, l_tck_in_ps), "Failed freq() accessor" ); - FAPI_TRY( calc_nck(i_timing_in_ps, l_tck_in_ps, INVERSE_DDR4_CORRECTION_FACTOR, l_temp_nck), + FAPI_TRY( calc_nck(i_timing_in_ps, l_tck_in_ps, spd::INVERSE_DDR4_CORRECTION_FACTOR, l_temp_nck), "Failed calc_nck()" ); return l_temp_nck; |