diff options
Diffstat (limited to 'src/import/generic/memory/lib/data_engine/pre_data_init.H')
-rw-r--r-- | src/import/generic/memory/lib/data_engine/pre_data_init.H | 211 |
1 files changed, 112 insertions, 99 deletions
diff --git a/src/import/generic/memory/lib/data_engine/pre_data_init.H b/src/import/generic/memory/lib/data_engine/pre_data_init.H index 2daea4c15..068e4da4f 100644 --- a/src/import/generic/memory/lib/data_engine/pre_data_init.H +++ b/src/import/generic/memory/lib/data_engine/pre_data_init.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2018 */ +/* Contributors Listed Below - COPYRIGHT 2018,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,92 +38,17 @@ #include <cstring> #include <fapi2.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> #include <generic/memory/lib/spd/spd_facade.H> #include <generic/memory/lib/utils/find.H> -#include <generic/memory/lib/utils/shared/mss_generic_consts.H> +#include <generic/memory/lib/data_engine/p9n/p9n_data_init_traits.H> +#include <generic/memory/lib/data_engine/p9a/p9a_data_init_traits.H> +#include <generic/memory/lib/data_engine/data_engine_utils.H> namespace mss { /// -/// @brief enum list of preliminary data fields -/// -enum pre_data_init_fields -{ - DIMM_TYPE, - DRAM_GEN, - HYBRID, - HYBRID_MEDIA, - MRANKS, - DIMM_RANKS_CNFG, -}; - -/// -/// @brief Traits for pre_data_engine -/// @class preDataInitTraits -/// @tparam T proc_type (e.g. Nimbus, Axone, etc.) -/// @tparam TT pre_data_init_fields (e.g. DIMM_TYPE, MRANK, etc.) -/// -template< proc_type T, pre_data_init_fields TT > -class preDataInitTraits; - -/// -/// @brief Helper function for attribute setting -/// @tparam T processor type (e.g. NIMBUS, AXONE, etc.) -/// defaulted to NIMBUS -/// @tparam X size of 1st array index -/// @tparam Y size of 2nd array index -/// @tparam TT FAPI2 target type -/// @tparam IT Input/outpu data type -/// @param[in] i_target the MCS target -/// @param[in] i_setting array to set -/// @param[out] o_data attribute data structure to set -/// @warning This is Nimbus specific -/// -template < size_t X, size_t Y, typename IT > -void data_setter( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, - const IT i_setting, - IT (&o_data)[X][Y]) -{ - const size_t l_port_index = mss::index( find_target<fapi2::TARGET_TYPE_MCA>(i_target) ); - const size_t l_dimm_index = mss::index(i_target); - - o_data[l_port_index][l_dimm_index] = i_setting; -} - -/// -/// @brief Mapping boilerplate check -/// @tparam T FAPI2 target type -/// @tparam IT map key type -/// @tparam OT map value type -/// @param[in] i_map SPD to attribute data mapping -/// @param[in] i_ffdc_code FFDC function code -/// @param[in] i_key Key to query map -/// @param[out] o_output value from key -/// -template< fapi2::TargetType T, typename IT, typename OT > -fapi2::ReturnCode lookup_table_check(const fapi2::Target<T>& i_target, - const std::vector<std::pair<IT, OT>>& i_map, - const generic_ffdc_codes i_ffdc_code, - const IT i_key, - OT& o_output) -{ - const bool l_is_val_found = mss::find_value_from_key(i_map, i_key, o_output); - - FAPI_ASSERT( l_is_val_found, - fapi2::MSS_LOOKUP_FAILED() - .set_KEY(i_key) - .set_DATA(o_output) - .set_FUNCTION(i_ffdc_code) - .set_TARGET(i_target), - "Failed to find a mapped value for %d on %s", - i_key, - mss::spd::c_str(i_target) ); -fapi_try_exit: - return fapi2::current_err; -} - -/// /// @brief Sets preliminary data fields /// @tparam P processor type (e.g. NIMBUS, AXONE, etc.) /// @tparam F pre_data_init_fields @@ -139,18 +64,11 @@ template< proc_type P, typename IT, typename TT = preDataInitTraits<P, F> > -fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target, const IT i_setting) +inline fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target, + const IT i_setting) { - const auto l_target = mss::find_target<TT::TARGET_TYPE>(i_target); - typename TT::attr_type l_attr_list = {}; - IT l_mapping_value = i_setting; - - FAPI_TRY( TT::get_attr(l_target, l_attr_list) ); - - // Indexing isn't very general - data_setter(i_target, l_mapping_value, l_attr_list); - - FAPI_TRY( TT::set_attr(l_target, l_attr_list) ); + FAPI_TRY( (set_field<P, TT>(i_target, i_setting)), + "Failed set_field() for %s", spd::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; @@ -159,9 +77,9 @@ fapi_try_exit: /// /// @brief Data structure to set pre-effective config data /// @class pre_data_engine -/// @tparam T supported processor type (e.g. Nimbus, Axone, etc.) +/// @tparam P supported processor type (e.g. Nimbus, Axone, etc.) /// -template< proc_type T > +template< proc_type P > class pre_data_engine { private: @@ -197,37 +115,132 @@ class pre_data_engine /// @brief Set ATTR_EFF_DIMM_TYPE /// @return FAPI2_RC_SUCCESS iff ok /// - fapi2::ReturnCode set_dimm_type(); + fapi2::ReturnCode 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<P, 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 set_dram_gen(); + fapi2::ReturnCode 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<P, 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 set_hybrid(); + fapi2::ReturnCode 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<P, 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 set_hybrid_media(); + fapi2::ReturnCode 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<P, 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 set_master_ranks(); + fapi2::ReturnCode set_master_ranks() + { + uint8_t l_master_ranks = 0; + FAPI_TRY( get_master_ranks(l_master_ranks) ); + + FAPI_TRY( (set_field<P, MRANKS>(iv_dimm, l_master_ranks)) ); + + fapi_try_exit: + return fapi2::current_err; + } /// /// @brief Sets ATTR_EFF_DIMM_RANKS_CONFIGED /// @return FAPI2_RC_SUCCESS iff okay /// - fapi2::ReturnCode set_dimm_ranks_configured(); + fapi2::ReturnCode 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; + + // Make sure the number of master ranks is setup + uint8_t l_master_ranks = 0; + FAPI_TRY( get_master_ranks(l_master_ranks) ); + + FAPI_TRY( l_ranks_configed.setBit(0, l_master_ranks), + "%s. Failed to setBit", spd::c_str(iv_dimm) ); + + FAPI_TRY( (set_field<P, DIMM_RANKS_CNFG>(iv_dimm, uint8_t(l_ranks_configed))) ); + + fapi_try_exit: + return fapi2::current_err; + } + + private: + + /// + /// @brief Gets master ranks from SPD + /// @param[out] o_output num package ranks per DIMM + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode get_master_ranks(uint8_t& o_output) + { + // Sets up commonly used member variables + uint8_t l_master_ranks_spd = 0; + FAPI_TRY(iv_spd_data.num_package_ranks_per_dimm(l_master_ranks_spd), + "%s failed to get number of package ranks from SPD", spd::c_str(iv_dimm)); + + FAPI_TRY(lookup_table_check(iv_dimm, NUM_PACKAGE_RANKS_MAP, PRE_DATA_ENGINE_CTOR, l_master_ranks_spd, + o_output), "%s failed MASTER_RANKS lookup check", spd::c_str(iv_dimm)); + + fapi_try_exit: + return fapi2::current_err; + } }; /// |