summaryrefslogtreecommitdiffstats
path: root/src/import/generic/memory/lib/utils/mss_field.H
diff options
context:
space:
mode:
authorAndre Marin <aamarin@us.ibm.com>2018-07-24 00:02:23 -0500
committerRaja Das <rajadas2@in.ibm.com>2019-07-26 00:52:04 -0500
commitd74733f09bce980fb893a0211dd17c987a3d5971 (patch)
treef532514ea1a0eb8ebb836ab59f45e36dbfb022ff /src/import/generic/memory/lib/utils/mss_field.H
parentc0f3e0a8a82353b8ec59dd8160bfe67f0fc6f748 (diff)
downloadtalos-sbe-d74733f09bce980fb893a0211dd17c987a3d5971.tar.gz
talos-sbe-d74733f09bce980fb893a0211dd17c987a3d5971.zip
Generalize byte reading from SPD reading, for exp i2c reuse
Change-Id: I9bae39a281fbf65094de522323942b5b18f69a8d Original-Change-Id: I388e5abd6639464514fb9ca2d555362e431b753c Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/63209 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Diffstat (limited to 'src/import/generic/memory/lib/utils/mss_field.H')
-rw-r--r--src/import/generic/memory/lib/utils/mss_field.H314
1 files changed, 314 insertions, 0 deletions
diff --git a/src/import/generic/memory/lib/utils/mss_field.H b/src/import/generic/memory/lib/utils/mss_field.H
index 28a18b07..4ec021e4 100644
--- a/src/import/generic/memory/lib/utils/mss_field.H
+++ b/src/import/generic/memory/lib/utils/mss_field.H
@@ -22,3 +22,317 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mss_field.H
+/// @brief API for data fields and operations
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_FIELD_H_
+#define _MSS_FIELD_H_
+
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mss_generic_check.H>
+
+namespace mss
+{
+
+///
+/// @class field_t
+/// @brief data structure for byte fields
+/// @note holds byte index, start bit, and bit length of a decoded field
+///
+class field_t
+{
+ private:
+
+ const size_t iv_byte;
+ const size_t iv_start;
+ const size_t iv_length;
+
+ public:
+
+ // default ctor deleted
+ field_t() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_byte_index
+ /// @param[in] i_start_bit
+ /// @param[in] i_bit_length
+ ///
+ constexpr field_t(const size_t i_byte_index,
+ const size_t i_start_bit,
+ const size_t i_bit_length)
+ : iv_byte(i_byte_index),
+ iv_start(i_start_bit),
+ iv_length(i_bit_length)
+ {}
+
+ ///
+ /// @brief default dtor
+ ///
+ ~field_t() = default;
+
+ ///
+ /// @brief Byte index getter
+ /// @return the byte index for this field
+ ///
+ constexpr size_t get_byte() const
+ {
+ return iv_byte;
+ }
+
+ ///
+ /// @brief Starting bit getter
+ /// @return the starting bit position for this field
+ ///
+ constexpr size_t get_start() const
+ {
+ return iv_start;
+ }
+
+ ///
+ /// @brief bit length getter
+ /// @return the bit length of this field
+ ///
+ constexpr size_t get_length() const
+ {
+ return iv_length;
+ }
+
+};// field_t
+
+///
+/// @brief Checks input field against a custom conditional
+/// @tparam T field input type
+/// @tparam F Callable object type
+/// @param[in] i_field Extracted field
+/// @param[in] i_comparison_val value we are comparing against
+/// @param[in] i_op comparison operator function object
+/// @return boolean true or false
+///
+template < typename T, typename F >
+bool conditional(const T i_field,
+ const size_t i_comparison_val,
+ const F i_op)
+{
+ return i_op(i_field, i_comparison_val);
+}
+
+///
+/// @brief Helper function to extract byte information
+/// @tparam F the field to extract
+/// @tparam T the fapi2 target type
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_data the data
+/// @param[in] i_ffdc_codes FFDC code
+/// @param[out] o_value raw value for this field
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< const field_t& F, fapi2::TargetType T >
+fapi2::ReturnCode get_field(const fapi2::Target<T>& i_target,
+ const std::vector<uint8_t>& i_data,
+ const generic_ffdc_codes i_ffdc_codes,
+ uint8_t& o_value)
+{
+ constexpr size_t BYTE = F.get_byte();
+
+ FAPI_ASSERT( BYTE < i_data.size(),
+ fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
+ .set_INDEX(BYTE)
+ .set_LIST_SIZE(i_data.size())
+ .set_FUNCTION(i_ffdc_codes)
+ .set_TARGET(i_target),
+ "Out of bounds indexing (with %d) on a list of size %d for %s",
+ BYTE,
+ i_data.size(),
+ spd::c_str(i_target));
+
+ {
+ // Extracting desired bits
+ const fapi2::buffer<uint8_t> l_buffer(i_data[BYTE]);
+ l_buffer.extractToRight<F.get_start(), F.get_length()>(o_value);
+
+ FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
+ spd::c_str(i_target),
+ BYTE,
+ i_data[BYTE],
+ F.get_start(),
+ F.get_length(),
+ o_value);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Helper function to set byte field information
+/// @tparam F the field to extract
+/// @tparam T the fapi2 target type
+/// @param[in] i_target the fapi2 target
+/// @param[in] i_setting the setting to set
+/// @param[in] i_ffdc_codes FFDC code
+/// @param[in,out] io_data the data to modify
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< const field_t& F, fapi2::TargetType T >
+fapi2::ReturnCode set_field(const fapi2::Target<T>& i_target,
+ const size_t i_setting,
+ const generic_ffdc_codes i_ffdc_codes,
+ std::vector<uint8_t>& io_data)
+{
+ constexpr size_t BYTE = F.get_byte();
+
+ FAPI_ASSERT( BYTE < io_data.size(),
+ fapi2::MSS_OUT_OF_BOUNDS_INDEXING()
+ .set_INDEX(BYTE)
+ .set_LIST_SIZE(io_data.size())
+ .set_FUNCTION(i_ffdc_codes)
+ .set_TARGET(i_target),
+ "Out of bounds indexing (with %d) on a list of size %d for %s",
+ BYTE,
+ io_data.size(),
+ spd::c_str(i_target));
+
+ {
+ // Insert desired setting
+ fapi2::buffer<uint8_t> l_buffer(io_data[BYTE]);
+ l_buffer.insertFromRight<F.get_start(), F.get_length()>(i_setting);
+
+ io_data[BYTE] = static_cast<uint8_t>(l_buffer);
+
+ FAPI_DBG("%s data[%d] = 0x%02x. Field with start bit %d, bit len %d, has data 0x%02x.",
+ spd::c_str(i_target),
+ BYTE,
+ io_data[BYTE],
+ F.get_start(),
+ F.get_length(),
+ i_setting);
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief byte field reader
+/// @tparam F the byte field to read
+/// @tparam TT traits associated with F - required
+/// @tparam T the fapi2 target type
+/// @tparam IT data input type
+/// @tparam OT data output type
+/// @param[in] i_target the dimm target
+/// @param[in] i_data the data
+/// @param[in] i_ffdc_codes FFDC code
+/// @param[out] o_value raw value for this field
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< const field_t& F,
+ typename TT,
+ fapi2::TargetType T,
+ typename IT,
+ typename OT >
+inline fapi2::ReturnCode get_field( const fapi2::Target<T>& i_target,
+ const std::vector<IT>& i_data,
+ const generic_ffdc_codes i_ffdc_codes,
+ OT& o_value )
+{
+ IT l_temp = 0;
+ FAPI_TRY( get_field<F>(i_target, i_data, i_ffdc_codes, l_temp),
+ "Failed get_field() for %s", spd::c_str(i_target) );
+
+ // Test if retrieved data seems valid
+ FAPI_TRY( check::invalid_value(i_target,
+ conditional( l_temp,
+ TT::COMPARISON_VAL,
+ typename TT::template COMPARISON_OP<IT>() ),
+ F.get_byte(),
+ l_temp,
+ i_ffdc_codes),
+ "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );
+
+ // Output should only change if data check passes
+ o_value = static_cast<OT>(l_temp);
+
+ FAPI_ASSERT( o_value == l_temp,
+ fapi2::MSS_CONVERSION_ERROR()
+ .set_ORIGINAL_VAL(l_temp)
+ .set_CONVERTED_VAL(o_value)
+ .set_TARGET(i_target)
+ .set_FUNCTION(i_ffdc_codes),
+ "Conversion error between original %d to converted %d value for %s",
+ l_temp, o_value, spd::c_str(i_target) );
+
+ FAPI_INF("%s: 0x%02x for %s",
+ TT::FIELD_STR,
+ o_value,
+ spd::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief byte field writer
+/// @tparam F the byte field to read
+/// @tparam TT traits associated with writer
+/// @tparam T the fapi2 target type
+/// @tparam IT data input type
+/// @tparam OT data output type
+/// @param[in] i_target the dimm target
+/// @param[in] i_setting value to set for field
+/// @param[in] i_ffdc_codes FFDC code
+/// @param[in,out] io_data the data to modify
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< const field_t& F,
+ typename TT,
+ fapi2::TargetType T,
+ typename IT,
+ typename OT >
+fapi2::ReturnCode set_field( const fapi2::Target<T>& i_target,
+ const size_t i_setting,
+ const generic_ffdc_codes i_ffdc_codes,
+ std::vector<OT>& io_data )
+{
+ constexpr size_t BYTE = F.get_byte();
+
+ // Test if the data we want to set is valid for this field
+ FAPI_TRY( check::invalid_value(i_target,
+ conditional( i_setting,
+ TT::COMPARISON_VAL,
+ typename TT::template COMPARISON_OP<IT>() ),
+ BYTE,
+ i_setting,
+ i_ffdc_codes),
+ "Failed fail_for_invalid_value() for %s", spd::c_str(i_target) );
+
+ FAPI_TRY( set_field<F>(i_target, i_setting, i_ffdc_codes, io_data),
+ "Failed set_field() for %s", spd::c_str(i_target) );
+
+ FAPI_INF("%s: Set value of 0x%02x. Data for buffer at byte %d, is now 0x%02x for %s",
+ TT::FIELD_STR,
+ i_setting,
+ BYTE,
+ io_data[BYTE],
+ spd::c_str(i_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// mss
+
+#endif
OpenPOWER on IntegriCloud