From 0a6c8e400c83c63057cede1446a5e63ba35606e3 Mon Sep 17 00:00:00 2001 From: Caleb Palmer Date: Wed, 15 Aug 2018 16:18:00 -0500 Subject: 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 Reviewed-by: Benjamin J. Weisenbeck Reviewed-by: Brian J. Stegmiller Reviewed-by: Zane C. Shelley Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/64981 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins --- .../prdf/common/plat/prdfPlatServices_common.C | 133 ++++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) (limited to 'src/usr/diag/prdf/common/plat/prdfPlatServices_common.C') 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( TargetHandle_t i_mba, const MemRank & i_rank, return o_rc; } - //------------------------------------------------------------------------------ + template<> int32_t getDimmSpareConfig( TargetHandle_t i_mba, MemRank i_rank, uint8_t i_ps, uint8_t & o_spareConfig ) @@ -953,6 +953,137 @@ int32_t getDimmSpareConfig( TargetHandle_t i_mba, MemRank i_rank, #undef PRDF_FUNC } +//------------------------------------------------------------------------------ + +template<> +uint32_t isDramSparingEnabled( 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( TARGETING::TargetHandle_t i_trgt, + MemRank i_rank, uint8_t i_ps, + bool & o_spareEnable ) +{ + #define PRDF_FUNC "[PlatServices::isDramSparingEnabled] " + + 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( 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 +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( 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( 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 dqBitmap; + o_rc = getBadDqBitmap( 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( TARGETING::TargetHandle_t i_trgt, + MemRank i_rank, uint8_t i_ps, bool & o_spAvail, bool & o_eccAvail ) +{ + return __isSpareAvailable( i_trgt, i_rank, + i_ps, o_spAvail, o_eccAvail ); +} //------------------------------------------------------------------------------ -- cgit v1.2.1