From c96464c7d52540eda875ac62082f1ebf24de3f72 Mon Sep 17 00:00:00 2001 From: Stephen Glancy Date: Mon, 18 Feb 2019 10:25:11 -0500 Subject: Moves set bad bitmap into generic Change-Id: I0c9e8beb0e4cd930ebccbf26d1e8149b64fae65d Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72154 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Dev-Ready: STEPHEN GLANCY Reviewed-by: ANDRE A. MARIN Reviewed-by: Louis Stermole Tested-by: HWSV CI Tested-by: Hostboot CI Reviewed-by: Jennifer A. Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72163 Reviewed-by: Daniel M. Crowell Tested-by: Daniel M. Crowell --- .../chips/p9/procedures/hwp/memory/lib/fir/check.C | 20 +++---- .../chips/p9/procedures/hwp/memory/lib/fir/check.H | 16 +----- .../chips/p9/procedures/hwp/memory/lib/mc/port.C | 9 ++- .../hwp/memory/lib/mss_attribute_accessors.H | 65 ++++++++++----------- .../chips/p9/procedures/hwp/memory/lib/phy/dp16.C | 67 ++++++---------------- .../chips/p9/procedures/hwp/memory/lib/phy/dp16.H | 61 +++++++++++++++----- .../procedures/hwp/memory/lib/shared/mss_const.H | 2 - 7 files changed, 116 insertions(+), 124 deletions(-) (limited to 'src/import/chips/p9/procedures/hwp/memory') diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C index ddd5aaa6b..68a5c02a2 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -351,17 +351,16 @@ fapi_try_exit: } /// -/// @brief Checks whether any FIRs have lit up on a target -/// @tparam T the fapi2::TargetType which hold the FIR bits +/// @brief Checks whether any FIRs have lit up on a target - NIMBUS/MCBIST specialization /// @param[in] i_target - the target on which to operate /// @param[in,out] io_rc - the return code for the function /// @param[out] o_fir_error - true iff a FIR was hit /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok /// template< > -fapi2::ReturnCode bad_fir_bits( const fapi2::Target& i_target, - fapi2::ReturnCode& io_rc, - bool& o_fir_error ) +fapi2::ReturnCode bad_fir_bits( const fapi2::Target& i_target, + fapi2::ReturnCode& io_rc, + bool& o_fir_error ) { // Start by assuming we do not have a FIR o_fir_error = false; @@ -414,17 +413,16 @@ fapi_try_exit: } /// -/// @brief Checks whether any FIRs have lit up on a target -/// @tparam T the fapi2::TargetType which hold the FIR bits +/// @brief Checks whether any FIRs have lit up on a target - NIMBUS/MCA sepcialization /// @param[in] i_target - the target on which to operate /// @param[in,out] io_rc - the return code for the function /// @param[out] o_fir_error - true iff a FIR was hit /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok /// template< > -fapi2::ReturnCode bad_fir_bits( const fapi2::Target& i_target, - fapi2::ReturnCode& io_rc, - bool& o_fir_error ) +fapi2::ReturnCode bad_fir_bits( const fapi2::Target& i_target, + fapi2::ReturnCode& io_rc, + bool& o_fir_error ) { const auto& l_mcbist = mss::find_target(i_target); // Start by assuming we do not have a FIR diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.H b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.H index 9f1e96c92..6bf155317 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/fir/check.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2018 */ +/* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -38,6 +38,7 @@ #include #include +#include namespace mss { @@ -93,17 +94,6 @@ fapi2::ReturnCode pll_fir( const fapi2::Target& i_tar fapi2::ReturnCode& io_rc, bool& o_fir_error ); -/// -/// @brief Checks whether any FIRs have lit up on a target -/// @tparam T the fapi2::TargetType which hold the FIR bits -/// @param[in] i_target - the target on which to operate -/// @param[in,out] io_rc - the return code for the function -/// @param[out] o_fir_error - true iff a FIR was hit -/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok -/// -template< fapi2::TargetType T > -fapi2::ReturnCode bad_fir_bits( const fapi2::Target& i_target, fapi2::ReturnCode& io_rc, bool& o_fir_error ); - /// /// @brief Checks whether the passed in FIRs have any un-masked errors set /// @tparam T the fapi2::TargetType which hold the FIR bits @@ -168,7 +158,7 @@ fapi2::ReturnCode hostboot_fir_or_pll_fail( const fapi2::Target& i_target, fa FAPI_ERR("%s has a bad return code, time to check some firs!", mss::c_str(i_target)); - l_fircheck_scom_err = bad_fir_bits(i_target, io_rc, l_fir_error); + l_fircheck_scom_err = bad_fir_bits(i_target, io_rc, l_fir_error); FAPI_ERR("%s took a fail. FIR was %s", mss::c_str(i_target), l_fir_error ? "set - returning FIR RC" : "unset - returning inputted RC"); diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C index 75d15c1d1..5c1433bbe 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C @@ -403,11 +403,10 @@ fapi_try_exit: /// @param[out] o_repairs_exceeded 2-bit mask, where a bit set means a DIMM had more bad bits than could be repaired (bit0-1 = DIMM0-1) /// @return FAPI2_RC_SUCCESS if and only if ok /// -// TODO RTC:157753 Template parameters here are Nimbus specific. Convert to attribute/trait of TARGET_TYPE_MCA when traits are created. template<> -fapi2::ReturnCode restore_repairs_helper( +fapi2::ReturnCode restore_repairs_helper( const fapi2::Target& i_target, - const uint8_t i_bad_bits[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT], + const uint8_t i_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT], fapi2::buffer& o_repairs_applied, fapi2::buffer& o_repairs_exceeded) { @@ -476,7 +475,7 @@ fapi2::ReturnCode restore_repairs( const fapi2::Target& fapi2::buffer& o_repairs_applied, fapi2::buffer& o_repairs_exceeded) { - uint8_t l_bad_bits[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT] = {}; + uint8_t l_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] = {}; o_repairs_applied = 0; o_repairs_exceeded = 0; @@ -485,7 +484,7 @@ fapi2::ReturnCode restore_repairs( const fapi2::Target& { FAPI_TRY( mss::bad_dq_bitmap(l_dimm, &(l_bad_bits[0][0])) ); - FAPI_TRY( (restore_repairs_helper( + FAPI_TRY( (restore_repairs_helper( l_dimm, l_bad_bits, o_repairs_applied, o_repairs_exceeded)) ); } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H index d5840df40..f47729e87 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H @@ -34,6 +34,39 @@ namespace mss { +/// +/// @brief ATTR_BAD_DQ_BITMAP getter +/// @param[in] const ref to the TARGET_TYPE_DIMM +/// @param[out] uint8_t* memory to store the value +/// @note Generated by gen_accessors.pl generateParameters (PROC_CHIP) +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK +/// @note Bad DQ bitmap from a controller point of view. The data is a 10 byte bitmap for +/// each of 4 possible ranks. The bad DQ data is stored in NVRAM, and it is stored +/// in a special format translated to a DIMM Connector point of view. All of these +/// details are hidden from the user of this +/// attribute. +/// +inline fapi2::ReturnCode bad_dq_bitmap(const fapi2::Target& i_target, uint8_t* o_array) +{ + if (o_array == nullptr) + { + FAPI_ERR("nullptr passed to attribute accessor %s", __func__); + return fapi2::FAPI2_RC_INVALID_PARAMETER; + } + + uint8_t l_value[4][10]; + + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_BAD_DQ_BITMAP, i_target, l_value) ); + memcpy(o_array, &l_value, 40); + return fapi2::current_err; + +fapi_try_exit: + FAPI_ERR("failed accessing ATTR_BAD_DQ_BITMAP: 0x%lx", + uint64_t(fapi2::current_err)); + return fapi2::current_err; +} + + /// /// @brief ATTR_MSS_VOLT_VDDR getter /// @param[in] const ref to the TARGET_TYPE_MCBIST @@ -21281,38 +21314,6 @@ fapi_try_exit: return fapi2::current_err; } -/// -/// @brief ATTR_BAD_DQ_BITMAP getter -/// @param[in] const ref to the TARGET_TYPE_DIMM -/// @param[out] uint8_t* memory to store the value -/// @note Generated by gen_accessors.pl generateParameters (PROC_CHIP) -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK -/// @note Bad DQ bitmap from a controller point of view. The data is a 10 byte bitmap for -/// each of 4 possible ranks. The bad DQ data is stored in NVRAM, and it is stored -/// in a special format translated to a DIMM Connector point of view. All of these -/// details are hidden from the user of this -/// attribute. -/// -inline fapi2::ReturnCode bad_dq_bitmap(const fapi2::Target& i_target, uint8_t* o_array) -{ - if (o_array == nullptr) - { - FAPI_ERR("nullptr passed to attribute accessor %s", __func__); - return fapi2::FAPI2_RC_INVALID_PARAMETER; - } - - uint8_t l_value[4][10]; - - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_BAD_DQ_BITMAP, i_target, l_value) ); - memcpy(o_array, &l_value, 40); - return fapi2::current_err; - -fapi_try_exit: - FAPI_ERR("failed accessing ATTR_BAD_DQ_BITMAP: 0x%lx", - uint64_t(fapi2::current_err)); - return fapi2::current_err; -} - /// /// @brief ATTR_MSS_OVERRIDE_MEMDIAGS_BCMODE getter diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C index c7b557d9a..d98f7a56f 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -4065,7 +4065,7 @@ fapi2::ReturnCode reset_bad_bits( const fapi2::Target& i { for( const auto& d : mss::find_targets(i_target) ) { - uint8_t l_bad_dq[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT] = {}; + uint8_t l_bad_dq[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] = {}; FAPI_TRY( mss::bad_dq_bitmap(d, &(l_bad_dq[0][0])), "%s failed bad_dq_bitmap", mss::c_str(d) ); FAPI_TRY( reset_bad_bits_helper(d, l_bad_dq), "%s failed reset_bad_bits_helper", mss::c_str(d) ); @@ -4144,7 +4144,7 @@ fapi_try_exit: /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff no errors on the scoms /// fapi2::ReturnCode reset_bad_bits_helper( const fapi2::Target& i_target, - const uint8_t i_bad_dq[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT]) + const uint8_t (&i_bad_dq)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]) { typedef dp16Traits TT; @@ -4198,59 +4198,16 @@ fapi_try_exit: return fapi2::current_err; } -/// -/// @brief Write disable bits -/// @note This is different than a register write as it writes attributes which -/// cause firmware to act on the disabled bits. -/// @param[in] i_target the fapi2 target of the port -/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if no error on the scoms or attribute sets -/// -fapi2::ReturnCode record_bad_bits( const fapi2::Target& i_target ) -{ - // If we have a FIR set that could have caused our training fail, then skip checking bad bits in FW - // PRD will handle the FIR and retrigger the procedure -#ifdef __HOSTBOOT_MODULE - bool l_fir_error = false; - - // Note: using success here will cause an RC to not be logged - // We can still see if we do have a FIR error though - fapi2::ReturnCode l_rc(fapi2::FAPI2_RC_SUCCESS); - FAPI_TRY(mss::check::bad_fir_bits(i_target, l_rc, l_fir_error), "%s took an error while checking FIR's", - mss::c_str(i_target)); - - // Exit if we took a FIR error - PRD will handle bad bits - if(l_fir_error) - { - FAPI_INF("%s has FIR's set, exiting to let PRD handle it", mss::c_str(i_target)); - return fapi2::FAPI2_RC_SUCCESS; - } - -#endif - - for( const auto& d : mss::find_targets(i_target) ) - { - uint8_t l_data[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT] = {}; - - FAPI_TRY( mss::dp16::record_bad_bits_helper(d, l_data) ); - - // Write - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_BAD_DQ_BITMAP, d, l_data) ); - } - -fapi_try_exit: - return fapi2::current_err; -} - /// /// @brief Write disable bits - helper for testing /// @note This is different than a register write as it writes attributes which /// cause firmware to act on the disabled bits. /// @param[in] i_target the fapi2 target of the port -/// @param[out] o_bad_dq an array of [MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT] containing the attribute information +/// @param[out] o_bad_dq an array of [BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] containing the attribute information /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if bad bits can be repaired /// fapi2::ReturnCode record_bad_bits_helper( const fapi2::Target& i_target, - uint8_t (&o_bad_dq)[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT] ) + uint8_t (&o_bad_dq)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] ) { typedef dp16Traits TT; @@ -4749,5 +4706,19 @@ fapi_try_exit: } // close namespace wr_vref } // close namespace dp16 + +/// +/// @brief A generic bad bits setter - Nimbus specialization +/// @param[in] i_target the fapi2 target oon which training was conducted +/// @param[in] i_array the bad bits to set +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if bad bits can be repaired +/// +template <> +fapi2::ReturnCode set_bad_dq_bitmap(const fapi2::Target& i_target, + uint8_t (&i_array)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]) +{ + return FAPI_ATTR_SET(fapi2::ATTR_BAD_DQ_BITMAP, i_target, i_array); +} + } // close namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H index b7c22d974..bfde9b4ad 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015,2018 */ +/* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -43,6 +43,7 @@ #include #include +#include #include #include @@ -1063,7 +1064,7 @@ fapi2::ReturnCode reset_bad_bits(const fapi2::Target& i_ /// @return FAPI2_RC_SUCCESS if and only if ok /// fapi2::ReturnCode reset_bad_bits_helper(const fapi2::Target& i_target, - const uint8_t i_bad_dq[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT]); + const uint8_t (&i_bad_dq)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]); /// /// @brief Configures the DQS_DISABLE register based upon the bad DQ information for x4 DRAM @@ -2055,25 +2056,16 @@ fapi2::ReturnCode process_bad_bits( const fapi2::Target& const fapi2::Target& i_dimm, const uint64_t l_rp ); -/// -/// @brief Write disable bits -/// @note This is different than a register write as it writes attributes which -/// cause firmware to act on the disabled bits. -/// @param[in] i_target the fapi2 target of the port -/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if bad bits can be repaired -/// -fapi2::ReturnCode record_bad_bits( const fapi2::Target& i_target ); - /// /// @brief Write disable bits - helper for testing /// @note This is different than a register write as it writes attributes which /// cause firmware to act on the disabled bits. /// @param[in] i_target the fapi2 target of the port -/// @param[out] o_bad_dq an array of [MAX_DIMM_PER_PORT][MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT] containing the attribute information +/// @param[out] o_bad_dq an array of [MAX_DIMM_PER_PORT][BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] containing the attribute information /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if bad bits can be repaired /// fapi2::ReturnCode record_bad_bits_helper( const fapi2::Target& i_target, - uint8_t (&o_bad_dq)[MAX_RANK_PER_DIMM][BAD_DQ_BYTE_COUNT] ); + uint8_t (&o_bad_dq)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] ); /// /// @brief Process read vref calibration errors @@ -2508,6 +2500,49 @@ inline void get_wr_vref_value( const fapi2::buffer i_data, } } // close namespace wr_vref + +/// +/// @brief Interface class for recording bad bits +/// @note Bad bits could change for new generations of chips +/// an interface class is used to simplify the interactions +/// +class bad_bits_interface +{ + public: + + /// + /// @brief Default constructor + /// + bad_bits_interface() = default; + + /// + /// @brief Default destructor + /// + ~bad_bits_interface() = default; + + /// + /// @param[in] i_target the DIMM to record training results on + /// @param[out] o_bad_bits the processed bad bits + /// + fapi2::ReturnCode record_bad_bits_interface( const fapi2::Target& i_target, + uint8_t (&o_bad_dq)[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT]) const + { + return record_bad_bits_helper(i_target, o_bad_dq); + } +}; + +/// +/// @brief Writes the bad bits into the bad bits attribute +/// @note Wrapper function to beautify the interface to the genric function +/// @param[in] i_target the fapi2 target of the port +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if bad bits can be repaired +/// +inline fapi2::ReturnCode record_bad_bits( const fapi2::Target& i_target ) +{ + bad_bits_interface l_interface; + return mss::record_bad_bits(i_target, l_interface); +} + } // close namespace dp16 } // close namespace mss diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H index 510cc1a19..d82723973 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H @@ -75,8 +75,6 @@ enum sizes NUM_MRW_FREQS = 4, ///< Used for ATTR_MSS_MRW_SUPPORTED_FREQ NUM_LRDIMM_TRAINING_PATTERNS = 5, ///< Used for ATTR_MSS_LRDIMM_TRAINING_PATTERN - - BAD_DQ_BYTE_COUNT = 10, ///< Elements in a BAD_DQ_BITMAP attribute array ROW_REPAIR_BYTE_COUNT = 4, ///< Elements in a ROW_REPAIR_DATA attribute array. BYTES_PER_GB = 1000000000, ///< Multiplier to go from GB to B -- cgit v1.2.1