summaryrefslogtreecommitdiffstats
path: root/src/import/chips/centaur
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2018-03-19 14:47:00 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-07-19 11:03:50 -0500
commit5b93d4000b1cdab6a8a778cfae858a8ca4cb7dfb (patch)
tree6bc7a0cb51d591fc98ebd74b04541851a153aa93 /src/import/chips/centaur
parentfc9830a4a2b1384dc29fcca0d8c7f2d4ac4c0b23 (diff)
downloadtalos-hostboot-5b93d4000b1cdab6a8a778cfae858a8ca4cb7dfb.tar.gz
talos-hostboot-5b93d4000b1cdab6a8a778cfae858a8ca4cb7dfb.zip
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 <fsp-CI-jenkins+hostboot@us.ibm.com> Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/56041 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/centaur')
-rw-r--r--src/import/chips/centaur/procedures/hwp/initfiles/centaur_mba_scom.C27
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.C817
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_mc.H120
-rw-r--r--src/import/chips/centaur/procedures/xml/error_info/p9c_memory_mss_draminit_mc_errors.xml18
4 files changed, 682 insertions, 300 deletions
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<fapi2::TARGET_TYPE_MBA>&
&& (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<fapi2::TARGET_TYPE_MBA>&
&& (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<fapi2::TARGET_TYPE_MBA>&
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<fapi2::TARGET_TYPE_MBA>&
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<fapi2::TARGET_TYPE_MBA>&
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<fapi2::TARGET_TYPE_MBA>&
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 <p9c_mss_unmask_errors.H>
#include <p9c_mss_draminit_mc.H>
#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/find.H>
#include <dimmConsts.H>
//----------------------------------------------------------------------
// Address Includes
//----------------------------------------------------------------------
#include <cen_gen_scom_addresses.H>
+#include <cen_gen_scom_addresses_fld.H>
extern "C" {
@@ -72,44 +74,43 @@ extern "C" {
const auto l_mbaChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MBA>();
// 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<CEN_MBA_MBAREF0Q_CFG_REFRESH_ENABLE>();
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<fapi2::TARGET_TYPE_MBA>& i_target)
+ fapi2::ReturnCode check_parity_and_enable_rcd_recovery(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
{
- fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> 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<uint64_t> 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<CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_IGNORE_RCD_PARITY_ERR>(),
+ 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<CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_DISABLE_RCD_RECOVERY>();
+
+ // 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<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::buffer<uint64_t> l_mbeccfir_mask_or;
+ fapi2::buffer<uint64_t> 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<fapi2::TARGET_TYPE_MEMBUF_CHIP>(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<CEN_ECC01_MBECCFIR_MAINTENANCE_RCD_PARITY_ERROR>();
+ // 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<CEN_MBA_MBACALFIRQ_RCD_PARITY_ERROR_0>();
+ l_mbacalfir_mask_or.setBit<CEN_MBA_MBACALFIRQ_RCD_PARITY_ERROR_1>();
+ // 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<fapi2::TARGET_TYPE_MBA>& i_target,
+ uint8_t& o_max_rcd_protect)
+ {
+ fapi2::buffer<uint64_t> 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<CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_WRDATA_DLY, CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_WRDATA_DLY_LEN>
+ (l_cfg_wrdone_dly);
+ // Get 36:41 cfg_rdtag_dly
+ l_mba_dsm0.extractToRight<CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_RDTAG_DLY, CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_RDTAG_DLY_LEN>
+ (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<fapi2::TARGET_TYPE_MBA>& 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<uint64_t> 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<CEN_MBA_MBMCTQ_MAINT_CMD_TYPE, CEN_MBA_MBMCTQ_MAINT_CMD_TYPE_LEN>(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<STOP_CONDITION, STOP_CONDITION_LEN>();
+ l_data.clearBit<CEN_MBA_MBASCTLQ_MBSPA_BIT_0_MODE>();
+ 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<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::buffer<uint64_t> l_data;
+ l_data.flush<1>();
+ // Clears the RCD parity FIR (bit 45) in the AND mask
+ l_data.clearBit<CEN_ECC01_MBECCFIR_MAINTENANCE_RCD_PARITY_ERROR>();
+
+ const auto& l_cen = mss::find_target<fapi2::TARGET_TYPE_MEMBUF_CHIP>(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<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::buffer<uint64_t> l_data;
+ l_data.flush<1>();
+ // Clear RCD parity bits (bit 4,7) in the AND mask
+ l_data.clearBit<CEN_MBA_MBACALFIRQ_RCD_PARITY_ERROR_0>();
+ l_data.clearBit<CEN_MBA_MBACALFIRQ_RCD_PARITY_ERROR_1>();
+ // 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<uint64_t>& io_data)
+ {
+ // Set cfg_rcd_protection_time
+ io_data.insertFromRight<CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_RCD_PROTECTION_TIME,
+ CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_RCD_PROTECTION_TIME_LEN>( 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<uint64_t>& io_data)
+ {
+ // Select single shot
+ io_data.clearBit<CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_INJECT_PARITY_ERR_CONSTANT>();
+
+ if(i_port == 0)
{
- // port0/1 port2/3
- CEN_ECC01_MBECCFIR_WOX_AND, CEN_ECC23_MBECCFIR_WOX_AND
- };
+ // Select port0 CAS
+ io_data.setBit<CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_INJECT_PARITY_ERR_CAS0>();
+ }
+ else
+ {
+ // Select port1 CAS
+ io_data.setBit<CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_INJECT_PARITY_ERR_CAS1>();
+ }
+ }
+
+ ///
+ /// @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<fapi2::TARGET_TYPE_MBA>& i_target,
+ const uint8_t i_time,
+ const uint8_t i_port)
+ {
+ fapi2::buffer<uint64_t> 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<fapi2::TARGET_TYPE_MBA>& i_target,
+ const uint8_t i_dimm)
+ {
+ fapi2::buffer<uint64_t> l_data;
+
+ // Load start address in MBMACA for the given DIMM
+ if(i_dimm == 1)
+ {
+ l_data.setBit<CEN_MBA_MBMACAQ_CMD_DIMM_SELECT>();
+ }
+
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBMACAQ, l_data));
+
+ // Start the command: MBMCCQ
+ l_data.flush<0>();
+ l_data.setBit<CEN_MBA_MBMCCQ_MAINT_CMD_START>();
+ 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<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::buffer<uint64_t> l_data;
+
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBAFIRQ, l_data));
+
+ if(l_data.getBit<CEN_MBA_MBAFIRQ_INVALID_MAINT_ADDRESS>())
+ {
+ fapi2::buffer<uint64_t> 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<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::buffer<uint64_t> 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<CEN_MBA_MBMSRQ_MAINT_CMD_IP>())
+ {
+ fapi2::buffer<uint64_t> l_mbmct;
+ fapi2::buffer<uint64_t> l_mbmaca;
+ fapi2::buffer<uint64_t> l_mbasctl;
+ fapi2::buffer<uint64_t> l_mbmcc;
+ fapi2::buffer<uint64_t> 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<fapi2::TARGET_TYPE_MBA>& 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<uint64_t> l_mbeccfir;
+ constexpr uint32_t l_mbeccfir_address[MAX_MBA_PER_CEN] =
{
// port0/1 port2/3
CEN_ECC01_MBECCFIR, CEN_ECC23_MBECCFIR
};
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_target_dimm_array;
+ const auto& l_cen = mss::find_target<fapi2::TARGET_TYPE_MEMBUF_CHIP>(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<uint64_t> l_mbeccfir_mask_or;
- fapi2::buffer<uint64_t> l_mbeccfir_and;
- fapi2::buffer<uint64_t> l_mbeccfir;
- fapi2::buffer<uint64_t> l_mbacalfir_mask_or;
+ // If FIR bit set
+ if (l_mbeccfir.getBit<CEN_ECC01_MBECCFIR_MAINTENANCE_RCD_PARITY_ERROR>())
+ {
+ // 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<uint64_t> l_mbacalfir;
+ fapi2::buffer<uint64_t> l_mba_farb0;
+ fapi2::buffer<uint64_t> 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<CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_WRDATA_DLY, CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_WRDATA_DLY_LEN>
+ (l_cfg_wrdone_dly);
+ l_mba_dsm0.extractToRight<CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_RDTAG_DLY, CEN_MBA_MBA_DSM0Q_DSM0Q_CFG_RDTAG_DLY_LEN>
+ (l_cfg_rdtag_dly);
+
+ // Get DIMM targets for this MBA
+ const auto& l_target_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(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<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
fapi2::buffer<uint64_t> l_mbacalfir_mask_and;
- fapi2::buffer<uint64_t> l_mbacalfir_and;
- fapi2::buffer<uint64_t> l_mbacalfir;
- fapi2::buffer<uint64_t> l_mba_dsm0;
+ l_mbacalfir_mask_and.flush<1>();
+ // Set bit 4,7 in the AND mask
+ l_mbacalfir_mask_and.clearBit<CEN_MBA_MBACALFIRQ_RCD_PARITY_ERROR_0>();
+ l_mbacalfir_mask_and.clearBit<CEN_MBA_MBACALFIRQ_RCD_PARITY_ERROR_1>();
+ // 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<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> 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<uint64_t> l_mba_farb0;
- fapi2::buffer<uint64_t> l_mbmct;
- fapi2::buffer<uint64_t> l_mbmaca;
- fapi2::buffer<uint64_t> l_mbasctl;
- fapi2::buffer<uint64_t> l_mbmcc;
- fapi2::buffer<uint64_t> l_mbafir;
- fapi2::buffer<uint64_t> l_mbmsr;
+ FAPI_INF("%s starting mss_check_RCD_protect_time", mss::c_str(i_target));
//------------------------------------------------------
// Get DIMM type
@@ -384,36 +829,12 @@ extern "C" {
|| (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<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
- //------------------------------------------------------
- // 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<fapi2::TARGET_TYPE_DIMM>();
-
- // 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<CEN_MBA_MBA_FARB0Q_FARB0Q_CFG_DISABLE_RCD_RECOVERY>();
// 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. */
/* */
/* */
@@ -86,6 +86,124 @@ extern "C"
fapi2::ReturnCode mss_ccs_mode_reset(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<uint64_t>& 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<uint64_t>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& 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<fapi2::TARGET_TYPE_MBA>& i_target);
+
+ ///
///@brief validate RCD protect time
///@param[in] i_target Membuf target
///@return FAPI2_RC_SUCCESS iff function complete
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 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2016,2017 -->
+<!-- Contributors Listed Below - COPYRIGHT 2016,2018 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -108,4 +108,20 @@
<gard><target>MBA</target></gard>
</hwpError>
+
+<hwpError>
+ <rc>RC_CEN_MSS_DRAMINIT_MC_PARITY_CHECKING_DISABLED</rc>
+ <description>Parity checking is disabled on this MBA, when it is expected to be enabled</description>
+ <!-- FFDC: Capture register with the RCD retry settings -->
+ <ffdc>MBA_FARB0</ffdc>
+ <!-- Callout FW HIGH -->
+ <callout><procedure>CODE</procedure><priority>HIGH</priority></callout>
+ <!-- Callout MBA LOW -->
+ <callout><target>MBA</target><priority>LOW</priority></callout>
+ <!-- Deconfigure MBA -->
+ <deconfigure><target>MBA</target></deconfigure>
+ <!-- Create GARD record for MBA -->
+ <gard><target>MBA</target></gard>
+</hwpError>
+
</hwpErrors>
OpenPOWER on IntegriCloud