Skip to content

Commit

Permalink
Fix 1-rank row repair case in p9c draminit_training and draminit_mc
Browse files Browse the repository at this point in the history
Change-Id: I91a83bbee82a01c5c065974afaf9e4291fa071f8
CQ:SW450686
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/69536
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Dev-Ready: Louis Stermole <stermole@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/69568
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
  • Loading branch information
stermole authored and crgeddes committed Feb 11, 2019
1 parent 99bfd4b commit 142cc29
Show file tree
Hide file tree
Showing 7 changed files with 312 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2016,2018 */
/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -76,7 +76,8 @@ enum consts : size_t

LANES_PER_BLOCK = 16,
MAX_BLOCKS_PER_RANK = 5,
MAX_BYTES_PER_BLOCK = 2,
MAX_BYTES_PER_BLOCK = LANES_PER_BLOCK / BITS_PER_BYTE,
MAX_NIBBLES_PER_BLOCK = LANES_PER_BLOCK / BITS_PER_NIBBLE,
MAX_BYTES_PER_RANK = MAX_BYTES_PER_BLOCK * MAX_BLOCKS_PER_RANK,
LANES_PER_PORT = LANES_PER_BLOCK * MAX_BLOCKS_PER_RANK,

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2012,2018 */
/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -222,6 +222,39 @@ extern "C"
const uint8_t i_state,
uint32_t& io_ccs_inst_cnt);

///
/// @brief Check row repair requests for a bad nibble and decide whether it affects training
/// @param[in] i_target mba target
/// @param[in] i_port port index
/// @param[in] i_rank rank index
/// @param[in] i_dp DP18 index of nibble in question
/// @param[in] i_lane DP18 lane of nibble in question
/// @param[in] i_dram_width DRAM width
/// @param[in] i_repairs_per_dimm table of row repair requests, from build_row_repair_table
/// @param[out] o_workaround_needed true if the workaround applies (we should train the nibble or clear the row repair request), false if not
/// @return FAPI2_RC_SUCCESS iff successful
///
bool row_repair_workaround_check(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
const uint8_t i_port,
const uint8_t i_rank,
const uint8_t i_dp,
const uint8_t i_lane,
const uint8_t i_dram_width,
const std::vector<fapi2::buffer<uint32_t>> i_repairs_per_dimm,
bool& o_workaround_needed);

///
/// @brief Find a DIMM target on an MBA target, from a port and DIMM index
/// @param[in] i_target mba target
/// @param[in] i_port_index port index
/// @param[in] i_dimm_index DIMM index
/// @param[out] o_dimm DIMM target
/// @return FAPI2_RC_SUCCESS iff successful
///
fapi2::ReturnCode find_dimm_from_index(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
const uint8_t i_port_index,
const uint8_t i_dimm_index,
fapi2::Target<fapi2::TARGET_TYPE_DIMM>& o_dimm);
} // extern "C"

#endif // mss_draminit_training_H_
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
# Contributors Listed Below - COPYRIGHT 2016,2017
# Contributors Listed Below - COPYRIGHT 2016,2019
# [+] International Business Machines Corp.
#
#
Expand All @@ -32,5 +32,7 @@ lib${PROCEDURE}_DEPLIBS+=p9c_mss_mrs6_DDR4
lib${PROCEDURE}_DEPLIBS+=p9c_mss_ddr4_funcs
lib${PROCEDURE}_DEPLIBS+=p9c_mss_access_delay_reg
lib${PROCEDURE}_DEPLIBS+=p9c_mss_unmask_errors
lib${PROCEDURE}_DEPLIBS+=p9c_mss_rowRepairFuncs
lib${PROCEDURE}_DEPLIBS+=p9c_mss_row_repair
$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
Original file line number Diff line number Diff line change
Expand Up @@ -378,17 +378,32 @@ extern "C"
/// @param[in] i_dram_width the DRAM width
/// @param[in] i_dram the DRAM index
/// @param[in] i_rankpair_table table of rank to rank pairs for this port
/// @param[in] i_ranks_on_port number of ranks on this port
/// @param[in] i_bad_bits array bad bits data from VPD for all ranks on the port
/// @param[out] o_uncalibrated true if DRAM was marked bad in all ranks, false otherwise
/// @return FAPI2_RC_SUCCESS iff successful
fapi2::ReturnCode check_for_uncalibrated_dram(const uint8_t i_dram_width,
const uint8_t i_dram,
const uint8_t (&i_rankpair_table)[MAX_RANKS_PER_PORT],
const uint8_t i_ranks_on_port,
const uint8_t (&i_bad_bits)[MAX_RANKS_PER_PORT][DIMM_DQ_RANK_BITMAP_SIZE],
bool& o_uncalibrated)
{
constexpr uint8_t NO_RP = 255;

// On a port with only 1 rank configured, we can't tell if a DRAM is uncalibrated or if it just
// failed calibration.
// This is handled in draminit_training by calibrating any DRAM with a row repair request
// (regardless of whether it had bad bits set), and clearing the row repair request if the
// DRAM fails training. So by the time we get here, if we're 1-rank and a row repair
// request exists, we know the DRAM has been calibrated.
if (i_ranks_on_port == 1)
{
FAPI_INF("DRAM index %d was calibrated since it's on a single-rank port", i_dram);
o_uncalibrated = false;
return fapi2::FAPI2_RC_SUCCESS;
}

// The DRAM index in ATTR_ROW_REPAIR_DATA is relative to Centaur perspective.
// The bad_bits attribute is as well, so we can just index into the bad bits array
// using the DRAM index
Expand Down Expand Up @@ -566,6 +581,23 @@ extern "C"
return fapi2::current_err;
}

