From de35db8a7994cf356e76bedefe27e5190f63b77a Mon Sep 17 00:00:00 2001 From: Stephen Glancy Date: Mon, 22 Jul 2019 10:16:46 -0400 Subject: Fixes MCBIST ecc/spare data pattern bug MCBIST wasn't setting up the ecc/spare DRAM's data pattern registers. This commit fixes that bug by taking the first byte of data and putting it into the ecc/spare data registers Change-Id: I5cdda1de8d123ff5f3bb991a2182c5027abb4f29 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/80769 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Tested-by: Hostboot CI Tested-by: HWSV CI Reviewed-by: Mark Pizzutillo Reviewed-by: Louis Stermole Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/80790 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Christian R Geddes --- .../procedures/hwp/memory/lib/mcbist/exp_mcbist.H | 32 +++++++++- .../p9/procedures/hwp/memory/lib/mcbist/mcbist.H | 22 +++++++ .../memory/lib/utils/mcbist/gen_mss_mcbist.H | 74 ++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H index 747b47311..df3b9af2a 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/mcbist/exp_mcbist.H @@ -52,6 +52,36 @@ #include #include -// This file is still necessary to put traits and generic code together +namespace mss +{ +namespace mcbist +{ + +/// +/// @brief Load MCBIST ECC (and?) spare data pattern given a pattern - explorer specialization +/// @param[in] i_target the target to effect +/// @param[in] i_pattern an mcbist::patterns +/// @param[in] i_invert whether to invert the pattern or not +/// @return FAPI2_RC_SUCCSS iff ok +/// +template< > +inline fapi2::ReturnCode load_eccspare_pattern( + const fapi2::Target& i_target, + const pattern& i_pattern, + const bool i_invert ) +{ + // First up assemble the pattern + const auto l_pattern = generate_eccspare_pattern(i_pattern, i_invert); + + FAPI_TRY(fapi2::putScom(i_target, EXPLR_MCBIST_MCBFDQ, l_pattern)); + FAPI_TRY(fapi2::putScom(i_target, EXPLR_MCBIST_MCBFDSPQ, l_pattern)); + +fapi_try_exit: + return fapi2::current_err; +} + +} // ns mss + +} // ns mcbist #endif diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H index 80c5eab20..02f3a2ba5 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H @@ -126,6 +126,28 @@ fapi2::ReturnCode setup_broadcast_port_select(const fapi2::Target& i_target, template< mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T > fapi2::ReturnCode enable_broadcast_mode(const fapi2::Target& i_target, mcbist::program<>& io_program); +/// +/// @brief Load MCBIST ECC (and?) spare data pattern given a pattern - explorer specialization +/// @param[in] i_target the target to effect +/// @param[in] i_pattern an mcbist::patterns +/// @param[in] i_invert whether to invert the pattern or not +/// @note this overload disappears when we have real patterns. +/// @return FAPI2_RC_SUCCSS iff ok +/// +template< > +inline fapi2::ReturnCode load_eccspare_pattern( + const fapi2::Target& i_target, + const pattern& i_pattern, + const bool i_invert ) +{ + // First up assemble the pattern + const auto l_pattern = generate_eccspare_pattern(i_pattern, i_invert); + + FAPI_TRY(fapi2::putScom(i_target, MCBIST_MCBFDQ, l_pattern)); + +fapi_try_exit: + return fapi2::current_err; +} } // namespace MCBIST } // namespace mss diff --git a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H index 2fbe18d25..03966e570 100644 --- a/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H +++ b/src/import/generic/memory/lib/utils/mcbist/gen_mss_mcbist.H @@ -2779,6 +2779,78 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Helper for assembling the ecc/spare pattern +/// @param[in] i_data the data pattern for a single beat +/// @param[in] i_invert true if the data should be inverted +/// @return The data pattern for this beat (a single byte of dataa) +/// +inline uint8_t generate_eccspare_pattern_helper(const uint64_t& i_data, const bool i_invert ) +{ + fapi2::buffer l_data(i_invert ? ~i_data : i_data); + uint8_t l_byte = 0; + l_data.extractToRight<0, BITS_PER_BYTE>(l_byte); + return l_byte; +} + +/// +/// @brief Generates the pattern for the ECC and/or spare data +/// @param[in] i_pattern the pattern on which to operate +/// @param[in] i_invert true if the pattern should be inverted +/// @return ECC/spare pattern as needing to be put into the ECC/spare registers +/// +inline fapi2::buffer generate_eccspare_pattern(const pattern& i_pattern, const bool i_invert ) +{ + constexpr uint64_t BYTE0 = BITS_PER_BYTE * 0; + constexpr uint64_t BYTE1 = BITS_PER_BYTE * 1; + constexpr uint64_t BYTE2 = BITS_PER_BYTE * 2; + constexpr uint64_t BYTE3 = BITS_PER_BYTE * 3; + constexpr uint64_t BYTE4 = BITS_PER_BYTE * 4; + constexpr uint64_t BYTE5 = BITS_PER_BYTE * 5; + constexpr uint64_t BYTE6 = BITS_PER_BYTE * 6; + constexpr uint64_t BYTE7 = BITS_PER_BYTE * 7; + + fapi2::buffer l_pattern; + + // Pattern assembly is a tad weird for ECC/spare + // The pattern is stored in the same register by byte + // So we want to keep the same data as the rest of the data + // As such, we want to grab each piece of data on a byte by byte basis, flip as needed, and append it to the pattern + + // Beat 0/1 + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[0].first, i_invert)); + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[0].second, i_invert)); + + // Beat 2/3 + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[1].first, i_invert)); + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[1].second, i_invert)); + + // Beat 4/5 + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[2].first, i_invert)); + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[2].second, i_invert)); + + // Beat 6/7 + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[3].first, i_invert)); + l_pattern.insertFromRight(generate_eccspare_pattern_helper(i_pattern[3].second, i_invert)); + + return l_pattern; +} + +/// +/// @brief Load MCBIST ECC (and?) spare data pattern given a pattern +/// @tparam MC the mc type of the T +/// @tparam T, the fapi2::TargetType - derived +/// @tparam TT, the mcbistTraits associated with T - derived +/// @param[in] i_target the target to effect +/// @param[in] i_pattern an mcbist::patterns +/// @param[in] i_invert whether to invert the pattern or not +/// @note this overload disappears when we have real patterns. +/// @return FAPI2_RC_SUCCSS iff ok +/// +template< mss::mc_type MC, fapi2::TargetType T, typename TT = mcbistTraits > +inline fapi2::ReturnCode load_eccspare_pattern( const fapi2::Target& i_target, const pattern& i_pattern, + const bool i_invert ); + /// /// @brief Load MCBIST pattern given a pattern /// @tparam MC the mc type of the T @@ -2810,6 +2882,8 @@ inline fapi2::ReturnCode load_pattern( const fapi2::Target& i_target, const p ++l_address; } + FAPI_TRY(load_eccspare_pattern( i_target, i_pattern, i_invert )); + fapi_try_exit: return fapi2::current_err; } -- cgit v1.2.1