From 3302fd380ebaf395839932ab00e009567a829037 Mon Sep 17 00:00:00 2001 From: Matt Derksen Date: Wed, 23 May 2018 13:38:38 -0500 Subject: Additional DRAM sparing support functions Ported isSpareAvailable(), setDramSpare(), and setEccSpare() Created common updateSpared method for MemSymbol Change-Id: I02d4616137f65cf5216b83495594e45f52a93470 RTC: 189221 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59388 Reviewed-by: Caleb N. Palmer Tested-by: Jenkins Server Reviewed-by: Zane C. Shelley Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60137 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW --- .../diag/prdf/common/plat/mem/prdfMemCaptureData.C | 17 +- .../diag/prdf/common/plat/mem/prdfMemDqBitmap.C | 149 +++++++++++ .../diag/prdf/common/plat/mem/prdfMemDqBitmap.H | 31 ++- src/usr/diag/prdf/common/plat/mem/prdfMemMark.C | 44 ++-- src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C | 38 ++- src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H | 17 +- src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C | 33 +-- .../prdf/common/plat/prdfPlatServices_common.C | 276 ++++++++++++--------- .../prdf/common/plat/prdfPlatServices_common.H | 65 ++--- src/usr/diag/prdf/plat/mem/prdfMemDsd.H | 13 +- src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C | 13 +- .../diag/prdf/plat/mem/prdfRestoreDramRepairs.C | 16 +- src/usr/diag/prdf/plat/prdfPlatServices.C | 131 ---------- src/usr/diag/prdf/plat/prdfPlatServices.H | 41 --- 14 files changed, 482 insertions(+), 402 deletions(-) diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C b/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C index 4e566f5d3..985c3dcd6 100644 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemCaptureData.C @@ -168,21 +168,19 @@ void captureDramRepairsData( TARGETING::TargetHandle_t i_trgt, break; } - -/* TODO: 189221 - uint8_t spareConfig = ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE; + uint8_t spareConfig = CEN_VPD_DIMM_SPARE_NO_SPARE; // check for spare DRAM. Port does not matter. - // Also this configuration is same for all ranks on MBA. - rc = getDimmSpareConfig( i_trgt, masterRanks[0], 0, spareConfig ); + // Also this configuration is same for all ranks on MBA. (MCA no-op) + rc = getDimmSpareConfig( i_trgt, masterRanks[0], 0, spareConfig ); if( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "getDimmSpareConfig() failed" ); break; } - if( ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE != spareConfig ) + if( CEN_VPD_DIMM_SPARE_NO_SPARE != spareConfig ) data.header.isSpareDram = true; -*/ + // Iterate all ranks to get DRAM repair data for ( auto & rank : masterRanks ) @@ -207,14 +205,13 @@ void captureDramRepairsData( TARGETING::TargetHandle_t i_trgt, // Get DRAM spares MemSymbol sp0, sp1, ecc; -/* TODO: 189221 - rc = mssGetSteerMux( i_trgt, rank, sp0, sp1, ecc ); + rc = mssGetSteerMux( i_trgt, rank, sp0, sp1, ecc ); if ( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed"); continue; } -*/ + // Add data DramRepairRankData rankData = { rank.getMaster(), cm.getSymbol().getSymbol(), diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C index cabaf8979..2e99ce5c7 100644 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.C @@ -486,7 +486,156 @@ std::vector MemDqBitmap::getSymbolList( } //------------------------------------------------------------------------------ +template <> +int32_t MemDqBitmap::isSpareAvailable( uint8_t i_portSlct, + bool & o_dramSpare, bool & o_eccSpare ) +{ + #define PRDF_FUNC "[MemDqBitmap::isSpareAvailable] " + + int32_t o_rc = SUCCESS; + + o_dramSpare = false; + o_eccSpare = false; + + do + { + if ( MBA_DIMMS_PER_RANK <= i_portSlct ) + { + PRDF_ERR( PRDF_FUNC "Invalid parameter: i_portSlct=%d", i_portSlct); + o_rc = FAIL; break; + } + + uint8_t spareConfig = TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE; + o_rc = getDimmSpareConfig( iv_trgt , iv_rank, + i_portSlct, spareConfig ); + if( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getDimmSpareConfig() failed" ); + break; + } + uint8_t spareDqBits = iv_data[i_portSlct][DRAM_SPARE_BYTE]; + + if ( iv_x4Dram ) + { + // Check for DRAM spare + if ( TARGETING::CEN_VPD_DIMM_SPARE_LOW_NIBBLE == spareConfig ) + { + o_dramSpare = ( 0 == ( spareDqBits & 0xf0 ) ); + } + else if ( TARGETING::CEN_VPD_DIMM_SPARE_HIGH_NIBBLE == spareConfig ) + { + o_dramSpare = ( 0 == ( spareDqBits & 0x0f ) ); + } + + // Check for ECC spare + uint8_t eccDqBits = iv_data[ECC_SPARE_PORT][ECC_SPARE_BYTE]; + o_eccSpare = ( 0 == (eccDqBits & 0x0f) ); + } + else + { + if ( TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE == spareConfig ) + { + // spare is not available. + o_dramSpare = false; + } + else + { + o_dramSpare = ( 0 == spareDqBits ); + } + } + + } while (0); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ +template <> +int32_t MemDqBitmap::setDramSpare( uint8_t i_portSlct, + uint8_t i_pins ) +{ + #define PRDF_FUNC "[MemDqBitmap::setDramSpare] " + + int32_t o_rc = SUCCESS; + + do + { + if ( MBA_DIMMS_PER_RANK <= i_portSlct ) + { + PRDF_ERR( PRDF_FUNC "Invalid parameter: i_portSlct=%d", i_portSlct); + o_rc = FAIL; break; + } + + uint8_t spareConfig = TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE; + o_rc = getDimmSpareConfig( iv_trgt, iv_rank, + i_portSlct, spareConfig ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "getDimmSpareConfig() failed" ); + o_rc = FAIL; break; + } + + if ( TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE == spareConfig ) + { + PRDF_ERR( PRDF_FUNC "DRAM Spare is not avaiable" ); + o_rc = FAIL; break; + } + + if ( iv_x4Dram ) + { + i_pins &= 0xf; // limit to 4 bits + + if ( TARGETING::CEN_VPD_DIMM_SPARE_LOW_NIBBLE == spareConfig ) + { + i_pins = i_pins << DQS_PER_NIBBLE; + } + iv_data[i_portSlct][DRAM_SPARE_BYTE] |= i_pins; + } + else + { + i_pins &= 0xff; // limit to 8 bits + iv_data[i_portSlct][DRAM_SPARE_BYTE] |= i_pins; + } + + } while (0); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ +template <> +int32_t MemDqBitmap::setEccSpare( uint8_t i_pins ) +{ + #define PRDF_FUNC "[MemDqBitmap::setEccSpare] " + + int32_t o_rc = SUCCESS; + + do + { + if ( !iv_x4Dram ) + { + PRDF_ERR( PRDF_FUNC "MBA 0x %08x does not support x4 ECC spare", + getHuid(iv_trgt) ); + o_rc = FAIL; break; + } + + i_pins &= 0xf; // limit to 4 bits + iv_data[ECC_SPARE_PORT][ECC_SPARE_BYTE] |= i_pins; + + } while( 0 ); + + return o_rc; + + #undef PRDF_FUNC +} + + +//------------------------------------------------------------------------------ // Avoid linker errors with the template. template class MemDqBitmap; template class MemDqBitmap; diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H index 46fc31369..390e6d3b7 100644 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemDqBitmap.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2017 */ +/* Contributors Listed Below - COPYRIGHT 2013,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -167,6 +167,35 @@ class MemDqBitmap */ std::vector getSymbolList( uint8_t i_portSlct = 0 ); + + /** + * @brief Queries for DRAM spare status. + * @param i_portSlct The target port. + * @param o_dramSpare TRUE if the DRAM spare is available, FALSE otherwise. + * @param o_eccSpare TRUE if the ECC spare is available, FALSE otherwise. + * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise. + */ + int32_t isSpareAvailable( uint8_t i_portSlct, + bool & o_dramSpare, bool & o_eccSpare ); + + /** + * @brief Sets the ECC spare on the specified port (x4 mode only). + * @param i_pins Optional 4-bit value of the DRAM's pins. + * The default is to set all pins. + * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise. + */ + int32_t setEccSpare( uint8_t i_pins = 0x0f ); + + /** + * @brief Sets the DRAM spare on the specified port. + * @param i_portSlct The target port. + * @param i_pins Optional 8-bit (x8 mode) or 4-bit (x4 mode) value of + * the DRAM's pins. The default is to set all pins. + * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise. + */ + int32_t setDramSpare( uint8_t i_portSlct, uint8_t i_pins = 0xff ); + + private: // instance variables TARGETING::TargetHandle_t iv_trgt; ///< Target MBA/MCA diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C index 64193ea66..567c01c33 100644 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemMark.C @@ -370,8 +370,18 @@ uint32_t __readMarks( ExtensibleChip * i_chip, const MemRank & i_rank, MemSymbol l_smSym = MemSymbol::fromSymbol( i_chip->getTrgt(), i_rank, l_sm ); - //TODO RTC 189221 DRAM sparing support // Check if the chip mark is on any of the spares + MemSymbol sp0, sp1, ecc; + o_rc = mssGetSteerMux( i_chip->getTrgt(), i_rank, + sp0, sp1, ecc ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed. HUID: 0x%08x " + "rank: 0x%02x", i_chip->getHuid(), i_rank.getKey() ); + break; + } + l_cmSym.updateSpared(sp0,sp1,ecc); + l_smSym.updateSpared(sp0,sp1,ecc); o_chipMark = MemMark( i_chip->getTrgt(), i_rank, l_cmSym ); o_symMark = MemMark( i_chip->getTrgt(), i_rank, l_smSym ); @@ -947,33 +957,31 @@ uint32_t __applyRasPolicies( ExtensibleChip * i_chip, if ( !isEnabled ) { - /* TODO RTC 189221 // Check for any DRAM spares. - uint8_t cnfg = ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE; - o_rc = getDimmSpareConfig( i_chip, i_rank, ps, cnfg ); + uint8_t cnfg = TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE; + o_rc = getDimmSpareConfig( 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 = (ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE != cnfg); - */ + isEnabled = (TARGETING::CEN_VPD_DIMM_SPARE_NO_SPARE != cnfg); } if ( isEnabled ) { // Sparing is enabled. Get the current spares in hardware. MemSymbol sp0, sp1, ecc; - /* TODO RTC 189221 - o_rc = mssGetSteerMux( i_chip, i_rank, sp0, sp1, ecc ); + o_rc = mssGetSteerMux( i_chip->getTrgt(), + i_rank, sp0, sp1, ecc ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "mssGetSteerMux(0x%08x,0x%02x) failed", i_chip->getHuid(), i_rank.getKey() ); break; } - */ // Add the spares to the callout list if they exist. __addCallout( i_chip, i_rank, sp0, io_sc ); @@ -997,15 +1005,23 @@ uint32_t __applyRasPolicies( ExtensibleChip * i_chip, // the manufacturer. Check the VPD for available spares. bool dramSparePossible = false; bool eccSparePossible = false; - /* TODO RTC 189221 - o_rc = bitmap.isSpareAvailable( ps, dramSparePossible, - eccSparePossible ); + + MemDqBitmap dqBitmap; + o_rc = getBadDqBitmap( 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 "isDramSpareAvailable() failed" ); + PRDF_ERR( PRDF_FUNC "isSpareAvailable() failed" ); break; } - */ if ( dramSparePossible && (0 == ps ? !sp0.isValid() : !sp1.isValid()) ) diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C index 30db870cf..51d81d780 100755 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2017 */ +/* Contributors Listed Below - COPYRIGHT 2013,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -144,6 +144,28 @@ uint8_t MemSymbol::getGalois() const return symbol2Galois[iv_symbol]; } +//------------------------------------------------------------------------------ + +void MemSymbol::updateSpared(const MemSymbol & i_sp0, + const MemSymbol & i_sp1, + const MemSymbol & i_ecc) +{ + if (!iv_isDramSpared) + { + if ( ( i_sp0.isValid() && (i_sp0.getDram() == getDram()) ) || + ( i_sp1.isValid() && (i_sp1.getDram() == getDram()) ) ) + { + setDramSpared(); + } + } + + if ( (!iv_isEccSpared) && + ( i_ecc.isValid() && (i_ecc.getDram() == getDram())) ) + { + setEccSpared(); + } +} + //------------------------------------------------------------------------------ // Symbol Accessor Functions //------------------------------------------------------------------------------ @@ -193,8 +215,6 @@ uint32_t getMemReadSymbol( ExtensibleChip * i_chip, o_sym1 = MemSymbol::fromGalois( i_chip->getTrgt(), i_rank, g1, m1 ); o_sym2 = MemSymbol::fromGalois( i_chip->getTrgt(), i_rank, g2, m2 ); - // TODO: RTC 157888 Check if the symbol is on a spare DRAM. - } while (0); return o_rc; @@ -217,6 +237,7 @@ uint32_t getMemReadSymbol( ExtensibleChip * i_chip, uint32_t o_rc = SUCCESS; + // o_sym2 is just a placeholder for TYPE_MBA o_sym1 = o_sym2 = MemSymbol(); // both initially invalid do @@ -242,7 +263,16 @@ uint32_t getMemReadSymbol( ExtensibleChip * i_chip, // Get the NCE symbol. o_sym1 = MemSymbol::fromGalois( i_chip->getTrgt(), i_rank, g1, m1 ); - // TODO: RTC 157888 Check if the symbol is on a spare DRAM. + MemSymbol sp0, sp1, ecc; + o_rc = mssGetSteerMux( i_chip->getTrgt(), i_rank, + sp0, sp1, ecc ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed. HUID: 0x%08x " + "rank: 0x%02x", i_chip->getHuid(), i_rank.getKey() ); + break; + } + o_sym1.updateSpared(sp0, sp1, ecc); } while (0); diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H index c69cd4a7b..d52bf7c8c 100755 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemSymbol.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2017 */ +/* Contributors Listed Below - COPYRIGHT 2013,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -174,6 +174,21 @@ class MemSymbol (iv_rank == i_symbol.iv_rank ) ); } + /** + * @brief Checks if the current symbol is on any of the spares + * Sets iv_isDramSpared if found on at least one of the valid spares + * Sets iv_isEccSpared if found on valid i_ecc + * Usually call mssGetSteerMux to fill in associated symbols + * + * @param i_sp0 A symbol associated with the spare on port 0. + * @param i_sp1 A symbol associated with the spare on port 1. + * @param i_ecc A symbol associated with the ECC spare (x4 mode only). + */ + void updateSpared(const MemSymbol & i_sp0, + const MemSymbol & i_sp1, + const MemSymbol & i_ecc); + + private: // instance variables TARGETING::TargetHandle_t iv_trgt = nullptr; ///< Target handle. diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C b/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C index 3e3743dd7..f02ca0a9f 100755 --- a/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C +++ b/src/usr/diag/prdf/common/plat/mem/prdfMemUtils.C @@ -253,15 +253,13 @@ int32_t collectCeStats( ExtensibleChip * i_chip, // Get the current spares on this rank. MemSymbol sp0, sp1, ecc; - - /* TODO RTC 157888/189221 - uncomment when mssGetSteerMux is working - o_rc = mssGetSteerMux( mbaTrgt, i_rank, sp0, sp1, ecc ); + o_rc = mssGetSteerMux( mbaTrgt, i_rank, sp0, sp1, ecc ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed." ); break; } - */ + // Use this map to keep track of the total counts per DRAM. DramCountMap dramCounts; @@ -317,21 +315,8 @@ int32_t collectCeStats( ExtensibleChip * i_chip, } else { - /* TODO RTC 157888/189221 - sp0 and sp1 aren't defined yet // Check if this symbol is on any of the spares. - if ( ( sp0.isValid() && - (sp0.getDram() == symData.symbol.getDram()) ) || - ( sp1.isValid() && - (sp1.getDram() == symData.symbol.getDram()) ) ) - { - symData.symbol.setDramSpared(); - } - */ - if ( ecc.isValid() && - (ecc.getDram() == symData.symbol.getDram()) ) - { - symData.symbol.setEccSpared(); - } + symData.symbol.updateSpared(sp0, sp1, ecc); // Add the symbol to the list. symData.count = count; @@ -371,18 +356,8 @@ int32_t collectCeStats( ExtensibleChip * i_chip, o_chipMark = MemSymbol::fromSymbol( mbaTrgt, i_rank, sym ); - /* TODO RTC 157888/18922uncomment when mssGetSteerMux is working1 - sp0 and sp1 aren't defined yet // Check if this symbol is on any of the spares. - if ( ( sp0.isValid() && (sp0.getDram() == o_chipMark.getDram()) ) || - ( sp1.isValid() && (sp1.getDram() == o_chipMark.getDram()) ) ) - { - o_chipMark.setDramSpared(); - } - */ - if ( ecc.isValid() && (ecc.getDram() == o_chipMark.getDram()) ) - { - o_chipMark.setEccSpared(); - } + o_chipMark.updateSpared(sp0, sp1, ecc); } } while(0); diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C index b00291622..b7f58445c 100644 --- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C +++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.C @@ -44,6 +44,7 @@ #endif #ifdef __HOSTBOOT_MODULE +#include #include #include #include @@ -383,179 +384,216 @@ int32_t setBadDqBitmap( TargetHandle_t i_trgt, const MemRank & i_rank, const MemDqBitmap & i_bitmap ); + + //------------------------------------------------------------------------------ -/* -int32_t mssGetMarkStore( TargetHandle_t i_mba, const MemRank & i_rank, - MemMark & o_mark ) +template<> +void getDimmDqAttr( TargetHandle_t i_target, + uint8_t (&o_dqMapPtr)[DQS_PER_DIMM] ) { - #define PRDF_FUNC "[PlatServices::mssGetMarkStore] " + #define PRDF_FUNC "[PlatServices::getDimmDqAttr] " - int32_t o_rc = SUCCESS; + PRDF_ASSERT( TYPE_MCA == getTargetType(i_target) ); - do - { - errlHndl_t errl = NULL; - uint8_t symbolMark, chipMark; - fapi2::Target fapiMba(i_mba); - FAPI_INVOKE_HWP( errl, mss_get_mark_store, fapiMba, - i_rank.getMaster(), symbolMark, chipMark ); + TargetHandle_t mcs = getConnectedParent( i_target, TYPE_MCS ); - if ( NULL != errl ) - { - PRDF_ERR( PRDF_FUNC "mss_get_mark_store() failed. HUID: 0x%08x " - "rank: %d", getHuid(i_mba), i_rank.getMaster() ); - PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); - o_rc = FAIL; break; - } + uint32_t mcaRelMcs = getTargetPosition( i_target ) % MAX_MCA_PER_MCS; + uint8_t tmpData[MAX_MCA_PER_MCS][DQS_PER_DIMM]; - MemSymbol sm = MemSymbol::fromSymbol( i_mba, i_rank, symbolMark ); - MemSymbol cm = MemSymbol::fromSymbol( i_mba, i_rank, chipMark ); + if ( !mcs->tryGetAttr(tmpData) ) + { + PRDF_ERR( PRDF_FUNC "Failed to get ATTR_MSS_VPD_DQ_MAP" ); + PRDF_ASSERT( false ); + } - // Check if the chip or symbol mark are on any of the spares. - MemSymbol sp0, sp1, ecc; - o_rc = mssGetSteerMux( i_mba, i_rank, sp0, sp1, ecc ); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed. HUID: 0x%08x " - "rank: %d", getHuid(i_mba), i_rank.getMaster() ); - break; - } + memcpy( &o_dqMapPtr[0], &tmpData[mcaRelMcs][0], DQS_PER_DIMM ); - if ( sp0.isValid() ) - { - if ( sp0.getDram() == sm.getDram() ) sm.setDramSpared(); - if ( sp0.getDram() == cm.getDram() ) cm.setDramSpared(); - } + #undef PRDF_FUNC +} // end function getDimmDqAttr - if ( sp1.isValid() ) - { - if ( sp1.getDram() == sm.getDram() ) sm.setDramSpared(); - if ( sp1.getDram() == cm.getDram() ) cm.setDramSpared(); - } +template<> +void getDimmDqAttr( TargetHandle_t i_target, + uint8_t (&o_dqMapPtr)[DQS_PER_DIMM] ) +{ + #define PRDF_FUNC "[PlatServices::getDimmDqAttr] " - if ( ecc.isValid() ) - { - if ( ecc.getDram() == sm.getDram() ) sm.setEccSpared(); - if ( ecc.getDram() == cm.getDram() ) cm.setEccSpared(); - } + PRDF_ASSERT( TYPE_DIMM == getTargetType(i_target) ); - o_mark = CenMark( sm, cm ); + const uint8_t DIMM_BAD_DQ_SIZE_BYTES = 80; - } while (0); + uint8_t tmpData[DIMM_BAD_DQ_SIZE_BYTES]; - return o_rc; + if ( !i_target->tryGetAttr(tmpData) ) + { + PRDF_ERR( PRDF_FUNC "Failed to get ATTR_CEN_DQ_TO_DIMM_CONN_DQ" ); + PRDF_ASSERT( false ); + } + + memcpy( &o_dqMapPtr[0], &tmpData[0], DQS_PER_DIMM ); #undef PRDF_FUNC -} -*/ +} // end function getDimmDqAttr //------------------------------------------------------------------------------ - -/* TODO RTC 157888 -int32_t mssSetMarkStore( TargetHandle_t i_mba, const CenRank & i_rank, - CenMark & io_mark, bool & o_writeBlocked, - bool i_allowWriteBlocked ) +template<> +int32_t mssGetSteerMux( TargetHandle_t i_mca, + const MemRank & i_rank, + MemSymbol & o_port0Spare, + MemSymbol & o_port1Spare, + MemSymbol & o_eccSpare ) { - #define PRDF_FUNC "[PlatServices::mssSetMarkStore] " + // NO-OP for MCA + o_port0Spare = MemSymbol(); // default invalid + o_port1Spare = MemSymbol(); // default invalid + o_eccSpare = MemSymbol(); // default invalid + return SUCCESS; +} +template<> +int32_t mssGetSteerMux( TargetHandle_t i_mba, const MemRank & i_rank, + MemSymbol & o_port0Spare, MemSymbol & o_port1Spare, + MemSymbol & o_eccSpare ) +{ int32_t o_rc = SUCCESS; + // called by FSP code so can't just move to hostboot side +#ifdef __HOSTBOOT_MODULE errlHndl_t errl = NULL; - o_writeBlocked = false; - uint8_t sm = io_mark.getSM().isValid() ? io_mark.getSM().getSymbol() - : MSS_INVALID_SYMBOL; - uint8_t cm = io_mark.getCM().isValid() ? io_mark.getCM().getDramSymbol() - : MSS_INVALID_SYMBOL; + uint8_t port0Spare, port1Spare, eccSpare; - fapi::ReturnCode l_rc = mss_put_mark_store( getFapiTarget(i_mba), - i_rank.getMaster(), sm, cm ); + fapi2::Target fapiMba(i_mba); + FAPI_INVOKE_HWP( errl, mss_check_steering, fapiMba, + i_rank.getMaster(), port0Spare, port1Spare, eccSpare ); - if ( i_allowWriteBlocked && - fapi::RC_MSS_MAINT_MARKSTORE_WRITE_BLOCKED == l_rc ) + if ( NULL != errl ) { - o_writeBlocked = true; - - // Read hardware and get the new chip mark. - CenMark hwMark; - o_rc = mssGetMarkStore( i_mba, i_rank, hwMark ); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "mssGetMarkStore() failed." ); - } - else - { - // Update io_mark with the new chip mark. - io_mark.setCM( hwMark.getCM() ); - } + PRDF_ERR( "[PlatServices::mssGetSteerMux] mss_check_steering() " + "failed. HUID: 0x%08x rank: %d", + getHuid(i_mba), i_rank.getMaster() ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; } else { - errl = fapi::fapiRcToErrl(l_rc); - if ( NULL != errl ) - { - PRDF_ERR( PRDF_FUNC "mss_put_mark_store() failed. HUID: 0x%08x " - "rank: %d sm: %d cm: %d", getHuid(i_mba), - i_rank.getMaster(), sm, cm ); - PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); - o_rc = FAIL; - } + o_port0Spare = MemSymbol::fromSymbol( i_mba, i_rank, port0Spare ); + o_port1Spare = MemSymbol::fromSymbol( i_mba, i_rank, port1Spare ); + o_eccSpare = MemSymbol::fromSymbol( i_mba, i_rank, eccSpare ); } - +#endif return o_rc; - - #undef PRDF_FUNC } -*/ //------------------------------------------------------------------------------ + template<> -void getDimmDqAttr( TargetHandle_t i_target, - uint8_t (&o_dqMapPtr)[DQS_PER_DIMM] ) +int32_t mssSetSteerMux( TargetHandle_t i_mba, const MemRank & i_rank, + const MemSymbol & i_symbol, bool i_x4EccSpare ) { - #define PRDF_FUNC "[PlatServices::getDimmDqAttr] " - - PRDF_ASSERT( TYPE_MCA == getTargetType(i_target) ); + int32_t o_rc = SUCCESS; +#ifdef __HOSTBOOT_MODULE + errlHndl_t errl = NULL; + fapi2::Target fapiMba(i_mba); - TargetHandle_t mcs = getConnectedParent( i_target, TYPE_MCS ); + uint8_t l_dramSymbol = PARSERUTILS::dram2Symbol( + i_symbol.getDram(), + isDramWidthX4(i_mba) ); - uint32_t mcaRelMcs = getTargetPosition( i_target ) % MAX_MCA_PER_MCS; - uint8_t tmpData[MAX_MCA_PER_MCS][DQS_PER_DIMM]; + FAPI_INVOKE_HWP( errl, mss_do_steering, fapiMba, + i_rank.getMaster(), l_dramSymbol, + i_x4EccSpare ); - if ( !mcs->tryGetAttr(tmpData) ) + if ( NULL != errl ) { - PRDF_ERR( PRDF_FUNC "Failed to get ATTR_MSS_VPD_DQ_MAP" ); - PRDF_ASSERT( false ); + PRDF_ERR( "[PlatServices::mssSetSteerMux] mss_do_steering " + "failed. HUID: 0x%08x rank: %d symbol: %d eccSpare: %c", + getHuid(i_mba), i_rank.getMaster(), l_dramSymbol, + i_x4EccSpare ? 'T' : 'F' ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; } +#endif + return o_rc; +} - memcpy( &o_dqMapPtr[0], &tmpData[mcaRelMcs][0], DQS_PER_DIMM ); - #undef PRDF_FUNC -} // end function getDimmDqAttr +//------------------------------------------------------------------------------ +template<> +int32_t getDimmSpareConfig( TargetHandle_t i_mba, MemRank i_rank, + uint8_t i_ps, uint8_t & o_spareConfig ) +{ + // No spares for MCAs + o_spareConfig = CEN_VPD_DIMM_SPARE_NO_SPARE; + return SUCCESS; +} template<> -void getDimmDqAttr( TargetHandle_t i_target, - uint8_t (&o_dqMapPtr)[DQS_PER_DIMM] ) +int32_t getDimmSpareConfig( TargetHandle_t i_mba, MemRank i_rank, + uint8_t i_ps, uint8_t & o_spareConfig ) { - #define PRDF_FUNC "[PlatServices::getDimmDqAttr] " + #define PRDF_FUNC "[PlatServices::getDimmSpareConfig] " + int32_t o_rc = SUCCESS; - PRDF_ASSERT( TYPE_DIMM == getTargetType(i_target) ); +#ifdef __HOSTBOOT_MODULE + using namespace fapi2; - const uint8_t DIMM_BAD_DQ_SIZE_BYTES = 80; + ATTR_CEN_VPD_DIMM_SPARE_Type attr; + o_spareConfig = ENUM_ATTR_CEN_VPD_DIMM_SPARE_NO_SPARE; + do + { + if( TYPE_MBA != getTargetType( i_mba ) ) + { + PRDF_ERR( PRDF_FUNC "Invalid Target:0x%08X", getHuid( i_mba ) ); + o_rc = FAIL; break; + } - uint8_t tmpData[DIMM_BAD_DQ_SIZE_BYTES]; + if ( MAX_PORT_PER_MBA <= i_ps ) + { + PRDF_ERR( PRDF_FUNC "Invalid parameters i_ps:%u", i_ps ); + o_rc = FAIL; break; + } - if ( !i_target->tryGetAttr(tmpData) ) - { - PRDF_ERR( PRDF_FUNC "Failed to get ATTR_CEN_DQ_TO_DIMM_CONN_DQ" ); - PRDF_ASSERT( false ); - } + fapi2::Target fapiMba(i_mba); + ReturnCode l_rc = FAPI_ATTR_GET(ATTR_CEN_VPD_DIMM_SPARE, fapiMba, attr); + errlHndl_t errl = fapi2::rcToErrl(l_rc); + if ( NULL != errl ) + { + PRDF_ERR( PRDF_FUNC "Failed to get ATTR_VPD_DIMM_SPARE for Target:" + "0x%08X", getHuid( i_mba ) ); + PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); + o_rc = FAIL; break; + } + o_spareConfig = attr[i_ps][i_rank.getDimmSlct()][i_rank.getRankSlct()]; - memcpy( &o_dqMapPtr[0], &tmpData[0], DQS_PER_DIMM ); + // Check for valid values + // For X4 DRAM, we can not have full byte as spare config. Also for X8 + // DRAM we can not have nibble as spare. + + if( ENUM_ATTR_CEN_VPD_DIMM_SPARE_NO_SPARE == o_spareConfig) break; + + bool isFullByte = ( ENUM_ATTR_CEN_VPD_DIMM_SPARE_FULL_BYTE == + o_spareConfig ); + bool isX4Dram = isDramWidthX4(i_mba); + + if ( ( isX4Dram && isFullByte ) || ( !isX4Dram && !isFullByte ) ) + { + PRDF_ERR( PRDF_FUNC "Invalid Configuration: o_spareConfig:%u", + o_spareConfig ); + o_rc = FAIL; break; + } + + }while(0); +#endif + return o_rc; #undef PRDF_FUNC -} // end function getDimmDqAttr +} + + + + + //------------------------------------------------------------------------------ diff --git a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H index 30ec6a103..97cf0a5b5 100755 --- a/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H +++ b/src/usr/diag/prdf/common/plat/prdfPlatServices_common.H @@ -226,44 +226,47 @@ int32_t setBadDqBitmap( TARGETING::TargetHandle_t i_trgt, const MemDqBitmap & i_bitmap ); /** - * @brief Invokes the get mark store hardware procedure. - * @param i_mba Target MBA. - * @param i_rank Target rank. - * @param o_mark The returned mark. + * @brief Invokes the get steer mux hardware procedure. + * @param i_mba Target MBA/MCA + * @param i_rank Target rank. + * @param o_port0Spare A symbol associated with the spare on port 0. + * @param o_port1Spare A symbol associated with the spare on port 1. + * @param o_eccSpare A symbol associated with the ECC spare (x4 mode only). * @return Non-SUCCESS in internal function fails, SUCCESS otherwise. */ -/* -int32_t mssGetMarkStore( TARGETING::TargetHandle_t i_mba, - const CenRank & i_rank, CenMark & o_mark ); -*/ +template +int32_t mssGetSteerMux( TARGETING::TargetHandle_t i_mba, const MemRank & i_rank, + MemSymbol & o_port0Spare, MemSymbol & o_port1Spare, + MemSymbol & o_eccSpare ); /** - * @brief Invokes the set mark store hardware procedure. - * @param i_mba Target MBA. - * @param i_rank Target rank. - * @param io_mark The mark to write. If hardware blocks the write - * to markstore and the block is allowed, io_mark - * will be updated with the new chip mark set by - * hardware. - * @param o_writeBlocked TRUE if a blocke write is allowed and hardware - * blocked the write to markstore. - * @param i_allowWriteBlocked TRUE if a blocked write is allowed. This means - * the user will need to read what hardware just - * placed in the markstore and retry. If FALSE and - * the write was blocked, this function will commit - * the FAPI error log and return a non-SUCCESS. The - * default value is FALSE. - * @note Both the chip mark and the symbol mark will be written at the same - * time, so do a RMW operation to avoid overwritting a previous mark. + * @brief Invokes the set steer mux hardware procedure. + * @param i_mba Target MBA. + * @param i_rank Target rank. + * @param i_symbol A symbol associated with the DRAM to be spared. + * @param i_x4EccSpare If true, will set ECC spare instead (x4 mode only). + * @note The procedure will be able to derive the port from the given symbol. * @return Non-SUCCESS in internal function fails, SUCCESS otherwise. */ -/* TODO RTC 157888 -int32_t mssSetMarkStore( TARGETING::TargetHandle_t i_mba, - const CenRank & i_rank, CenMark & io_mark, - bool & o_writeBlocked, - bool i_allowWriteBlocked = false ); -*/ +template +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. + * @param i_rank Rank. + * @param i_ps MBA port select. + * @param o_spareConfig Spare DRAM config information. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + * @note On a DIMM its possible that spare is not present. Also on X4 DRAM + * spare can be on High nibble or low nibble. This function will + * populate spare config information in o_spareConfig. + */ +template +int32_t getDimmSpareConfig( TARGETING::TargetHandle_t i_mba, MemRank i_rank, + uint8_t i_ps, uint8_t & o_spareConfig ); /** diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDsd.H b/src/usr/diag/prdf/plat/mem/prdfMemDsd.H index ac1b1e044..5990a902e 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemDsd.H +++ b/src/usr/diag/prdf/plat/mem/prdfMemDsd.H @@ -66,10 +66,11 @@ class DsdEvent : public TdEntry { #define PRDF_FUNC "[DsdEvent::nextStep] " - // TODO: RTC 189221 should assert if DRAM Sparing is NOT supported. - uint32_t o_rc = SUCCESS; + // NOTE: DRAM Sparing should already be supported if we get this far, + // so just continue without checking for the support here + o_done = false; do @@ -154,16 +155,16 @@ class DsdEvent : public TdEntry { // Before starting the first command, set iv_mark in the // hardware steer mux. - /* TODO: RTC 189221 - o_rc = mssSetSteerMux( iv_chip, iv_rank, iv_mark, - iv_eccSpare ); + o_rc = PlatServices::mssSetSteerMux(iv_chip->getTrgt(), + iv_rank, + iv_mark.getSymbol(), + iv_eccSpare ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "mssSetSteerMux(0x%08x,0x%2x) failed", iv_chip->getHuid(), getKey() ); break; } - */ break; // Nothing to analyze yet. } diff --git a/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C index a7de2d38c..559e384fa 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemDsd_ipl.C @@ -128,10 +128,10 @@ uint32_t DsdEvent::verifySpare( const uint32_t & i_eccAttns, // Set the bad spare in the VPD. At this point, the chip mark // should have already been set in the VPD because it was recently // verified. + MemDqBitmap bitmap; + o_rc = getBadDqBitmap( iv_chip->getTrgt(), + iv_rank, bitmap ); - /* TODO: RTC 189221 - CenDqBitmap bitmap; - o_rc = getBadDqBitmap( iv_mbaTrgt, iv_rank, bitmap ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "getBadDqBitmap() failed" ); @@ -143,7 +143,7 @@ uint32_t DsdEvent::verifySpare( const uint32_t & i_eccAttns, } else { - o_rc = bitmap.setDramSpare( iv_mark.getCM().getPortSlct() ); + o_rc = bitmap.setDramSpare( iv_mark.getSymbol().getPortSlct() ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "setDramSpare() failed" ); @@ -151,13 +151,14 @@ uint32_t DsdEvent::verifySpare( const uint32_t & i_eccAttns, } } - o_rc = setBadDqBitmap( iv_mbaTrgt, iv_rank, bitmap ); + o_rc = setBadDqBitmap( iv_chip->getTrgt(), + iv_rank, bitmap ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "setBadDqBitmap() failed" ); break; } - */ + } else { diff --git a/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C b/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C index c32dd52a7..7dbdd9beb 100644 --- a/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C +++ b/src/usr/diag/prdf/plat/mem/prdfRestoreDramRepairs.C @@ -319,15 +319,13 @@ bool processRepairedRanks( TargetHandle_t i_trgt, MemSymbol sp0, sp1, ecc; - /* TODO RTC 189221 DRAM sparing - if ( SUCCESS != mssGetSteerMux(i_trgt, rank, sp0, sp1, ecc) ) + if ( SUCCESS != mssGetSteerMux(i_trgt, rank, sp0, sp1, ecc) ) { PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed: MBA=0x%08x " "rank=%d", getHuid(i_trgt), rank.getMaster() ); analysisErrors = true; continue; // skip this rank } - */ bool isCm = chipMark.isValid(); // chip mark bool isSm = symMark.isValid(); // symbol mark @@ -576,9 +574,9 @@ void deployDramSpares( TargetHandle_t i_trgt, const std::vector & i_ranks ) { PRDF_TRAC( "deployDramSpares: Function not implemented yet" ); - /* TODO RTC 189221 + bool x4 = isDramWidthX4( i_trgt ); - bool cenDimm = isMembufOnDimm( i_mba ); + bool cenDimm = isMembufOnDimm( i_trgt ); for ( auto & rank : i_ranks ) { @@ -593,12 +591,12 @@ void deployDramSpares( TargetHandle_t i_trgt, if ( cenDimm ) { - l_rc |= mssSetSteerMux( i_trgt, rank, symPort0, false ); - l_rc |= mssSetSteerMux( i_trgt, rank, symPort1, false ); + l_rc |= mssSetSteerMux( i_trgt, rank, symPort0, false ); + l_rc |= mssSetSteerMux( i_trgt, rank, symPort1, false ); } if ( x4 ) - l_rc |= mssSetSteerMux( i_trgt, rank, symEccSp, true ); + l_rc |= mssSetSteerMux( i_trgt, rank, symEccSp, true ); if ( SUCCESS != l_rc ) { @@ -607,7 +605,7 @@ void deployDramSpares( TargetHandle_t i_trgt, // warning in Hostboot. continue; } - }*/ + } } } // end namespace RDR diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C index 0c7210d7c..afd3ac492 100644 --- a/src/usr/diag/prdf/plat/prdfPlatServices.C +++ b/src/usr/diag/prdf/plat/prdfPlatServices.C @@ -419,137 +419,6 @@ uint32_t getMemAddrRange( ExtensibleChip * i_chip, } -//------------------------------------------------------------------------------ -template<> -int32_t mssGetSteerMux( TargetHandle_t i_mba, const MemRank & i_rank, - MemSymbol & o_port0Spare, MemSymbol & o_port1Spare, - MemSymbol & o_eccSpare ) -{ - int32_t o_rc = SUCCESS; - - errlHndl_t errl = NULL; - - uint8_t port0Spare, port1Spare, eccSpare; - - fapi2::Target fapiMba(i_mba); - FAPI_INVOKE_HWP( errl, mss_check_steering, fapiMba, - i_rank.getMaster(), port0Spare, port1Spare, eccSpare ); - - if ( NULL != errl ) - { - PRDF_ERR( "[PlatServices::mssGetSteerMux] mss_check_steering() " - "failed. HUID: 0x%08x rank: %d", - getHuid(i_mba), i_rank.getMaster() ); - PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); - o_rc = FAIL; - } - else - { - o_port0Spare = MemSymbol::fromSymbol( i_mba, i_rank, port0Spare ); - o_port1Spare = MemSymbol::fromSymbol( i_mba, i_rank, port1Spare ); - o_eccSpare = MemSymbol::fromSymbol( i_mba, i_rank, eccSpare ); - } - - return o_rc; -} - - -//------------------------------------------------------------------------------ - -template<> -int32_t mssSetSteerMux( TargetHandle_t i_mba, const MemRank & i_rank, - const MemSymbol & i_symbol, bool i_x4EccSpare ) -{ - int32_t o_rc = SUCCESS; - - errlHndl_t errl = NULL; - fapi2::Target fapiMba(i_mba); - - uint8_t l_dramSymbol = PARSERUTILS::dram2Symbol( - i_symbol.getDram(), - isDramWidthX4(i_mba) ); - - FAPI_INVOKE_HWP( errl, mss_do_steering, fapiMba, - i_rank.getMaster(), l_dramSymbol, - i_x4EccSpare ); - - if ( NULL != errl ) - { - PRDF_ERR( "[PlatServices::mssSetSteerMux] mss_do_steering " - "failed. HUID: 0x%08x rank: %d symbol: %d eccSpare: %c", - getHuid(i_mba), i_rank.getMaster(), l_dramSymbol, - i_x4EccSpare ? 'T' : 'F' ); - PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); - o_rc = FAIL; - } - - return o_rc; -} - - -//------------------------------------------------------------------------------ - -template<> -int32_t getDimmSpareConfig( TargetHandle_t i_mba, MemRank i_rank, - uint8_t i_ps, uint8_t & o_spareConfig ) -{ - #define PRDF_FUNC "[PlatServices::getDimmSpareConfig] " - int32_t o_rc = SUCCESS; - - using namespace fapi2; - - ATTR_CEN_VPD_DIMM_SPARE_Type attr; - o_spareConfig = ENUM_ATTR_CEN_VPD_DIMM_SPARE_NO_SPARE; - do - { - if( TYPE_MBA != getTargetType( i_mba ) ) - { - PRDF_ERR( PRDF_FUNC "Invalid Target:0x%08X", getHuid( i_mba ) ); - o_rc = FAIL; break; - } - - if ( MAX_PORT_PER_MBA <= i_ps ) - { - PRDF_ERR( PRDF_FUNC "Invalid parameters i_ps:%u", i_ps ); - o_rc = FAIL; break; - } - - fapi2::Target fapiMba(i_mba); - ReturnCode l_rc = FAPI_ATTR_GET(ATTR_CEN_VPD_DIMM_SPARE, fapiMba, attr); - errlHndl_t errl = fapi2::rcToErrl(l_rc); - if ( NULL != errl ) - { - PRDF_ERR( PRDF_FUNC "Failed to get ATTR_VPD_DIMM_SPARE for Target:" - "0x%08X", getHuid( i_mba ) ); - PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); - o_rc = FAIL; break; - } - o_spareConfig = attr[i_ps][i_rank.getDimmSlct()][i_rank.getRankSlct()]; - - // Check for valid values - // For X4 DRAM, we can not have full byte as spare config. Also for X8 - // DRAM we can not have nibble as spare. - - if( ENUM_ATTR_CEN_VPD_DIMM_SPARE_NO_SPARE == o_spareConfig) break; - - bool isFullByte = ( ENUM_ATTR_CEN_VPD_DIMM_SPARE_FULL_BYTE == - o_spareConfig ); - bool isX4Dram = isDramWidthX4(i_mba); - - if ( ( isX4Dram && isFullByte ) || ( !isX4Dram && !isFullByte ) ) - { - PRDF_ERR( PRDF_FUNC "Invalid Configuration: o_spareConfig:%u", - o_spareConfig ); - o_rc = FAIL; break; - } - - }while(0); - - return o_rc; - #undef PRDF_FUNC -} - - //------------------------------------------------------------------------------ MemAddr __convertMssMcbistAddr( const mss::mcbist::address & i_addr ) diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.H b/src/usr/diag/prdf/plat/prdfPlatServices.H index 5641738fe..bd20bd239 100644 --- a/src/usr/diag/prdf/plat/prdfPlatServices.H +++ b/src/usr/diag/prdf/plat/prdfPlatServices.H @@ -158,48 +158,7 @@ uint32_t getMemAddrRange( ExtensibleChip * i_chip, VT & o_startAddr, VT & o_endAddr, uint8_t i_dimmSlct = MAX_DIMM_PER_PORT ); -/** - * @brief Invokes the get steer mux hardware procedure. - * @param i_mba Target MBA. - * @param i_rank Target rank. - * @param o_port0Spare A symbol associated with the spare on port 0. - * @param o_port1Spare A symbol associated with the spare on port 1. - * @param o_eccSpare A symbol associated with the ECC spare (x4 mode only). - * @return Non-SUCCESS in internal function fails, SUCCESS otherwise. - */ -template -int32_t mssGetSteerMux( TARGETING::TargetHandle_t i_mba, const MemRank & i_rank, - MemSymbol & o_port0Spare, MemSymbol & o_port1Spare, - MemSymbol & o_eccSpare ); -/** - * @brief Invokes the set steer mux hardware procedure. - * @param i_mba Target MBA. - * @param i_rank Target rank. - * @param i_symbol A symbol associated with the DRAM to be spared. - * @param i_x4EccSpare If true, will set ECC spare instead (x4 mode only). - * @note The procedure will be able to derive the port from the given symbol. - * @return Non-SUCCESS in internal function fails, SUCCESS otherwise. - */ -template -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 target. - * @param i_rank Rank. - * @param i_ps MBA port select. - * @param o_spareConfig Spare DRAM config information. - * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. - * @note On a DIMM its possible that spare is not present. Also on X4 DRAM - * spare can be on High nibble or low nibble. This function will - * populate spare config information in o_spareConfig. - */ -template -int32_t getDimmSpareConfig( TARGETING::TargetHandle_t i_mba, MemRank i_rank, - uint8_t i_ps, uint8_t & o_spareConfig ); //############################################################################## //## Nimbus/Centaur Maintenance Command wrappers //############################################################################## -- cgit v1.2.1