Skip to content

Commit

Permalink
exp draminit & draminit_mc phase 3 update for PRD logging
Browse files Browse the repository at this point in the history
- Adding firChecklist as a template parameter for firmware
  fir_or_pll bit checks
- Creating helper functions for fir_or_pll fails to check
  specific masks
- Creating unit test for fir_with_mask_helper
- Updating NIMBUS code to accept firChecklist template param
- Adding CCS fir checklist; to be checked when row repair is
  implemented into exp_draminit_mc

Change-Id: I4fe7e146a3b4c6e2eefa542916b737d613c3ecc3
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/91915
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Dev-Ready: NICOLAS R FAJARDO <nicolas.fajardo@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/92710
Reviewed-by: Christian R Geddes <crgeddes@us.ibm.com>
  • Loading branch information
NicoFajardo authored and crgeddes committed Mar 25, 2020
1 parent f1c57dd commit 9b6bd57
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 80 deletions.
Expand Up @@ -43,6 +43,7 @@
#include <lib/shared/exp_consts.H>
#include <generic/memory/mss_git_data_helper.H>
#include <generic/memory/lib/utils/fir/gen_mss_unmask.H>
#include <generic/memory/lib/utils/mss_generic_check.H>

extern "C"
{
Expand Down Expand Up @@ -100,6 +101,7 @@ extern "C"
// Due to the RAS/PRD requirements, we need to check for FIR's
// If any FIR's have lit up, this draminit fail could have been caused by the FIR, rather than bad hardware
// So, let PRD retrigger this step to see if we can resolve the issue
return mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER>(i_target, fapi2::current_err);
return mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER, mss::check::firChecklist::DRAMINIT>(i_target,
fapi2::current_err);
}
}
Expand Up @@ -54,7 +54,6 @@ extern "C"
{
mss::display_git_commit_info("exp_draminit_mc");


FAPI_INF("%s Start exp_draminit MC", mss::c_str(i_target));

//skip this ocmb_chip if we have no DIMM's configured
Expand Down Expand Up @@ -100,13 +99,18 @@ extern "C"
FAPI_TRY( mss::enable_read_ecc<mss::mc_type::EXPLORER>(i_target), "%s Failed enable_read_ecc", mss::c_str(i_target) );

// Apply marks from OCMB VPD
FAPI_TRY( mss::apply_mark_store(i_target), "%s Failed enable_read_ecc", mss::c_str(i_target) );
FAPI_TRY(mss::apply_mark_store(i_target), "%s Failed apply_mark_store", mss::c_str(i_target));

// Unmask registers after draminit_mc
FAPI_TRY(mss::unmask::after_draminit_mc(i_target), "%s Failed after_draminit_mc", mss::c_str(i_target));

fapi_try_exit:
// TODO: Implement apply row repairs and perform fir_or_pll_fail for firChecklist::CCS

FAPI_INF("%s End exp_draminit MC", mss::c_str(i_target));
return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:

return fapi2::current_err;
}
}
Expand Up @@ -86,7 +86,7 @@ extern "C"
// gets resolved.
#ifdef FIRS_AVAIL_AFTER_BOOT_CONFIG_0_FAIL
// If BOOT_CONFIG_0 failed or timed out, we need to check some FIRs
FAPI_TRY(mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER>(i_target, l_rc));
FAPI_TRY( (mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER, mss::check::firChecklist::OMI>(i_target, l_rc)) );
#else
FAPI_TRY(l_rc, "%s BOOT_CONFIG_0 either failed or timed out", mss::c_str(i_target));
#endif
Expand Down
Expand Up @@ -87,7 +87,7 @@ extern "C"
l_rc = mss::exp::i2c::check_fw_status_busy(i_target);

// If BOOT_CONFIG_1 failed or timed out, we need to check some FIRs
FAPI_TRY(mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER>(i_target, l_rc));
FAPI_TRY( (mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER, mss::check::firChecklist::OMI>(i_target, l_rc)) );
}
else
{
Expand Down
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -104,7 +104,7 @@ fapi_try_exit:
// Due to the PRD update, we need to check for FIR's
// If any FIR's have lit up, this CCS fail could have been caused by the FIR
// So, let PRD retrigger this step to see if we can resolve the issue
return mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER>(i_target, fapi2::current_err);
return mss::check::fir_or_pll_fail<mss::mc_type::EXPLORER, mss::check::firChecklist::CCS>(i_target, fapi2::current_err);
}

