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 - .../xml/attribute_info/memory_dq_attributes.xml | 20 +----- .../memory/lib/mss_generic_attribute_getters.H | 27 ++++++++ src/import/generic/memory/lib/utils/mss_bad_bits.H | 80 ++++++++++++++++++++++ .../generic/memory/lib/utils/mss_generic_check.H | 12 ++++ .../memory/lib/utils/shared/mss_generic_consts.H | 2 + src/import/generic/memory/tools/gen_accessors.pl | 4 +- src/import/generic/memory/tools/gen_accessors.pm | 28 ++++++-- .../xml/attribute_info/generic_dq_attributes.xml | 19 +++++ 15 files changed, 282 insertions(+), 150 deletions(-) (limited to 'src') 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 diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_dq_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_dq_attributes.xml index 977094159..df84976f0 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/memory_dq_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_dq_attributes.xml @@ -5,7 +5,7 @@ - + @@ -40,22 +40,4 @@ 2 72 - - ATTR_BAD_DQ_BITMAP - TARGET_TYPE_DIMM - - 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. - - uint8 - bad_dq_bitmap - 4 10 - - - - - diff --git a/src/import/generic/memory/lib/mss_generic_attribute_getters.H b/src/import/generic/memory/lib/mss_generic_attribute_getters.H index d97816d47..dc22d4fb0 100644 --- a/src/import/generic/memory/lib/mss_generic_attribute_getters.H +++ b/src/import/generic/memory/lib/mss_generic_attribute_getters.H @@ -956,6 +956,33 @@ fapi_try_exit: } +/// +/// @brief ATTR_BAD_DQ_BITMAP getter +/// @param[in] const ref to the TARGET_TYPE_DIMM +/// @param[out] uint8_t&[] array reference to store the value +/// @note Generated by gen_accessors.pl generate_other_attr_params +/// @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 get_bad_dq_bitmap(const fapi2::Target& i_target, + uint8_t (&o_array)[4][10]) +{ + 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 getting ATTR_BAD_DQ_BITMAP: 0x%lx", + uint64_t(fapi2::current_err)); + return fapi2::current_err; +} + + /// /// @brief ATTR_MEM_EFF_DRAM_GEN getter /// @param[in] const ref to the TARGET_TYPE_DIMM 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 859a12b5e..cae2bd543 100644 --- a/src/import/generic/memory/lib/utils/mss_bad_bits.H +++ b/src/import/generic/memory/lib/utils/mss_bad_bits.H @@ -22,3 +22,83 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mss_bad_bits.C +/// @brief Contains the generic bad bits logic +/// +// *HWP HWP Owner: Stephen Glancy +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_BAD_BITS_H_ +#define _MSS_BAD_BITS_H_ + +#include +#include +#include +#include + +namespace mss +{ + +/// +/// @brief A generic bad bits setter +/// @tparam MC type memory controller type +/// @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]); + +/// +/// @brief Records bad bits into the bad bits attribute +/// @tparam MC MC type on which training was run +/// @tparam T fapi2::TargetType on which training was conducted +/// @tparam I Interface class used to abstract converting bad bits into the attribute +/// @param[in] i_target the fapi2 target oon which training was conducted +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if bad bits can be repaired +/// +template +inline fapi2::ReturnCode record_bad_bits( const fapi2::Target& i_target, const I& i_helper ) +{ + // 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[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] = {}; + + FAPI_TRY( i_helper.record_bad_bits_interface(d, l_data) ); + + // Write + FAPI_TRY(set_bad_dq_bitmap(d, l_data)); + } + +fapi_try_exit: + return fapi2::current_err; +} + +} // ns +#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 f10f4d79a..be9e12f14 100644 --- a/src/import/generic/memory/lib/utils/mss_generic_check.H +++ b/src/import/generic/memory/lib/utils/mss_generic_check.H @@ -45,6 +45,18 @@ namespace mss namespace check { +/// +/// @brief Checks whether any FIRs have lit up on a target +/// @tparam MC MC type for which to check FIR's +/// @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< mss::mc_type MC, fapi2::TargetType T > +fapi2::ReturnCode bad_fir_bits( const fapi2::Target& i_target, fapi2::ReturnCode& io_rc, bool& o_fir_error ); + /// /// @brief Checks conditional passes and implements traces & exits if it fails /// @tparam T fapi2 target type 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 d95ebcf45..c3c3a8f4a 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 @@ -50,6 +50,8 @@ enum common_consts { DEFAULT_POLL_LIMIT = 50, ///< the number of poll attempts in the event we can't calculate another MEMCMP_EQUAL = 0, ///< Equal comparison value for memcmp + BAD_BITS_RANKS = 4, ///< Bad bit attribute's number of ranks + BAD_DQ_BYTE_COUNT = 10, ///< Bad bit attribute's number of byte }; /// diff --git a/src/import/generic/memory/tools/gen_accessors.pl b/src/import/generic/memory/tools/gen_accessors.pl index b70cef8d7..4100069d0 100755 --- a/src/import/generic/memory/tools/gen_accessors.pl +++ b/src/import/generic/memory/tools/gen_accessors.pl @@ -66,8 +66,8 @@ BEGIN } use lib "$pwd"; -use lib $ENV{PROJECT_ROOT} . "/generic/memory/tools"; # EKB Path -use lib $ENV{PROJECT_ROOT} . "/src/import/generic/memory/tools"; # Hostboot Path +use lib $ENV{PROJECT_ROOT} . "/generic/memory/tools"; # EKB Path +use lib $ENV{PROJECT_ROOT} . "/src/import/generic/memory/tools"; # Hostboot Path use English; use Carp qw( croak ); diff --git a/src/import/generic/memory/tools/gen_accessors.pm b/src/import/generic/memory/tools/gen_accessors.pm index a3adddf42..ddcb1e0f6 100755 --- a/src/import/generic/memory/tools/gen_accessors.pm +++ b/src/import/generic/memory/tools/gen_accessors.pm @@ -940,6 +940,28 @@ sub generate_setters } +# +# @brief Helper function to idenitify if we're an MC port target +# @param[in] system - system type +# @return reference to an array of target types +# +sub identify_mc_port_helper +{ + + # Gets input and checks to make sure it's valid + croak "Incorrect number of inputs passed into gen_accessors::identify_mc_port_helper" if ( @ARG != 1 ); + + my ($system) = @ARG; + + my @mc_port_target_types = (); + foreach my $type ( keys( %{ ${ +TARGET_TYPES }{$system} } ) ) + { + push( @mc_port_target_types, ${ +TARGET_TYPES }{$system}{$type} ) if ( $type ne "DIMM" ); + } + + return \@mc_port_target_types; +} + # # @brief Generate accessor methods for a given attribute # @param[in] system - system type @@ -960,11 +982,7 @@ sub generate_accessor_methods my @s_parameters = (); # Generate parameter info depending on target type - my @target_types = (); - foreach my $type ( keys( %{ ${ +TARGET_TYPES }{$system} } ) ) - { - push( @target_types, ${ +TARGET_TYPES }{$system}{$type} ); - } + my @target_types = @{ identify_mc_port_helper($system) }; my $attr_type = $attr->{targetType}; if ( grep( /^$attr_type$/, @target_types ) ) diff --git a/src/import/generic/procedures/xml/attribute_info/generic_dq_attributes.xml b/src/import/generic/procedures/xml/attribute_info/generic_dq_attributes.xml index 333ee3d82..267e30d70 100644 --- a/src/import/generic/procedures/xml/attribute_info/generic_dq_attributes.xml +++ b/src/import/generic/procedures/xml/attribute_info/generic_dq_attributes.xml @@ -23,4 +23,23 @@ + + + ATTR_BAD_DQ_BITMAP + TARGET_TYPE_DIMM + + 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. + + uint8 + bad_dq_bitmap + 4 10 + + + + + -- cgit v1.2.1