summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C58
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C616
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H3
3 files changed, 582 insertions, 95 deletions
diff --git a/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C b/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C
index b6a3146a3..b07e9c281 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/lib/utils/mem_size.C
@@ -74,6 +74,41 @@ bool is_dimm_functional(const uint8_t i_valid_dimm_bitmap,
return fapi2::buffer<uint8_t>(i_valid_dimm_bitmap).getBit(VALID_DIMM_POS[i_port][i_dimm]);
}
+
+///
+/// @brief Return the total memory size behind an MBA
+/// @param[in] i_target the MBA target
+/// @param[out] o_size the size of memory in GB behind the target
+/// @return FAPI2_RC_SUCCESS if ok
+///
+template<>
+fapi2::ReturnCode eff_memory_size( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, uint64_t& o_size )
+{
+ o_size = 0;
+ uint8_t l_sizes[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {};
+ uint8_t l_func_dimms_bitmap = 0;
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, i_target, l_func_dimms_bitmap),
+ "Failed to access attribute ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR for %s", mss::c_str(i_target) );
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_SIZE, i_target, l_sizes),
+ "Failed to access attribute ATTR_CEN_EFF_DIMM_SIZE for %s", mss::c_str(i_target) );
+
+ for( size_t p = 0; p < MAX_PORTS_PER_MBA; ++p)
+ {
+ for( size_t d = 0; d < MAX_DIMM_PER_PORT; ++d)
+ {
+ if( is_dimm_functional(l_func_dimms_bitmap, p, d) )
+ {
+ o_size += l_sizes[p][d];
+ }
+ }// dimm
+ }// port
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
///
/// @brief Return the total memory size behind a DMI
/// @param[in] i_target the DMI target
@@ -87,25 +122,10 @@ fapi2::ReturnCode eff_memory_size( const fapi2::Target<fapi2::TARGET_TYPE_DMI>&
for (const auto& mba : mss::find_targets<fapi2::TARGET_TYPE_MBA>(i_target))
{
- uint8_t l_sizes[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {};
- uint8_t l_func_dimms_bitmap = 0;
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, mba, l_func_dimms_bitmap),
- "Failed to access attribute ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR for %s", mss::c_str(mba) );
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_SIZE, mba, l_sizes),
- "Failed to access attribute ATTR_CEN_EFF_DIMM_SIZE for %s", mss::c_str(mba) );
-
- for( size_t p = 0; p < MAX_PORTS_PER_MBA; ++p)
- {
- for( size_t d = 0; d < MAX_DIMM_PER_PORT; ++d)
- {
- if( is_dimm_functional(l_func_dimms_bitmap, p, d) )
- {
- o_size += l_sizes[p][d];
- }
- }// dimm
- }// port
+ uint64_t l_mba_size;
+ FAPI_TRY(eff_memory_size(mba, l_mba_size),
+ "Error from eff_memory_size (mba: %s)", mss::c_str(mba));
+ o_size += l_mba_size;
}// mba
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
index 0149317da..d6178bea6 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.C
@@ -89,6 +89,57 @@ enum GroupAllowed
GROUP_8,
};
+// matrix for port-pair based deconfiguration combinations
+const uint8_t MAX_MBA_PERMUTATIONS = 9;
+const uint8_t MBA_PERMUTATIONS[MAX_MBA_PERMUTATIONS][NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF] =
+{
+ {
+ // case 0
+ {0, 0}, // port 0 - MBA0 x MBA1 x
+ {0, 0} // port 1 - MAX0 x MBA1 x
+ },
+ {
+ // case 1
+ {1, 0}, // port 0 - MBA0 + MBA1 x
+ {1, 0} // port 1 - MAX0 + MBA1 x
+ },
+ {
+ // case 2
+ {0, 1}, // port 0 - MBA0 x MBA1 +
+ {0, 1} // port 1 - MAX0 x MBA1 +
+ },
+ {
+ // case 3
+ {1, 0}, // port 0 - MBA0 + MBA1 x
+ {0, 1} // port 1 - MAX0 x MBA1 +
+ },
+ {
+ // case 4
+ {0, 1}, // port 0 - MBA0 x MBA1 +
+ {1, 0} // port 1 - MAX0 + MBA1 x
+ },
+ {
+ // case 5
+ {0, 1}, // port 0 - MBA0 x MBA1 +
+ {1, 1} // port 1 - MAX0 + MBA1 +
+ },
+ {
+ // case 6
+ {1, 0}, // port 0 - MBA0 + MBA1 x
+ {1, 1} // port 1 - MAX0 + MBA1 +
+ },
+ {
+ // case 7
+ {1, 1}, // port 0 - MBA0 + MBA1 +
+ {1, 0} // port 1 - MAX0 + MBA1 x
+ },
+ {
+ // case 8
+ {1, 1}, // port 0 - MBA0 + MBA1 +
+ {0, 1} // port 1 - MAX0 x MBA1 +
+ }
+};
+
///----------------------------------------------------------------------------
/// struct EffGroupingSysAttrs
///----------------------------------------------------------------------------
@@ -2758,11 +2809,13 @@ void grouping_group1PortsPerGroup(const EffGroupingMemInfo& i_memInfo,
return;
}
+///
/// @brief Callout DIMM attached to ungrouped port, appends
/// MSS_EFF_GROUPING_UNABLE_TO_GROUP_DIMM to input return code
///
/// Ensure any ungrouped DIMMs are called out for deconfiguration
///
+/// @tparam T Template paramter, passed in port target type
/// @param[in] i_dimm_target Target identifying DIMM attached to ungrouped port
/// @param[in] i_port_target Target identifying with ungrouped port
/// @param[in] i_portIndex Port number associated with target
@@ -2811,12 +2864,15 @@ void calloutDIMM(
return;
}
-/// @brief Determine set of DIMM targets attached to channel target
-/// (MCA/DMI)
-/// @tparam T template paramter, passed in target
-/// @param[in] i_target Channel target (of type T)
-/// @param[out] o_dimm_targets Set of attached DIMM targets
///
+/// @brief Determine set of DIMM targets attached to target
+/// (MCA/DMI/MBA)
+///
+/// @tparam T Template paramter, passed in target
+///
+/// @param[in] i_target Target (of type T)
+/// @param[out] o_dimm_targets Vector of DIMM targets, attached
+/// DIMMs will be appended at end
/// @return void
///
template<fapi2::TargetType T>
@@ -2830,7 +2886,30 @@ void getAttachedDimms(
const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets)
{
- o_dimm_targets = i_target.template getChildren<fapi2::TARGET_TYPE_DIMM>();
+ FAPI_DBG("Start");
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimm_targets =
+ i_target.template getChildren<fapi2::TARGET_TYPE_DIMM>();
+
+ o_dimm_targets.insert(o_dimm_targets.end(),
+ l_dimm_targets.begin(),
+ l_dimm_targets.end());
+ FAPI_DBG("End");
+}
+
+/// template specialization for MBA target type
+template <>
+void getAttachedDimms(
+ const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets)
+{
+ FAPI_DBG("Start");
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimm_targets =
+ i_target.template getChildren<fapi2::TARGET_TYPE_DIMM>();
+
+ o_dimm_targets.insert(o_dimm_targets.end(),
+ l_dimm_targets.begin(),
+ l_dimm_targets.end());
+ FAPI_DBG("End");
}
/// template specialization for DMI target type
@@ -2839,23 +2918,22 @@ void getAttachedDimms(
const fapi2::Target<fapi2::TARGET_TYPE_DMI>& i_target,
std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets)
{
+ FAPI_DBG("Start");
+
// determine attached Centaur chip
for (auto l_cen_target : i_target.template getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>())
{
// get set of valid MBAs
for (auto l_mba_target : l_cen_target.template getChildren<fapi2::TARGET_TYPE_MBA>())
{
- // DIMMs are children of MBAs
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimm_targets_on_this_mba;
- l_dimm_targets_on_this_mba = l_mba_target.template getChildren<fapi2::TARGET_TYPE_DIMM>();
- o_dimm_targets.insert(o_dimm_targets.end(),
- l_dimm_targets_on_this_mba.begin(),
- l_dimm_targets_on_this_mba.end());
+ getAttachedDimms<fapi2::TARGET_TYPE_MBA>(l_mba_target, o_dimm_targets);
}
}
-}
+ FAPI_DBG("End");
+}
+///
/// @brief Utility function to generate base return code for ungrouped port
/// error reporting
///
@@ -2879,13 +2957,385 @@ fapi_try_exit:
///
+/// @brief Determine if port pair is groupable given MBA sizes
+/// and proposed configuration
+///
+/// @param[in] i_mba_size Array of per-MBA sizes
+/// @param[in] i_mba_config Array of proposed per-MBA configuration
+/// @param[out] o_size Resultant aggregate size
+///
+/// @return bool indicating if configuration produces groupable
+/// port pair
+bool portPairIsGroupable(
+ const uint64_t i_mba_size[NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF],
+ const uint8_t i_mba_config[NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF],
+ uint64_t& o_size)
+{
+ uint64_t l_mba_size[NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF];
+ uint64_t l_port_size[NUM_PORTS_PER_PAIR];
+ uint64_t l_common_size = 0;
+
+ o_size = 0;
+
+ for (uint8_t ii = 0; ii < NUM_PORTS_PER_PAIR; ii++)
+ {
+ l_port_size[ii] = 0;
+ }
+
+ for (uint8_t ii = 0; ii < NUM_PORTS_PER_PAIR; ii++)
+ {
+ for (uint8_t jj = 0; jj < NUM_MBA_PER_MEMBUF; jj++)
+ {
+ l_mba_size[ii][jj] = (i_mba_config[ii][jj]) ?
+ (i_mba_size[ii][jj]) :
+ (0);
+ l_port_size[ii] += l_mba_size[ii][jj];
+ o_size += l_mba_size[ii][jj];
+ }
+
+ if (ii == 0)
+ {
+ l_common_size = l_port_size[ii];
+ }
+
+ if (l_common_size != l_port_size[ii])
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+///
+/// @brief Find minset of DIMMs to remove to make DMI port pair groupable
+///
+/// @param[in] i_targetA_func TargetA functional?
+/// @param[in] i_targetA TargetA
+/// @param[in] i_targetA_ungrouped Target A has memory and is ungrouped?
+/// @param[in] i_targetB_func TargetB functional?
+/// @param[in] i_targetB TargetB
+/// @param[in] i_targetB_ungrouped Target B has memory and is ungrouped?
+/// @param[in] o_dimm_targets Vector of DIMM targets to deconfigure
+///
+/// @return ReturnCode
+//
+fapi2::ReturnCode findMinDeconfigForPortPair(
+ const bool i_targetA_func,
+ const fapi2::Target<fapi2::TARGET_TYPE_DMI> i_targetA,
+ const bool i_targetA_ungrouped,
+ const bool i_targetB_func,
+ const fapi2::Target<fapi2::TARGET_TYPE_DMI> i_targetB,
+ const bool i_targetB_ungrouped,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets)
+{
+ FAPI_DBG("Start");
+
+ // if only one port is functional, all of its DIMMs must be called out
+ if ((!i_targetA_func || !i_targetA_ungrouped) &&
+ ( i_targetB_func && i_targetB_ungrouped))
+ {
+ FAPI_DBG("Calling out all DIMMs on port B");
+ getAttachedDimms(i_targetB, o_dimm_targets);
+ }
+ else if ((i_targetA_func && i_targetA_ungrouped) &&
+ (!i_targetB_func || !i_targetB_ungrouped))
+ {
+ FAPI_DBG("Calling out all DIMMs on port A");
+ getAttachedDimms(i_targetA, o_dimm_targets);
+ }
+ // do nothing if neither is functional, else look across both
+ // members of port pair to perform deconfigurations
+ else if (i_targetA_func && i_targetA_ungrouped &&
+ i_targetB_func && i_targetB_ungrouped)
+ {
+ FAPI_DBG("A and B are functional, calling out based on minset MBA configuation");
+ char l_targetA_string[fapi2::MAX_ECMD_STRING_LEN];
+ char l_targetB_string[fapi2::MAX_ECMD_STRING_LEN];
+ fapi2::toString(i_targetA, l_targetA_string, fapi2::MAX_ECMD_STRING_LEN);
+ fapi2::toString(i_targetB, l_targetB_string, fapi2::MAX_ECMD_STRING_LEN);
+
+ // get targets
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MBA>> l_mba_targets[NUM_PORTS_PER_PAIR];
+ l_mba_targets[0] = i_targetA.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>()
+ .front()
+ .getChildren<fapi2::TARGET_TYPE_MBA>();
+ l_mba_targets[1] = i_targetB.getChildren<fapi2::TARGET_TYPE_MEMBUF_CHIP>()
+ .front()
+ .getChildren<fapi2::TARGET_TYPE_MBA>();
+
+ FAPI_DBG("Retrieving MBA children:3");
+ FAPI_DBG(" DMI target A = %s, %d MBA children", l_targetA_string, l_mba_targets[0].size());
+ FAPI_DBG(" DMI target B = %s, %d MBA children", l_targetB_string, l_mba_targets[1].size());
+
+ uint8_t l_mba_functional[NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF];
+ uint8_t l_mba_tgt_index[NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF];
+ uint64_t l_mba_size[NUM_PORTS_PER_PAIR][NUM_MBA_PER_MEMBUF];
+
+ uint64_t l_max_size = 0;
+ uint8_t l_max_size_idx = 0;
+
+ // initialize array storage
+ for (uint8_t ii = 0; ii < NUM_PORTS_PER_PAIR; ii++)
+ {
+ for (uint8_t jj = 0; (jj < NUM_MBA_PER_MEMBUF); jj++)
+ {
+ l_mba_functional[ii][jj] = 0;
+ l_mba_tgt_index[ii][jj] = 0;
+ l_mba_size[ii][jj] = 0;
+ }
+ }
+
+ // mark functional MBAs & associated targets
+ for (uint8_t ii = 0; ii < NUM_PORTS_PER_PAIR; ii++)
+ {
+ for (uint8_t jj = 0; jj < l_mba_targets[ii].size(); jj++)
+ {
+ uint8_t l_unit_pos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_mba_targets[ii][jj],
+ l_unit_pos),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");
+ l_mba_functional[ii][l_unit_pos] = 1;
+ l_mba_tgt_index[ii][l_unit_pos] = jj;
+ }
+ }
+
+ // retrieve per-MBA sizes
+ for (uint8_t ii = 0; ii < NUM_PORTS_PER_PAIR; ii++)
+ {
+ for (uint8_t jj = 0; jj < NUM_MBA_PER_MEMBUF; jj++)
+ {
+ if (l_mba_functional[ii][jj])
+ {
+ FAPI_TRY(mss::eff_memory_size(l_mba_targets[ii][l_mba_tgt_index[ii][jj]],
+ l_mba_size[ii][jj]),
+ "Error from eff_memory_size");
+ FAPI_DBG("Set MBA size[%d][%d] = %d",
+ ii, jj, l_mba_size[ii][jj]);
+ }
+ }
+ }
+
+ // walk all permutations of MBA configurations, select
+ // the combination which leaves us the largest amount
+ // of memory
+ for (uint8_t ll = 0; ll < MAX_MBA_PERMUTATIONS; ll++)
+ {
+ uint64_t l_size;
+
+ if (portPairIsGroupable(l_mba_size,
+ MBA_PERMUTATIONS[ll],
+ l_size))
+ {
+ if (l_size > l_max_size)
+ {
+ l_max_size = l_size;
+ l_max_size_idx = ll;
+ }
+ }
+ }
+
+ FAPI_ERR("Selected permutation index = %d, size = %lld",
+ l_max_size_idx, l_max_size);
+
+ // best option selected, deconfigure based on combination of
+ // selected permutation and current functional state
+ for (uint8_t ii = 0; ii < NUM_PORTS_PER_PAIR; ii++)
+ {
+ for (uint8_t jj = 0; jj < NUM_MBA_PER_MEMBUF; jj++)
+ {
+ if (l_mba_functional[ii][jj] &&
+ !MBA_PERMUTATIONS[l_max_size_idx][ii][jj])
+ {
+ FAPI_ERR("Deconfiguring MBA[%d][%d]",
+ ii, jj);
+ getAttachedDimms(l_mba_targets[ii][l_mba_tgt_index[ii][jj]],
+ o_dimm_targets);
+ }
+ }
+ }
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Generate DIMM callouts based on ports which are ungrouped
+///
+/// @tparam T Template paramter, passed in port target
+///
+/// @param[in] i_ports_functional Per-port functional status
+/// @param[in] i_ports_ungrouped Per-port grouping status
+/// @param[in] i_ports_tgt_index Per-port target vector index
+/// @param[in] i_ports_targets Set of port targets
+/// @param[in] i_memInfo Reference to Memory Info
+/// @param[in] i_hwMirrorEnabled Mirroring policy
+/// @param[in] o_dimm_targets Vector of DIMM targets to append deconfigurations
+/// @param[in] o_rc Return code object to append deconfigurations
+///
+/// @return FAPI2_RC_SUCCESS if success, else error code.
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode calloutDimmsForUngroupedPorts(
+ const uint8_t i_ports_functional[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_ungrouped[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_tgt_index[NUM_MC_PORTS_PER_PROC],
+ const std::vector<fapi2::Target<T>>& i_port_targets,
+ const EffGroupingMemInfo& i_memInfo,
+ const uint8_t i_hwMirrorEnabled,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets,
+ fapi2::ReturnCode& o_rc);
+
+/// template specialization for DMI target type
+template<>
+fapi2::ReturnCode calloutDimmsForUngroupedPorts(
+ const uint8_t i_ports_functional[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_ungrouped[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_tgt_index[NUM_MC_PORTS_PER_PROC],
+ const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DMI>>& i_port_targets,
+ const EffGroupingMemInfo& i_memInfo,
+ const uint8_t i_hwMirrorEnabled,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets,
+ fapi2::ReturnCode& o_rc)
+{
+ FAPI_DBG("Start");
+
+ // o_rc contains the error we're going to append to
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // if mirroring is required, calculate deconfiguration across
+ // port pairs -- try to maintain ability to mirror with minimal
+ // loss of DIMMs
+ if (i_hwMirrorEnabled == fapi2::ENUM_ATTR_MRW_HW_MIRRORING_ENABLE_TRUE)
+ {
+ for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii += 2)
+ {
+ if ((i_ports_functional[ii] && i_ports_ungrouped[ii]) ||
+ (i_ports_functional[ii + 1] && i_ports_ungrouped[ii + 1]))
+ {
+ FAPI_TRY(findMinDeconfigForPortPair(i_ports_functional[ii],
+ i_port_targets[i_ports_tgt_index[ii]],
+ i_ports_ungrouped[ii],
+ i_ports_functional[ii + 1],
+ i_port_targets[i_ports_tgt_index[ii + 1]],
+ i_ports_ungrouped[ii + 1],
+ o_dimm_targets),
+ "Error from FindMinDeconfigForPortPair");
+ }
+ }
+ }
+ // if mirroring is disabled or requested, callout each DIMM which is
+ // associated with each ungrouped port
+ else
+ {
+ for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii += 1)
+ {
+ if (i_ports_functional[ii] && i_ports_ungrouped[ii])
+ {
+ getAttachedDimms(i_port_targets[i_ports_tgt_index[ii]],
+ o_dimm_targets);
+ }
+ }
+ }
+
+ FAPI_ERR("Calling out %d DIMMs",
+ o_dimm_targets.size());
+
+ // add DIMM callouts
+ for (const auto& l_dimm_target : o_dimm_targets)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_DMI> l_port_target = l_dimm_target
+ .getParent<fapi2::TARGET_TYPE_MBA>()
+ .getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>()
+ .getParent<fapi2::TARGET_TYPE_DMI>();
+ uint8_t l_port_index = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_port_target,
+ l_port_index),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");
+
+ calloutDIMM(l_dimm_target,
+ l_port_target,
+ l_port_index,
+ i_memInfo.iv_portSize[l_port_index],
+ o_rc);
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+/// template specialization for MCA target type
+template<>
+fapi2::ReturnCode calloutDimmsForUngroupedPorts(
+ const uint8_t i_ports_functional[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_ungrouped[NUM_MC_PORTS_PER_PROC],
+ const uint8_t i_ports_tgt_index[NUM_MC_PORTS_PER_PROC],
+ const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>>& i_port_targets,
+ const EffGroupingMemInfo& i_memInfo,
+ const uint8_t i_hwMirrorEnabled,
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& o_dimm_targets,
+ fapi2::ReturnCode& o_rc)
+{
+ FAPI_DBG("Start");
+
+ // o_rc contains the error we're going to append to
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // callout each DIMM which is associated with each ungrouped port
+ for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii += 1)
+ {
+ if (i_ports_functional[ii] && i_ports_ungrouped[ii])
+ {
+ getAttachedDimms(i_port_targets[i_ports_tgt_index[ii]],
+ o_dimm_targets);
+ }
+ }
+
+ // add DIMM callouts
+ for (const auto& l_dimm_target : o_dimm_targets)
+ {
+ fapi2::Target<fapi2::TARGET_TYPE_MCA> l_port_target = l_dimm_target
+ .getParent<fapi2::TARGET_TYPE_MCA>();
+ uint8_t l_port_index = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_port_target,
+ l_port_index),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");
+
+ calloutDIMM(l_dimm_target,
+ l_port_target,
+ l_port_index,
+ i_memInfo.iv_portSize[l_port_index],
+ o_rc);
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
/// @brief Finds ungrouped ports
///
-/// If any are found then their associated DIMMs will be deconfigured
+/// If any are found then DIMMs will be deconfigured to attempt to satisfy
+/// grouping rules
///
-/// @param[in] i_target Reference to processor chip target
-/// @param[in] i_memInfo Reference to Memory Info
-/// @param[in] i_groupData Reference to Group data
+/// @tparam T Template paramter, port target type
+///
+/// @param[in] i_target Reference to processor chip target
+/// @param[in] i_memInfo Reference to Memory Info
+/// @param[in] i_groupData Reference to Group data
+/// @param[in] i_hwMirrorEnabled Mirroring policy
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
///
@@ -2893,86 +3343,94 @@ template<fapi2::TargetType T>
fapi2::ReturnCode grouping_findUngroupedPorts(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
const EffGroupingMemInfo& i_memInfo,
- const EffGroupingData& i_groupData)
+ const EffGroupingData& i_groupData,
+ const uint8_t i_hwMirrorEnabled)
{
FAPI_DBG("Entering");
- std::vector<fapi2::Target<T>> l_mcTargets = i_target.getChildren<T>();
+ // get vector of functional port targets
+ std::vector<fapi2::Target<T>> l_port_targets = i_target.getChildren<T>();
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ // build per-port vectors tracking:
+ // - functional status
+ // - grouped state
+ // - index for associated target
+ uint8_t l_ports_functional[NUM_MC_PORTS_PER_PROC];
+ uint8_t l_ports_ungrouped[NUM_MC_PORTS_PER_PROC];
+ uint8_t l_ports_tgt_index[NUM_MC_PORTS_PER_PROC];
bool l_all_grouped = true;
+ // initialize array storage
+ for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii++)
+ {
+ l_ports_functional[ii] = 0;
+ l_ports_ungrouped[ii] = 0;
+ l_ports_tgt_index[ii] = 0;
+ }
+
+ // mark functional ports & associated targets
+ for (uint8_t jj = 0; (jj < l_port_targets.size()); jj++)
+ {
+ uint8_t l_unit_pos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_port_targets[jj], l_unit_pos),
+ "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");
+ l_ports_functional[l_unit_pos] = 1;
+ l_ports_tgt_index[l_unit_pos] = jj;
+ }
+
// determine if any ports are not grouped
- for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC) && l_all_grouped; ii++)
+ for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii++)
{
if ((i_memInfo.iv_portSize[ii] != 0) &&
(i_groupData.iv_portGrouped[ii] == false))
{
- FAPI_ERR("grouping_findUngroupedPorts: Unable to group port %u", ii);
-
- for (auto l_mc : l_mcTargets)
- {
- // Get the MCA position
- uint8_t l_unitPos = 0;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_unitPos),
- "Error getting MCA ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
- (uint64_t)fapi2::current_err);
-
- // found an ungrouped port
- if (l_unitPos == ii)
- {
- l_all_grouped = false;
- break;
- }
- }
+ FAPI_ERR("grouping_findUngroupedPorts: Unable to group port %u",
+ ii);
+ l_ports_ungrouped[ii] = 1;
+ l_all_grouped = false;
}
}
+ // initialize array storage
+ for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii++)
+ {
+ FAPI_DBG("Port %d", ii);
+ FAPI_DBG(" functional: %d", l_ports_functional[ii]);
+ FAPI_DBG(" ungrouped: %d", l_ports_ungrouped[ii]);
+ FAPI_DBG(" tgt_index: %d", l_ports_tgt_index[ii]);
+ }
+
// assert if there are any ungrouped ports on this chip
if (!l_all_grouped)
{
+ // DIMMs to be called out
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimm_targets;
+
// create base HWP error
- fapi2::ReturnCode l_rc;
l_rc = emitUnableToGroupError(i_memInfo.iv_maxGroupMemSize);
- // rerun loop and append error for each DIMM which is associated with an
- // ungrouped port
- for (uint8_t ii = 0; (ii < NUM_MC_PORTS_PER_PROC); ii++)
- {
- if ((i_memInfo.iv_portSize[ii] != 0) &&
- (i_groupData.iv_portGrouped[ii] == false))
- {
- FAPI_ERR("grouping_findUngroupedPorts: Unable to group port %u", ii);
-
- for (auto l_mc : l_mcTargets)
- {
- // Get the MCA position
- uint8_t l_unitPos = 0;
- (void) FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mc, l_unitPos);
-
- // for each ungrouped port, commit an error for each downstream DIMM
- if (l_unitPos == ii)
- {
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimm_targets;
- getAttachedDimms(l_mc, l_dimm_targets);
-
- for (const auto& l_dimm_target : l_dimm_targets)
- {
- calloutDIMM(l_dimm_target,
- l_mc,
- ii,
- i_memInfo.iv_portSize[ii],
- l_rc);
- }
- }
- }
- }
- }
-
- fapi2::current_err = l_rc;
+ // append all DIMM callouts
+ calloutDimmsForUngroupedPorts(l_ports_functional,
+ l_ports_ungrouped,
+ l_ports_tgt_index,
+ l_port_targets,
+ i_memInfo,
+ i_hwMirrorEnabled,
+ l_dimm_targets,
+ l_rc);
}
fapi_try_exit:
FAPI_DBG("Exiting");
- return fapi2::current_err;
+
+ if (l_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ return l_rc;
+ }
+ else
+ {
+ return fapi2::current_err;
+ }
}
///
@@ -3663,13 +4121,19 @@ fapi2::ReturnCode p9_mss_eff_grouping(
// Verify all ports are grouped, or error out
if (l_memInfo.iv_nimbusProc == true)
{
- FAPI_TRY(grouping_findUngroupedPorts<fapi2::TARGET_TYPE_MCA>(i_target, l_memInfo, l_groupData),
+ FAPI_TRY(grouping_findUngroupedPorts<fapi2::TARGET_TYPE_MCA>(i_target,
+ l_memInfo,
+ l_groupData,
+ l_sysAttrs.iv_hwMirrorEnabled),
"grouping_findUngroupedPorts() returns an error, l_rc 0x%.8X",
(uint64_t)fapi2::current_err);
}
else
{
- FAPI_TRY(grouping_findUngroupedPorts<fapi2::TARGET_TYPE_DMI>(i_target, l_memInfo, l_groupData),
+ FAPI_TRY(grouping_findUngroupedPorts<fapi2::TARGET_TYPE_DMI>(i_target,
+ l_memInfo,
+ l_groupData,
+ l_sysAttrs.iv_hwMirrorEnabled),
"grouping_findUngroupedPorts() returns an error, l_rc 0x%.8X",
(uint64_t)fapi2::current_err);
}
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H
index 6b9e5370a..1bb1d0f71 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H
@@ -86,6 +86,9 @@ const uint8_t NUM_MCS_PER_PROC = 4;
const uint8_t NUM_MC_PORTS_PER_PROC = 8;
const uint8_t NUM_DIMMS_PER_DRAM_PORT = 2; // 2 DIMMs per DRAM port
+const uint8_t NUM_PORTS_PER_PAIR = 2;
+const uint8_t NUM_MBA_PER_MEMBUF = 2;
+
/// Function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_mss_eff_grouping_FP_t)(
const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);
OpenPOWER on IntegriCloud