From 5318cf7e4a01aaca4663fbb04c2ef3dd10277bfc Mon Sep 17 00:00:00 2001 From: Nico Fajardo Date: Wed, 20 Nov 2019 15:45:52 -0600 Subject: Porting repair_state class and related functions Cleaning up ported p9 code; fixing code beauty in exp_port_ut; fixing lingering configure_wrq issues; cleaning up more ported p9 code; fixing include order errors in nvdimm; both p9 & exp build cleanly; fixing 1R DIMM exclusion in explorer_mss_ut; fixing bad call to cycle time with include order change; fixing exp_scrub issue with cycle time; fixing exp UT fail Change-Id: If88a5931c09e305aa115c367b54e2b586db37e58 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/87535 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Reviewed-by: Louis Stermole Reviewed-by: STEPHEN GLANCY Dev-Ready: STEPHEN GLANCY Tested-by: Hostboot CI Tested-by: HWSV CI Reviewed-by: Mark Pizzutillo Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/89104 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Daniel M Crowell --- .../chips/p9/procedures/hwp/memory/lib/mc/port.C | 250 +-------------------- 1 file changed, 1 insertion(+), 249 deletions(-) (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C') 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 079bdbde2..a07fea3d9 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 @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2019 */ +/* Contributors Listed Below - COPYRIGHT 2016,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -306,210 +306,6 @@ fapi_try_exit: return fapi2::current_err; } -/// -/// @brief Convert a bitmap from the BAD_DQ_BITMAP attribute to a vector of bad DQ indexes -/// @param[in] i_bad_bits an 8-bit bitmap of bad bits -/// @param[in] i_nibble which nibble of the bitmap to convert -/// @return std::vector of DQ bits marked as bad in the bitmap -/// -std::vector bad_bit_helper(const uint8_t i_bad_bits, const size_t i_nibble) -{ - std::vector l_output; - fapi2::buffer l_bit_buffer(i_bad_bits); - - const size_t l_start = (i_nibble == 0) ? 0 : BITS_PER_NIBBLE; - - for (size_t l_offset = 0; l_offset < BITS_PER_NIBBLE; ++l_offset) - { - if (l_bit_buffer.getBit(l_start + l_offset)) - { - l_output.push_back(l_start + l_offset); - } - } - - return l_output; -} - -/// -/// @brief Place a symbol mark in a Firmware Mark Store register -/// @param[in] i_target the DIMM target -/// @param[in] i_rank the rank -/// @param[in] i_dq the bad DQ bit -/// @return FAPI2_RC_SUCCESS if and only if ok -/// -template<> -fapi2::ReturnCode place_symbol_mark(const fapi2::Target& i_target, - const uint64_t i_rank, - const uint64_t i_dq) -{ - const auto& l_mca = mss::find_target(i_target); - const auto l_dimm_idx = mss::index(i_target); - const auto l_rank_idx = mss::index(i_rank); - - uint8_t l_galois = 0; - mss::mcbist::address l_addr; - - // For symbol marks, we set the appropriate Firmware Mark Store reg, with the symbol's - // Galois code, mark_type=SYMBOL, mark_region=MRANK, and the address of the DIMM+MRANK - // TODO RTC:165133 Remove static_cast once Galois API is updated to accept uint64_t input - FAPI_TRY( mss::ecc::dq_to_galois(static_cast(i_dq), l_galois) ); - - l_addr.set_dimm(l_dimm_idx).set_master_rank(l_rank_idx); - - FAPI_INF("%s Setting firmware symbol mark on rank:%d dq:%d galois:0x%02x", - mss::c_str(i_target), i_rank, i_dq, l_galois); - FAPI_TRY( mss::ecc::set_fwms(l_mca, i_rank, l_galois, mss::ecc::fwms::mark_type::SYMBOL, - mss::ecc::fwms::mark_region::MRANK, l_addr) ); - - // Apply workaround for HW474117 if we place a symbol mark - FAPI_TRY( mss::workarounds::disable_bypass(l_mca) ); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Place a chip mark in a Hardware Mark Store register -/// @param[in] i_target the DIMM target -/// @param[in] i_rank the rank -/// @param[in] i_dq one of the bad DQ bits in the bad nibble -/// @return FAPI2_RC_SUCCESS if and only if ok -/// -template<> -fapi2::ReturnCode place_chip_mark(const fapi2::Target& i_target, - const uint64_t i_rank, - const uint64_t i_dq) -{ - const auto& l_mca = mss::find_target(i_target); - - uint8_t l_galois = 0; - uint8_t l_symbol = 0; - - // For chip marks, we set the appropriate Hardware Mark Store reg, with the Galois code - // of the first (smallest) symbol in the bad nibble, and both confirmed and exit1 bits set - FAPI_TRY( mss::ecc::dq_to_symbol(static_cast(i_dq), l_symbol) ); - - // Round down to the nearest "nibble" to get the correct symbol, then get the Galois code for it - l_symbol = (l_symbol / BITS_PER_NIBBLE) * BITS_PER_NIBBLE; - FAPI_TRY( mss::ecc::symbol_to_galois(l_symbol, l_galois) ); - - FAPI_INF("%s Setting hardware (chip) mark on rank:%d galois:0x%02x", mss::c_str(i_target), i_rank, l_galois); - FAPI_TRY( mss::ecc::set_hwms(l_mca, i_rank, l_galois) ); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute, helper function for unit testing -/// Specialization for TARGET_TYPE_DIMM -/// @param[in] i_target the DIMM target -/// @param[in] i_bad_bits the bad bits values from the VPD, for the specified DIMM -/// @param[out] o_repairs_applied 8-bit mask, where a bit set means a rank had repairs applied (bit0-7 = rank0-7) -/// @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 -/// -template<> -fapi2::ReturnCode restore_repairs_helper( - const fapi2::Target& i_target, - const uint8_t i_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT], - fapi2::buffer& o_repairs_applied, - fapi2::buffer& o_repairs_exceeded) -{ - FAPI_INF("%s Restore repair marks from bad DQ data", mss::c_str(i_target)); - - std::vector l_ranks; - const auto l_dimm_idx = mss::index(i_target); - - FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); - - // loop through ranks - for (const auto l_rank : l_ranks) - { - const auto l_rank_idx = mss::index(l_rank); - - repair_state_machine l_machine; - - // loop through bytes - for (uint64_t l_byte = 0; l_byte < (MAX_DQ_NIBBLES / NIBBLES_PER_BYTE); ++l_byte) - { - for (size_t l_nibble = 0; l_nibble < NIBBLES_PER_BYTE; ++l_nibble) - { - const auto l_bad_dq_vector = bad_bit_helper(i_bad_bits[l_rank_idx][l_byte], l_nibble); - FAPI_DBG("Total bad bits on DIMM:%d rank:%d nibble%d: %d", - l_dimm_idx, l_rank, (l_byte * NIBBLES_PER_BYTE) + l_nibble, l_bad_dq_vector.size()); - - // apply repairs and update repair machine state - // if there are no bad bits (l_bad_dq_vector.size() == 0) no action is necessary - if (l_bad_dq_vector.size() == 1) - { - // l_bad_dq_vector is per byte, so multiply up to get the bad dq's index - const uint64_t l_dq = l_bad_dq_vector[0] + (l_byte * BITS_PER_BYTE); - FAPI_TRY( l_machine.one_bad_dq(i_target, l_rank, l_dq, o_repairs_applied, o_repairs_exceeded) ); - } - else if (l_bad_dq_vector.size() > 1) - { - // l_bad_dq_vector is per byte, so multiply up to get the bad dq's index - const uint64_t l_dq = l_bad_dq_vector[0] + (l_byte * BITS_PER_BYTE); - FAPI_TRY( l_machine.multiple_bad_dq(i_target, l_rank, l_dq, o_repairs_applied, o_repairs_exceeded) ); - } - - // if repairs have been exceeded, we're done - if (o_repairs_exceeded.getBit(l_dimm_idx)) - { - FAPI_INF("Repairs exceeded on DIMM %s", mss::c_str(i_target)); - return fapi2::FAPI2_RC_SUCCESS; - } - } // end loop through nibbles - } // end loop through bytes - } // end loop through ranks - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Restore symbol and chip marks according to BAD_DQ_BITMAP attribute -/// Specialization for TARGET_TYPE_MCA -/// @param[in] i_target A target representing a port -/// @param[out] o_repairs_applied 8-bit mask, where a bit set means a rank had repairs applied (bit0-7 = rank0-7) -/// @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 -/// -template<> -fapi2::ReturnCode restore_repairs( const fapi2::Target& i_target, - fapi2::buffer& o_repairs_applied, - fapi2::buffer& o_repairs_exceeded) -{ - uint8_t l_bad_bits[BAD_BITS_RANKS][BAD_DQ_BYTE_COUNT] = {}; - - o_repairs_applied = 0; - o_repairs_exceeded = 0; - - for (const auto& l_dimm : mss::find_targets(i_target)) - { - FAPI_TRY( mss::bad_dq_bitmap(l_dimm, &(l_bad_bits[0][0])) ); - - FAPI_TRY( (restore_repairs_helper( - l_dimm, l_bad_bits, o_repairs_applied, o_repairs_exceeded)) ); - } - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Set a new state in the repair state machine -/// @tparam T, the fapi2 target type of the DIMM -/// @param[in,out] io_machine the repair state machine -/// @param[in] i_state shared pointer to the new state to set -/// -template< fapi2::TargetType T > -void repair_state::set_state(repair_state_machine& io_machine, std::shared_ptr> i_state) -{ - io_machine.update_state(i_state); -} - /// /// @brief Perform a repair for a single bad DQ bit in a nibble /// Specialization for TARGET_TYPE_DIMM @@ -803,48 +599,4 @@ fapi2::ReturnCode chip_and_symbol_mark::multiple_bad_dq return fapi2::FAPI2_RC_SUCCESS; } -/// -/// @brief Perform a repair for a single bad DQ bit in a nibble -/// @tparam T, the fapi2 target type of the DIMM -/// @param[in] i_target the DIMM target -/// @param[in] i_rank the rank -/// @param[in] i_dq the DQ bit index -/// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied -/// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired -/// @return FAPI2_RC_SUCCESS if and only if ok -/// -template< fapi2::TargetType T > -fapi2::ReturnCode repair_state_machine::one_bad_dq(const fapi2::Target& i_target, - const uint64_t i_rank, - const uint64_t i_dq, - fapi2::buffer& io_repairs_applied, - fapi2::buffer& io_repairs_exceeded) -{ - FAPI_TRY( iv_repair_state->one_bad_dq(*this, i_target, i_rank, i_dq, io_repairs_applied, io_repairs_exceeded) ); -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief Perform a repair for multiple bad DQ bits in a nibble -/// @tparam T, the fapi2 target type of the DIMM -/// @param[in] i_target the DIMM target -/// @param[in] i_rank the rank -/// @param[in] i_dq one of the bad DQ bit indexes -/// @param[in,out] io_repairs_applied 8-bit mask, where a bit set means that rank had repairs applied -/// @param[in,out] io_repairs_exceeded 2-bit mask, where a bit set means that DIMM had more bad bits than could be repaired -/// @return FAPI2_RC_SUCCESS if and only if ok -/// -template< fapi2::TargetType T > -fapi2::ReturnCode repair_state_machine::multiple_bad_dq(const fapi2::Target& i_target, - const uint64_t i_rank, - const uint64_t i_dq, - fapi2::buffer& io_repairs_applied, - fapi2::buffer& io_repairs_exceeded) -{ - FAPI_TRY( iv_repair_state->multiple_bad_dq(*this, i_target, i_rank, i_dq, io_repairs_applied, io_repairs_exceeded) ); -fapi_try_exit: - return fapi2::current_err; -} - } // ns mss -- cgit v1.2.1