diff options
author | Caleb Palmer <cnpalmer@us.ibm.com> | 2018-08-15 16:18:00 -0500 |
---|---|---|
committer | Zane C. Shelley <zshelle@us.ibm.com> | 2018-08-23 10:19:13 -0500 |
commit | 0a6c8e400c83c63057cede1446a5e63ba35606e3 (patch) | |
tree | 46bdc4d864b9bbcd5f5240bd19fdcb4efd395413 /src | |
parent | 34d3b9353e228c9b9ff73c8c7e84873c251c06e2 (diff) | |
download | talos-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.C | 10 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/mem/prdfMemMark.C | 48 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/prdfPlatServices_common.C | 133 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/plat/prdfPlatServices_common.H | 25 |
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. |