summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfTargetServices.C60
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfTargetServices.H14
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C86
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H7
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C148
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C91
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H5
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfCenLogParse.C18
-rwxr-xr-xsrc/usr/diag/prdf/common/plugins/prdfDramRepairUsrData.H13
-rw-r--r--src/usr/diag/prdf/plat/pegasus/prdfCenMbaTdCtlr.C6
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" );
OpenPOWER on IntegriCloud