summaryrefslogtreecommitdiffstats
path: root/src/usr/diag
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2016-09-15 10:51:16 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-09-21 10:43:29 -0400
commit8c46cb6573e2e9009e7afdc22c2f03d9ad195409 (patch)
treec8492e67b6f5005ad1753dcce0002da963452f72 /src/usr/diag
parent8d93ed2681d1f61485a1ebf162c2cafbeba46aa9 (diff)
downloadtalos-hostboot-8c46cb6573e2e9009e7afdc22c2f03d9ad195409.tar.gz
talos-hostboot-8c46cb6573e2e9009e7afdc22c2f03d9ad195409.zip
PRD: Created PlatServices::getSlaveRanks()
Change-Id: Ib8269faa471c2fa60c3f8eff90ae5e60d8e5b728 Squashed: Ie8d944589987b7fee877c10ddc26d7665b730b06 RTC: 160971 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29782 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com> Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29966 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/diag')
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfTargetServices.C233
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfTargetServices.H59
2 files changed, 195 insertions, 97 deletions
diff --git a/src/usr/diag/prdf/common/plat/prdfTargetServices.C b/src/usr/diag/prdf/common/plat/prdfTargetServices.C
index d18a1beca..9f92b0057 100755
--- a/src/usr/diag/prdf/common/plat/prdfTargetServices.C
+++ b/src/usr/diag/prdf/common/plat/prdfTargetServices.C
@@ -1316,83 +1316,6 @@ bool isDramWidthX4( TargetHandle_t i_mba )
//------------------------------------------------------------------------------
-uint8_t getRanksPerDimm( TargetHandle_t i_mba, uint8_t i_ds )
-{
- #define PRDF_FUNC "[PlatServices::getRanksPerDimm] "
-
- uint8_t rankCount = 0; // default if something fails
-
- do
- {
- if ( MAX_DIMM_PER_PORT <= i_ds )
- {
- PRDF_ERR( PRDF_FUNC "Invalid parameters i_ds:%u", i_ds );
- break;
- }
-
- // NOTE: Unable to use getAttr() because it is not able to return an
- // array. Otherwise, all of the following would be able to fit in
- // one line of code. The targeting may fix this later.
-
- ATTR_EFF_NUM_RANKS_PER_DIMM_type attr;
- if ( !i_mba->tryGetAttr<ATTR_EFF_NUM_RANKS_PER_DIMM>(attr) )
- {
- PRDF_ERR( PRDF_FUNC "failed to get ATTR_EFF_NUM_RANKS_PER_DIMM" );
- break;
- }
-
- // Note that DIMMs are plugged in pairs so the rank numbers should be
- // the same for each port.
- rankCount = attr[0][i_ds];
-
- } while(0);
-
- return rankCount;
-
- #undef PRDF_FUNC
-}
-
-//------------------------------------------------------------------------------
-
-uint8_t getMasterRanksPerDimm( TARGETING::TargetHandle_t i_mbaTarget,
- uint8_t i_ds )
-{
- #define PRDF_FUNC "[PlatServices::getMasterRanksPerDimm] "
-
- uint8_t rankCount = 0; // default if something fails
-
- do
- {
- if ( MAX_DIMM_PER_PORT <= i_ds )
- {
- PRDF_ERR( PRDF_FUNC"Invalid parameters i_ds:%u", i_ds );
- break;
- }
-
- // NOTE: Unable to use getAttr() because it is not able to return an
- // array. Otherwise, all of the following would be able to fit in
- // one line of code. The targeting may fix this later.
-
- ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_type attr;
- if (!i_mbaTarget->tryGetAttr<ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM>(attr))
- {
- PRDF_ERR(PRDF_FUNC"fail get ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM");
- break;
- }
-
- // Note that DIMMs are plugged in pairs so the rank numbers should be
- // the same for each port.
- rankCount = attr[0][i_ds];
-
- } while(0);
-
- return rankCount;
-
- #undef PRDF_FUNC
-}
-
-//------------------------------------------------------------------------------
-
template<TARGETING::TYPE T>
void __getMasterRanks( TargetHandle_t i_trgt, std::vector<MemRank> & o_ranks,
uint8_t i_pos, uint8_t i_ds )
@@ -1427,11 +1350,15 @@ void __getMasterRanks( TargetHandle_t i_trgt, std::vector<MemRank> & o_ranks,
{
if ( 0 != (rankMask & (0x80 >> rs)) )
{
+ // Note that the ranks are getting inserted in order so no need
+ // to sort later.
o_ranks.push_back( MemRank((ds << 2) | rs) );
}
}
}
+ PRDF_ASSERT( !o_ranks.empty() ); // target configured with no ranks
+
#undef PRDF_FUNC
}
@@ -1462,6 +1389,158 @@ void getMasterRanks<TYPE_MBA>( TargetHandle_t i_trgt,
__getMasterRanks<TYPE_MBA>( i_trgt, o_ranks, 0, i_ds );
}
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+void getSlaveRanks( TargetHandle_t i_trgt, std::vector<MemRank> & o_ranks,
+ uint8_t i_ds )
+{
+ PRDF_ASSERT( nullptr != i_trgt );
+ PRDF_ASSERT( T == getTargetType(i_trgt) );
+ PRDF_ASSERT( i_ds <= MAX_DIMM_PER_PORT ); // can equal MAX_DIMM_PER_PORT
+
+ o_ranks.clear();
+
+ for ( uint32_t ds = 0; ds < MAX_DIMM_PER_PORT; ds++ )
+ {
+ // Check if user gave a specific value for i_ds.
+ if ( (MAX_DIMM_PER_PORT != i_ds) && (ds != i_ds) )
+ continue;
+
+ // Get the number of slave ranks per master rank.
+ uint8_t numRanks = getNumRanksPerDimm<T> ( i_trgt, i_ds );
+ uint8_t numMasterRanks = getNumMasterRanksPerDimm<T>( i_trgt, i_ds );
+ uint8_t numSlaveRanks = numRanks / numMasterRanks;
+
+ // Get the current list of master ranks for this DIMM select
+ std::vector<MemRank> tmpList;
+ getMasterRanks<T>( i_trgt, tmpList, i_ds );
+
+ // Start inserting the slave ranks into the list.
+ for ( auto & mrank : tmpList )
+ {
+ for ( uint8_t s = 0; s < numSlaveRanks; s++ )
+ {
+ // Note that the ranks are getting inserted in order so no need
+ // to sort later.
+ o_ranks.push_back( MemRank(mrank.getMaster(), s) );
+ }
+ }
+ }
+
+ PRDF_ASSERT( !o_ranks.empty() ); // target configured with no ranks
+}
+
+template<>
+void getSlaveRanks<TYPE_MCA>( TargetHandle_t i_trgt,
+ std::vector<MemRank> & o_ranks,
+ uint8_t i_ds );
+
+template<>
+void getSlaveRanks<TYPE_MBA>( TargetHandle_t i_trgt,
+ std::vector<MemRank> & o_ranks,
+ uint8_t i_ds );
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+uint8_t __getNumMasterRanksPerDimm( TargetHandle_t i_trgt,
+ uint8_t i_pos, uint8_t i_ds )
+{
+ #define PRDF_FUNC "[__getNumMasterRanksPerDimm] "
+
+ PRDF_ASSERT( nullptr != i_trgt );
+ PRDF_ASSERT( T == getTargetType(i_trgt) );
+ PRDF_ASSERT( i_pos < 2 );
+ PRDF_ASSERT( i_ds < MAX_DIMM_PER_PORT );
+
+ ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM_type attr;
+ if ( !i_trgt->tryGetAttr<ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM>(attr) )
+ {
+ PRDF_ERR( PRDF_FUNC "tryGetAttr<ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM> "
+ "failed: i_trgt=0x%08x", getHuid(i_trgt) );
+ PRDF_ASSERT( false ); // attribute does not exist for target
+ }
+
+ return attr[i_pos][i_ds];
+
+ #undef PRDF_FUNC
+}
+
+template<>
+uint8_t getNumMasterRanksPerDimm<TYPE_MCA>( TargetHandle_t i_trgt,
+ uint8_t i_ds )
+{
+ PRDF_ASSERT( nullptr != i_trgt );
+ PRDF_ASSERT( TYPE_MCA == getTargetType(i_trgt) );
+
+ // NOTE: The attribute lives on the MCS. So need to get the MCS target and
+ // the position of the MCA relative to the MCS.
+ TargetHandle_t mcsTrgt = getConnectedParent( i_trgt, TYPE_MCS );
+ uint8_t relPos = getTargetPosition(i_trgt) % MAX_MCA_PER_MCS;
+
+ return __getNumMasterRanksPerDimm<TYPE_MCS>( mcsTrgt, relPos, i_ds );
+}
+
+template<>
+uint8_t getNumMasterRanksPerDimm<TYPE_MBA>( TargetHandle_t i_trgt,
+ uint8_t i_ds )
+{
+ // NOTE: DIMMs must be plugged into pairs. So the values for each port
+ // select will be the same for each DIMM select. There is no need to
+ // iterate on both port selects.
+ return __getNumMasterRanksPerDimm<TYPE_MBA>( i_trgt, 0, i_ds );
+}
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T>
+uint8_t __getNumRanksPerDimm( TargetHandle_t i_trgt,
+ uint8_t i_pos, uint8_t i_ds )
+{
+ #define PRDF_FUNC "[__getNumRanksPerDimm] "
+
+ PRDF_ASSERT( nullptr != i_trgt );
+ PRDF_ASSERT( T == getTargetType(i_trgt) );
+ PRDF_ASSERT( i_pos < 2 );
+ PRDF_ASSERT( i_ds < MAX_DIMM_PER_PORT );
+
+ ATTR_EFF_NUM_RANKS_PER_DIMM_type attr;
+ if ( !i_trgt->tryGetAttr<ATTR_EFF_NUM_RANKS_PER_DIMM>(attr) )
+ {
+ PRDF_ERR( PRDF_FUNC "tryGetAttr<ATTR_EFF_NUM_RANKS_PER_DIMM> "
+ "failed: i_trgt=0x%08x", getHuid(i_trgt) );
+ PRDF_ASSERT( false ); // attribute does not exist for target
+ }
+
+ return attr[i_pos][i_ds];
+
+ #undef PRDF_FUNC
+}
+
+template<>
+uint8_t getNumRanksPerDimm<TYPE_MCA>( TargetHandle_t i_trgt, uint8_t i_ds )
+{
+ PRDF_ASSERT( nullptr != i_trgt );
+ PRDF_ASSERT( TYPE_MCA == getTargetType(i_trgt) );
+
+ // NOTE: The attribute lives on the MCS. So need to get the MCS target and
+ // the position of the MCA relative to the MCS.
+ TargetHandle_t mcsTrgt = getConnectedParent( i_trgt, TYPE_MCS );
+ uint8_t relPos = getTargetPosition(i_trgt) % MAX_MCA_PER_MCS;
+
+ return __getNumRanksPerDimm<TYPE_MCS>( mcsTrgt, relPos, i_ds );
+}
+
+template<>
+uint8_t getNumRanksPerDimm<TYPE_MBA>( TargetHandle_t i_trgt, uint8_t i_ds )
+{
+ // NOTE: DIMMs must be plugged into pairs. So the values for each port
+ // select will be the same for each DIMM select. There is no need to
+ // iterate on both port selects.
+ return __getNumRanksPerDimm<TYPE_MBA>( i_trgt, 0, i_ds );
+}
+
//##############################################################################
//##
//## Clock specific functions
diff --git a/src/usr/diag/prdf/common/plat/prdfTargetServices.H b/src/usr/diag/prdf/common/plat/prdfTargetServices.H
index aca7d70b5..a26c682a3 100755
--- a/src/usr/diag/prdf/common/plat/prdfTargetServices.H
+++ b/src/usr/diag/prdf/common/plat/prdfTargetServices.H
@@ -364,38 +364,57 @@ int32_t getDimmRowCol( TARGETING::TargetHandle_t i_mba, uint8_t & o_rowNum,
uint8_t & o_colNum );
/**
- * @brief Obtains number of ranks (including slave ranks) per DIMM select.
- * @param i_mbaTarget MBA target.
- * @param i_ds DIMM select for DIMM.
- * @return Number of ranks confgured per DIMM select. If internal function
- * fails it will return 0.
- */
-uint8_t getRanksPerDimm( TARGETING::TargetHandle_t i_mbaTarget, uint8_t i_ds );
-
-/**
- * @brief Obtains number of MASTER ranks per DIMM select.
- * @param i_mbaTarget MBA target.
- * @param i_ds DIMM select for DIMM.
- * @return Number of MASTER ranks confgured per DIMM select. If internal function
- * fails it will return 0.
- */
-uint8_t getMasterRanksPerDimm( TARGETING::TargetHandle_t i_mbaTarget,
- uint8_t i_ds );
-
-/**
- * @brief Returns a list of configured master ranks for an MCA or MBA.
+ * @brief Returns a sorted list of configured master ranks for an MCA or MBA.
* @param i_trgt MCA or MBA target.
* @param o_ranks The returned list.
* @param i_ds When used, this function will only return the list of ranks
* for the target DIMM select. Otherwise, the default is to
* return the list for all DIMM selects.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ * @note Will assert if the list is empty because the target should not be
+ * configured with no memory.
*/
template<TARGETING::TYPE T>
void getMasterRanks( TARGETING::TargetHandle_t i_trgt,
std::vector<MemRank> & o_ranks,
uint8_t i_ds = MAX_DIMM_PER_PORT );
+/**
+ * @brief Returns a sorted list of configured slave ranks for an MCA or MBA.
+ * @param i_trgt MCA or MBA target.
+ * @param o_ranks The returned list.
+ * @param i_ds When used, this function will only return the list of ranks
+ * for the target DIMM select. Otherwise, the default is to
+ * return the list for all DIMM selects.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ * @note Will assert if the list is empty because the target should not be
+ * configured with no memory.
+ */
+template<TARGETING::TYPE T>
+void getSlaveRanks( TARGETING::TargetHandle_t i_trgt,
+ std::vector<MemRank> & o_ranks,
+ uint8_t i_ds = MAX_DIMM_PER_PORT );
+
+/**
+ * @brief Obtains the number of master ranks per DIMM select.
+ * @param i_trgt MCA or MBA target.
+ * @param i_ds DIMM select.
+ * @return Total number of master ranks configured per DIMM select.
+ */
+template<TARGETING::TYPE T>
+uint8_t getNumMasterRanksPerDimm( TARGETING::TargetHandle_t i_trgt,
+ uint8_t i_ds );
+
+/**
+ * @brief Obtains the total number of ranks (including slave ranks) per DIMM
+ * select.
+ * @param i_trgt MCA or MBA target.
+ * @param i_ds DIMM select.
+ * @return Total number of ranks configured per DIMM select.
+ */
+template<TARGETING::TYPE T>
+uint8_t getNumRanksPerDimm( TARGETING::TargetHandle_t i_trgt, uint8_t i_ds );
+
//##############################################################################
//##
//## Clock specific functions
OpenPOWER on IntegriCloud