From 5b93d4000b1cdab6a8a778cfae858a8ca4cb7dfb Mon Sep 17 00:00:00 2001 From: Stephen Glancy Date: Mon, 19 Mar 2018 14:47:00 -0500 Subject: Enables RCD protect for centaur systems Change-Id: I725cc6f8f9b6ff4ffd691a0f1ebe0cc3a0cb8a65 CQ:SW438004 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56031 Tested-by: FSP CI Jenkins Dev-Ready: STEPHEN GLANCY Reviewed-by: Louis Stermole Tested-by: Jenkins Server Reviewed-by: ANDRE A. MARIN Tested-by: Hostboot CI Reviewed-by: Jennifer A. Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/56041 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Daniel M. Crowell --- .../procedures/hwp/initfiles/centaur_mba_scom.C | 27 +- .../procedures/hwp/memory/p9c_mss_draminit_mc.C | 817 +++++++++++++-------- .../procedures/hwp/memory/p9c_mss_draminit_mc.H | 120 ++- .../p9c_memory_mss_draminit_mc_errors.xml | 18 +- 4 files changed, 682 insertions(+), 300 deletions(-) (limited to 'src/import/chips') diff --git a/src/import/chips/centaur/procedures/hwp/initfiles/centaur_mba_scom.C b/src/import/chips/centaur/procedures/hwp/initfiles/centaur_mba_scom.C index 1ba41401d..459c81468 100644 --- a/src/import/chips/centaur/procedures/hwp/initfiles/centaur_mba_scom.C +++ b/src/import/chips/centaur/procedures/hwp/initfiles/centaur_mba_scom.C @@ -1238,6 +1238,8 @@ fapi2::ReturnCode centaur_mba_scom(const fapi2::Target& && (l_TGT0_ATTR_CEN_EFF_IBM_TYPE[literal_0][literal_0] == literal_23))) && (l_TGT0_ATTR_CEN_EFF_NUM_DROPS_PER_PORT == literal_1)) && (l_TGT0_ATTR_CEN_EFF_DIMM_TYPE == literal_3)); uint64_t l_def_IS7C = (l_def_7c_1socket || l_def_7c_2socket); + uint64_t l_def_IS3A = (l_def_3a_1socket || l_def_3a_2socket); + uint64_t l_def_IS3B = (l_def_3b_1socket || l_def_3b_2socket); uint64_t l_def_7b_2socket = (((((l_TGT0_ATTR_CHIP_UNIT_POS == literal_1) && (l_TGT0_ATTR_CEN_EFF_IBM_TYPE[literal_1][literal_0] == literal_22)) || ((l_TGT0_ATTR_CHIP_UNIT_POS == literal_0) && (l_TGT0_ATTR_CEN_EFF_IBM_TYPE[literal_0][literal_0] == literal_22))) @@ -1253,7 +1255,6 @@ fapi2::ReturnCode centaur_mba_scom(const fapi2::Target& && (l_TGT0_ATTR_CEN_EFF_CUSTOM_DIMM == literal_1))); uint64_t l_def_IS3b_IS7b = ((((l_def_3b_1socket || l_def_3b_2socket) || l_def_4b_ddr4_cdimm) || l_def_7b_1socket) || l_def_7b_2socket); - uint64_t l_def_IS3B = (l_def_3b_1socket || l_def_3b_2socket); fapi2::ATTR_CEN_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA_Type l_TGT0_ATTR_CEN_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA, TGT0, l_TGT0_ATTR_CEN_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA)); @@ -5404,7 +5405,11 @@ fapi2::ReturnCode centaur_mba_scom(const fapi2::Target& l_scom_buffer.insert<0, 6, 58, uint64_t>(literal_0b010000 ); } - if ((l_def_IS3A_IS3B == literal_1)) + if ((l_def_IS3A == literal_1)) + { + l_scom_buffer.insert<12, 6, 58, uint64_t>(literal_0b111100 ); + } + else if ((l_def_IS3B == literal_1)) { l_scom_buffer.insert<12, 6, 58, uint64_t>(literal_0b010100 ); } @@ -5461,7 +5466,11 @@ fapi2::ReturnCode centaur_mba_scom(const fapi2::Target& l_scom_buffer.insert<12, 6, 58, uint64_t>(literal_0b010100 ); } - if ((l_def_IS3A_IS3B == literal_1)) + if ((l_def_IS3A == literal_1)) + { + l_scom_buffer.insert<18, 6, 58, uint64_t>(literal_0b111100 ); + } + else if ((l_def_IS3B == literal_1)) { l_scom_buffer.insert<18, 6, 58, uint64_t>(literal_0b011100 ); } @@ -5880,7 +5889,11 @@ fapi2::ReturnCode centaur_mba_scom(const fapi2::Target& l_scom_buffer.insert<0, 6, 58, uint64_t>(literal_0b101100 ); } - if ((l_def_IS3A_IS3B == literal_1)) + if ((l_def_IS3A == literal_1)) + { + l_scom_buffer.insert<12, 6, 58, uint64_t>(literal_0b111100 ); + } + else if ((l_def_IS3B == literal_1)) { l_scom_buffer.insert<12, 6, 58, uint64_t>(literal_0b100100 ); } @@ -5921,7 +5934,11 @@ fapi2::ReturnCode centaur_mba_scom(const fapi2::Target& l_scom_buffer.insert<12, 6, 58, uint64_t>(literal_0b111100 ); } - if ((l_def_IS3A_IS3B == literal_1)) + if ((l_def_IS3A == literal_1)) + { + l_scom_buffer.insert<18, 6, 58, uint64_t>(literal_0b111100 ); + } + else if ((l_def_IS3B == literal_1)) { l_scom_buffer.insert<18, 6, 58, uint64_t>(literal_0b101100 ); } diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C index babd24945..7366c3f84 100644 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -52,11 +52,13 @@ #include #include #include +#include #include //---------------------------------------------------------------------- // Address Includes //---------------------------------------------------------------------- #include +#include extern "C" { @@ -72,44 +74,43 @@ extern "C" { const auto l_mbaChiplets = i_target.getChildren(); // Step One: Set IML COMPLETE - FAPI_INF( "+++ Setting IML Complete +++"); + FAPI_INF( "%s +++ Setting IML Complete +++", mss::c_str(i_target)); FAPI_TRY(mss_set_iml_complete(i_target)); // Loop through the 2 MBA's for (const auto& l_mba : l_mbaChiplets) { // Step Two: Disable CCS address lines - FAPI_INF( "+++ Disabling CCS Address Lines +++"); + FAPI_INF( "%s +++ Disabling CCS Address Lines +++", mss::c_str(i_target)); FAPI_TRY(mss_ccs_mode_reset(l_mba), "---Error During CCS Mode Reset"); // Step Two.1: Check RCD protect time on RDIMM and LRDIMM - FAPI_INF( "+++ Check RCD protect time on RDIMM and LRDIMM +++"); - //forced this to only run if the test type is NOT DDR4 - as DDR4 ISRDIMMs are having IPL issues - //FAPI_TRY(mss_check_RCD_protect_time(l_mba), "---Error During Check RCD protect time"); + FAPI_INF( "%s +++ Check RCD protect time on RDIMM and LRDIMM +++", mss::c_str(i_target)); + FAPI_TRY(mss_check_RCD_protect_time(l_mba), "---Error During Check RCD protect time"); //Step Two.2: Enable address inversion on each MBA for ALL CARDS - FAPI_INF("+++ Setting up adr inversion for port 1 +++"); + FAPI_INF( "%s +++ Setting up adr inversion for port 1 +++", mss::c_str(i_target)); FAPI_TRY(mss_enable_addr_inversion(l_mba), "---Error During ADR Inversion"); // Step Three: Enable Refresh - FAPI_INF( "+++ Enabling Refresh +++"); + FAPI_INF( "%s +++ Enabling Refresh +++", mss::c_str(i_target)); FAPI_TRY(fapi2::getScom(l_mba, CEN_MBA_MBAREF0Q, l_mba01_ref0q_data_buffer_64)); //Bit 0 is enable - l_mba01_ref0q_data_buffer_64.setBit<0>(); + l_mba01_ref0q_data_buffer_64.setBit(); FAPI_TRY(fapi2::putScom(l_mba, CEN_MBA_MBAREF0Q, l_mba01_ref0q_data_buffer_64)); // Step Four: Setup Periodic Cals - FAPI_INF( "+++ Setting Up Periodic Cals +++"); + FAPI_INF( "%s +++ Setting Up Periodic Cals +++", mss::c_str(i_target)); FAPI_TRY(mss_enable_periodic_cal(l_mba), "---Error During Periodic Cal Setup and Enable"); } // Step Six: Setup Control Bit ECC - FAPI_INF( "+++ Setting Up Control Bit ECC +++"); + FAPI_INF( "%s +++ Setting Up Control Bit ECC +++", mss::c_str(i_target)); FAPI_TRY(mss_enable_control_bit_ecc(i_target), "---Error During Control Bit ECC Setup"); FAPI_TRY(mss_unmask_maint_errors(i_target)); - FAPI_DBG("mss_draminit_mc complete"); + FAPI_DBG( "%s mss_draminit_mc complete", mss::c_str(i_target)); fapi_try_exit: return fapi2::current_err; @@ -313,64 +314,508 @@ extern "C" { } /// - ///@brief validate RCD protect time - ///@param[in] i_target Membuf target - ///@return FAPI2_RC_SUCCESS iff function complete + /// @brief Checks parity error reporting and sets up RCD recovery + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete /// - fapi2::ReturnCode mss_check_RCD_protect_time (const fapi2::Target& i_target) + fapi2::ReturnCode check_parity_and_enable_rcd_recovery(const fapi2::Target& i_target) { - fapi2::Target l_targetCentaur; - uint8_t l_mbaPosition = 0; - uint8_t l_dimm_type = 0; - uint8_t l_cfg_wrdone_dly = 0; - uint8_t l_cfg_rdtag_dly = 0; - uint8_t l_cfg_rcd_protection_time = 0; - uint8_t l_highest_cfg_rcd_protection_time = 0; - uint8_t l_max_cfg_rcd_protection_time = 0; - uint8_t l_cmdType = 0x10; // DISPLAY, bit 0:5 = 10000b - uint8_t l_valid_dimms = 0; - uint8_t l_valid_dimm[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; - uint8_t l_port = 0; - uint8_t l_dimm = 0; - uint8_t l_dimm_index = 0; - uint8_t l_target_port = 0; - uint8_t l_target_dimm = 0; + fapi2::buffer l_mba_farb0; + //------------------------------------------------------ + // Exit if parity error reporting disabled + //------------------------------------------------------ + // NOTE: This is just to be safe, so we don't create errors in case the initfile is out of sync. + // Read FARB0 + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); + + // We're ok if bit ignoring RCD parity (bit 60) is not set... + FAPI_ASSERT(!l_mba_farb0.getBit(), + fapi2::CEN_MSS_DRAMINIT_MC_PARITY_CHECKING_DISABLED() + .set_MBA(i_target) + .set_MBA_FARB0(l_mba_farb0), + "Exit mss_check_RCD_protect_time, since parity error reporting disabled on %s.", mss::c_str(i_target)); + + //------------------------------------------------------ + // Enable RCD recovery + //------------------------------------------------------ + l_mba_farb0.clearBit(); + + // Write FARB0 + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Sets up the firs for the RCD response time calibration + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode setup_firs_for_rcd_response_time_calibration(const fapi2::Target& i_target) + { + fapi2::buffer l_mbeccfir_mask_or; + fapi2::buffer l_mbacalfir_mask_or; - uint32_t l_mbeccfir_mask_or_address[MAX_MBA_PER_CEN] = + constexpr uint32_t l_mbeccfir_mask_or_address[MAX_MBA_PER_CEN] = { // port0/1 port2/3 CEN_ECC01_MBECCFIR_MASK_WO_OR, CEN_ECC23_MBECCFIR_MASK_WO_OR }; - uint32_t l_mbeccfir_and_address[MAX_MBA_PER_CEN] = + //------------------------------------------------------ + // Get MBA position: 0 = mba01, 1 = mba23 + //------------------------------------------------------ + uint8_t l_mbaPosition = 0; + + const auto& l_cen = mss::find_target(i_target); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_mbaPosition)); + + //------------------------------------------------------ + // Mask MBECCFIR bit 45: maint RCD parity error + //------------------------------------------------------ + // Set bit 45 in the OR mask + l_mbeccfir_mask_or.setBit(); + // Write OR mask + FAPI_TRY(fapi2::putScom(l_cen, l_mbeccfir_mask_or_address[l_mbaPosition], l_mbeccfir_mask_or)); + + //------------------------------------------------------ + // Mask MBACALFIR bits 4,7: port0,1 RCD parity error + //------------------------------------------------------ + // Set bit 4,7 in the OR mask + l_mbacalfir_mask_or.setBit(); + l_mbacalfir_mask_or.setBit(); + // Write OR mask + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_OR, l_mbacalfir_mask_or)); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Finds the maximum allowable RCD protect time + /// @param[in] i_target MBA target + /// @param[out] o_max_rcd_protect maximum allowable RCD protect time + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode find_max_rcd_protect_time(const fapi2::Target& i_target, + uint8_t& o_max_rcd_protect) + { + fapi2::buffer l_mba_dsm0; + o_max_rcd_protect = 0; + uint8_t l_cfg_wrdone_dly = 0; + uint8_t l_cfg_rdtag_dly = 0; + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_DSM0Q, l_mba_dsm0)); + // Get 24:29 cfg_wrdone_dly + l_mba_dsm0.extractToRight + (l_cfg_wrdone_dly); + // Get 36:41 cfg_rdtag_dly + l_mba_dsm0.extractToRight + (l_cfg_rdtag_dly); + + // Pick lower of the two: cfg_wrdone_dly and cfg_rdtag_dly, and use that for l_max_cfg_rcd_protection_time + o_max_rcd_protect = std::min(l_cfg_wrdone_dly, l_cfg_rdtag_dly); + FAPI_DBG("%s 0x%016lx %d %d %d", mss::c_str(i_target), l_mba_dsm0, l_cfg_wrdone_dly, l_cfg_rdtag_dly, + o_max_rcd_protect); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Loads the RCD protection maint commands + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode load_rcd_protect_maint_cmd(const fapi2::Target& i_target) + { + // Constexpr's for beautification + // Note: these are a conglomeration of a bunch of stop conditions, so no official values exist for them + constexpr uint64_t STOP_CONDITION = 0; + constexpr uint64_t STOP_CONDITION_LEN = 13; + + fapi2::buffer l_data; + // DISPLAY, bit 0:5 = 10000b + constexpr uint8_t DISPLAY_CMD = 0x10; + + // Load display cmd type: MBMCT, 0:5 = 10000b + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMCTQ, l_data)); + l_data.insertFromRight(DISPLAY_CMD); + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBMCTQ, l_data)); + + // Clear all stop conditions in MBASCTL + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBASCTLQ, l_data)); + l_data.clearBit(); + l_data.clearBit(); + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBASCTLQ, l_data)); + + fapi_try_exit: + return fapi2::current_err; + } + + static constexpr uint32_t l_mbeccfir_and_address[MAX_MBA_PER_CEN] = + { + // port0/1 port2/3 + CEN_ECC01_MBECCFIR_WOX_AND, CEN_ECC23_MBECCFIR_WOX_AND + }; + + /// + /// @brief Clears the RCD parity FIR bit + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode clear_rcd_parity_fir(const fapi2::Target& i_target) + { + fapi2::buffer l_data; + l_data.flush<1>(); + // Clears the RCD parity FIR (bit 45) in the AND mask + l_data.clearBit(); + + const auto& l_cen = mss::find_target(i_target); + uint8_t l_mbaPosition = 0; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_mbaPosition)); + // Write AND mask + FAPI_TRY(fapi2::putScom(l_cen, l_mbeccfir_and_address[l_mbaPosition], l_data)); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Clears the RCD parity FIR bit + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode clear_rcd_parity_mbacal_fir(const fapi2::Target& i_target) + { + fapi2::buffer l_data; + l_data.flush<1>(); + // Clear RCD parity bits (bit 4,7) in the AND mask + l_data.clearBit(); + l_data.clearBit(); + // Write AND mask + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIRQ_WOX_AND, l_data)); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Sets up the RCD protect time + /// @param[in] i_time the RCD protect time + /// @param[in,out] io_data the data buffer to modify + /// + void set_rcd_protect_time(const uint8_t i_time, fapi2::buffer& io_data) + { + // Set cfg_rcd_protection_time + io_data.insertFromRight( i_time ); + } + + /// + /// @brief Sets up the RCD parity inject + /// @param[in] i_port the port on which to do the inject + /// @param[in,out] io_data the data buffer to modify + /// + void set_rcd_inject(const uint8_t i_port, fapi2::buffer& io_data) + { + // Select single shot + io_data.clearBit(); + + if(i_port == 0) { - // port0/1 port2/3 - CEN_ECC01_MBECCFIR_WOX_AND, CEN_ECC23_MBECCFIR_WOX_AND - }; + // Select port0 CAS + io_data.setBit(); + } + else + { + // Select port1 CAS + io_data.setBit(); + } + } + + /// + /// @brief Setup RCD parity inject and time + /// @param[in] i_target MBA target + /// @param[in] i_time the RCD protect time + /// @param[in] i_port the port on which to operate + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode setup_rcd_protect_inject_time(const fapi2::Target& i_target, + const uint8_t i_time, + const uint8_t i_port) + { + fapi2::buffer l_data; + // Read FARB0 + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_FARB0Q, l_data)); + + // Sets up the RCD protect time + set_rcd_protect_time(i_time, l_data); + + // Sets up the RCD inject + set_rcd_inject(i_port, l_data); + + // Write FARB0 + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBA_FARB0Q, l_data)); + + fapi_try_exit: + return fapi2::current_err; + } - uint32_t l_mbeccfir_address[MAX_MBA_PER_CEN] = + /// + /// @brief Setup RCD parity inject and time + /// @param[in] i_target MBA target + /// @param[in] i_dimm the DIMM number on which to operate + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode start_single_address_maint(const fapi2::Target& i_target, + const uint8_t i_dimm) + { + fapi2::buffer l_data; + + // Load start address in MBMACA for the given DIMM + if(i_dimm == 1) + { + l_data.setBit(); + } + + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBMACAQ, l_data)); + + // Start the command: MBMCCQ + l_data.flush<0>(); + l_data.setBit(); + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBMCCQ, l_data)); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Checks the maintenance engine's address FIR for errors + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode check_maint_fir(const fapi2::Target& i_target) + { + fapi2::buffer l_data; + + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBAFIRQ, l_data)); + + if(l_data.getBit()) + { + fapi2::buffer l_mbmaca; + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMACAQ, l_mbmaca)); + + FAPI_ASSERT(false, + fapi2::CEN_MSS_DRAMINIT_MC_DISPLAY_INVALID_ADDR(). + set_MBA(i_target). + set_MBMACA(l_mbmaca). + set_MBAFIR(l_data), + "Display invalid address on %s.", + mss::c_str(i_target)); + } + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Checks the maintenance engine's address FIR for errors + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode check_maint_timeout(const fapi2::Target& i_target) + { + fapi2::buffer l_data; + + // Delay 1 mSec + fapi2::delay(DELAY_1MS, DELAY_200000SIMCYCLES); + + // See if MBMSRQ[0] maint cmd in progress bit if off + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMSRQ, l_data)); + + // If cmd still in progress + if(l_data.getBit()) + { + fapi2::buffer l_mbmct; + fapi2::buffer l_mbmaca; + fapi2::buffer l_mbasctl; + fapi2::buffer l_mbmcc; + fapi2::buffer l_mbafir; + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMCTQ, l_mbmct)); + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMACAQ, l_mbmaca)); + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBASCTLQ, l_mbasctl)); + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMCCQ, l_mbmcc)); + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBAFIRQ, l_mbafir)); + + FAPI_ASSERT(false, + fapi2::CEN_MSS_DRAMINIT_MC_DISPLAY_TIMEOUT(). + set_MBA(i_target). + set_MBMCT(l_mbmct). + set_MBMACA(l_mbmaca). + set_MBASCTL(l_mbasctl). + set_MBMCC(l_mbmcc). + set_MBMSR(l_data). + set_MBAFIR(l_mbafir), + "Display timeout on %s.", mss::c_str(i_target)); + } + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Processes the RCD timeout results + /// @param[in] i_target MBA target + /// @param[in] i_port the port on which the code is operating + /// @param[in] i_dimm the DIMM on which the code is operating + /// @param[in] i_max_cfg_rcd_protection_time maximum allowable configuration time + /// @param[in,out] io_cfg_rcd_protection_time current RCD protection time + /// @param[in,out] io_highest_cfg_rcd_protection_time highest configuration time from all calibrated ports + /// @param[out] o_loop_done true if the RCD error was found and the current loop is done + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode process_rcd_timeout_results(const fapi2::Target& i_target, + const uint8_t i_port, + const uint8_t i_dimm, + const uint8_t i_max_cfg_rcd_protection_time, + uint8_t& io_cfg_rcd_protection_time, + uint8_t& io_highest_cfg_rcd_protection_time, + bool& o_loop_done) + { + fapi2::buffer l_mbeccfir; + constexpr uint32_t l_mbeccfir_address[MAX_MBA_PER_CEN] = { // port0/1 port2/3 CEN_ECC01_MBECCFIR, CEN_ECC23_MBECCFIR }; - std::vector> l_target_dimm_array; + const auto& l_cen = mss::find_target(i_target); + o_loop_done = false; + uint8_t l_mbaPosition = 0; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_mbaPosition)); + + FAPI_TRY(fapi2::getScom(l_cen, l_mbeccfir_address[l_mbaPosition], l_mbeccfir)); - fapi2::buffer l_mbeccfir_mask_or; - fapi2::buffer l_mbeccfir_and; - fapi2::buffer l_mbeccfir; - fapi2::buffer l_mbacalfir_mask_or; + // If FIR bit set + if (l_mbeccfir.getBit()) + { + // Save highest value seen on this MBA + if (io_cfg_rcd_protection_time > io_highest_cfg_rcd_protection_time) + { + io_highest_cfg_rcd_protection_time = io_cfg_rcd_protection_time; + } + + // Exit do-while loop and move on to another DIMM + o_loop_done = true; + } + // Else FIR not set + else + { + // Reached max_cfg_rcd_protection_time + if (io_cfg_rcd_protection_time >= i_max_cfg_rcd_protection_time) + { + FAPI_ERR("Injected RCD parity error detected too late for RCD retry to be effective, max_cfg_rcd_protection_time=%d, port%d, dimm%d, %s", + i_max_cfg_rcd_protection_time, i_port, i_dimm, mss::c_str(i_target)); + + fapi2::buffer l_mbacalfir; + fapi2::buffer l_mba_farb0; + fapi2::buffer l_mba_dsm0; + uint8_t l_dimm_index = 0; + uint8_t l_cfg_wrdone_dly = 0; + uint8_t l_cfg_rdtag_dly = 0; + + //Read mbacalfir for FFDC + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIRQ, l_mbacalfir)); + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); + FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_dsm0)); + l_mba_dsm0.extractToRight + (l_cfg_wrdone_dly); + l_mba_dsm0.extractToRight + (l_cfg_rdtag_dly); + + // Get DIMM targets for this MBA + const auto& l_target_dimms = mss::find_targets(i_target); + + // Find DIMM target for this i_port and i_dimm + for (l_dimm_index = 0; l_dimm_index < l_target_dimms.size(); l_dimm_index++) + { + uint8_t l_target_port = 0; + uint8_t l_target_dimm = 0; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_PORT, l_target_dimms[l_dimm_index], l_target_port)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_DIMM, l_target_dimms[l_dimm_index], l_target_dimm)); + + if ((l_target_port == i_port) && (l_target_dimm == i_dimm)) + { + break; // Break out of for loop since we found the DIMM target for this i_port and i_dimm + } + } + + FAPI_ASSERT(false, + fapi2::CEN_MSS_DRAMINIT_MC_INSUF_RCD_PROTECT_TIME(). + set_DIMM(l_target_dimms[l_dimm_index]). + set_MBA(i_target). + set_PORT_SELECT(i_port). + set_DIMM_SELECT(i_dimm). + set_CFG_WRDONE_DLY(l_cfg_wrdone_dly). + set_CFG_RDTAG_DLY(l_cfg_rdtag_dly). + set_MAX_CFG_RCD_PROTECTION_TIME(i_max_cfg_rcd_protection_time). + set_MBA_FARB0(l_mba_farb0). + set_MBACALFIR(l_mbacalfir)); + + // Including this in here for safety's sake + o_loop_done = true; + } + + // Else increment cfg_rcd_protection_time and try again + else + { + io_cfg_rcd_protection_time++; + } + } + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Sets up the FIR mask for the RCD parity error in mainline + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode setup_firs_mask_rcd_parity_mainline(const fapi2::Target& i_target) + { fapi2::buffer l_mbacalfir_mask_and; - fapi2::buffer l_mbacalfir_and; - fapi2::buffer l_mbacalfir; - fapi2::buffer l_mba_dsm0; + l_mbacalfir_mask_and.flush<1>(); + // Set bit 4,7 in the AND mask + l_mbacalfir_mask_and.clearBit(); + l_mbacalfir_mask_and.clearBit(); + // Write AND mask + FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_AND, l_mbacalfir_mask_and)); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + ///@brief validate RCD protect time + ///@param[in] i_target Membuf target + ///@return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode mss_check_RCD_protect_time (const fapi2::Target& i_target) + { + fapi2::Target l_targetCentaur; + uint8_t l_dimm_type = 0; + uint8_t l_cfg_rcd_protection_time = 0; + uint8_t l_highest_cfg_rcd_protection_time = 0; + uint8_t l_max_cfg_rcd_protection_time = 0; + uint8_t l_valid_dimms = 0; + uint8_t l_valid_dimm[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; + uint8_t l_port = 0; + uint8_t l_dimm = 0; + fapi2::buffer l_mba_farb0; - fapi2::buffer l_mbmct; - fapi2::buffer l_mbmaca; - fapi2::buffer l_mbasctl; - fapi2::buffer l_mbmcc; - fapi2::buffer l_mbafir; - fapi2::buffer l_mbmsr; + FAPI_INF("%s starting mss_check_RCD_protect_time", mss::c_str(i_target)); //------------------------------------------------------ // Get DIMM type @@ -383,37 +828,13 @@ extern "C" { if ((l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_RDIMM) || (l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_LRDIMM)) { - //------------------------------------------------------ - // Exit if parity error reporting disabled - //------------------------------------------------------ - // NOTE: This is just to be safe, so we don't create errors in case the initfile is out of sync. - // Read FARB0 - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); - - if(l_mba_farb0.getBit<60>()) - { - FAPI_ERR("Exit mss_check_RCD_protect_time, since parity error reporting disabled on %s.", mss::c_str(i_target)); - return fapi2::FAPI2_RC_FALSE; - } - - //------------------------------------------------------ - // Enable RCD recovery - //------------------------------------------------------ - l_mba_farb0.clearBit<54>(); - - // Write FARB0 - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); - - //------------------------------------------------------ // Get Centaur target for the given MBA //------------------------------------------------------ l_targetCentaur = i_target.getParent(); - //------------------------------------------------------ - // Get MBA position: 0 = mba01, 1 = mba23 - //------------------------------------------------------ - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_mbaPosition)); + // Checks parity checking is setup correctly and enables RCD recovery + FAPI_TRY(check_parity_and_enable_rcd_recovery(i_target)); //------------------------------------------------------ // Find out which DIMMs are functional @@ -424,62 +845,18 @@ extern "C" { l_valid_dimm[1][0] = (l_valid_dimms & 0x08); // port1, dimm0 l_valid_dimm[1][1] = (l_valid_dimms & 0x04); // port1, dimm1 - - //------------------------------------------------------ - // Mask MBECCFIR bit 45: maint RCD parity error - //------------------------------------------------------ - l_mbeccfir_mask_or.flush<0>(); - // Set bit 45 in the OR mask - l_mbeccfir_mask_or.setBit<45>(); - // Write OR mask - FAPI_TRY(fapi2::putScom(l_targetCentaur, l_mbeccfir_mask_or_address[l_mbaPosition], l_mbeccfir_mask_or)); - - - //------------------------------------------------------ - // Mask MBACALFIR bits 4,7: port0,1 RCD parity error - //------------------------------------------------------ - l_mbacalfir_mask_or.flush<0>(); - // Set bit 4,7 in the OR mask - l_mbacalfir_mask_or.setBit<4>(); - l_mbacalfir_mask_or.setBit<7>(); - // Write OR mask - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_OR, l_mbacalfir_mask_or)); - + // Sets up the FIRs for RCD parity response calibration + FAPI_TRY(setup_firs_for_rcd_response_time_calibration(i_target)); //------------------------------------------------------ // Find l_max_cfg_rcd_protection_time //------------------------------------------------------ - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_DSM0Q, l_mba_dsm0)); - // Get 24:29 cfg_wrdone_dly - FAPI_TRY(l_mba_dsm0.extract(l_cfg_wrdone_dly, 24, 6, 8 - 6)); - // Get 36:41 cfg_rdtag_dly - FAPI_TRY(l_mba_dsm0.extract(l_cfg_rdtag_dly, 36, 6, 8 - 6)); - - // Pick lower of the two: cfg_wrdone_dly and cfg_rdtag_dly, and use that for l_max_cfg_rcd_protection_time - if (l_cfg_wrdone_dly <= l_cfg_rdtag_dly) - { - l_max_cfg_rcd_protection_time = l_cfg_wrdone_dly; - } - else - { - l_max_cfg_rcd_protection_time = l_cfg_rdtag_dly; - } + FAPI_TRY(find_max_rcd_protect_time(i_target, l_max_cfg_rcd_protection_time)); //------------------------------------------------------ // Maint cmd setup steps we can do once per MBA //------------------------------------------------------ - - // Load display cmd type: MBMCT, 0:5 = 10000b - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMCTQ, l_mbmct)); - FAPI_TRY(l_mbmct.insert(l_cmdType, 0, 5, 8 - 5 )); - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBMCTQ, l_mbmct)); - - // Clear all stop conditions in MBASCTL - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBASCTLQ, l_mbasctl)); - l_mbasctl.clearBit<0, 13>(); - l_mbasctl.clearBit<16>(); - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBASCTLQ, l_mbasctl)); - + FAPI_TRY(load_rcd_protect_maint_cmd(i_target)); //------------------------------------------------------ // For each port in the given MBA:0,1 @@ -504,212 +881,66 @@ extern "C" { //------------------------------------------------------ // Clear MBECCFIR bit 45: maint RCD parity error //------------------------------------------------------ - l_mbeccfir_and.flush<1>(); - // Clear bit 45 in the AND mask - l_mbeccfir_and.clearBit<45>(); - // Write AND mask - FAPI_TRY(fapi2::putScom(l_targetCentaur, l_mbeccfir_and_address[l_mbaPosition], l_mbeccfir_and)); + FAPI_TRY(clear_rcd_parity_fir(i_target)); //------------------------------------------------------ // Loop until we find a passing cfg_rcd_protection_time //------------------------------------------------------ + bool l_loop_done = false; + do { //------------------------------------------------------ // Clear MBACALFIR bits 4,7: port0,1 RCD parity error //------------------------------------------------------ - // NOTE: Clearing these each time so they will be accrate for FFDC - l_mbacalfir_and.flush<1>(); - // Clear bit 4,7 in the AND mask - l_mbacalfir_and.clearBit<4>(); - l_mbacalfir_and.clearBit<7>(); - // Write AND mask - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIRQ_WOX_AND, l_mbacalfir_and)); - + // NOTE: Clearing these each time so they will be accurate for FFDC + FAPI_TRY(clear_rcd_parity_mbacal_fir(i_target)); //------------------------------------------------------ // Set l_cfg_rcd_protection_time //------------------------------------------------------ - // Read FARB0 - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); - - // Set cfg_rcd_protection_time - FAPI_TRY(l_mba_farb0.insert( l_cfg_rcd_protection_time, 48, 6, 8 - 6 )); - - //------------------------------------------------------ // Arm single shot RCD parity error for the given port //------------------------------------------------------ - // Select single shot - l_mba_farb0.clearBit<59>(); - - if(l_port == 0) - { - // Select port0 CAS - l_mba_farb0.setBit<40>(); - } - else - { - // Select port1 CAS - l_mba_farb0.setBit<42>(); - } - - // Write FARB0 - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); - + FAPI_TRY(setup_rcd_protect_inject_time(i_target, l_cfg_rcd_protection_time, l_port)); //------------------------------------------------------ // Do single address display cmd //------------------------------------------------------ - - // Load start address in MBMACA for the given DIMM - l_mbmaca.flush<0>(); - - if(l_dimm == 1) - { - l_mbmaca.setBit<1>(); - } - - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBMACAQ, l_mbmaca)); - - // Start the command: MBMCCQ - l_mbmcc.flush<0>(); - l_mbmcc.setBit<0>(); - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBMCCQ, l_mbmcc)); + FAPI_TRY(start_single_address_maint(i_target, l_dimm)); // Check for MBAFIR[1], invalid maint address. - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBAFIRQ, l_mbafir)); - - FAPI_ASSERT(!l_mbafir.getBit<1>(), - fapi2::CEN_MSS_DRAMINIT_MC_DISPLAY_INVALID_ADDR(). - set_MBA(i_target). - set_MBMACA(l_mbmaca). - set_MBAFIR(l_mbafir), - "Display invalid address on port%d, dimm%d, %s.", - l_port, l_dimm, mss::c_str(i_target)); - - // Delay 1 mSec - fapi2::delay(DELAY_1MS, DELAY_200000SIMCYCLES); - - // See if MBMSRQ[0] maint cmd in progress bit if off - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBMSRQ, l_mbmsr)); - - // If cmd still in progress - FAPI_ASSERT(!l_mbmsr.getBit<1>(), - fapi2::CEN_MSS_DRAMINIT_MC_DISPLAY_TIMEOUT(). - set_MBA(i_target). - set_MBMCT(l_mbmct). - set_MBMACA(l_mbmaca). - set_MBASCTL(l_mbasctl). - set_MBMCC(l_mbmcc). - set_MBMSR(l_mbmsr). - set_MBAFIR(l_mbafir), - "Display timeout on %s.", mss::c_str(i_target)); - - // DEBUG Read MBACALFIR - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIRQ, l_mbacalfir)); + FAPI_TRY(check_maint_fir(i_target)); + + // Checks for a maintenance timeout + FAPI_TRY(check_maint_timeout(i_target)); //------------------------------------------------------ // Check for MBECCFIR bit 45: maint RCD parity error //------------------------------------------------------ - - FAPI_TRY(fapi2::getScom(l_targetCentaur, l_mbeccfir_address[l_mbaPosition], l_mbeccfir)); - - // If FIR bit set - if (l_mbeccfir.getBit<45>()) - { - // Save highest value seen on this MBA - if (l_cfg_rcd_protection_time > l_highest_cfg_rcd_protection_time) - { - l_highest_cfg_rcd_protection_time = l_cfg_rcd_protection_time; - } - - break; // Exit do-while loop and move on to another DIMM - } - // Else FIR not set - else - { - // Reached max_cfg_rcd_protection_time - if (l_cfg_rcd_protection_time == l_max_cfg_rcd_protection_time) - { - FAPI_ERR("Injected RCD parity error detected too late for RCD retry to be effective, max_cfg_rcd_protection_time=%d, port%d, dimm%d, %s", - l_max_cfg_rcd_protection_time, l_port, l_dimm, mss::c_str(i_target)); - - //Read mbacalfir for FFDC - FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIRQ, l_mbacalfir)); - - // Get DIMM targets for this MBA - l_target_dimm_array = i_target.getChildren(); - - // Find DIMM target for this l_port and l_dimm - for (l_dimm_index = 0; l_dimm_index < l_target_dimm_array.size(); l_dimm_index ++) - { - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_PORT, l_target_dimm_array[l_dimm_index], l_target_port)); - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_DIMM, l_target_dimm_array[l_dimm_index], l_target_dimm)); - - if ((l_target_port == l_port) && (l_target_dimm == l_dimm)) - { - break; // Break out of for loop since we found the DIMM target for this l_port and l_dimm - } - } - - FAPI_ASSERT(false, - fapi2::CEN_MSS_DRAMINIT_MC_INSUF_RCD_PROTECT_TIME(). - set_DIMM(l_target_dimm_array[l_dimm_index]). - set_MBA(i_target). - set_PORT_SELECT(l_port). - set_DIMM_SELECT(l_dimm). - set_CFG_WRDONE_DLY(l_cfg_wrdone_dly). - set_CFG_RDTAG_DLY(l_cfg_rdtag_dly). - set_MAX_CFG_RCD_PROTECTION_TIME(l_max_cfg_rcd_protection_time). - set_MBA_FARB0(l_mba_farb0). - set_MBACALFIR(l_mbacalfir)); - - - break; // Exit do-while loop and move on to another DIMM - } - - // Else increment cfg_rcd_protection_time and try again - else - { - l_cfg_rcd_protection_time++; - } - } + FAPI_TRY(process_rcd_timeout_results(i_target, l_port, l_dimm, l_max_cfg_rcd_protection_time, l_cfg_rcd_protection_time, + l_highest_cfg_rcd_protection_time, l_loop_done)); } - while (1); + while (!l_loop_done); }// End if valid DIMM }// End for each DIMM select }// End for each port //------------------------------------------------------ - // Clear MBECCFIR bit 45 + // Clear MBECCFIR bit 45: maint RCD parity error //------------------------------------------------------ - l_mbeccfir_and.flush<1>(); - // Clear bit 45 in the AND mask - l_mbeccfir_and.clearBit<45>(); - // Write AND mask - FAPI_TRY(fapi2::putScom(l_targetCentaur, l_mbeccfir_and_address[l_mbaPosition], l_mbeccfir_and)); + FAPI_TRY(clear_rcd_parity_fir(i_target)); //------------------------------------------------------ // Clear MBACALFIR bits 4,7: port0,1 RCD parity error //------------------------------------------------------ - l_mbacalfir_and.flush<1>(); - // Clear bit 4,7 in the AND mask - l_mbacalfir_and.clearBit<4>(); - l_mbacalfir_and.clearBit<7>(); - // Write AND mask - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIRQ_WOX_AND, l_mbacalfir_and)); + FAPI_TRY(clear_rcd_parity_mbacal_fir(i_target)); //------------------------------------------------------ // Unmask MBACALFIR bits 4,7: port0,1 RCD parity error //------------------------------------------------------ - l_mbacalfir_mask_and.flush<1>(); - // Set bit 4,7 in the AND mask - l_mbacalfir_mask_and.clearBit<4>(); - l_mbacalfir_mask_and.clearBit<7>(); - // Write AND mask - FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_AND, l_mbacalfir_mask_and)); + FAPI_TRY(setup_firs_mask_rcd_parity_mainline(i_target)); // Read FARB0 FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); @@ -720,19 +951,19 @@ extern "C" { // NOTE: We are loading highest_cfg_rcd_protection_time here just so we can stop after mss_draminit_mc and read out the values from the hw as a way to debug // NOTE: The final value we want to load is max_cfg_rcd_protection_time, which we will do in mss_thermal_init, before we enable RCD recovery. // NOTE: If no DIMM on this MBA passed, highest_cfg_rcd_protection_time will be 0 - FAPI_TRY(l_mba_farb0.insert( l_highest_cfg_rcd_protection_time, 48, 6, 8 - 6 )); + set_rcd_protect_time( l_highest_cfg_rcd_protection_time, l_mba_farb0 ); //------------------------------------------------------ // Disable RCD recovery //------------------------------------------------------ - l_mba_farb0.setBit<54>(); + l_mba_farb0.setBit(); // Write FARB0 FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBA_FARB0Q, l_mba_farb0)); } // End if RDIMM or LRDIMM - FAPI_INF("+++ mss_check_RCD_protect_time complete +++"); + FAPI_INF("+++ %s mss_check_RCD_protect_time complete +++", mss::c_str(i_target)); fapi_try_exit: return fapi2::current_err; } diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.H index 450abf5e0..e6e4df5d0 100644 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.H +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* Contributors Listed Below - COPYRIGHT 2016,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -85,6 +85,124 @@ extern "C" /// fapi2::ReturnCode mss_ccs_mode_reset(const fapi2::Target& i_target); + /// + /// @brief Checks parity error reporting and sets up RCD recovery + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode check_parity_and_enable_rcd_recovery(const fapi2::Target& i_target); + + /// + /// @brief Sets up the firs for the RCD response time calibration + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode setup_firs_for_rcd_response_time_calibration(const fapi2::Target& i_target); + + /// + /// @brief Finds the maximum allowable RCD protect time + /// @param[in] i_target MBA target + /// @param[out] o_max_rcd_protect maximum allowable RCD protect time + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode find_max_rcd_protect_time(const fapi2::Target& i_target, + uint8_t& o_max_rcd_protect); + + /// + /// @brief Loads the RCD protection maint commands + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode load_rcd_protect_maint_cmd(const fapi2::Target& i_target); + + /// + /// @brief Clears the RCD parity FIR bit + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode clear_rcd_parity_fir(const fapi2::Target& i_target); + + /// + /// @brief Clears the RCD parity errors in the MBACAL FIR register + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode clear_rcd_parity_mbacal_fir(const fapi2::Target& i_target); + + /// + /// @brief Sets up the RCD protect time + /// @param[in] i_time the RCD protect time + /// @param[in,out] io_data the data buffer to modify + /// + void set_rcd_protect_time(const uint8_t i_time, fapi2::buffer& io_data); + + /// + /// @brief Sets up the RCD parity inject + /// @param[in] i_port the port on which to do the inject + /// @param[in,out] io_data the data buffer to modify + /// + void set_rcd_inject(const uint8_t i_port, fapi2::buffer& io_data); + + /// + /// @brief Setup RCD parity inject and time + /// @param[in] i_target MBA target + /// @param[in] i_time the RCD protect time + /// @param[in] i_port the port on which to operate + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode setup_rcd_protect_inject_time(const fapi2::Target& i_target, + const uint8_t i_time, + const uint8_t i_port); + + /// + /// @brief Setup RCD parity inject and time + /// @param[in] i_target MBA target + /// @param[in] i_dimm the DIMM number on which to operate + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode start_single_address_maint(const fapi2::Target& i_target, + const uint8_t i_dimm); + + /// + /// @brief Checks the maintenance engine's address FIR for errors + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode check_maint_fir(const fapi2::Target& i_target); + + /// + /// @brief Checks the maintenance engine's address FIR for errors + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode check_maint_timeout(const fapi2::Target& i_target); + + /// + /// @brief Processes the RCD timeout results + /// @param[in] i_target MBA target + /// @param[in] i_port the port on which the code is operating + /// @param[in] i_dimm the DIMM on which the code is operating + /// @param[in] i_max_cfg_rcd_protection_time maximum allowable configuration time + /// @param[in,out] io_cfg_rcd_protection_time current RCD protection time + /// @param[in,out] io_highest_cfg_rcd_protection_time highest configuration time from all calibrated ports + /// @param[out] o_loop_done true if the RCD error was found and the current loop is done + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode process_rcd_timeout_results(const fapi2::Target& i_target, + const uint8_t i_port, + const uint8_t i_dimm, + const uint8_t i_max_cfg_rcd_protection_time, + uint8_t& io_cfg_rcd_protection_time, + uint8_t& io_highest_cfg_rcd_protection_time, + bool& o_loop_done); + + /// + /// @brief Sets up the FIR mask for the RCD parity error in mainline + /// @param[in] i_target MBA target + /// @return FAPI2_RC_SUCCESS iff function complete + /// + fapi2::ReturnCode setup_firs_mask_rcd_parity_mainline(const fapi2::Target& i_target); + /// ///@brief validate RCD protect time ///@param[in] i_target Membuf target diff --git a/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_draminit_mc_errors.xml b/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_draminit_mc_errors.xml index fe07f5f96..289f26559 100644 --- a/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_draminit_mc_errors.xml +++ b/src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_draminit_mc_errors.xml @@ -5,7 +5,7 @@ - + @@ -108,4 +108,20 @@ MBA + + + RC_CEN_MSS_DRAMINIT_MC_PARITY_CHECKING_DISABLED + Parity checking is disabled on this MBA, when it is expected to be enabled + + MBA_FARB0 + + CODEHIGH + + MBALOW + + MBA + + MBA + + -- cgit v1.2.1