summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/check.C20
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/check.H16
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C9
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H65
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C67
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H61
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H2
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/memory_dq_attributes.xml20
-rw-r--r--src/import/generic/memory/lib/mss_generic_attribute_getters.H27
-rw-r--r--src/import/generic/memory/lib/utils/mss_bad_bits.H80
-rw-r--r--src/import/generic/memory/lib/utils/mss_generic_check.H12
-rw-r--r--src/import/generic/memory/lib/utils/shared/mss_generic_consts.H2
-rwxr-xr-xsrc/import/generic/memory/tools/gen_accessors.pl4
-rwxr-xr-xsrc/import/generic/memory/tools/gen_accessors.pm28
-rw-r--r--src/import/generic/procedures/xml/attribute_info/generic_dq_attributes.xml19
15 files changed, 282 insertions, 150 deletions
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<fapi2::TARGET_TYPE_MCBIST>& i_target,
- fapi2::ReturnCode& io_rc,
- bool& o_fir_error )
+fapi2::ReturnCode bad_fir_bits<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& 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<fapi2::TARGET_TYPE_MCA>& i_target,
- fapi2::ReturnCode& io_rc,
- bool& o_fir_error )
+fapi2::ReturnCode bad_fir_bits<mss::mc_type::NIMBUS>( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ fapi2::ReturnCode& io_rc,
+ bool& o_fir_error )
{
const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(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 <fapi2.H>
#include <generic/memory/lib/utils/scom.H>
+#include <generic/memory/lib/utils/mss_generic_check.H>
namespace mss
{
@@ -94,17 +95,6 @@ fapi2::ReturnCode pll_fir( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_tar
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<T>& 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
/// @param[in] i_target - the target on which to operate
@@ -168,7 +158,7 @@ fapi2::ReturnCode hostboot_fir_or_pll_fail( const fapi2::Target<T>& 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<mss::mc_type::NIMBUS>(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::TARGET_TYPE_DIMM, MAX_RANK_PER_DIMM, BAD_DQ_BYTE_COUNT>(
+fapi2::ReturnCode restore_repairs_helper<fapi2::TARGET_TYPE_DIMM, BAD_BITS_RANKS, BAD_DQ_BYTE_COUNT>(
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& 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<uint8_t>& o_repairs_applied,
fapi2::buffer<uint8_t>& o_repairs_exceeded)
{
@@ -476,7 +475,7 @@ fapi2::ReturnCode restore_repairs( const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
fapi2::buffer<uint8_t>& o_repairs_applied,
fapi2::buffer<uint8_t>& 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<fapi2::TARGET_TYPE_MCA>&
{
FAPI_TRY( mss::bad_dq_bitmap(l_dimm, &(l_bad_bits[0][0])) );
- FAPI_TRY( (restore_repairs_helper<fapi2::TARGET_TYPE_DIMM, MAX_RANK_PER_DIMM, BAD_DQ_BYTE_COUNT>(
+ FAPI_TRY( (restore_repairs_helper<fapi2::TARGET_TYPE_DIMM, BAD_BITS_RANKS, BAD_DQ_BYTE_COUNT>(
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
@@ -35,6 +35,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<fapi2::TARGET_TYPE_DIMM>& 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
/// @param[out] uint32_t& reference to store the value
@@ -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<fapi2::TARGET_TYPE_DIMM>& 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<fapi2::TARGET_TYPE_MCA>& i
{
for( const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(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<fapi2::TARGET_TYPE_DIMM>& 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<TARGET_TYPE_MCA> TT;
@@ -4199,58 +4199,15 @@ fapi_try_exit:
}
///
-/// @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<fapi2::TARGET_TYPE_MCA>& 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<fapi2::TARGET_TYPE_DIMM>(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<fapi2::TARGET_TYPE_DIMM>& 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<TARGET_TYPE_MCA> 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<mss::mc_type::NIMBUS>(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& 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 <generic/memory/lib/utils/scom.H>
#include <generic/memory/lib/utils/find.H>
+#include <generic/memory/lib/utils/mss_bad_bits.H>
#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
@@ -1063,7 +1064,7 @@ fapi2::ReturnCode reset_bad_bits(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_
/// @return FAPI2_RC_SUCCESS if and only if ok
///
fapi2::ReturnCode reset_bad_bits_helper(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& 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
@@ -2056,24 +2057,15 @@ fapi2::ReturnCode process_bad_bits( const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
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<fapi2::TARGET_TYPE_MCA>& 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<fapi2::TARGET_TYPE_DIMM>& 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<uint64_t> 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<fapi2::TARGET_TYPE_DIMM>& 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<fapi2::TARGET_TYPE_MCA>& i_target )
+{
+ bad_bits_interface l_interface;
+ return mss::record_bad_bits<mss::mc_type::NIMBUS>(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 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016,2017 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -40,22 +40,4 @@
<array>2 72</array>
</attribute>
- <attribute>
- <id>ATTR_BAD_DQ_BITMAP</id>
- <targetType>TARGET_TYPE_DIMM</targetType>
- <description>
- 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.
- </description>
- <valueType>uint8</valueType>
- <mssAccessorName>bad_dq_bitmap</mssAccessorName>
- <array>4 10</array>
- <platInit/>
- <initToZero/>
- <writeable/>
- </attribute>
-
</attributes>
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
@@ -957,6 +957,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<fapi2::TARGET_TYPE_DIMM>& 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
/// @param[out] uint8_t& reference to store the value
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 <sglancy@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: FSP:HB
+
+#ifndef _MSS_BAD_BITS_H_
+#define _MSS_BAD_BITS_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mss_generic_check.H>
+#include <generic/memory/lib/mss_generic_attribute_setters.H>
+
+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 <mss::mc_type MC>
+fapi2::ReturnCode set_bad_dq_bitmap(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& 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 <mss::mc_type MC, fapi2::TargetType T, class I >
+inline fapi2::ReturnCode record_bad_bits( const fapi2::Target<T>& 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<MC, T>(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<fapi2::TARGET_TYPE_DIMM>(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<MC>(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
@@ -46,6 +46,18 @@ 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<T>& 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
/// @tparam IT input data 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
@@ -941,6 +941,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
# @param[in] attr - reference to the attribute to process
@@ -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 @@
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
<attributes>
+
+ <attribute>
+ <id>ATTR_BAD_DQ_BITMAP</id>
+ <targetType>TARGET_TYPE_DIMM</targetType>
+ <description>
+ 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.
+ </description>
+ <valueType>uint8</valueType>
+ <mssAccessorName>bad_dq_bitmap</mssAccessorName>
+ <array>4 10</array>
+ <platInit/>
+ <initToZero/>
+ <writeable/>
+ </attribute>
+
</attributes>
OpenPOWER on IntegriCloud