summaryrefslogtreecommitdiffstats
path: root/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H')
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H245
1 files changed, 236 insertions, 9 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H
index 8cd501d67..dc599616c 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.H
@@ -41,6 +41,7 @@
#include <lib/shared/exp_defaults.H>
#include <lib/dimm/exp_rank.H>
#include <exp_data_structs.H>
+#include <generic/memory/lib/utils/endian_utils.H>
#include <generic/memory/lib/utils/mss_bad_bits.H>
#include <generic/memory/lib/mss_generic_attribute_setters.H>
#include <generic/memory/lib/mss_generic_attribute_getters.H>
@@ -51,20 +52,204 @@ namespace exp
{
///
-/// @brief Reads the training response structure
-/// @param[in] i_target the target associated with the response data
-/// @param[in] i_data the response data to read
-/// @param[out] o_resp the processed training response class
-/// @return FAPI2_RC_SUCCESS if ok
+/// @brief Read eye capture response data from explorer data buffer
+///
+/// @tparam T Response struct type
+/// @param[in] i_target OCMB target
+/// @param[in] i_data Raw data bytes
+/// @param[in,out] io_current_idx Current parsing index
+/// @param[in,out] io_pass any errors occurred during reading/endian-swapping
+/// @param[in,out] io_resp response struct
+/// @note this function expects io_current_index to be set correctly to the start of eye capture data
+///
+template <typename T>
+void read_eye_capture_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ uint32_t& io_current_idx,
+ bool& io_pass,
+ T& io_resp);
+
+///
+/// @brief Read eye capture response data from explorer data buffer (eye capture step 1)
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_data Raw data bytes
+/// @param[in,out] io_current_idx Current parsing index
+/// @param[in,out] io_pass any errors occurred during reading/endian-swapping
+/// @param[in,out] io_resp train_2d_read_eye_msdg
+/// @note this function expects io_current_index to be set correctly to the start of eye capture data
///
-fapi2::ReturnCode read_training_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+template<>
+inline void read_eye_capture_response<user_2d_eye_response_1_msdg>(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target,
const std::vector<uint8_t>& i_data,
- user_response_msdg& o_resp);
+ uint32_t& io_current_idx,
+ bool& io_pass,
+ user_2d_eye_response_1_msdg& io_resp)
+{
+ // Eye capture step 1 struct
+ uint32_t l_idx = io_current_idx;
+ bool l_pass = io_pass;
+
+ // VrefDAC0: 3D array of 2 1D arrays
+ for (uint8_t l_num_ranks = 0; l_num_ranks < TRAINING_RESPONSE_NUM_RANKS; ++l_num_ranks)
+ {
+ for (uint8_t l_dbyte_n_size = 0; l_dbyte_n_size < DBYTE_N_SIZE; ++ l_dbyte_n_size)
+ {
+ for (uint8_t l_bit_n_sze = 0; l_bit_n_sze < BIT_N_SIZE; ++ l_bit_n_sze)
+ {
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.read_2d_eye_resp.VrefDAC0[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_min[0]);
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.read_2d_eye_resp.VrefDAC0[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_max[0]);
+ }
+ }
+ }
+
+ // 2D array VrefDAC0_Center [DBYTE_N_SIZE][BIT_N_SIZE]
+ l_pass &= readLEArray(i_data, (DBYTE_N_SIZE * BIT_N_SIZE), l_idx,
+ &io_resp.read_2d_eye_resp.VrefDAC0_Center[0][0]);
+
+ // 2D array RxClkDly_Center [TRAINING_RESPONSE_NUM_RANKS][NIBBLE_N_SIZE]
+ l_pass &= readLEArray(i_data, (TRAINING_RESPONSE_NUM_RANKS * NIBBLE_N_SIZE), l_idx,
+ &io_resp.read_2d_eye_resp.RxClkDly_Center[0][0]);
+
+ io_pass = l_pass;
+ io_current_idx = l_idx;
+}
+
+///
+/// @brief Read eye capture response data from explorer data buffer (eye capture step 2)
+///
+/// @param[in] i_target OCMB target
+/// @param[in] i_data Raw data bytes
+/// @param[in,out] io_current_idx Current parsing index
+/// @param[in,out] io_pass any errors occurred during reading/endian-swapping
+/// @param[in,out] io_resp user_2d_eye_response_2_msdg
+/// @note this function expects io_current_index to be set correctly to the start of eye capture data
+///
+template<>
+inline void read_eye_capture_response<user_2d_eye_response_2_msdg>(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&
+ i_target,
+ const std::vector<uint8_t>& i_data,
+ uint32_t& io_current_idx,
+ bool& io_pass,
+ user_2d_eye_response_2_msdg& io_resp)
+{
+
+ // Eye capture step 1 struct
+ uint32_t l_idx = io_current_idx;
+ bool l_pass = io_pass;
+
+ // VrefDQ: 3D array of 2 1D arrays
+ for (uint8_t l_num_ranks = 0; l_num_ranks < TRAINING_RESPONSE_NUM_RANKS; ++l_num_ranks)
+ {
+ for (uint8_t l_dbyte_n_size = 0; l_dbyte_n_size < DBYTE_N_SIZE; ++ l_dbyte_n_size)
+ {
+ for (uint8_t l_bit_n_sze = 0; l_bit_n_sze < BIT_N_SIZE; ++ l_bit_n_sze)
+ {
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.write_2d_eye_resp.VrefDQ[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_min[0]);
+ l_pass &= readLEArray(i_data, EYE_MIN_MAX_SIZE, l_idx,
+ &io_resp.write_2d_eye_resp.VrefDQ[l_num_ranks][l_dbyte_n_size][l_bit_n_sze].eye_max[0]);
+ }
+ }
+ }
+
+ // 2D array VrefDQ_Center [TRAINING_RESPONSE_NUM_RANKS][NIBBLE_N_SIZE]
+ l_pass &= readLEArray(i_data, (TRAINING_RESPONSE_NUM_RANKS * NIBBLE_N_SIZE), l_idx,
+ &io_resp.write_2d_eye_resp.VrefDQ_Center[0][0]);
+
+ // 3D array TxDqDly_Center [TRAINING_RESPONSE_NUM_RANKS][DBYTE_N_SIZE][DBYTE_N_SIZE]
+ l_pass &= readLEArray(i_data, (TRAINING_RESPONSE_NUM_RANKS * DBYTE_N_SIZE * BIT_N_SIZE), l_idx,
+ &io_resp.write_2d_eye_resp.TxDqDly_Center[0][0][0]);
+
+ io_pass = l_pass;
+ io_current_idx = l_idx;
+
+ return;
+}
+
+///
+/// @brief Read the common block of fields from the training response structs
+///
+/// @tparam T training repsonse struct type
+/// @param[in] i_target OCMB chip
+/// @param[in] i_data response data
+/// @param[in] i_current_idx last index left off
+/// @param[in] i_pass response parsing success thus far
+/// @param[in,out] io_resp response struct
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
+///
+template <typename T>
+fapi2::ReturnCode read_tm_err_mrs_rc_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ const uint32_t i_current_idx,
+ const bool i_pass,
+ T& io_resp)
+{
+ uint32_t l_idx = i_current_idx;
+ bool l_pass = i_pass;
+
+ uint16_t l_DFIMRL_DDRCLK_trained = 0;
+
+ // Reads in the timing portion of the training response
+ l_pass &= readLE(i_data, l_idx, l_DFIMRL_DDRCLK_trained);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_RR[0][0]);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_WW[0][0]);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_RW[0][0]);
+ l_pass &= readLEArray(i_data, TIMING_RESPONSE_2D_ARRAY_SIZE, l_idx, &io_resp.tm_resp.CDD_WR[0][0]);
+
+ // Write to user_response_msdg
+ io_resp.tm_resp.DFIMRL_DDRCLK_trained = l_DFIMRL_DDRCLK_trained;
+
+ // Error response
+ l_pass &= readLEArray(i_data, 80, l_idx, io_resp.err_resp.Failure_Lane);
+
+ uint16_t l_MR0 = 0;
+ uint16_t l_MR3 = 0;
+ uint16_t l_MR4 = 0;
+
+ // MRS response
+ l_pass &= readLE(i_data, l_idx, l_MR0);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, io_resp.mrs_resp.MR1);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, io_resp.mrs_resp.MR2);
+ l_pass &= readLE(i_data, l_idx, l_MR3);
+ l_pass &= readLE(i_data, l_idx, l_MR4);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RANKS, l_idx, io_resp.mrs_resp.MR5);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_MR6_SIZE, l_idx, &io_resp.mrs_resp.MR6[0][0]);
+
+ io_resp.mrs_resp.MR0 = l_MR0;
+ io_resp.mrs_resp.MR3 = l_MR3;
+ io_resp.mrs_resp.MR4 = l_MR4;
+
+ // Register Control Word (RCW) response
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F0RC_D0);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F1RC_D0);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F0RC_D1);
+ l_pass &= readLEArray(i_data, TRAINING_RESPONSE_NUM_RC, l_idx, io_resp.rc_resp.F1RC_D1);
+
+ // Check if we have errors
+ FAPI_ASSERT( l_pass,
+ fapi2::EXP_INBAND_LE_DATA_RANGE()
+ .set_TARGET(i_target)
+ .set_FUNCTION(mss::exp::READ_TRAINING_RESPONSE_STRUCT)
+ .set_DATA_SIZE(i_data.size())
+ .set_MAX_INDEX(sizeof(T)),
+ "%s Failed to convert from data to host_fw_response_struct data size %u expected size %u",
+ mss::c_str(i_target), i_data.size(), sizeof(T));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
///
/// @brief Explorer's bad bit interface class
-/// @brief Explorer's bad bit interface class
+/// @tparam T user response struct type
///
+template <typename T>
class bad_bit_interface
{
public:
@@ -85,7 +270,7 @@ class bad_bit_interface
/// @brief Constructor
/// @param[in] i_response response data from training
///
- bad_bit_interface(const user_response_msdg_t& i_response )
+ bad_bit_interface(const T& i_response )
{
// First, clear everything
std::fill(&iv_bad_bits[0][0], &iv_bad_bits[0][0] + sizeof(iv_bad_bits), 0);
@@ -171,6 +356,48 @@ class bad_bit_interface
}
};
+
+///
+/// @brief Reads the training response structure
+/// @param[in] i_target the target associated with the response data
+/// @param[in] i_data the response data to read
+/// @param[out] o_resp the processed training response class
+/// @return FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode read_normal_training_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ user_response_msdg& o_resp);
+
+///
+/// @brief Reads user 2d eye response 1
+/// @tparam T response struct
+/// @param[in] i_target the target associated with the response data
+/// @param[in] i_data the response data to read
+/// @param[out] o_resp the processed training response class
+/// @return FAPI2_RC_SUCCESS if ok
+///
+template <typename T>
+inline fapi2::ReturnCode read_user_2d_eye_response(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ T& o_resp)
+{
+ // First let's erase the struct
+ memset(&o_resp, 0, sizeof(T));
+ // We assert at the end to avoid LOTS of fapi asserts
+ uint32_t l_idx = 0;
+ uint32_t l_version_number = 0;
+ bool l_pass = readLE(i_data, l_idx, l_version_number);
+ o_resp.version_number = l_version_number;
+
+ read_eye_capture_response<T>(i_target, i_data, l_idx, l_pass, o_resp);
+
+ FAPI_TRY(read_tm_err_mrs_rc_response<T>(i_target, i_data, l_idx, l_pass, o_resp));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
} // ns exp
} // ns mss
OpenPOWER on IntegriCloud