summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCaleb Palmer <cnpalmer@us.ibm.com>2018-08-15 16:18:00 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-08-23 10:19:13 -0500
commit0a6c8e400c83c63057cede1446a5e63ba35606e3 (patch)
tree46bdc4d864b9bbcd5f5240bd19fdcb4efd395413 /src
parent34d3b9353e228c9b9ff73c8c7e84873c251c06e2 (diff)
downloadtalos-hostboot-0a6c8e400c83c63057cede1446a5e63ba35606e3.tar.gz
talos-hostboot-0a6c8e400c83c63057cede1446a5e63ba35606e3.zip
PRDF: Add utilities for checking dram spares
Change-Id: Idbf7f5adce94466def8d7ee42a3c8e836fdbd309 RTC: 196073 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64610 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64981 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C10
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemMark.C48
-rw-r--r--src/usr/diag/prdf/common/plat/prdfPlatServices_common.C133
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/prdfPlatServices_common.H25
4 files changed, 177 insertions, 39 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C
index 2e99ce5c7..4efb13f4e 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C
@@ -554,6 +554,16 @@ int32_t MemDqBitmap<DIMMS_PER_RANK::MBA>::isSpareAvailable( uint8_t i_portSlct,
//------------------------------------------------------------------------------
template <>
+int32_t MemDqBitmap<DIMMS_PER_RANK::MCA>::isSpareAvailable( uint8_t i_portSlct,
+ bool & o_dramSpare, bool & o_eccSpare )
+{
+ // spares not supported on MCA
+ o_dramSpare = false;
+ o_eccSpare = false;
+ return SUCCESS;
+}
+//------------------------------------------------------------------------------
+template <>
int32_t MemDqBitmap<DIMMS_PER_RANK::MBA>::setDramSpare( uint8_t i_portSlct,
uint8_t i_pins )
{
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C
index 0e99d8a49..568063d65 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C
@@ -953,21 +953,13 @@ uint32_t __applyRasPolicies<TYPE_MBA>( ExtensibleChip * i_chip,
const bool isX4 = isDramWidthX4( i_chip->getTrgt() );
// Determine if DRAM sparing is enabled.
- bool isEnabled = isX4; // Always an ECC spare in x4 mode.
-
- if ( !isEnabled )
+ bool isEnabled = false;
+ o_rc = isDramSparingEnabled<TYPE_MBA>( i_chip->getTrgt(), i_rank, ps,
+ isEnabled );
+ if ( SUCCESS != o_rc )
{
- // Check for any DRAM spares.
- uint8_t cnfg = TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE;
- o_rc = getDimmSpareConfig<TARGETING::TYPE_MBA>( i_chip->getTrgt(),
- i_rank, ps, cnfg );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "getDimmSpareConfig(0x%08x,0x%02x,%d) "
- "failed", i_chip->getHuid(), i_rank.getKey(), ps );
- break;
- }
- isEnabled = (TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE != cnfg);
+ PRDF_ERR( PRDF_FUNC "isDramSparingEnabled() failed." );
+ break;
}
if ( isEnabled )
@@ -1003,34 +995,16 @@ uint32_t __applyRasPolicies<TYPE_MBA>( ExtensibleChip * i_chip,
// Certain DIMMs may have had spares intentially made unavailable by
// the manufacturer. Check the VPD for available spares.
- bool dramSparePossible = false;
- bool eccSparePossible = false;
-
- MemDqBitmap<DIMMS_PER_RANK::MBA> dqBitmap;
- o_rc = getBadDqBitmap<DIMMS_PER_RANK::MBA>( i_chip->getTrgt(),
- i_rank, dqBitmap );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "getBadDqBitmap() failed" );
- break;
- }
-
- o_rc = dqBitmap.isSpareAvailable( ps, dramSparePossible,
- eccSparePossible );
- if ( SUCCESS != o_rc )
- {
- PRDF_ERR( PRDF_FUNC "isSpareAvailable() failed" );
- break;
- }
-
- if ( dramSparePossible &&
- (0 == ps ? !sp0.isValid() : !sp1.isValid()) )
+ bool spAvail, eccAvail;
+ o_rc = isSpareAvailable<TYPE_MBA>( i_chip->getTrgt(), i_rank, ps,
+ spAvail, eccAvail );
+ if ( spAvail )
{
// A spare DRAM is available.
o_dsdEvent = new DsdEvent<TYPE_MBA>{ i_chip, i_rank,
i_chipMark };
}
- else if ( eccSparePossible && !ecc.isValid() )
+ else if ( eccAvail )
{
// The ECC spare is available.
o_dsdEvent = new DsdEvent<TYPE_MBA>{ i_chip, i_rank,
diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
index d11255001..5b98ff63a 100644
--- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
+++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C
@@ -880,8 +880,8 @@ int32_t mssSetSteerMux<TYPE_MBA>( TargetHandle_t i_mba, const MemRank & i_rank,
return o_rc;
}
-
//------------------------------------------------------------------------------
+
template<>
int32_t getDimmSpareConfig<TYPE_MCA>( TargetHandle_t i_mba, MemRank i_rank,
uint8_t i_ps, uint8_t & o_spareConfig )
@@ -953,6 +953,137 @@ int32_t getDimmSpareConfig<TYPE_MBA>( TargetHandle_t i_mba, MemRank i_rank,
#undef PRDF_FUNC
}
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t isDramSparingEnabled<TYPE_MCA>( TARGETING::TargetHandle_t i_trgt,
+ MemRank i_rank, uint8_t i_ps,
+ bool & o_spareEnable )
+{
+ // DRAM sparing not supported for MCA
+ o_spareEnable = false;
+ return SUCCESS;
+}
+
+template<>
+uint32_t isDramSparingEnabled<TYPE_MBA>( TARGETING::TargetHandle_t i_trgt,
+ MemRank i_rank, uint8_t i_ps,
+ bool & o_spareEnable )
+{
+ #define PRDF_FUNC "[PlatServices::isDramSparingEnabled<TYPE_MBA>] "
+
+ uint32_t o_rc = SUCCESS;
+ o_spareEnable = false;
+
+ do
+ {
+ const bool isX4 = isDramWidthX4( i_trgt );
+ if ( isX4 )
+ {
+ // Always an ECC spare in x4 mode.
+ o_spareEnable = true;
+ break;
+ }
+
+ // Check for any DRAM spares.
+ uint8_t cnfg = TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE;
+ o_rc = getDimmSpareConfig<TYPE_MBA>( i_trgt, i_rank, i_ps, cnfg );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getDimmSpareConfig(0x%08x,0x%02x,%d) "
+ "failed", getHuid(i_trgt), i_rank.getKey(), i_ps );
+ break;
+ }
+ o_spareEnable = (TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE != cnfg);
+
+ }while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<TARGETING::TYPE T, DIMMS_PER_RANK D>
+uint32_t __isSpareAvailable( TARGETING::TargetHandle_t i_trgt, MemRank i_rank,
+ uint8_t i_ps, bool & o_spAvail, bool & o_eccAvail )
+{
+ #define PRDF_FUNC "[PlatServices::isSpareAvailable] "
+
+ uint32_t o_rc = SUCCESS;
+
+ o_spAvail = false;
+ o_eccAvail = false;
+
+ do
+ {
+ bool dramSparingEnabled = false;
+ o_rc = isDramSparingEnabled<T>( i_trgt, i_rank, i_ps,
+ dramSparingEnabled );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "isDramSparingEnabled() failed." );
+ break;
+ }
+
+ // Break out if dram sparing isn't enabled
+ if ( !dramSparingEnabled ) break;
+
+ // Get the current spares in hardware
+ MemSymbol sp0, sp1, ecc;
+ o_rc = mssGetSteerMux<T>( i_trgt, i_rank, sp0, sp1, ecc );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "mssGetSteerMux(0x%08x,0x%02x) failed",
+ getHuid(i_trgt), i_rank.getKey() );
+ break;
+ }
+
+ bool dramSparePossible = false;
+ bool eccSparePossible = false;
+
+ // Get the bad dq data
+ MemDqBitmap<D> dqBitmap;
+ o_rc = getBadDqBitmap<D>( i_trgt, i_rank, dqBitmap );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getBadDqBitmap() failed" );
+ break;
+ }
+
+ o_rc = dqBitmap.isSpareAvailable( i_ps, dramSparePossible,
+ eccSparePossible );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "isSpareAvailable() failed" );
+ break;
+ }
+
+ if (dramSparePossible && (0 == i_ps ? !sp0.isValid() : !sp1.isValid()))
+ {
+ o_spAvail = true;
+ }
+ if ( eccSparePossible && !ecc.isValid() )
+ {
+ o_eccAvail = true;
+ }
+
+ }while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+
+}
+
+template<>
+uint32_t isSpareAvailable<TYPE_MBA>( TARGETING::TargetHandle_t i_trgt,
+ MemRank i_rank, uint8_t i_ps, bool & o_spAvail, bool & o_eccAvail )
+{
+ return __isSpareAvailable<TYPE_MBA, DIMMS_PER_RANK::MBA>( i_trgt, i_rank,
+ i_ps, o_spAvail, o_eccAvail );
+}
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
index 744c66f2a..2c6c9c4df 100755
--- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
+++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H
@@ -244,7 +244,6 @@ template<TARGETING::TYPE T>
int32_t mssSetSteerMux( TARGETING::TargetHandle_t i_mba, const MemRank & i_rank,
const MemSymbol & i_symbol, bool i_x4EccSpare );
-
/**
* @brief Get spare DRAM information on a DIMM.
* @param i_mba MBA/MCA target.
@@ -260,6 +259,30 @@ template<TARGETING::TYPE T>
int32_t getDimmSpareConfig( TARGETING::TargetHandle_t i_mba, MemRank i_rank,
uint8_t i_ps, uint8_t & o_spareConfig );
+/**
+ * @brief Checks if DRAM sparing is enabled.
+ * @param i_trgt Target MBA
+ * @param i_rank Target rank
+ * @param i_ps MBA Port select
+ * @param o_spareEnable Whether DRAM sparing is enabled or not.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+template<TARGETING::TYPE T>
+uint32_t isDramSparingEnabled( TARGETING::TargetHandle_t i_trgt, MemRank i_rank,
+ uint8_t i_ps, bool & o_spareEnable );
+
+/**
+ * @brief Checks to see if the spares are available on given target and port.
+ * @param i_trgt Target MBA
+ * @param i_rank Target rank
+ * @param i_ps Port select
+ * @param o_spAvail If the spare on inputted port select is available
+ * @param o_eccAvail If the ecc spare is available
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+template<TARGETING::TYPE T>
+uint32_t isSpareAvailable( TARGETING::TargetHandle_t i_trgt, MemRank i_rank,
+ uint8_t i_ps, bool & o_spAvail, bool & o_eccAvail );
/**
* @brief Returns the raw card type of a buffered DIMM.
OpenPOWER on IntegriCloud