/// @brief Count the number of ranks per port
/// @param[in] i_target_mba mba target
/// @return FAPI2_RC_SUCCESS iff successful
void count_ranks_per_port(const uint8_t (&i_ranks_per_dimm)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT],
uint8_t (&o_ranks_per_port)[MAX_PORTS_PER_MBA])
{
for (uint8_t l_port = 0; l_port < MAX_PORTS_PER_MBA; ++l_port)
{
o_ranks_per_port[l_port] = 0;

for (uint8_t l_dimm = 0; l_dimm < MAX_DIMM_PER_PORT; ++l_dimm)
{
o_ranks_per_port[l_port] += i_ranks_per_dimm[l_port][l_dimm];
}
}
}

/// @brief Deploy PPR row repairs, if supported, according to VPD attributes
/// @param[in] i_target_mba mba target
/// @return FAPI2_RC_SUCCESS iff successful
Expand All @@ -576,6 +608,8 @@ extern "C"
bool l_sppr_supported = true;
uint64_t l_mnfg_flags = 0;
uint8_t l_dram_width = 0;
uint8_t l_ranks_per_dimm[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT];
uint8_t l_ranks_per_port[MAX_PORTS_PER_MBA];
uint8_t l_dram = 0;
uint8_t l_srank = 0;
uint8_t l_bg = 0;
Expand All @@ -587,6 +621,10 @@ extern "C"

FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MNFG_FLAGS, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_mnfg_flags));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_WIDTH, i_target_mba, l_dram_width));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_NUM_RANKS_PER_DIMM, i_target_mba, l_ranks_per_dimm));

// Calculate the number of ranks on each port
count_ranks_per_port(l_ranks_per_dimm, l_ranks_per_port);

// If row repairs are not supported, we're done
for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target_mba))
Expand Down Expand Up @@ -681,7 +719,8 @@ extern "C"

// If a DRAM position is marked bad in VPD for all valid ranks, skip row repair and clear row repair entry from VPD
// as this means the DRAM position has not been calibrated during draminit_training (Centaur workaround)
FAPI_TRY(check_for_uncalibrated_dram(l_dram_width, l_dram, l_rankpair_table, l_bad_bits, l_uncalibrated));
FAPI_TRY(check_for_uncalibrated_dram(l_dram_width, l_dram, l_rankpair_table, l_ranks_per_port[l_port],
l_bad_bits, l_uncalibrated));

if (l_uncalibrated)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,14 @@ extern "C"
/// @param[in] i_dram_width the DRAM width
/// @param[in] i_dram the DRAM index
/// @param[in] i_rankpair_table table of rank to rank pairs for this port
/// @param[in] i_ranks_on_port number of ranks on this port
/// @param[in] i_bad_bits array bad bits data from VPD for all ranks on the port
/// @param[out] o_uncalibrated true if DRAM was marked bad in all ranks, false otherwise
/// @return FAPI2_RC_SUCCESS iff successful
fapi2::ReturnCode check_for_uncalibrated_dram(const uint8_t i_dram_width,
const uint8_t i_dram,
const uint8_t (&i_rankpair_table)[MAX_RANKS_PER_PORT],
const uint8_t i_ranks_on_port,
const uint8_t (&i_bad_bits)[MAX_RANKS_PER_PORT][DIMM_DQ_RANK_BITMAP_SIZE],
bool& o_uncalibrated);

Expand Down Expand Up @@ -143,6 +145,12 @@ extern "C"
const uint8_t i_dram_width,
const uint8_t i_row_repair_data[MAX_RANKS_PER_DIMM][ROW_REPAIR_BYTES_PER_RANK],
std::vector<fapi2::buffer<uint32_t>>& o_repairs_per_dimm);

/// @brief Count the number of ranks per port
/// @param[in] i_target_mba mba target
/// @return FAPI2_RC_SUCCESS iff successful
void count_ranks_per_port(const uint8_t (&i_ranks_per_dimm)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT],
uint8_t (&o_ranks_per_port)[MAX_PORTS_PER_MBA]);
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
<!-- Contributors Listed Below - COPYRIGHT 2016,2018 -->
<!-- Contributors Listed Below - COPYRIGHT 2016,2019 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
Expand Down Expand Up @@ -370,4 +370,16 @@
</callout>
</hwpError>

<hwpError>
<rc>RC_CEN_DIMM_NOT_FOUND_FROM_INDEX</rc>
<description>A DIMM target could not be found for the given port and DIMM index.</description>
<ffdc>MBA</ffdc>
<ffdc>PORT_INDEX</ffdc>
<ffdc>DIMM_INDEX</ffdc>
<callout>
<procedure>CODE</procedure>
<priority>HIGH</priority>
</callout>
</hwpError>

</hwpErrors>

0 comments on commit 142cc29

Please sign in to comment.