///
Expand Down
248 changes: 209 additions & 39 deletions src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/fir/exp_fir.C
Expand Up @@ -22,7 +22,6 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

///
/// @file exp_fir.C
/// @brief Memory subsystem FIR support
Expand Down Expand Up @@ -50,53 +49,77 @@ namespace mss
namespace check
{

// Declares FIR registers that are re-used between multiple functions
// Vectors of FIR and mask registers to read through
// As check_fir can be called in multiple places, we don't know what the mask may hold
// In order to tell if a FIR is legit or not, we read the FIR and check it against the mask reg
// Note: using a vector here in case we need to expand
static const std::vector<std::pair<uint64_t, uint64_t>> EXPLORER_FIR_REGS =
///
/// Declares FIR registers that are re-used between multiple functions
/// Vectors of FIR and mask registers to read through
/// As check_fir can be called in multiple places, we don't know what the mask may hold
/// In order to tell if a FIR is legit or not, we read the FIR and check it against the mask reg
/// Note: using a vector here in case we need to expand
/// Note: the format for these vectors is [TARGET_TYPE]_[PROCEDURE]_FIR_REGS
/// Note: if you change the order of the regs, update indicies in bad_fir_bits below
///
static const std::vector<std::pair<uint64_t, uint64_t>> EXPLORER_OMI_INIT_FIR_REGS =
{
// Explorer LOCAL_FIR
{EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR, EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK},

// Explorer MC_OMI_FIR_REG
{EXPLR_DLX_MC_OMI_FIR_REG, EXPLR_DLX_MC_OMI_FIR_MASK_REG},

// Explorer SRQFIR
{EXPLR_SRQ_SRQFIRQ, EXPLR_SRQ_SRQFIR_MASK},
};

static const std::vector<std::pair<uint64_t, uint64_t>> EXPLORER_DRAMINIT_FIR_REGS =
{
// Explorer SRQFIR
{EXPLR_SRQ_SRQFIRQ, EXPLR_SRQ_SRQFIR_MASK},

// Explorer LOCAL_FIR
{EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR, EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_MASK},
};

static const std::vector<std::pair<uint64_t, uint64_t>> EXPLORER_CCS_FIR_REGS =
{
// Explorer SRQFIR
{EXPLR_SRQ_SRQFIRQ, EXPLR_SRQ_SRQFIR_MASK},

// Explorer MCBISTFIR
{EXPLR_MCBIST_MCBISTFIRQ, EXPLR_MCBIST_MCBISTFIRMASK},

};

static const std::vector<std::pair<uint64_t, uint64_t>> MC_FIR_REGS =
static const std::vector<std::pair<uint64_t, uint64_t>> MC_OMI_INIT_FIR_REGS =
{
// Axone MC_OMI_FIR_REG
{P9A_MC_REG0_OMI_FIR, P9A_MC_REG0_OMI_FIR_MASK},
};

static const std::vector<std::pair<uint64_t, uint64_t>> MCC_FIR_REGS =
static const std::vector<std::pair<uint64_t, uint64_t>> MCC_OMI_INIT_FIR_REGS =
{
// Axone DSTLFIR
{P9A_MCC_DSTLFIR, P9A_MCC_DSTLFIRMASK},
};

///
/// @brief Checks whether any FIRs have lit up on a target
/// @brief Helper for bad_fir_bits to loop through reg/mask pairs for FIRs
/// @tparam T the fapi2::TargetType that we are targeting for fir reg checking, inherited
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @param[out] o_fir_error - true iff a FIR was hit
/// @param[in] i_checklist - the list of vectour reg/mask pairs to search; default exp omi init firs
/// @note i_checklist is last since optional parameter w/ default needs to be end of list
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template< >
fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
fapi2::ReturnCode& io_rc,
bool& o_fir_error )
template< fapi2::TargetType T >
fapi2::ReturnCode bad_fir_bits_helper(const fapi2::Target<T>& i_target,
fapi2::ReturnCode& io_rc,
bool& o_fir_error,
const std::vector<std::pair<uint64_t, uint64_t>>& i_checklist)
{
const auto& l_mcc = mss::find_target<fapi2::TARGET_TYPE_MCC>(i_target);
const auto& l_mc = mss::find_target<fapi2::TARGET_TYPE_MC>(l_mcc);

// Start by assuming we do not have a FIR
o_fir_error = false;

// Loop, check the scoms, and check the FIR
// Note: we return out if any FIR is bad
for(const auto& l_fir_reg : EXPLORER_FIR_REGS)
for(const auto& l_fir_reg : i_checklist)
{
FAPI_TRY(fir_with_mask<mss::mc_type::EXPLORER>(i_target, l_fir_reg, o_fir_error));

Expand All @@ -110,37 +133,184 @@ fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER>( const fapi2::Target<fapi
}
}

for(const auto& l_fir_reg : MC_FIR_REGS)
fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Helper for bad_fir_bits to check a fir register/mask pair against a desired mask value
/// @param[in] i_target - the target on which to operate
/// @param[in] i_reg_addr - the address of the register address to compare against mask
/// @param[in] i_mask - the 64-bit mask that we want to compare the reg against
/// @param[in,out] io_rc - the return code for the function
/// @param[out] o_fir_error - true iff a FIR was hit
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode bad_fir_bits_helper_with_mask(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const uint64_t i_reg_addr,
const fapi2::buffer<uint64_t>& i_mask,
fapi2::ReturnCode& io_rc,
bool& o_fir_error)
{
fapi2::buffer<uint64_t> l_reg_data;

FAPI_TRY(fapi2::getScom(i_target, i_reg_addr, l_reg_data));

o_fir_error = fir_with_mask_helper(l_reg_data, i_mask);

FAPI_INF("%s %s on reg 0x%016lx value 0x%016lx and mask value 0x%016lx", mss::c_str(i_target),
o_fir_error ? "has FIR's set" : "has no FIR's set",
i_reg_addr, l_reg_data, i_mask);

// Log the error if need be
log_fir_helper(i_target, o_fir_error, io_rc);

// Exit if we have found a FIR
if(o_fir_error)
{
FAPI_TRY(fir_with_mask<mss::mc_type::EXPLORER>(l_mc, l_fir_reg, o_fir_error));
return fapi2::FAPI2_RC_SUCCESS;
}

// Log the error if need be
log_fir_helper(l_mc, o_fir_error, io_rc);
fapi_try_exit:

// Exit if we have found a FIR
if(o_fir_error)
{
return fapi2::FAPI2_RC_SUCCESS;
}
return fapi2::current_err;
}

///
/// @brief Checks whether any FIRs have lit up on a target
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @param[out] o_fir_error - true iff a FIR was hit
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
/// @note specialization for EXPLORER and fir checklist for OMI regs
///
template<>
fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER, firChecklist::OMI>( const
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
fapi2::ReturnCode& io_rc,
bool& o_fir_error)
{
const auto& l_mcc = mss::find_target<fapi2::TARGET_TYPE_MCC>(i_target);
const auto& l_mc = mss::find_target<fapi2::TARGET_TYPE_MC>(l_mcc);

// Start by assuming we do not have a FIR; if true at any point, skip other checks to preserve error
o_fir_error = false;

// For OMI case, we want to check all bits on fir registers (no custom mask)
FAPI_TRY(bad_fir_bits_helper(i_target, io_rc, o_fir_error, EXPLORER_OMI_INIT_FIR_REGS));

if (o_fir_error != true)
{
FAPI_TRY(bad_fir_bits_helper(l_mc, io_rc, o_fir_error, MC_OMI_INIT_FIR_REGS));
}

for(const auto& l_fir_reg : MCC_FIR_REGS)
if (o_fir_error != true)
{
FAPI_TRY(fir_with_mask<mss::mc_type::EXPLORER>(l_mcc, l_fir_reg, o_fir_error));
FAPI_TRY(bad_fir_bits_helper(l_mcc, io_rc, o_fir_error, MCC_OMI_INIT_FIR_REGS));
}

// Log the error if need be
log_fir_helper(l_mcc, o_fir_error, io_rc);
fapi_try_exit:
return fapi2::current_err;
}

// Exit if we have found a FIR
if(o_fir_error)
{
return fapi2::FAPI2_RC_SUCCESS;
}
///
/// @brief Checks whether any FIRs have lit up on a target
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @param[out] o_fir_error - true iff a FIR was hit
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
/// @note specialization for EXPLORER and fir checklist for DRAMINIT regs
///
template<>
fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER, firChecklist::DRAMINIT>( const
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
fapi2::ReturnCode& io_rc,
bool& o_fir_error)
{
// For draminit case, we want to check SRQFIR[4] and LOCAL_FIR[20,36] only, so unmask checkbits
// NOTE: if you change DRAMINIT_FIR_REGS, you need to update these indices
const uint64_t l_srqfir_reg_addr = EXPLORER_DRAMINIT_FIR_REGS.at(0).first;
const uint64_t l_localfir_reg_addr = EXPLORER_DRAMINIT_FIR_REGS.at(1).first;
fapi2::buffer<uint64_t> l_check_mask(0xFFFFFFFFFFFFFFFF);

// Start by assuming we do not have a FIR; if true at any point, skip other checks to preserve error
o_fir_error = false;

// Unmask bit 4
l_check_mask.clearBit<EXPLR_SRQ_SRQFIRQ_RCD_PARITY_ERROR>();
FAPI_TRY(bad_fir_bits_helper_with_mask(i_target, l_srqfir_reg_addr, l_check_mask, io_rc, o_fir_error));

// Mask all, then unmask bits 20,36
if (o_fir_error != true)
{
l_check_mask.flush<1>().clearBit<EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_PCS_GPBC_IRQ_106>()
.clearBit<EXPLR_TP_MB_UNIT_TOP_LOCAL_FIR_DDR4_PHY__FATAL>();

FAPI_TRY(bad_fir_bits_helper_with_mask(i_target, l_localfir_reg_addr, l_check_mask, io_rc, o_fir_error));
}

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Checks whether any FIRs have lit up on a target
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @param[out] o_fir_error - true iff a FIR was hit
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
/// @note specialization for EXPLORER and fir checklist for CCS regs
///
template<>
fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER, firChecklist::CCS>( const
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
fapi2::ReturnCode& io_rc,
bool& o_fir_error)
{
// For draminit_mc case, we want to check SRQFIR[4] and MBISTFIR[2,3] only, so unmask checkbits
// NOTE: if you change DRAMINIT_MC_FIR_REGS, you need to update these indices
const uint64_t l_srqfir_reg_addr = EXPLORER_CCS_FIR_REGS.at(0).first;
const uint64_t l_mcbistfir_reg_addr = EXPLORER_CCS_FIR_REGS.at(1).first;
fapi2::buffer<uint64_t> l_check_mask(0xFFFFFFFFFFFFFFFF);

// Start by assuming we do not have a FIR; if true at any point, skip other checks to preserve error
o_fir_error = false;

// Unmask bit 4
l_check_mask.clearBit<EXPLR_SRQ_SRQFIRQ_RCD_PARITY_ERROR>();
FAPI_TRY(bad_fir_bits_helper_with_mask(i_target, l_srqfir_reg_addr, l_check_mask, io_rc, o_fir_error));

// Mask all, then unmask bits 2,3
if (o_fir_error != true)
{
l_check_mask.flush<1>().clearBit<EXPLR_MCBIST_MCBISTFIRQ_INTERNAL_FSM_ERROR>()
.clearBit<EXPLR_MCBIST_MCBISTFIRQ_CCS_ARRAY_UNCORRECT_CE_OR_UE>();

FAPI_TRY(bad_fir_bits_helper_with_mask(i_target, l_mcbistfir_reg_addr, l_check_mask, io_rc, o_fir_error));
}

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Checks whether any FIRs have lit up on a target
/// @param[in] i_target - the target on which to operate
/// @param[in,out] io_rc - the return code for the function
/// @param[out] o_fir_error - true iff a FIR was hit
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
/// @note specialization for EXPLORER and fir checklist for GENERIC case
///
template<>
fapi2::ReturnCode bad_fir_bits<mss::mc_type::EXPLORER, firChecklist::GENERIC>( const
fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
fapi2::ReturnCode& io_rc,
bool& o_fir_error)
{
// NOTE: Redirecting the GENERIC case to the DRAMINIT checks because no FIR checklist is defined for GENERIC.
// GENERIC case required for bad_fir_bits call in mss_bad_bits.H -- update if GENERIC check needed
return bad_fir_bits<mss::mc_type::EXPLORER, firChecklist::DRAMINIT>(i_target, io_rc, o_fir_error);
}

} // end check ns
} // end mss ns

0 comments on commit 9b6bd57

Please sign in to comment.