diff options
Diffstat (limited to 'src')
7 files changed, 125 insertions, 13 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C index 685ec22e7..78d941db2 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_draminit.C @@ -33,9 +33,10 @@ // *HWP Level: 2 // *HWP Consumed by: FSP:HB -#include <exp_inband.H> #include <lib/shared/exp_consts.H> +#include <exp_inband.H> #include <generic/memory/lib/utils/c_str.H> +#include <generic/memory/lib/utils/mss_bad_bits.H> #include <lib/exp_draminit_utils.H> #include <lib/phy/exp_train_display.H> #include <lib/phy/exp_train_handler.H> @@ -91,7 +92,7 @@ extern "C" // If not, then we need to process the bad bitmap if(l_rc != fapi2::FAPI2_RC_SUCCESS) { - mss::exp::bad_bit_interface l_interface; + mss::exp::bad_bit_interface l_interface(l_train_response); // Record bad bits should only fail if we have an attributes issue - that's a major issue FAPI_TRY(mss::record_bad_bits<mss::mc_type::EXPLORER>(i_target, l_interface)); diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C index 976812fc0..0418b59d1 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/phy/exp_train_handler.C @@ -42,7 +42,6 @@ #include <generic/memory/lib/mss_generic_attribute_getters.H> #include <exp_train_handler.H> - namespace mss { @@ -73,9 +72,12 @@ namespace check // TK update this when FIR's are fully reviewed template<> fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + fapi2::ReturnCode& io_rc, bool& o_fir_error ) + { + io_rc = fapi2::FAPI2_RC_SUCCESS; o_fir_error = false; return fapi2::FAPI2_RC_SUCCESS; } 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 bb6bca47a..41c868946 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 @@ -61,16 +61,18 @@ fapi2::ReturnCode read_training_response(const fapi2::Target<fapi2::TARGET_TYPE_ /// /// @brief Explorer's bad bit interface class -/// @note L1 functionality Place holder to avoid merge conflicts. This will be updated in another commit +/// @brief Explorer's bad bit interface class /// class bad_bit_interface { public: - /// - /// @brief Default constructor - /// - bad_bit_interface() = default; + // Data that actually stores all of the bad bit information + // We do some processing in the constructor + uint8_t iv_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]; + + // No default constructor + bad_bit_interface() = delete; /// /// @brief Default destructor @@ -78,14 +80,108 @@ class bad_bit_interface ~bad_bit_interface() = default; /// + /// @brief Constructor + /// @param[in] i_response response data from training + /// + bad_bit_interface(const user_response_msdg_t& i_response ) + { + // First, clear everything + std::fill(&iv_bad_bits[0][0], &iv_bad_bits[0][0] + sizeof(iv_bad_bits), 0); + + // Loop through and process by bytes + for(uint64_t l_byte = 0; l_byte < BAD_DQ_BYTE_COUNT; ++l_byte) + { + const auto l_bit_start = l_byte * BITS_PER_BYTE; + + fapi2::buffer<uint8_t> l_rank0; + fapi2::buffer<uint8_t> l_rank1; + fapi2::buffer<uint8_t> l_rank2; + fapi2::buffer<uint8_t> l_rank3; + + // Process bit by bit for all ranks + // TK update to be the real bits + process_bit<0>(i_response.err_resp.Failure_Lane[l_bit_start], l_rank0, l_rank1, l_rank2, l_rank3); + process_bit<1>(i_response.err_resp.Failure_Lane[l_bit_start + 1], l_rank0, l_rank1, l_rank2, l_rank3); + process_bit<2>(i_response.err_resp.Failure_Lane[l_bit_start + 2], l_rank0, l_rank1, l_rank2, l_rank3); + process_bit<3>(i_response.err_resp.Failure_Lane[l_bit_start + 3], l_rank0, l_rank1, l_rank2, l_rank3); + process_bit<4>(i_response.err_resp.Failure_Lane[l_bit_start + 4], l_rank0, l_rank1, l_rank2, l_rank3); + process_bit<5>(i_response.err_resp.Failure_Lane[l_bit_start + 5], l_rank0, l_rank1, l_rank2, l_rank3); + process_bit<6>(i_response.err_resp.Failure_Lane[l_bit_start + 6], l_rank0, l_rank1, l_rank2, l_rank3); + process_bit<7>(i_response.err_resp.Failure_Lane[l_bit_start + 7], l_rank0, l_rank1, l_rank2, l_rank3); + + // Assign the results to the bad bits internal structure + // At this point, we want to assign all data + // We'll only copy real data over to the bad bit attribute IFF + iv_bad_bits[0][l_byte] = l_rank0; + iv_bad_bits[1][l_byte] = l_rank1; + iv_bad_bits[2][l_byte] = l_rank2; + iv_bad_bits[3][l_byte] = l_rank3; + } + } + + /// + /// @brief Processes a single bit from the response structure + /// @tparam B the bit position to process + /// @param[in] i_data the encoded data from the response structure + /// @param[in,out] io_rank0 rank 0's values + /// @param[in,out] io_rank1 rank 1's values + /// @param[in,out] io_rank2 rank 2's values + /// @param[in,out] io_rank3 rank 3's values + /// + template <uint64_t B> + void process_bit(const fapi2::buffer<uint16_t>& i_data, + fapi2::buffer<uint8_t>& io_rank0, + fapi2::buffer<uint8_t>& io_rank1, + fapi2::buffer<uint8_t>& io_rank2, + fapi2::buffer<uint8_t>& io_rank3) + { + constexpr uint64_t RANK_LEN = 4; + constexpr uint64_t RANK0 = 12; + constexpr uint64_t RANK1 = 8; + constexpr uint64_t RANK2 = 4; + constexpr uint64_t RANK3 = 0; + + io_rank0.writeBit<B>(i_data.getBit<RANK0, RANK_LEN>()); + io_rank1.writeBit<B>(i_data.getBit<RANK1, RANK_LEN>()); + io_rank2.writeBit<B>(i_data.getBit<RANK2, RANK_LEN>()); + io_rank3.writeBit<B>(i_data.getBit<RANK3, RANK_LEN>()); + } + + /// /// @param[in] i_target the DIMM to record training results on /// @param[out] o_bad_bits the processed bad bits - /// @return FAPI2_RC_SUCCESS if ok /// fapi2::ReturnCode record_bad_bits_interface( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t (&o_bad_dq)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]) const { + // Gets the rank offset for this DIMM + const uint64_t DIMM_OFFSET = mss::index(i_target) == 0 ? 0 : 2; + + // Loops through all of the ranks on this DIMM + uint8_t l_num_ranks = 0; + FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_target, l_num_ranks)); + + // TK Add in num ranks check here + // TK update for the ranks API + + for(uint64_t l_rank = 0; l_rank < l_num_ranks; ++l_rank) + { + const uint64_t RANK = DIMM_OFFSET + l_rank; + FAPI_ASSERT(RANK < mss::exp::MAX_RANK_PER_DIMM, + fapi2::MSS_EXP_DRAMINIT_BAD_NUM_RANKS() + .set_NUM_RANKS(RANK) + .set_MAX_RANKS(mss::exp::MAX_RANK_PER_DIMM) + .set_TARGET(i_target), + "%s bad number of ranks passed num:%u, max:%u", + mss::c_str(i_target), RANK, mss::exp::MAX_RANK_PER_DIMM); + + memcpy(&o_bad_dq[RANK], &iv_bad_bits[RANK], sizeof(uint8_t[BAD_DQ_BYTE_COUNT])); + } + return fapi2::FAPI2_RC_SUCCESS; + + fapi_try_exit: + return fapi2::current_err; } }; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H index 3e514ff99..c55d2d4d5 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/shared/exp_consts.H @@ -77,6 +77,7 @@ enum sizes { MAX_DIMM_PER_PORT = 2, MAX_RANK_PER_DIMM = 4, + MAX_BITS_PER_PORT = 80, }; /// diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml index 278d3790d..d2b864abf 100644 --- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml +++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml @@ -5,7 +5,7 @@ <!-- --> <!-- OpenPOWER HostBoot Project --> <!-- --> -<!-- Contributors Listed Below - COPYRIGHT 2018 --> +<!-- Contributors Listed Below - COPYRIGHT 2018,2019 --> <!-- [+] International Business Machines Corp. --> <!-- --> <!-- --> @@ -25,6 +25,18 @@ <hwpErrors> <hwpError> + <rc>RC_MSS_EXP_DRAMINIT_BAD_NUM_RANKS</rc> + <description>Bad number of ranks were passed in the bad bits functionality</description> + <ffdc>TARGET</ffdc> + <ffdc>NUM_RANKS</ffdc> + <ffdc>MAX_RANKS</ffdc> + <callout> + <target>CODE</target> + <priority>HIGH</priority> + </callout> + </hwpError> + + <hwpError> <rc>RC_MSS_EXP_DRAMINIT_UNSUPPORTED_DIMM_TYPE</rc> <description>Unsupported DIMM type encountered in draminit_training procedure</description> <ffdc>OCMB_TARGET</ffdc> diff --git a/src/import/generic/memory/lib/utils/mss_bad_bits.H b/src/import/generic/memory/lib/utils/mss_bad_bits.H index 84e62da5e..e6d2cdfa5 100644 --- a/src/import/generic/memory/lib/utils/mss_bad_bits.H +++ b/src/import/generic/memory/lib/utils/mss_bad_bits.H @@ -38,9 +38,9 @@ #include <fapi2.H> #include <generic/memory/lib/utils/shared/mss_generic_consts.H> +#include <generic/memory/lib/utils/find.H> #include <generic/memory/lib/utils/mss_generic_check.H> #include <generic/memory/lib/mss_generic_attribute_setters.H> -#include <generic/memory/lib/utils/find.H> namespace mss { @@ -101,5 +101,5 @@ fapi_try_exit: return fapi2::current_err; } -} // ns +} // ns 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 7a15bdfe0..bcf4f1207 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 @@ -355,6 +355,7 @@ enum class throttle_type THERMAL = 1, }; + /// /// @brief Trait classes for mc_type /// @tparam MC the mc_type @@ -399,7 +400,6 @@ struct mcTypeTraits<mc_type::EXPLORER> }; }; - }// mss #endif |