summaryrefslogtreecommitdiffstats
path: root/src
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-25 03:43:53 -0500
commite454167d53751dc70b9b92f1d5195e5232a89c1e (patch)
treed539ae4d816dda6e8e4072bfbf6702f94918a1c1 /src
parent50a5bf7b5d31fb1c61547a8122a0016e80e15cf3 (diff)
downloadtalos-sbe-e454167d53751dc70b9b92f1d5195e5232a89c1e.tar.gz
talos-sbe-e454167d53751dc70b9b92f1d5195e5232a89c1e.zip
Generalize byte reading from SPD reading, for exp i2c reuse
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> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/80957 Reviewed-by: RAJA DAS <rajadas2@in.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/import/generic/memory/lib/utils/mss_field.H314
-rw-r--r--src/import/generic/memory/lib/utils/mss_generic_check.H65
-rw-r--r--src/import/generic/memory/lib/utils/shared/mss_generic_consts.H6
3 files changed, 383 insertions, 2 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
diff --git a/src/import/generic/memory/lib/utils/mss_generic_check.H b/src/import/generic/memory/lib/utils/mss_generic_check.H
index bf483982..56910d7e 100644
--- a/src/import/generic/memory/lib/utils/mss_generic_check.H
+++ b/src/import/generic/memory/lib/utils/mss_generic_check.H
@@ -22,3 +22,68 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mss_generic_check.H
+/// @brief Checker functions for generic API
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_GENERIC_CHECK_H_
+#define _MSS_GENERIC_CHECK_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/c_str.H>
+
+namespace mss
+{
+namespace check
+{
+
+///
+/// @brief Checks conditional passes and implements traces & exits if it fails
+/// @tparam T fapi2 target type
+/// @tparam IT input data type
+/// @param[in] i_target fapi2 target
+/// @param[in] i_conditional conditional that we are testing against
+/// @param[in] i_byte_index byte index
+/// @param[in] i_data debug data
+/// @param[in] i_ffdc_codes FFDC code
+/// @param[in] i_err_str error string - defaulted to ""
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< fapi2::TargetType T, typename IT >
+inline fapi2::ReturnCode invalid_value(const fapi2::Target<T>& i_target,
+ const bool i_conditional,
+ const size_t i_byte_index,
+ const IT i_data,
+ const generic_ffdc_codes i_ffdc_codes,
+ const char* i_err_str = "")
+{
+ FAPI_ASSERT(i_conditional,
+ fapi2::MSS_FAILED_DATA_INTEGRITY_CHECK().
+ set_VALUE(i_data).
+ set_BYTE(i_byte_index).
+ set_TARGET(i_target).
+ set_FFDC_CODE(i_ffdc_codes),
+ "%s %s Byte %d, Data returned: %d.",
+ spd::c_str(i_target),
+ i_err_str,
+ i_byte_index,
+ i_data);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+
+} // fail_for_invalid_value
+
+} // check
+}// mss
+
+#endif
diff --git a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
index dc615d4b..356179a7 100644
--- a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
+++ b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
@@ -70,8 +70,8 @@ enum generic_ffdc_codes
SET_ATTR_HYBRID_MEDIA = 0x1003,
SET_ATTR_MASTER_RANKS = 0x1004,
PRE_DATA_ENGINE_CTOR = 0x1005,
- EXTRACT_SPD_FLD = 0x1006,
- SPD_READER = 0x1007,
+ GET_FIELD = 0x1006,
+ READ_SPD_FIELD = 0x1007,
BASE_CFG_PARAM_SELECT = 0x1008,
DIMM_MODULE_PARAM_SELECT = 0x1009,
BASE_CFG_FACTORY = 0x100A,
@@ -93,6 +93,8 @@ enum generic_ffdc_codes
TWTR_L_MIN = 0x101A,
DEVICE_TYPE = 0x101B,
BASE_MODULE_TYPE = 0x101C,
+ BAD_SPD_DATA = 0x101C,
+ SET_FIELD = 0x101D,
};
///
OpenPOWER on IntegriCloud