diff options
10 files changed, 328 insertions, 120 deletions
diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C index f3f76bab3..764ea5d1f 100755 --- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C +++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C @@ -1183,6 +1183,66 @@ bool isDramWidthX4( TargetHandle_t i_mba ) //------------------------------------------------------------------------------ +int32_t getDimmSpareConfig( TargetHandle_t i_mba, CenRank i_rank, + uint8_t i_ps, uint8_t & o_spareConfig ) +{ + #define PRDF_FUNC "[PlatServices::getDimmSpareConfig] " + int32_t o_rc = SUCCESS; + + using namespace fapi; + + ATTR_EFF_DIMM_SPARE_type attr; + o_spareConfig = ENUM_ATTR_EFF_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; + } + + // Using namespace explicitly in ATTR_EFF_DIMM_SPARE as otherwise it + // has conflict with fapi namespace. + if ( SUCCESS != i_mba->tryGetAttr< TARGETING::ATTR_EFF_DIMM_SPARE> + ( attr )) + { + PRDF_ERR( PRDF_FUNC"Failed to get ATTR_EFF_DIMM_SPARE for Target:" + "0x%08X", getHuid( i_mba ) ); + 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_EFF_DIMM_SPARE_NO_SPARE == o_spareConfig) break; + + bool isFullByte = ( ENUM_ATTR_EFF_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 +} + +//------------------------------------------------------------------------------ + uint8_t getRanksPerDimm( TargetHandle_t i_mba, uint8_t i_ds ) { #define PRDF_FUNC "[PlatServices::getRanksPerDimm] " diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H index 10e47cd03..19dd32b97 100755 --- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H +++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H @@ -365,6 +365,20 @@ bool isDramWidthX4(TARGETING::TargetHandle_t i_mbaTarget); */ uint8_t getRanksPerDimm( TARGETING::TargetHandle_t i_mbaTarget, uint8_t i_ds ); +/** + * @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. + */ +int32_t getDimmSpareConfig( TARGETING::TargetHandle_t i_mba, CenRank i_rank, + uint8_t i_ps, uint8_t & o_spareConfig ); + //############################################################################## //## //## Clock specific functions diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C index 28a1400cc..d08f4020c 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C @@ -32,6 +32,7 @@ namespace PRDF { using namespace PlatServices; +using namespace fapi; // for spare dram config bool CenDqBitmap::badDqs() const { @@ -251,11 +252,30 @@ int32_t CenDqBitmap::setDramSpare( uint8_t i_portSlct, uint8_t i_pins ) o_rc = FAIL; break; } + uint8_t spareConfig = ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE; + o_rc = getDimmSpareConfig( iv_mba , iv_rank, i_portSlct, + spareConfig ); + if( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC"getDimmSpareConfig() failed" ); + o_rc = FAIL; break; + } + + if ( ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE == spareConfig ) + { + PRDF_ERR( PRDF_FUNC" Spare is not avaiable" ); + o_rc = FAIL; break; + } + if ( isDramWidthX4(iv_mba) ) { i_pins &= 0xf; // limit to 4 bits - // TODO: RTC 68096 Need to check if this is correct behavior. - iv_data[i_portSlct][DIMM_DQ_RANK_BITMAP_SIZE-1] |= i_pins << 4; + + if( ENUM_ATTR_EFF_DIMM_SPARE_HIGH_NIBBLE == spareConfig ) + { + i_pins = i_pins << 4; + } + iv_data[i_portSlct][DIMM_DQ_RANK_BITMAP_SIZE-1] |= i_pins; } else { @@ -274,18 +294,25 @@ int32_t CenDqBitmap::setDramSpare( uint8_t i_portSlct, uint8_t i_pins ) int32_t CenDqBitmap::setEccSpare( uint8_t i_pins ) { + #define PRDF_FUNC "[CenDqBitmap::setEccSpare] " int32_t o_rc = SUCCESS; do { - // TODO: RTC 68096 Need to add x4 ECC support. - - } while (0); + if ( ! isDramWidthX4(iv_mba) ) + { + PRDF_ERR( PRDF_FUNC"Invalid Call. Function called for MBA having " + "non X4 DRAM" ); + o_rc = FAIL; break; + } + // ECC spare bits are stored in port1, dq bits 68-71 + // Call setDram with symbol 0 to update the VPD for these bits. + setDram( 0, i_pins ); + }while( 0 ); return o_rc; - #undef PRDF_FUNC } @@ -308,14 +335,55 @@ int32_t CenDqBitmap::isDramSpareAvailable( uint8_t i_portSlct, o_rc = FAIL; break; } + uint8_t spareConfig = ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE; + o_rc = getDimmSpareConfig( iv_mba , iv_rank, i_portSlct, + spareConfig ); + if( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC"getDimmSpareConfig() failed" ); + break; + } + + uint8_t spareDqBits = iv_data[i_portSlct][DIMM_DQ_RANK_BITMAP_SIZE-1]; + if ( isDramWidthX4(iv_mba) ) { - // TODO: RTC 68096 Need to add x4 ECC support. + // Check for DRAM spare + if( ENUM_ATTR_EFF_DIMM_SPARE_HIGH_NIBBLE == spareConfig ) + { + o_available = ( 0 == ( spareDqBits & 0xf0 ) ); + } + else if( ENUM_ATTR_EFF_DIMM_SPARE_LOW_NIBBLE == spareConfig ) + { + o_available = ( 0 == ( spareDqBits & 0x0f ) ); + } + + if( false == o_available ) + { + // check for ecc spare + // ECC spare bits are stored in port1, dq bits 68-71 + // These bits map to symbol 0. Use isChipMark to check + // if these bits are all 1. + o_rc = isChipMark( 0, o_available ); + if( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC"isChipMark() failed" ); + break; + } + // isChipMark return true if chip Mark is present. + // Invert its value to get the right result. + o_available = !(o_available); + } } else { - o_available = - ( 0 == iv_data[i_portSlct][DIMM_DQ_RANK_BITMAP_SIZE-1] ); + if ( ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE == spareConfig ) + { + // spare is not available. + o_available = false; + } + else + o_available = ( 0 == spareDqBits ); } } while (0); diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H index 340c872bd..d7abe46b5 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H @@ -120,12 +120,11 @@ class CenDqBitmap /** * @brief Sets the ECC spare on the specified port (x4 mode only). - * @param i_portSlct The target port. - * @param i_pins Optional 2-bit value of the symbol's pins. The default - * is to set both pins. + * @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 ); + int32_t setEccSpare( uint8_t i_pins = 0xf ); /** * @brief Queries for DRAM spare status. diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C index beeebf421..4e28272cf 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C @@ -165,80 +165,114 @@ void addMemEccData( ExtensibleChip * i_mbaChip, STEP_CODE_DATA_STRUCT & io_sc ) void captureDramRepairsData( TARGETING::TargetHandle_t i_mbaTrgt, CaptureData & io_cd ) { + #define PRDF_FUNC "[CenMbaCaptureData::captureDramRepairsData] " + using namespace fapi; // for spare config + int32_t rc = SUCCESS; DramRepairMbaData mbaData; - // Iterate all ranks to get DRAM repair data - for ( uint32_t r = 0; r < MASTER_RANKS_PER_MBA; r++ ) - { - CenRank rank ( r ); + mbaData.header.isSpareDram = false; + std::vector<CenRank> masterRanks; - // Get chip/symbol marks - CenMark mark; - rc = PlatServices::mssGetMarkStore( i_mbaTrgt, rank, mark ); + do + { + rc = getMasterRanks( i_mbaTrgt, masterRanks ); if ( SUCCESS != rc ) { - PRDF_ERR("Failed to get markstore data"); - continue; + PRDF_ERR( PRDF_FUNC"getMasterRanks() failed" ); + break; } - - // Get DRAM spares - CenSymbol sp0, sp1, ecc; - rc = PlatServices::mssGetSteerMux( i_mbaTrgt, rank, sp0, sp1, ecc ); - if ( SUCCESS != rc ) + if( masterRanks.empty() ) { - PRDF_ERR("Failed to get DRAM steer data"); - continue; + PRDF_ERR( PRDF_FUNC"Master Rank list size is 0"); + break;; } - - // Add data - DramRepairRankData rankData = { rank.getMaster(), - mark.getCM().getSymbol(), - mark.getSM().getSymbol(), - sp0.getSymbol(), - sp1.getSymbol(), - ecc.getSymbol() }; - if ( rankData.valid() ) + uint8_t spareConfig = ENUM_ATTR_EFF_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_mbaTrgt, masterRanks[0], 0, spareConfig ); + if( SUCCESS != rc ) { - mbaData.rankDataList.push_back(rankData); + PRDF_ERR( PRDF_FUNC"getDimmSpareConfig() failed" ); + break; } - } - // If MBA had some DRAM repair data, add header information - if( mbaData.rankDataList.size() > 0 ) - { - bool isCentaurDimm = true; - mbaData.header.rankCount = mbaData.rankDataList.size(); - PlatServices::isMembufOnDimm( i_mbaTrgt, isCentaurDimm ); - mbaData.header.isIsDimm = !isCentaurDimm; - mbaData.header.isX4Dram = PlatServices::isDramWidthX4( i_mbaTrgt ); - UtilMem dramStream; - dramStream << mbaData; - - #ifndef PPC - // Fix endianess issues with non PPC machines. - // This is a workaround. Though UtilMem takes care of endianess, - // It seems with capture data its not working - const size_t sz_word = sizeof(uint32_t); - - // Allign data with 32 bit boundary - for (uint32_t i = 0; i < ( dramStream.size()%sz_word ); i++) + + if( ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE != spareConfig ) + mbaData.header.isSpareDram = true; + + // Iterate all ranks to get DRAM repair data + for ( std::vector<CenRank>::iterator it = masterRanks.begin(); + it != masterRanks.end(); it++ ) { - uint8_t dummy = 0; - dramStream << dummy; + // Get chip/symbol marks + CenMark mark; + rc = mssGetMarkStore( i_mbaTrgt, *it, mark ); + if ( SUCCESS != rc ) + { + PRDF_ERR( PRDF_FUNC"mssGetMarkStore() Failed"); + continue; + } + + // Get DRAM spares + CenSymbol sp0, sp1, ecc; + rc = mssGetSteerMux( i_mbaTrgt, *it, sp0, sp1, ecc ); + if ( SUCCESS != rc ) + { + PRDF_ERR( PRDF_FUNC"mssGetSteerMux() failed"); + continue; + } + + // Add data + DramRepairRankData rankData = { (*it).getMaster(), + mark.getCM().getSymbol(), + mark.getSM().getSymbol(), + sp0.getSymbol(), + sp1.getSymbol(), + ecc.getSymbol() }; + if ( rankData.valid() ) + { + mbaData.rankDataList.push_back(rankData); + } } - for ( uint32_t i = 0; i < ( dramStream.size()/sz_word); i++ ) + // If MBA had some DRAM repair data, add header information + if( mbaData.rankDataList.size() > 0 ) { - ((uint32_t*)dramStream.base())[i] = + mbaData.header.rankCount = mbaData.rankDataList.size(); + mbaData.header.isX4Dram = isDramWidthX4( i_mbaTrgt ); + UtilMem dramStream; + dramStream << mbaData; + + #ifndef PPC + // Fix endianess issues with non PPC machines. + // This is a workaround. Though UtilMem takes care of endianess, + // It seems with capture data its not working + const size_t sz_word = sizeof(uint32_t); + + // Allign data with 32 bit boundary + for (uint32_t i = 0; i < ( dramStream.size()%sz_word ); i++) + { + uint8_t dummy = 0; + dramStream << dummy; + } + for ( uint32_t i = 0; i < ( dramStream.size()/sz_word); i++ ) + { + ((uint32_t*)dramStream.base())[i] = htonl(((uint32_t*)dramStream.base())[i]); - } - #endif + } + #endif - // Allocate space for the capture data. - BIT_STRING_ADDRESS_CLASS dramRepairData ( 0, ( dramStream.size() )*8, + // Allocate space for the capture data. + BIT_STRING_ADDRESS_CLASS dramRepairData ( 0,( dramStream.size() )*8, (CPU_WORD *) dramStream.base() ); - io_cd.Add( i_mbaTrgt, Util::hashString("DRAM_REPAIRS_DATA"), - dramRepairData ); - } + io_cd.Add( i_mbaTrgt, Util::hashString("DRAM_REPAIRS_DATA"), + dramRepairData ); + } + }while(0); + + if( FAIL == rc ) + PRDF_ERR( PRDF_FUNC"Failed for MBA 0x%08X", getHuid( i_mbaTrgt ) ); + + #undef PRDF_FUNC } //------------------------------------------------------------------------------ diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C index 58782055b..15850695d 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C @@ -356,8 +356,11 @@ int32_t CenMbaTdCtlrCommon::handleMCE_VCM2( STEP_CODE_DATA_STRUCT & io_sc ) { #define PRDF_FUNC "[CenMbaTdCtlrCommon::handleMCE_VCM2] " + using namespace fapi; // For spare config macros. + int32_t o_rc = SUCCESS; + iv_isEccSteer = false; do { if ( VCM_PHASE_2 != iv_tdState ) @@ -413,25 +416,25 @@ int32_t CenMbaTdCtlrCommon::handleMCE_VCM2( STEP_CODE_DATA_STRUCT & io_sc ) break; } - // RAS callout policies can be determined by the DIMM type. We can - // assume IS DIMMs are on low end systems and Centaur DIMMs are on - // mid/high end systems. - bool isCenDimm = false; - o_rc = isMembufOnDimm( iv_mbaTrgt, isCenDimm ); + uint8_t ps = iv_mark.getCM().getPortSlct(); + uint8_t spareConfig = ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE; + o_rc = getDimmSpareConfig( iv_mbaTrgt, iv_rank, ps, + spareConfig ); if ( SUCCESS != o_rc ) { - PRDF_ERR( PRDF_FUNC"isMembufOnDimm() failed" ); + PRDF_ERR( PRDF_FUNC"getDimmSpareConfig() failed" ); break; } + bool isX4Dimm = isDramWidthX4( iv_mbaTrgt ); - if ( isCenDimm ) // Medium/high end systems + // Chaeck if DRAM spare is present. + // Also eccspare is available on all X4 DIMMS. + if ( ( ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE != spareConfig ) || isX4Dimm ) { - uint8_t ps = iv_mark.getCM().getPortSlct(); // It is possible that a Centaur DIMM does not have spare DRAMs. - // Check the VPD for available spares. Note that a x4 DIMM may have - // one or two spare DRAMs so check for availability on both. - // TODO: RTC 68096 Add support for x4 DRAMs. + // Check the VPD for available spares. Note that a x4 DIMM have + // DRAM spare and eccspare, so check for availability on both. bool dramSparePossible = false; o_rc = bitmap.isDramSpareAvailable( ps, dramSparePossible ); if ( SUCCESS != o_rc ) @@ -444,7 +447,6 @@ int32_t CenMbaTdCtlrCommon::handleMCE_VCM2( STEP_CODE_DATA_STRUCT & io_sc ) { // Verify the spare is not already used. CenSymbol sp0, sp1, ecc; - // TODO: RTC 68096 need to support ECC spare. o_rc = mssGetSteerMux( iv_mbaTrgt, iv_rank, sp0, sp1, ecc ); if ( SUCCESS != o_rc ) { @@ -452,15 +454,14 @@ int32_t CenMbaTdCtlrCommon::handleMCE_VCM2( STEP_CODE_DATA_STRUCT & io_sc ) break; } - if ( ((0 == ps) && !sp0.isValid()) || - ((1 == ps) && !sp1.isValid()) ) - { - // A spare DRAM is available. - startDsdProcedure = true; - } - else if ( iv_mark.getCM().getDram() == + // If spare DRAM is bad, HW can not steer another DRAM even + // if it is available ( e.g. ecc Spare ). So if chip mark is on + // spare DRAM, update VPD and make predictive callout. + if ( ( iv_mark.getCM().getDram() == (0 == ps ? sp0.getDram() : sp1.getDram()) ) + || ( iv_mark.getCM().getDram() == ecc.getDram() )) { + setTdSignature( io_sc, PRDFSIG_VcmBadSpare ); // The chip mark was on the spare DRAM and it is bad, so @@ -469,19 +470,43 @@ int32_t CenMbaTdCtlrCommon::handleMCE_VCM2( STEP_CODE_DATA_STRUCT & io_sc ) MemoryMru memmru ( iv_mbaTrgt, iv_rank, iv_mark.getCM() ); memmru.setDramSpared(); io_sc.service_data->SetCallout( memmru ); + io_sc.service_data->SetServiceCall(); - o_rc = bitmap.setDramSpare( ps ); - if ( SUCCESS != o_rc ) + if ( iv_mark.getCM().getDram() == ecc.getDram() ) { - PRDF_ERR( PRDF_FUNC"setDramSpare() failed" ); - break; + o_rc = bitmap.setEccSpare(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC"setEccSpare() failed" ); + break; + } } + else + { + o_rc = bitmap.setDramSpare( ps ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC"setDramSpare() failed" ); + break; + } + } + } + else if ( ((0 == ps) && !sp0.isValid()) || + ((1 == ps) && !sp1.isValid()) ) + { + // A spare DRAM is available. + startDsdProcedure = true; + } + else if( isDramWidthX4 ( iv_mbaTrgt ) && !ecc.isValid() ) + { + startDsdProcedure = true; + iv_isEccSteer = true; } else { // Chip mark and DRAM spare are both used. - setTdSignature( io_sc, PRDFSIG_VcmMarksUnavail ); + io_sc.service_data->SetErrorSig( PRDFSIG_VcmMarksUnavail ); io_sc.service_data->SetServiceCall(); } } @@ -492,7 +517,7 @@ int32_t CenMbaTdCtlrCommon::handleMCE_VCM2( STEP_CODE_DATA_STRUCT & io_sc ) io_sc.service_data->SetServiceCall(); } } - else // Low end systems + else // DRAM spare not supported. { // Not able to do dram sparing. If there is a symbol mark, there are // no repairs available so call it out and set the error log to @@ -569,12 +594,18 @@ int32_t CenMbaTdCtlrCommon::handleMCE_DSD2( STEP_CODE_DATA_STRUCT & io_sc ) PRDF_ERR( PRDF_FUNC"getBadDqBitmap() failed" ); break; } - - o_rc = bitmap.setDramSpare( iv_mark.getCM().getPortSlct() ); - if ( SUCCESS != o_rc ) + if ( iv_isEccSteer ) { - PRDF_ERR( PRDF_FUNC"setDramSpare() failed" ); - break; + bitmap.setEccSpare(); + } + else + { + o_rc = bitmap.setDramSpare( iv_mark.getCM().getPortSlct() ); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC"setDramSpare() failed" ); + break; + } } o_rc = setBadDqBitmap( iv_mbaTrgt, iv_rank, bitmap ); diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H index 7f48bc758..5dcf9d8d2 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H @@ -127,7 +127,7 @@ class CenMbaTdCtlrCommon */ explicit CenMbaTdCtlrCommon( ExtensibleChip * i_mbaChip ) : iv_mbaChip(i_mbaChip), iv_initialized(false), iv_tdState(NO_OP), - iv_rank(), iv_mark(), iv_mssCmd(NULL) + iv_rank(), iv_mark(), iv_mssCmd(NULL), iv_isEccSteer(false) {} /** @brief Destructor */ @@ -402,6 +402,9 @@ class CenMbaTdCtlrCommon /** Current maintenance command */ PlatServices::mss_MaintCmdWrapper * iv_mssCmd; + /** Tells if in DSD procedure we should use eccSpare. */ + bool iv_isEccSteer; + }; // CenMbaTdCtlrCommon } // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C b/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C index 5a28b998a..ca8ab4c27 100644 --- a/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C +++ b/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C @@ -426,8 +426,8 @@ bool parseDramRepairsData( uint8_t * i_buffer, uint32_t i_buflen, snprintf(temp, 64, "%s SM: %s", data, symbolStr); snprintf(data, 64, temp); - // Display DRAM spare information for non-ISDIMMs - if ( !mbaData.header.isIsDimm ) + // Display DRAM spare information if spare DRAM is supported. + if ( !mbaData.header.isSpareDram ) { getDramRepairSymbolStr(rankEntry.port0Spare, symbolStr, 10); snprintf(temp, 64, "%s Sp0: %s", data, symbolStr); @@ -436,14 +436,14 @@ bool parseDramRepairsData( uint8_t * i_buffer, uint32_t i_buflen, getDramRepairSymbolStr(rankEntry.port1Spare, symbolStr, 10); snprintf(temp, 64, "%s Sp1: %s", data, symbolStr); snprintf(data, 64, temp); + } - // Display ECC spare information for X4 DRAMs - if ( mbaData.header.isX4Dram ) - { - getDramRepairSymbolStr( rankEntry.eccSpare, symbolStr, 10 ); - snprintf(temp, 64, "%s EccSp: %s", data, symbolStr); - snprintf(data, 64, temp); - } + // Display ECC spare information for X4 DRAMs + if ( mbaData.header.isX4Dram ) + { + getDramRepairSymbolStr( rankEntry.eccSpare, symbolStr, 10 ); + snprintf(temp, 64, "%s EccSp: %s", data, symbolStr); + snprintf(data, 64, temp); } i_parser.PrintString( "", data ); diff --git a/src/usr/diag/prdf/common/plugins/prdfDramRepairUsrData.H b/src/usr/diag/prdf/common/plugins/prdfDramRepairUsrData.H index 9970041c7..b7fe5f07f 100755 --- a/src/usr/diag/prdf/common/plugins/prdfDramRepairUsrData.H +++ b/src/usr/diag/prdf/common/plugins/prdfDramRepairUsrData.H @@ -49,10 +49,11 @@ namespace FSP */ struct DramRepairDataHdr { - uint8_t rankCount : 4; //Number of ranks with DRAM Repair data - uint8_t isX4Dram : 1; //Is this mba connected in x4 mode - uint8_t isIsDimm : 1; //Is this mba connected to Industry standadrd DIMM - uint8_t reserved : 2; // Future use + uint8_t rankCount : 4; // Number of ranks with DRAM Repair data + uint8_t isX4Dram : 1; // Is this mba connected in x4 mode + uint8_t isSpareDram : 1; // Is spare DRAM supported on DIMMS attached + // to this MBA. + uint8_t reserved : 2; // Future use uint8_t wiringType; // Future use. In case we need to display the DRAM // site location instead symbols (TBD). @@ -67,7 +68,7 @@ struct DramRepairDataHdr { i_left << ( uint8_t )(i_right.rankCount << 4 | i_right.isX4Dram << 3 - | i_right.isIsDimm << 2 + | i_right.isSpareDram << 2 | i_right.reserved ) << i_right.wiringType; return i_left; @@ -87,7 +88,7 @@ struct DramRepairDataHdr i_right.rankCount = temp >> 4; i_right.isX4Dram = temp >> 3; - i_right.isIsDimm = temp >> 2; + i_right.isSpareDram = temp >> 2; i_right.reserved = temp; return i_left; diff --git a/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr.C b/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr.C index aae34cd80..a3aaaa486 100644 --- a/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr.C +++ b/src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr.C @@ -39,9 +39,6 @@ #include <prdfCenMbaDataBundle.H> #include <prdfCenSymbol.H> -// TODO: RTC 68096 Currently we are only supporting x8 DRAM. Once support for x4 -// DRAM is available, it will have impact on DRAM spare. - using namespace TARGETING; namespace PRDF @@ -908,7 +905,8 @@ int32_t CenMbaTdCtlr::startDsdPhase1( STEP_CODE_DATA_STRUCT & io_sc ) } // Set the steer mux - o_rc = mssSetSteerMux( iv_mbaTrgt, iv_rank, iv_mark.getCM(), false ); + o_rc = mssSetSteerMux( iv_mbaTrgt, iv_rank, iv_mark.getCM(), + iv_isEccSteer ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC"mssSetSteerMux() failed" ); |