summaryrefslogtreecommitdiffstats
path: root/src/import/generic
diff options
context:
space:
mode:
authorMark Pizzutillo <Mark.Pizzutillo@ibm.com>2019-04-05 17:29:38 -0400
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-05-07 15:49:43 -0500
commit32bc3c06a9ba4b9b5037f09febff20b67ada278a (patch)
treedfbba2a8de9fdf58bd12a0c98d6bff2081f0e454 /src/import/generic
parent3498e76492e9b23271ed0a446d8ddedd32e70d0a (diff)
downloadtalos-hostboot-32bc3c06a9ba4b9b5037f09febff20b67ada278a.tar.gz
talos-hostboot-32bc3c06a9ba4b9b5037f09febff20b67ada278a.zip
Add API for axone p10 dimm rank
Change-Id: I92ceb8303371368064e0a958fa09846a689c7bd1 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72725 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/75501 Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/generic')
-rw-r--r--src/import/generic/memory/lib/utils/mss_rank.H267
-rw-r--r--src/import/generic/memory/lib/utils/shared/mss_generic_consts.H1
-rw-r--r--src/import/generic/procedures/xml/error_info/generic_error.xml55
3 files changed, 321 insertions, 2 deletions
diff --git a/src/import/generic/memory/lib/utils/mss_rank.H b/src/import/generic/memory/lib/utils/mss_rank.H
index b43e7e6ff..42cd7a25e 100644
--- a/src/import/generic/memory/lib/utils/mss_rank.H
+++ b/src/import/generic/memory/lib/utils/mss_rank.H
@@ -22,3 +22,270 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mss_rank.H
+/// @brief Tools to obtain rank info from DIMM or PORT target
+///
+// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_RANK_H_
+#define _MSS_RANK_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/utils/pos.H>
+#include <generic/memory/lib/utils/find.H>
+#include <mss_generic_attribute_getters.H>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+
+namespace mss
+{
+namespace rank
+{
+
+///
+/// @brief Rank traits class for variations depending on MC
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE>
+class rankTraits;
+
+///
+/// @brief Rank info class
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = rankTraits<MC>>
+class info
+{
+
+ public:
+ // Delete default constructor
+ info() = delete;
+
+ ///
+ /// @brief Constructor for info object
+ /// @param[in] i_target DIMM target
+ /// @param[in] i_index dimm rank index 0-3
+ /// @param[out] o_rc return code, FAPI2_RC_SUCCESS if no error
+ ///
+ info(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm_target, const uint8_t i_index, fapi2::ReturnCode& o_rc)
+ {
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ uint8_t l_master_ranks_per_dimm = 0;
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_dimm_target, l_master_ranks_per_dimm));
+
+ FAPI_ASSERT((i_index < l_master_ranks_per_dimm),
+ fapi2::MSS_RANK_OUT_OF_RANGE()
+ .set_TARGET(i_dimm_target)
+ .set_RANK(i_index),
+ "Rank %u provided to info constructor for DIMM %s exceeded the number of master ranks per DIMM",
+ i_index, mss::c_str(i_dimm_target));
+ // Targets
+ iv_dimm_target = i_dimm_target;
+ iv_port_target = mss::find_target<DEFAULT_MEM_PORT_TARGET>(i_dimm_target);
+
+ // Ranks
+ iv_dimm_rank = i_index;
+ iv_port_rank = iv_dimm_rank + ((mss::relative_pos<DEFAULT_MEM_PORT_TARGET>(i_dimm_target) * TT::RANK_INDEX_STEP));
+ fapi_try_exit:
+ o_rc = fapi2::current_err;
+ }
+
+ ///
+ /// @brief Constructor for info object
+ /// @param[in] i_target PORT target
+ /// @param[in] i_index port rank index 0-7
+ /// @param[out] o_rc return code, FAPI2_RC_SUCCESS if no error
+ ///
+ info(const fapi2::Target<DEFAULT_MEM_PORT_TARGET>& i_port_target, const uint8_t i_index, fapi2::ReturnCode& o_rc)
+ {
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // Dimm Target
+ const uint8_t l_target_index = i_index / TT::RANK_INDEX_STEP;
+ const auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_port_target);
+
+ // This assumes that the mc_type max # of dimms per port is correct
+ FAPI_ASSERT( !l_dimms.empty(),
+ fapi2::MSS_EMPTY_VECTOR().
+ set_FUNCTION(INIT_RANK_INFO).
+ set_TARGET(i_port_target),
+ "Empty dimm vector received on port %s",
+ mss::spd::c_str(i_port_target));
+
+ {
+ // This will remain false in two cases:
+ // Either:
+ // 1. The corresponding DIMM index is out of range (caused by port index out of range)
+ // 2. The corresponding DIMMs master_ranks_per_dimm is less than the desired rank
+ bool l_valid_rank = false;
+
+ for (const auto& l_dimm : l_dimms)
+ {
+ // Since we can't guarantee the order of the returned dimms, we iterate through until we (might) find
+ // the right one. There's a chance it may not exist for example given info(port, rank13) would give us
+ // a dimm index above 2, which may be out of range, so we could never find a matching dimm, so we will
+ // throw that error.
+ // If we do find the right dimm, we need to then make sure that the master_ranks_per_dimm attribute
+ // is greater than the expected dimm rank.
+ if (mss::relative_pos<DEFAULT_MEM_PORT_TARGET>(l_dimm) == l_target_index)
+ {
+ uint8_t l_master_ranks_per_dimm = 0;
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(l_dimm, l_master_ranks_per_dimm));
+
+ // The rank passed in matches one of a valid DIMM
+ l_valid_rank = (i_index % TT::RANK_INDEX_STEP) < l_master_ranks_per_dimm;
+
+ iv_dimm_target = l_dimm;
+ }
+ }
+
+ FAPI_ASSERT(l_valid_rank,
+ fapi2::MSS_RANK_OUT_OF_RANGE()
+ .set_TARGET(i_port_target)
+ .set_RANK(i_index),
+ "Rank %u provided to rank_info constructor for PORT %s was out of range",
+ i_index, mss::c_str(i_port_target));
+
+ // Port Target
+ iv_port_target = i_port_target;
+
+ // Ranks
+ iv_dimm_rank = i_index % TT::RANK_INDEX_STEP;
+ iv_port_rank = i_index;
+ }
+
+ fapi_try_exit:
+ o_rc = fapi2::current_err;
+ }
+
+ ///
+ /// @brief Accessor for port rank
+ /// @return the number (0-7) of the rank within its port
+ ///
+ inline const uint8_t get_port_rank() const
+ {
+ return iv_port_rank;
+ }
+ ///
+ /// @brief Accessor for rank number of DIMM
+ /// @return the number (0-3) of the DIMM
+ ///
+ inline const uint8_t get_dimm_rank() const
+ {
+ return iv_dimm_rank;
+ }
+
+ ///
+ /// @brief Accessor for DIMM target
+ /// @return the dimm target associated with the rank
+ ///
+ inline const fapi2::Target<fapi2::TARGET_TYPE_DIMM> get_dimm_target() const
+ {
+ return iv_dimm_target;
+ }
+
+ ///
+ /// @brief Accessor for PORT target
+ /// @return the port target associated with the rank
+ ///
+ inline const fapi2::Target<DEFAULT_MEM_PORT_TARGET> get_port_target() const
+ {
+ return iv_port_target;
+ }
+
+ private:
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_dimm_target;
+ fapi2::Target<DEFAULT_MEM_PORT_TARGET> iv_port_target;
+ uint8_t iv_dimm_rank;
+ uint8_t iv_port_rank;
+};
+
+///
+/// @brief Obtains all DIMM ranks on a given port target
+/// @param[in] i_port_target port target
+/// @param[out] o_vect vector of ranks
+/// @return FAPI2_RC_SUCCESS iff success
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = rankTraits<MC>>
+fapi2::ReturnCode ranks_on_port(const fapi2::Target<DEFAULT_MEM_PORT_TARGET>& i_port_target,
+ std::vector<info<MC>>& o_vect)
+{
+ o_vect.clear();
+
+ uint8_t l_master_ranks_per_dimm[TT::MAX_DIMMS_PER_PORT] = {0};
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_port_target, l_master_ranks_per_dimm));
+
+ FAPI_ASSERT(((l_master_ranks_per_dimm[0] <= TT::MAX_RANKS_PER_DIMM) &&
+ (l_master_ranks_per_dimm[1] <= TT::MAX_RANKS_PER_DIMM)),
+ fapi2::MSS_TOO_MANY_PRIMARY_RANKS_ON_PORT()
+ .set_PORT_TARGET(i_port_target),
+ "Primary ranks on PORT %s exceeded %u",
+ mss::c_str(i_port_target),
+ TT::MAX_RANKS_PER_DIMM);
+
+ for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_port_target))
+ {
+ const uint8_t l_dimm_pos = mss::relative_pos<DEFAULT_MEM_PORT_TARGET>(l_dimm);
+ const uint8_t l_port_index_start = l_dimm_pos * TT::RANK_INDEX_STEP;
+
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // For each rank index of the dimm from the port's perspective
+ for (uint8_t l_index = l_port_index_start; l_index < (l_port_index_start + l_master_ranks_per_dimm[l_dimm_pos]);
+ ++l_index)
+ {
+ o_vect.push_back(mss::rank::info<>(i_port_target, l_index, l_rc));
+ FAPI_TRY(l_rc);
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Obtains all ranks on a given DIMM target
+/// @param[in] i_target DIMM target
+/// @param[out] o_vect vector of ranks
+/// @return FAPI2_RC_SUCCESS iff success
+///
+template <mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = rankTraits<MC>>
+fapi2::ReturnCode ranks_on_dimm(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm_target,
+ std::vector<info<MC>>& o_vect)
+{
+ o_vect.clear();
+ uint8_t l_master_ranks_per_dimm = 0;
+ FAPI_TRY(mss::attr::get_num_master_ranks_per_dimm(i_dimm_target, l_master_ranks_per_dimm));
+
+ FAPI_ASSERT(l_master_ranks_per_dimm <= TT::MAX_RANKS_PER_DIMM,
+ fapi2::MSS_TOO_MANY_PRIMARY_RANKS_ON_DIMM()
+ .set_RANK_COUNT(l_master_ranks_per_dimm)
+ .set_DIMM_TARGET(i_dimm_target),
+ "Seeing %d primary ranks on DIMM %s",
+ l_master_ranks_per_dimm,
+ mss::c_str(i_dimm_target));
+ {
+ // Return code for constructor call
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+
+ // For each rank index from the dimm's perspective
+ for (uint8_t l_index = 0; l_index < l_master_ranks_per_dimm; l_index++)
+ {
+ o_vect.push_back(mss::rank::info<>(i_dimm_target, l_index, l_rc));
+ FAPI_TRY(l_rc, "ranks_on_dimm(): Error in rank::info constructor call for DIMM %s and rank %u",
+ mss::c_str(i_dimm_target), l_index);
+ }
+ }
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // rank
+} // mss
+#endif
diff --git a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
index 275cb9e82..6fcd73070 100644
--- a/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
+++ b/src/import/generic/memory/lib/utils/shared/mss_generic_consts.H
@@ -170,6 +170,7 @@ enum generic_ffdc_codes
SET_ATTR_HOST_TO_DDR_SPEED_RATIO = 0x102C,
SET_DIMM_RANKS_CNFG = 0x1039,
DDIMM_RAWCARD_DECODE = 0x103a,
+ INIT_RANK_INFO = 0x103B,
SET_DRAM_WIDTH = 0x1040,
SET_SI_VREF_DRAM_WR = 0x1041,
diff --git a/src/import/generic/procedures/xml/error_info/generic_error.xml b/src/import/generic/procedures/xml/error_info/generic_error.xml
index 78d852568..f09e3de8f 100644
--- a/src/import/generic/procedures/xml/error_info/generic_error.xml
+++ b/src/import/generic/procedures/xml/error_info/generic_error.xml
@@ -656,7 +656,7 @@
</callout>
</hwpError>
- <hwpError>
+ <hwpError>
<rc>RC_MSS_POWER_THERMAL_DIMM_INDEX_OUT_OF_BOUND</rc>
<description>
The dimm index is out of bound for the port
@@ -668,5 +668,56 @@
<priority>HIGH</priority>
</callout>
</hwpError>
-
+
+ <hwpError>
+ <rc>RC_MSS_TOO_MANY_PRIMARY_RANKS_ON_DIMM</rc>
+ <description>
+ Too many primary ranks were seen on the dimm according
+ to the call to master_ranks_per_dimm</description>
+ <ffdc>RANK_COUNT</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_TOO_MANY_PRIMARY_RANKS_ON_PORT</rc>
+ <description>
+ Too many primary ranks were seen on the port according
+ to the call to master_ranks_per_dimm</description>
+ <callout>
+ <target>PORT_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <deconfigure>
+ <target>PORT_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_RANK_OUT_OF_RANGE</rc>
+ <description>
+ The rank provided to the rank::info constructor exceeded
+ the maximum rank for the MC
+ </description>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>MEDIUM</priority>
+ </callout>
+ <ffdc>TARGET</ffdc>
+ <ffdc>RANK</ffdc>
+ </hwpError>
+
</hwpErrors>
OpenPOWER on IntegriCloud