summaryrefslogtreecommitdiffstats
path: root/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H')
-rw-r--r--src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H584
1 files changed, 584 insertions, 0 deletions
diff --git a/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H b/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H
index 7e2c47406..1c6365d37 100644
--- a/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H
+++ b/src/import/generic/memory/lib/utils/power_thermal/gen_decoder.H
@@ -22,3 +22,587 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file gen_decoder.H
+/// @brief Decoder for ATTR_MSS_MRW_PWR_CURVE_SLOPE and _INTERCEPT and THERMAL_POWER_LIMIT
+///
+// *HWP HWP Owner: Louis Stermole <stermole@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_GEN_POWER_DECODER__
+#define _MSS_GEN_POWER_DECODER__
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/count_dimm.H>
+#include <generic/memory/lib/utils/power_thermal/gen_throttle_traits.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/mss_generic_attribute_getters.H>
+
+namespace mss
+{
+
+namespace power_thermal
+{
+
+constexpr uint32_t ANY_SIZE = 0xFFFFFFFF;
+constexpr uint8_t ANY_TYPE = 0xFF;
+constexpr uint8_t ANY_GEN = 0xFF;
+constexpr uint8_t ANY_WIDTH = 0xFF;
+constexpr uint8_t ANY_DENSITY = 0xFF;
+constexpr uint8_t ANY_STACK_TYPE = 0xFF;
+constexpr uint16_t ANY_MFGID = 0xFFFF;
+constexpr uint8_t ANY_HEIGHT = 0xFF;
+constexpr uint8_t ANY_PORT = 0xFF;
+
+//Currently needs to be in sorted order for lookup to work
+static const std::vector< std::pair<uint32_t , uint8_t> > DIMM_SIZE_MAP =
+{
+ {4, 0b0000},
+ {8, 0b0001},
+ {16, 0b0010},
+ {32, 0b0011},
+ {64, 0b0100},
+ {128, 0b0101},
+ {256, 0b0110},
+ {512, 0b0111},
+ {ANY_SIZE, 0b1111}
+};
+
+
+
+static const std::vector< std::pair<uint8_t , uint8_t> > DRAM_GEN_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_EMPTY, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_DDR3, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_GEN_DDR4, 0b10},
+ {ANY_GEN, 0b11}
+};
+
+static const std::vector <std::pair<uint8_t, uint8_t> > DRAM_WIDTH_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X4, 0b000},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X8, 0b001},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X16, 0b010},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_WIDTH_X32, 0b011},
+ {ANY_WIDTH, 0b111}
+};
+
+static const std::vector< std::pair<uint8_t , uint8_t> > DRAM_DENSITY_MAP =
+{
+ {4, 0b000},
+ {8, 0b001},
+ {16, 0b010},
+ {32, 0b011},
+ {64, 0b100},
+ {ANY_DENSITY, 0b111}
+};
+
+static const std::vector <std::pair<uint8_t, uint8_t> > DRAM_STACK_TYPE_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_PRIM_STACK_TYPE_SDP, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_PRIM_STACK_TYPE_DDP_QDP, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_PRIM_STACK_TYPE_3DS, 0b10},
+ {ANY_STACK_TYPE, 0b11}
+};
+
+//Note, the first entries of the pairs need to be in sorted order!!
+static const std::vector <std::pair<uint16_t, uint8_t> > DRAM_MFGID_MAP =
+{
+ //Kingston
+ {0x0198, 0b011},
+ //A-data
+ {0x04CB, 0b101},
+ //Micron
+ {0x802C, 0b000},
+ //HYNIX
+ {0x80AD, 0b001},
+ //SAMSUNG
+ {0x80CE, 0b010},
+ //Innodisk
+ {0x86F1, 0b100},
+ // ANY
+ {ANY_MFGID, 0b111}
+};
+
+static const std::vector< std::pair<uint8_t , uint8_t> > DIMM_MODULE_HEIGHT_MAP =
+{
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_1U, 0b00},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_2U, 0b01},
+ {fapi2::ENUM_ATTR_MEM_EFF_DRAM_MODULE_HEIGHT_4U, 0b10},
+ {ANY_HEIGHT, 0b11}
+};
+
+static const std::vector < std::pair< uint8_t, uint8_t> > DIMMS_PORT_MAP =
+{
+ //Num dimms per MCA, only 1 or 2 possible options. 0 is no-op
+ {1, 0b00},
+ {2, 0b01},
+ {ANY_PORT, 0b11}
+};
+
+// Forward declaration
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode generate_wildcard_mask(const uint32_t i_hash, uint32_t& o_mask);
+
+
+///
+///@brief a compare functor for the decoder::find_attr functions below
+/// @tparam MC mss::mc_type
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE>
+struct is_match
+{
+ ///
+ ///@brief functor constructor
+ ///@param[in] i_gen_key the class object's constructed hash for the installed dimm, to be compared with the attr array
+ ///
+ is_match(const uint32_t i_gen_key) : iv_gen_key(i_gen_key) {}
+ const fapi2::buffer<uint32_t> iv_gen_key;
+
+ ///
+ ///@brief Boolean compare used for find_if function
+ ///
+ bool operator()(const uint64_t i_hash)
+ {
+ // l_this_hash is the first half of the i_hash's bits
+ const uint32_t l_this_hash = i_hash >> 32;
+ uint32_t l_wildcard_mask = 0;
+
+ // Get wildcard mask. If the decoding fails(value to key), we should continue
+ generate_wildcard_mask<MC>(l_this_hash, l_wildcard_mask);
+
+ // Mask the wildcard bits
+ return ((l_this_hash | l_wildcard_mask) == (iv_gen_key | l_wildcard_mask));
+ }
+};
+
+///
+/// @brief Encode the attribute into a bit encoding
+/// @tparam S *ATTR*_SIZE enum used for fapi2::buffer position
+/// @tparam L *ATTR*_LEN enum used for fapi2::buffer position
+/// @tparam T integral type of key
+/// @tparam OT fapi2::buffer of some integral type
+/// @param[in] i_target the DIMM the encoding is for
+/// @param[in] i_attr the attribute key being used for the encoding
+/// @param[in] i_map a vector of pairs of the ATTR values and encodings for each value, sorted
+/// @param[out] o_buf the fapi2::buffer where the encoding is going into
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff attribute is found in map lookup
+///
+template<size_t S, size_t L, typename T, typename OT>
+inline fapi2::ReturnCode encode ( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const T& i_attr,
+ const std::vector<std::pair<T, OT> >& i_map,
+ fapi2::buffer<uint32_t>& o_buf)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ //used to hold result from vector pair lookup
+ OT l_encoding = 0;
+
+ //Failing out if we don't find an encoding. All suported types should be encoded above
+ 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:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decode the attribute into a bit encoding
+/// @tparam S DRAM_GEN_SIZE enum used for fapi2::buffer position
+/// @tparam L DRAM_GEN_LEN enum used for fapi2::buffer position
+/// @tparam T integral type of key
+/// @tparam OT fapi2::buffer of some integral type
+/// @param[in] i_map a vector of pairs of the ATTR values and encodings for each value
+/// @param[in] i_buf the fapi2::buffer that has the encoding to parse
+/// @param[out] o_attr the attribute value from the encoding is going
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff attribute is found in map lookup
+///
+template<size_t S, size_t L, typename T, typename OT>
+inline fapi2::ReturnCode decode (const std::vector<std::pair<T, OT> >& i_map,
+ fapi2::buffer<uint32_t>& i_buf,
+ T& o_attr )
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ //used to hold result from vector pair lookup
+ OT l_encoding = 0;
+ i_buf.extractToRight<S, L>(l_encoding);
+
+ //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),
+ "Couldn't find encoding for power thermal decode");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief generates wildcard mask for the hash value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @tparam MC mss::mc_type
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+/// @param[in] i_hash The encoded value
+/// @param[out] o_mask The wildcard mask
+///
+
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode generate_wildcard_mask(const uint32_t i_hash, uint32_t& o_mask)
+{
+
+ fapi2::buffer<uint32_t> l_mask;
+ fapi2::buffer<uint32_t> l_hash = i_hash;
+ uint8_t l_uint8_buf = 0;
+ uint16_t l_uint16_buf = 0;
+ uint32_t l_uint32_buf = 0;
+
+ //DIMM_SIZE wildcard
+ FAPI_TRY(( decode<TT::DIMM_SIZE_START, TT::DIMM_SIZE_LEN>
+ (DIMM_SIZE_MAP, l_hash, l_uint32_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMM_SIZE", l_hash );
+
+ if(ANY_SIZE == l_uint32_buf)
+ {
+ l_mask.setBit(TT::DIMM_SIZE_START, TT::DIMM_SIZE_LEN);
+ }
+
+ //DRAM_GEN wildcard
+ FAPI_TRY(( decode<TT::DRAM_GEN_START, TT::DRAM_GEN_LEN>
+ (DRAM_GEN_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_GEN", l_hash);
+
+ if(ANY_GEN == l_uint8_buf)
+ {
+ l_mask.setBit(TT::DRAM_GEN_START, TT::DRAM_GEN_LEN);
+ }
+
+ //DIMM_TYPE wildcard
+ FAPI_TRY(( decode<TT::DIMM_TYPE_START, TT::DIMM_TYPE_LEN>
+ (TT::DIMM_TYPE_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMM_TYPE", l_hash);
+
+ if(ANY_TYPE == l_uint8_buf)
+ {
+ l_mask.setBit(TT::DIMM_TYPE_START, TT::DIMM_TYPE_LEN);
+ }
+
+ //DRAM_WIDTH wildcard
+ FAPI_TRY(( decode<TT::DRAM_WIDTH_START, TT::DRAM_WIDTH_LEN>
+ (DRAM_WIDTH_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_WIDTH", l_hash);
+
+ if(ANY_WIDTH == l_uint8_buf)
+ {
+ l_mask.setBit(TT::DRAM_WIDTH_START, TT::DRAM_WIDTH_LEN);
+ }
+
+ //DRAM_DENSITY wildcard
+ FAPI_TRY(( decode<TT::DRAM_DENSITY_START, TT::DRAM_DENSITY_LEN>
+ (DRAM_DENSITY_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_DENSITY", l_hash);
+
+ if(ANY_DENSITY == l_uint8_buf)
+ {
+ l_mask.setBit(TT::DRAM_DENSITY_START, TT::DRAM_DENSITY_LEN);
+ }
+
+ //DRAM_STACK_TYPE wildcard
+ FAPI_TRY(( decode<TT::DRAM_STACK_TYPE_START, TT::DRAM_STACK_TYPE_LEN>
+ (DRAM_STACK_TYPE_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_STACK_TYPE", l_hash);
+
+ if(ANY_STACK_TYPE == l_uint8_buf)
+ {
+ l_mask.setBit(TT::DRAM_STACK_TYPE_START, TT::DRAM_STACK_TYPE_LEN);
+ }
+
+ //DRAM_MFGID wildcard
+ FAPI_TRY(( decode<TT::DRAM_MFGID_START, TT::DRAM_MFGID_LEN>
+ (DRAM_MFGID_MAP, l_hash, l_uint16_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DRAM_MFG_ID", l_hash);
+
+ if(ANY_MFGID == l_uint16_buf)
+ {
+ l_mask.setBit(TT::DRAM_MFGID_START, TT::DRAM_MFGID_LEN);
+ }
+
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_MCS)
+ {
+ //NUM DROPS PER PORT wildcard
+ FAPI_TRY(( decode<TT::DIMMS_PER_PORT_START, TT::DIMMS_PER_PORT_LEN>
+ (DIMMS_PORT_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMMS_PER_PORT", l_hash);
+
+ if(ANY_PORT == l_uint8_buf)
+ {
+ l_mask.setBit(TT::DIMMS_PER_PORT_START, TT::DIMMS_PER_PORT_LEN);
+ }
+ }
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_OCMB_CHIP)
+ {
+ //MODUEL HEIGHT wildcard
+ FAPI_TRY(( decode<TT::DIMM_MODULE_HEIGHT_START, TT::DIMM_MODULE_HEIGHT_LEN>
+ (DIMM_MODULE_HEIGHT_MAP, l_hash, l_uint8_buf)),
+ "Failed to generate power thermal decoding for %s val %d",
+ "DIMMS_MODULE_HEIGHT", l_hash);
+
+ if(ANY_HEIGHT == l_uint8_buf)
+ {
+ l_mask.setBit(TT::DIMM_MODULE_HEIGHT_START, TT::DIMM_MODULE_HEIGHT_LEN);
+ }
+ }
+
+ o_mask = l_mask;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+///
+/// @class decoder
+/// @brief Decodes the power curve and thermal power limit attributes for eff_config_thermal
+/// @tparam MC mss::mc_type
+/// @tparam TT throttle_traits throttle traits for the given mc_type
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = throttle_traits<MC>>
+class decoder
+{
+ public:
+
+ //IVs for all of the attributes per MCS
+ const mss::dimm::kind iv_kind;
+
+ //Left in here rather than calculating during encode for testing
+ uint8_t iv_dimms_per_port;
+
+ //Power thermal attributes, both total and vddr versions will be used in eff_config_thermal
+ uint16_t iv_vddr_slope = 0;
+ uint16_t iv_vddr_intercept = 0;
+ uint16_t iv_total_slope = 0;
+ uint16_t iv_total_intercept = 0;
+
+ // Valid for OCMB only
+ uint32_t iv_power_limit = 0 ;
+
+ uint32_t iv_thermal_power_limit = 0;
+
+ //Generated key, used to decode all three power curve attributes
+ fapi2::buffer<uint32_t> iv_gen_key;
+
+ ///
+ /// @brief Constructor
+ /// @param[in] dimm::kind to call power thermal stuff on
+ ///
+ decoder( const mss::dimm::kind& i_kind):
+ iv_kind(i_kind)
+ {
+ iv_dimms_per_port = mss::count_dimm (find_target<TT::PORT_TARGET_TYPE>(iv_kind.iv_target));
+ };
+
+ //
+ // @brief Default destructor
+ //
+ ~decoder() = default;
+
+ ///
+ /// @brief generates the 32 bit encoding for the power curve attributes
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_gen_key
+ ///
+ fapi2::ReturnCode generate_encoding ();
+
+ ///
+ /// @brief Finds a value for the power curve slope attributes by matching the generated hashes
+ /// @param[in] i_array is a vector of the attribute values
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_vddr_slope, iv_total_slope
+ ///
+ fapi2::ReturnCode find_slope (const std::vector< const std::vector<uint64_t>* >& i_slope);
+
+ ///
+ /// @brief Finds a value for power curve intercept attributes by matching the generated hashes
+ /// @param[in] i_array is a vector of the attribute values
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_vddr_intercept, iv_total_intercept
+ ///
+ fapi2::ReturnCode find_intercept (const std::vector< const std::vector<uint64_t>* >& i_intercept);
+
+ ///
+ /// @brief Finds a value from ATTR_MSS_MRW_THERMAL_MEMORY_POWER_LIMIT and stores in iv variable
+ /// @param[in] i_array is a vector of the attribute values
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_thermal_power_limit
+ ///
+ fapi2::ReturnCode find_thermal_power_limit (const std::vector< const std::vector<uint64_t>* >& i_thermal_limits);
+
+ ///
+ /// @brief Helper function to find the value from attribute
+ /// @tparam FIELD_START the field start offset inside attribute
+ /// @tparam FIELD_LEN the field length to extract
+ /// @tparam FUNCTION the function of the field
+ /// @tparam OT output type
+ /// @param[in] i_array is a vector of the attribute values
+ /// @param[in] i_attr_description the attribute description
+ /// @param[out] o_value the output value
+ /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+ /// @note populates iv_thermal_power_limit
+ ///
+ template<size_t FIELD_START, size_t FIELD_LEN, generic_ffdc_codes FUNCTION, typename OT>
+ fapi2::ReturnCode get_power_thermal_value(const std::vector<uint64_t>& i_array,
+ const char* const i_attr_description,
+ OT& o_value);
+};
+
+///
+/// @brief generates the 32 bit encoding for the power curve attributes
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @note populates iv_gen_keys
+///
+template<mss::mc_type MC, typename TT>
+fapi2::ReturnCode decoder<MC, TT>::generate_encoding()
+{
+ //DIMM_SIZE
+ FAPI_TRY(( encode<TT::DIMM_SIZE_START, TT::DIMM_SIZE_LEN>
+ (iv_kind.iv_target, iv_kind.iv_size, DIMM_SIZE_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMM_SIZE", iv_kind.iv_size, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM_GEN
+ FAPI_TRY(( encode<TT::DRAM_GEN_START, TT::DRAM_GEN_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dram_generation, DRAM_GEN_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_GEN", iv_kind.iv_dram_generation, mss::c_str(iv_kind.iv_target) );
+
+ //DIMM_TYPE
+ FAPI_TRY(( encode<TT::DIMM_TYPE_START, TT::DIMM_TYPE_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dimm_type, TT::DIMM_TYPE_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMM_TYPE", iv_kind.iv_dimm_type, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM WIDTH
+ FAPI_TRY(( encode<TT::DRAM_WIDTH_START, TT::DRAM_WIDTH_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dram_width, DRAM_WIDTH_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_WIDTH", iv_kind.iv_dram_width, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM DENSITY
+ FAPI_TRY(( encode<TT::DRAM_DENSITY_START, TT::DRAM_DENSITY_LEN>
+ (iv_kind.iv_target, iv_kind.iv_dram_density, DRAM_DENSITY_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_DENSITY", iv_kind.iv_dram_density, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM STACK TYPE
+ FAPI_TRY(( encode<TT::DRAM_STACK_TYPE_START, TT::DRAM_STACK_TYPE_LEN>
+ (iv_kind.iv_target, iv_kind.iv_stack_type, DRAM_STACK_TYPE_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_STACK_TYPE", iv_kind.iv_stack_type, mss::c_str(iv_kind.iv_target) );
+
+ //DRAM MFG ID
+ FAPI_TRY(( encode<TT::DRAM_MFGID_START, TT::DRAM_MFGID_LEN>
+ (iv_kind.iv_target, iv_kind.iv_mfgid, DRAM_MFGID_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DRAM_MFG_ID", iv_kind.iv_mfgid, mss::c_str(iv_kind.iv_target) );
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_MCS)
+ {
+ //NUM DROPS PER PORT
+ FAPI_TRY(( encode<TT::DIMMS_PER_PORT_START, TT::DIMMS_PER_PORT_LEN>
+ (iv_kind.iv_target, iv_dimms_per_port, DIMMS_PORT_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMMS_PER_PORT", iv_dimms_per_port, mss::c_str(iv_kind.iv_target) );
+ }
+
+ if (TT::MC_TARGET_TYPE == fapi2::TARGET_TYPE_OCMB_CHIP)
+ {
+ //DIMM_MODULE_HEIGHT
+ FAPI_TRY(( encode<TT::DIMM_MODULE_HEIGHT_START, TT::DIMM_MODULE_HEIGHT_LEN>
+ (iv_kind.iv_target, iv_kind.iv_module_height, DIMM_MODULE_HEIGHT_MAP, iv_gen_key)),
+ "Failed to generate power thermal encoding for %s val %d on target: %s",
+ "DIMM_MODULE_HEIGHT", iv_kind.iv_module_height, mss::c_str(iv_kind.iv_target) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to find the value from attribute
+/// @param[in] i_array is a vector of the attribute values
+/// @param[in] i_attr_description the attribute description
+/// @param[out] o_value the output value
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff the encoding was successful
+/// @note populates iv_thermal_power_limit
+///
+template<mss::mc_type MC, typename TT>
+template<size_t FIELD_START, size_t FIELD_LEN, generic_ffdc_codes FUNCTION, typename OT>
+fapi2::ReturnCode decoder<MC, TT>::get_power_thermal_value(const std::vector<uint64_t>& i_array,
+ const char* const i_attr_description,
+ OT& o_value)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Find iterator to matching key (if it exists)
+ auto l_value_iterator = std::find_if(i_array.begin(),
+ i_array.end(),
+ is_match<>(iv_gen_key));
+
+ FAPI_ASSERT(l_value_iterator != i_array.end(),
+ fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
+ .set_GENERATED_KEY(iv_gen_key)
+ .set_FUNCTION(FUNCTION)
+ .set_DIMM_TARGET(iv_kind.iv_target)
+ .set_SIZE(iv_kind.iv_size)
+ .set_DRAM_GEN(iv_kind.iv_dram_generation)
+ .set_DIMM_TYPE(iv_kind.iv_dimm_type)
+ .set_DRAM_WIDTH( iv_kind.iv_dram_width)
+ .set_DRAM_DENSITY(iv_kind.iv_dram_density)
+ .set_STACK_TYPE(iv_kind.iv_stack_type)
+ .set_MFGID(iv_kind.iv_mfgid)
+ .set_MODULE_HEIGHT(iv_kind.iv_module_height),
+ "Couldn't find %s value for generated key:0x%08lx, for target %s. "
+ "DIMM values for generated key are "
+ "size is %d, gen is %d, type is %d, width is %d, density %d, stack %d, mfgid %d, dimms %d, height %d",
+ i_attr_description,
+ iv_gen_key,
+ mss::c_str(iv_kind.iv_target),
+ iv_kind.iv_size,
+ iv_kind.iv_dram_generation,
+ iv_kind.iv_dimm_type,
+ iv_kind.iv_dram_width,
+ iv_kind.iv_dram_density,
+ iv_kind.iv_stack_type,
+ iv_kind.iv_mfgid,
+ iv_dimms_per_port,
+ iv_kind.iv_module_height
+ );
+ {
+ const fapi2::buffer<uint64_t> l_temp(*l_value_iterator);
+ l_temp.extractToRight<FIELD_START, FIELD_LEN>(o_value);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // power_thermal
+} // mss
+#endif
OpenPOWER on IntegriCloud