summaryrefslogtreecommitdiffstats
path: root/src/usr/diag
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2013-09-30 15:22:47 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-10-09 21:34:24 -0500
commit8b35a2e4125b9b5d8263a6795e7e639f604ba397 (patch)
tree85265495915f2bec17db670c01c6eea2b4f524b4 /src/usr/diag
parent94c3f08b8e91b15ab139ee62fea3996c2a032687 (diff)
downloadtalos-hostboot-8b35a2e4125b9b5d8263a6795e7e639f604ba397.tar.gz
talos-hostboot-8b35a2e4125b9b5d8263a6795e7e639f604ba397.zip
PRD: Memory CE table support
Change-Id: Ibf65bd92e9ef412876603cab63fc06861e19b7c7 RTC: 81714 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5992 Reviewed-by: Zane Shelley <zshelle@us.ibm.com> Tested-by: Jenkins Server Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/6591 Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/diag')
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfTargetServices.C2
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfTargetServices.H2
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/Membuf.rule2
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/Membuf_acts_NEST.rule16
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule32
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C3
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.C237
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.H167
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H2
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenMbaThresholds_common.C4
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenMbaUeTable.C8
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenMembuf.C120
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMembufExtraSig.H33
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C82
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H19
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfCenLogParse.C84
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfCenLogParse.H9
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfLogParse_common.C4
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfParserEnums.H12
-rwxr-xr-xsrc/usr/diag/prdf/common/prd_pegasus.mk1
20 files changed, 804 insertions, 35 deletions
diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C
index 347b5a824..ac73b98a5 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C
+++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C
@@ -286,7 +286,7 @@ uint8_t getChipLevel( TARGETING::TargetHandle_t i_target )
if ( !l_parentTarget->tryGetAttr<ATTR_EC>(o_chipLvl) )
{
PRDF_ERR( "[getChipLevel] Failed to get ATTR_EC" );
- o_chipLvl = 0xff; // Just in case
+ o_chipLvl = 0; // Just in case
}
} while (0);
diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H
index db5d3666a..2421fc144 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H
+++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H
@@ -339,7 +339,7 @@ int32_t getMbaDimm( TARGETING::TargetHandle_t i_dimmTarget, uint8_t & o_dimm );
bool isDramWidthX4(TARGETING::TargetHandle_t i_mbaTarget);
/**
- * @brief Obtain ranks per DIMM select on an MBA.
+ * @brief Obtains number of ranks (including slave ranks) per DIMM select.
* @param i_mbaTarget MBA target.
* @param i_ds DIMM select for DIMM.
* @return Number of ranks confgured per DIMM select. If internal function
diff --git a/src/usr/diag/prdf/common/plat/pegasus/Membuf.rule b/src/usr/diag/prdf/common/plat/pegasus/Membuf.rule
index 809e8f2a5..9fab60ab6 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/Membuf.rule
+++ b/src/usr/diag/prdf/common/plat/pegasus/Membuf.rule
@@ -46,6 +46,8 @@ chip Membuf
dump DUMP_CONTENT_HWSUPERNOVA;
scomlen 64;
+.include "prdfCenMembufExtraSig.H";
+
#############################################################################
# #
# ###### #
diff --git a/src/usr/diag/prdf/common/plat/pegasus/Membuf_acts_NEST.rule b/src/usr/diag/prdf/common/plat/pegasus/Membuf_acts_NEST.rule
index a7446d857..c9110be2e 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/Membuf_acts_NEST.rule
+++ b/src/usr/diag/prdf/common/plat/pegasus/Membuf_acts_NEST.rule
@@ -1330,22 +1330,10 @@ actionclass analyzeFetchMpe0_7 { funccall("AnalyzeFetchMpe0_7"); };
actionclass analyzeFetchMpe1_7 { funccall("AnalyzeFetchMpe1_7"); };
/** Analyze a fetch NCE on MBA0 */
-actionclass analyzeFetchNce0
-{
- funccall("AnalyzeFetchNce0");
- # FIXME: RTC 47289 MNFG threshold temporarily set to 32/day until we add
- # actual support in the AnalyzeFetchNce plugins.
- threshold( field(32 / day), mfg(32 / day) );
-};
+actionclass analyzeFetchNce0 { funccall("AnalyzeFetchNce0"); };
/** Analyze a fetch NCE on MBA1 */
-actionclass analyzeFetchNce1
-{
- funccall("AnalyzeFetchNce1");
- # FIXME: RTC 47289 MNFG threshold temporarily set to 32/day until we add
- # actual support in the AnalyzeFetchNce plugins.
- threshold( field(32 / day), mfg(32 / day) );
-};
+actionclass analyzeFetchNce1 { funccall("AnalyzeFetchNce1"); };
# TODO: RTC 23125 The RAS spreadsheet action is RCE is: "Threshold per rank 8/24
# make a callout of DIMM pair". Needs discussion.
diff --git a/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule b/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule
index 134282142..740879f5f 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule
+++ b/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule
@@ -247,6 +247,22 @@
capture group FirRegs;
};
+ register MBA0_MBSECCFIR_MASK_AND
+ {
+ name "MBU.MBS.ECC01.MBECCFIR_MASK_AND";
+ scomaddr 0x02011444;
+ capture group never;
+ access write_only;
+ };
+
+ register MBA0_MBSECCFIR_MASK_OR
+ {
+ name "MBU.MBS.ECC01.MBECCFIR_MASK_OR";
+ scomaddr 0x02011445;
+ capture group never;
+ access write_only;
+ };
+
register MBA0_MBSECCFIR_ACT0
{
name "MBU.MBS.ECC01.MBECCFIR_ACTION0";
@@ -297,6 +313,22 @@
capture group FirRegs;
};
+ register MBA1_MBSECCFIR_MASK_AND
+ {
+ name "MBU.MBS.ECC23.MBECCFIR_MASK_AND";
+ scomaddr 0x02011484;
+ capture group never;
+ access write_only;
+ };
+
+ register MBA1_MBSECCFIR_MASK_OR
+ {
+ name "MBU.MBS.ECC23.MBECCFIR_MASK_OR";
+ scomaddr 0x02011485;
+ capture group never;
+ access write_only;
+ };
+
register MBA1_MBSECCFIR_ACT0
{
name "MBU.MBS.ECC23.MBECCFIR_ACTION0";
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C
index caf5e6aeb..d74c5da03 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C
@@ -160,6 +160,9 @@ void addMemEccData( ExtensibleChip * i_mbaChip, STEP_CODE_DATA_STRUCT & io_sc )
// Add UE table to capture data.
mbadb->iv_ueTable.addCapData( mbaTarget, cd );
+ // Add CE table to capture data.
+ mbadb->iv_ceTable.addCapData( mbaTarget, cd );
+
// Add DRAM repairs data from hardware.
captureDramRepairsData( mbaTarget, cd );
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.C
new file mode 100644
index 000000000..e58abb65b
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.C
@@ -0,0 +1,237 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#include <prdfCenMbaCeTable.H>
+
+#include <algorithm>
+
+// Framwork includes
+#include <iipServiceDataCollector.h>
+#include <UtilHash.H>
+
+// Pegasus includes
+#include <prdfCenMarkstore.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace CE_TABLE;
+
+//------------------------------------------------------------------------------
+
+bool CenMbaCeTable::addEntry( const CenAddr & i_addr,
+ const CenSymbol & i_symbol )
+{
+ bool o_doTps = false;
+
+ TableData data ( i_addr, i_symbol.getDram(), i_symbol.getDramPins(),
+ i_symbol.getPortSlct(), i_symbol.getWiringType() );
+
+ // First, check if the entry already exists. If so, increment its count and
+ // move it to the end of the queue.
+ CeTable::iterator it = std::find( iv_table.begin(), iv_table.end(), data );
+ if ( iv_table.end() != it )
+ {
+ // Update the count
+ data.count = it->count + 1;
+
+ // Update the DRAM pins
+ data.dramPins |= it->dramPins;
+
+ // Remove the old entry
+ iv_table.erase( it );
+ }
+
+ // Add the new entry to the end of the list.
+ iv_table.push_back( data );
+
+ // Check the new entry's count for single entry threshold.
+ if ( TPS_ENTRY_COUNT_TH <= data.count )
+ {
+ o_doTps = true;
+ }
+
+ // Get number of entries in this table on the same rank as the new entry and
+ // threshold if needed.
+ if ( !o_doTps ) // no point iterating the table if o_doTps is already true
+ {
+ CenRank thisRank = data.addr.getRank();
+ uint32_t rankCount = 0;
+ for ( CeTable::iterator it = iv_table.begin();
+ it != iv_table.end(); it++ )
+ {
+ if ( it->addr.getRank() == thisRank )
+ rankCount++;
+ }
+
+ if ( TPS_RANK_ENTRY_TH <= rankCount )
+ o_doTps = true;
+ }
+
+ // Note that we intentially checked the entries-per-rank threshold before
+ // removing any entries, if the table is full. This is to catch the corner
+ // case where the oldest entry is on the same rank as the new entry.
+
+ // If the table is full, remove the oldest inactive entry
+ if ( MAX_ENTRIES < iv_table.size() )
+ {
+ for ( CeTable::iterator it = iv_table.begin();
+ it != iv_table.end(); it++ )
+ {
+ if ( !it->active )
+ {
+ iv_table.erase( it );
+ break;
+ }
+ }
+ }
+
+ // If the table is still full, all entries are active. Pop off the oldest
+ // active entry.
+ if ( MAX_ENTRIES < iv_table.size() )
+ iv_table.pop_front();
+
+ // Do TPS if the table is full.
+ if ( MAX_ENTRIES == iv_table.size() )
+ o_doTps = true;
+
+ return o_doTps;
+}
+
+//------------------------------------------------------------------------------
+
+void CenMbaCeTable::deactivateAll()
+{
+ for ( CeTable::iterator it = iv_table.begin(); it != iv_table.end(); it++ )
+ it->active = false;
+}
+
+//------------------------------------------------------------------------------
+
+void CenMbaCeTable::deactivateRank( const CenRank & i_rank )
+{
+ for ( CeTable::iterator it = iv_table.begin(); it != iv_table.end(); it++ )
+ {
+ if ( it->addr.getRank() == i_rank )
+ it->active = false;
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void CenMbaCeTable::getMnfgCounts( const CenRank & i_rank,
+ const CenSymbol & i_symbol,
+ uint32_t & o_dramCount,
+ uint32_t & o_hrCount,
+ uint32_t & o_dimmCount )
+{
+ o_dramCount = 0; o_hrCount = 0; o_dimmCount = 0;
+
+ const uint32_t dram = i_symbol.getDram();
+ const uint32_t ps = i_symbol.getPortSlct();
+ const uint32_t ds = i_rank.getDimmSlct();
+
+ for ( CeTable::iterator it = iv_table.begin(); it != iv_table.end(); it++ )
+ {
+ if ( ps != it->portSlct ) continue;
+
+ CenRank itRank = it->addr.getRank();
+
+ if ( ds == itRank.getDimmSlct() )
+ {
+ o_dimmCount++;
+
+ if ( i_rank == itRank )
+ {
+ o_hrCount++;
+
+ if ( dram == it->dram )
+ o_dramCount++;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void CenMbaCeTable::addCapData( TargetHandle_t i_mbaTrgt, CaptureData & io_cd )
+{
+ static const size_t sz_word = sizeof(CPU_WORD);
+
+ // Get the maximum capture data size and adjust the size for endianess.
+ static const size_t sz_maxData = ((MAX_SIZE+sz_word-1) / sz_word) * sz_word;
+
+ // Initialize to 0.
+ uint8_t data[sz_maxData];
+ memset( data, 0x00, sz_maxData );
+
+ size_t sz_actData = 0;
+
+ for ( CeTable::iterator it = iv_table.begin(); it != iv_table.end(); it++ )
+ {
+ uint32_t mrnk = it->addr.getRank().getMaster(); // 3-bit
+ uint32_t srnk = it->addr.getRank().getSlave(); // 3-bit
+ uint32_t svld = it->addr.getRank().isSlaveValid() ? 1 : 0; // 1-bit
+ uint32_t bnk = it->addr.getBank(); // 4-bit
+ uint32_t row = it->addr.getRow(); // 17-bit
+ uint32_t col = it->addr.getCol(); // 12-bit
+
+ uint8_t row0 = (row & 0x10000) >> 16;
+ uint8_t row1_8 = (row & 0x0ff00) >> 8;
+ uint8_t row9_16 = row & 0x000ff;
+
+ uint8_t col0_3 = (col & 0xf00) >> 8;
+ uint8_t col4_11 = col & 0x0ff;
+
+ uint8_t active = it->active ? 1 : 0;
+
+ data[sz_actData ] = it->count;
+ data[sz_actData+1] = it->type << 4; // 4 spare bits
+ data[sz_actData+2] = (active << 6) | (it->dram & 0x3f); // 1 spare bit
+ data[sz_actData+3] = it->dramPins;
+ data[sz_actData+4] = (mrnk << 5) | (srnk << 2) | (svld << 1) | row0;
+ data[sz_actData+5] = row1_8;
+ data[sz_actData+6] = row9_16;
+ data[sz_actData+7] = (bnk << 4) | col0_3;
+ data[sz_actData+8] = col4_11;
+
+ sz_actData += ENTRY_SIZE;
+ }
+
+ if ( 0 != sz_actData )
+ {
+ // Fix endianess issues with non PPC machines.
+ sz_actData = ((sz_actData + sz_word-1) / sz_word) * sz_word;
+ for ( uint32_t i = 0; i < (sz_actData/sz_word); i++ )
+ ((CPU_WORD*)data)[i] = htonl(((CPU_WORD*)data)[i]);
+
+ // Add data to capture data.
+ BIT_STRING_ADDRESS_CLASS bs ( 0, sz_actData*8, (CPU_WORD *) &data );
+ io_cd.Add( i_mbaTrgt, Util::hashString("MEM_CE_TABLE"), bs );
+ }
+}
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.H
new file mode 100644
index 000000000..64b312ce9
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.H
@@ -0,0 +1,167 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __prdfCenMbaCeTable_H
+#define __prdfCenMbaCeTable_H
+
+/** @file prdfCenMbaCeTable.H */
+
+// Framwork includes
+#include <iipCaptureData.h>
+#include <prdfParserEnums.H>
+#include <prdfPlatServices.H>
+
+// Pegasus includes
+#include <prdfCenAddress.H>
+#include <prdfCenSymbol.H>
+
+// Other includes
+#include <list>
+
+namespace PRDF
+{
+
+class CenMark;
+
+/**
+ * @brief A table of memory CEs.
+ * @note Only one of these tables will exist per MBA.
+ * @note Will be used to determine when to do a TPS procedure for Targeted
+ * Diagnostics at runtime. Will be used for FFDC only during Hostboot.
+ */
+class CenMbaCeTable
+{
+
+ private: // constants, enums
+
+ /** @brief Table size limits. */
+ enum TableTHs
+ {
+ TPS_RANK_ENTRY_TH = 8, ///< Threshold of entries per rank that
+ ///< triggers a TPS procedure
+ TPS_ENTRY_COUNT_TH = 32, ///< Entry count threshold that triggers
+ ///< a TPS procedure
+ };
+
+ public: // functions
+
+ /**
+ * @brief Will attempt to add a new entry to the table.
+ *
+ * If an entry already exists, the entry's count is incremented. Otherwise,
+ * a new entry is created. Will return TRUE if the CE triggers one of the
+ * following TPS conditions:
+ * - A single entry reaches count of TPS_ENTRY_COUNT_TH.
+ * - A rank has an entry count of TPS_RANK_ENTRY_TH.
+ * - The table is full.
+ *
+ * @param i_addr The address reporting the CE.
+ * @param i_symbol The symbol reporting the CE.
+ * @return TRUE if TPS is required, FALSE otherwise.
+ */
+ bool addEntry( const CenAddr & i_addr, const CenSymbol & i_symbol );
+
+ /**
+ * @brief Deactivates all entries in the table.
+ */
+ void deactivateAll();
+
+ /**
+ * @brief Deactivates all entries covered by a rank.
+ * @param i_rank The target rank.
+ */
+ void deactivateRank( const CenRank & i_rank );
+
+ /**
+ * @brief Iterates the entire table and returns the number of unique entries
+ * that exist for the target DRAM, half-rank, logical DIMM.
+ * @param i_rank The failing rank.
+ * @param i_symbol The failing symbol.
+ * @param o_dramCount The entry count for the target dram.
+ * @param o_hrCount The entry count for the target half-rank (per rank
+ * per port select).
+ * @param o_dimmCount The entry count for the target logical DIMM.
+ */
+ void getMnfgCounts( const CenRank & i_rank, const CenSymbol & i_symbol,
+ uint32_t & o_dramCount, uint32_t & o_hrCount,
+ uint32_t & o_dimmCount );
+
+ /**
+ * @brief Gathers all table data to be stored in capture data.
+ * @param i_mbaTrgt An MBA target.
+ * @param io_cd Capture data struct.
+ */
+ void addCapData( TARGETING::TargetHandle_t i_mbaTrgt, CaptureData & io_cd );
+
+ private: // structs, typedefs
+
+ /** @brief Individual entries of iv_table. */
+ struct TableData
+ {
+ bool active; ///< TRUE if this entry is active
+ uint8_t count; ///< Number of times this entry is detected
+ CenAddr addr; ///< Physical address of this entry
+ uint8_t dram; ///< The DRAM in which the CE was detected
+ uint8_t dramPins; ///< The failing pins of the DRAM
+ uint8_t portSlct; ///< The port select of the DRAM
+ CenSymbol::WiringType type; ///< The wiring type
+
+ /** @brief Default constructor. */
+ TableData() :
+ active(false), count(0), addr(), dram(0), dramPins(0), portSlct(0),
+ type(CenSymbol::WIRING_INVALID)
+ {}
+
+ /**
+ * @brief Constructor from components.
+ * @param i_addr The physical address of this entry.
+ * @param i_dram The DRAM in which the CE was detected
+ * @param i_dramPins The failing pins of the DRAM
+ * @param i_type The wiring type (for DRAM site locations).
+ */
+ TableData( const CenAddr & i_addr, uint8_t i_dram, uint8_t i_dramPins,
+ uint8_t i_portSlct, CenSymbol::WiringType i_type ) :
+ active(true), count(1), addr(i_addr), dram(i_dram),
+ dramPins(i_dramPins), portSlct(i_portSlct), type(i_type)
+ {}
+
+ /** An entry is equivalent if the address and DRAM match. */
+ bool operator==( const TableData & i_data ) const
+ {
+ return ( this->addr == i_data.addr && this->dram == i_data.dram );
+ }
+ };
+
+ typedef std::list<TableData> CeTable;
+
+ private: // instance variables
+
+ /** A storage container for memory fetch CE errors. */
+ CeTable iv_table;
+
+};
+
+} // end namespace PRDF
+
+#endif // __prdfCenMbaCeTable_H
+
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H
index fc6eadafa..aa40507f1 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H
@@ -37,6 +37,7 @@
// Pegasus includes
#include <prdfCenMbaTdCtlr.H>
#include <prdfCenMbaUeTable.H>
+#include <prdfCenMbaCeTable.H>
namespace PRDF
{
@@ -97,6 +98,7 @@ class CenMbaDataBundleCommon : public DataBundle
CenMbaTdCtlr iv_tdCtlr; ///< Targeted Diagnostics Controller
CenMbaUeTable iv_ueTable; ///< UE table for FFDC
+ CenMbaCeTable iv_ceTable; ///< CE table for FFDC
};
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaThresholds_common.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaThresholds_common.C
index 58b664863..8975618f0 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaThresholds_common.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaThresholds_common.C
@@ -72,13 +72,13 @@ int32_t getMnfgMemCeTh( ExtensibleChip * i_mbaChip, const CenRank & i_rank,
break;
}
- // Get number of ranks DIMM select.
+ // Get number of ranks per DIMM select.
uint8_t rankCount = getRanksPerDimm( i_mbaChip->GetChipHandle(),
i_rank.getDimmSlct() );
if ( 0 == rankCount )
{
PRDF_ERR( PRDF_FUNC "PlatServices::getRanksPerDimm() failed" );
- break;
+ o_rc = FAIL; break;
}
// Get number of allowed CEs.
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaUeTable.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaUeTable.C
index 4c8217157..0f450d9de 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaUeTable.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaUeTable.C
@@ -57,12 +57,12 @@ void CenMbaUeTable::addEntry( UE_TABLE::Type i_type, const CenAddr & i_addr )
iv_table.erase( it );
}
- // Pop off the oldest entry if the table is full.
- if ( MAX_ENTRIES == iv_table.size() )
- iv_table.pop_front();
-
// Add the new entry to the end of the list.
iv_table.push_back( data );
+
+ // Pop off the oldest entry if the table is full.
+ if ( MAX_ENTRIES < iv_table.size() )
+ iv_table.pop_front();
}
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMembuf.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMembuf.C
index f0f0c9835..124a43af2 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMembuf.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMembuf.C
@@ -41,7 +41,9 @@
#include <prdfCenMbaCaptureData.H>
#include <prdfCenMbaDataBundle.H>
#include <prdfCenMbaTdCtlr_common.H>
+#include <prdfCenMbaThresholds.H>
#include <prdfCenMembufDataBundle.H>
+#include <prdfCenMembufExtraSig.H>
#include <prdfLaneRepair.H>
using namespace TARGETING;
@@ -510,6 +512,7 @@ int32_t AnalyzeFetchNce( ExtensibleChip * i_membChip,
PRDF_ERR( PRDF_FUNC"getMbaChip() returned NULL" );
l_rc = FAIL; break;
}
+ TargetHandle_t mbaTrgt = mbaChip->GetChipHandle();
CenAddr addr;
l_rc = getCenReadAddr( i_membChip, i_mbaPos, READ_NCE_ADDR, addr );
@@ -518,15 +521,105 @@ int32_t AnalyzeFetchNce( ExtensibleChip * i_membChip,
PRDF_ERR( PRDF_FUNC"getCenReadAddr() failed" );
break;
}
+ CenRank rank = addr.getRank();
- // FIXME: RTC 47289 Need to read MBSEVR to get the symbol. There is a
- // bug in DD1.x so we can't use this register. There is a
- // workaround but is it complicated. Need to check with Ken if it
- // is ok to just callout the rank for DD1.x.
+ if ( 0x20 > getChipLevel(i_membChip->GetChipHandle()) )
+ {
+ // There is a bug in DD1.x where the value of MBSEVR cannot be
+ // trusted. The workaround is too complicated for its value so
+ // callout the rank instead.
+ MemoryMru memmru ( mbaTrgt, rank, MemoryMruData::CALLOUT_RANK );
+ i_sc.service_data->SetCallout( memmru );
+ }
+ else // DD2.0+
+ {
+ // Get the failing symbol
+ const char * reg_str = (0 == i_mbaPos) ? "MBA0_MBSEVR"
+ : "MBA1_MBSEVR";
+ SCAN_COMM_REGISTER_CLASS * reg = i_membChip->getRegister(reg_str);
+ l_rc = reg->Read();
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC"Read() failed on %s", reg_str );
+ break;
+ }
- MemoryMru memmru ( mbaChip->GetChipHandle(), addr.getRank(),
- MemoryMruData::CALLOUT_RANK );
- i_sc.service_data->SetCallout( memmru );
+ uint8_t galois = reg->GetBitFieldJustified( 40, 8 );
+ uint8_t mask = reg->GetBitFieldJustified( 32, 8 );
+
+ CenSymbol symbol = CenSymbol::fromGalois( mbaTrgt, rank, galois,
+ mask );
+ if ( !symbol.isValid() )
+ {
+ PRDF_ERR( PRDF_FUNC"Failed to create symbol: galois=0x%02x "
+ "mask=0x%02x", galois, mask );
+ break;
+ }
+
+ // Add the DIMM to the callout list
+ MemoryMru memmru ( mbaTrgt, rank, symbol );
+ i_sc.service_data->SetCallout( memmru );
+
+ // Add to CE table
+ CenMbaDataBundle * mbadb = getMbaDataBundle( mbaChip );
+ bool doTps = mbadb->iv_ceTable.addEntry( addr, symbol );
+
+ if ( mfgMode() )
+ {
+ // Get the MNFG CE thresholds.
+ uint16_t dramTh, hrTh, dimmTh;
+ l_rc = getMnfgMemCeTh( mbaChip, rank, dramTh, hrTh, dimmTh );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC"getMnfgMemCeTh() failed: rank=m%ds%d",
+ rank.getMaster(), rank.getSlave() );
+ break;
+ }
+
+ // Get counts from CE table.
+ uint32_t dramCount, hrCount, dimmCount;
+ mbadb->iv_ceTable.getMnfgCounts( addr.getRank(), symbol,
+ dramCount, hrCount,
+ dimmCount );
+
+ if ( dramTh < dramCount )
+ {
+ i_sc.service_data->SetErrorSig( PRDFSIG_MnfgDramCte );
+ i_sc.service_data->AddSignatureList( mbaTrgt,
+ PRDFSIG_MnfgDramCte );
+ i_sc.service_data->SetServiceCall();
+ }
+
+ if ( hrTh < hrCount )
+ {
+ i_sc.service_data->SetErrorSig( PRDFSIG_MnfgHrCte );
+ i_sc.service_data->AddSignatureList( mbaTrgt,
+ PRDFSIG_MnfgHrCte );
+ i_sc.service_data->SetServiceCall();
+ }
+
+ if ( dimmTh < dimmCount )
+ {
+ i_sc.service_data->SetErrorSig( PRDFSIG_MnfgDimmCte );
+ i_sc.service_data->AddSignatureList( mbaTrgt,
+ PRDFSIG_MnfgDimmCte );
+ i_sc.service_data->SetServiceCall();
+ }
+ }
+
+ // Initiate a TPS procedure, if needed.
+ if ( doTps )
+ {
+ l_rc = mbadb->iv_tdCtlr.handleTdEvent( i_sc, rank,
+ CenMbaTdCtlrCommon::TPS_EVENT );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC"handleTdEvent() failed: rank=m%ds%d",
+ rank.getMaster(), rank.getSlave() );
+ break;
+ }
+ }
+ }
} while (0);
@@ -645,16 +738,27 @@ int32_t AnalyzeFetchUe( ExtensibleChip * i_membChip,
PRDF_ERR( PRDF_FUNC"getCenReadAddr() failed" );
break;
}
+ CenRank rank = addr.getRank();
// Add address to UE table.
CenMbaDataBundle * mbadb = getMbaDataBundle( mbaChip );
mbadb->iv_ueTable.addEntry( UE_TABLE::FETCH_UE, addr );
// Callout the rank.
- MemoryMru memmru ( mbaChip->GetChipHandle(), addr.getRank(),
+ MemoryMru memmru ( mbaChip->GetChipHandle(), rank,
MemoryMruData::CALLOUT_RANK );
i_sc.service_data->SetCallout( memmru );
+ // Add a TPS request to the TD queue.
+ l_rc = mbadb->iv_tdCtlr.handleTdEvent( i_sc, rank,
+ CenMbaTdCtlrCommon::TPS_EVENT );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC"handleTdEvent() failed: rank=m%ds%d",
+ rank.getMaster(), rank.getSlave() );
+ break;
+ }
+
} while (0);
// Add ECC capture data for FFDC.
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMembufExtraSig.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMembufExtraSig.H
new file mode 100644
index 000000000..fed2caeca
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMembufExtraSig.H
@@ -0,0 +1,33 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMembufExtraSig.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2013 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __prdfCenMembufExtraSig_H
+#define __prdfCenMembufExtraSig_H
+
+#include <prdrSignatures.H>
+
+PRDR_ERROR_SIGNATURE(MnfgDramCte, 0x44440000, "", "MNFG per DRAM CTE");
+PRDR_ERROR_SIGNATURE(MnfgHrCte, 0x44440001, "", "MNFG per half-rank CTE");
+PRDR_ERROR_SIGNATURE(MnfgDimmCte, 0x44440002, "", "MNFG per DIMM CTE");
+
+#endif // __prdfCenMembufExtraSig_H
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
index 04a4aea3d..dfffc0377 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
@@ -33,6 +33,19 @@ namespace PRDF
using namespace PlatServices;
+static const uint8_t symbol2Galois[] =
+{
+ 0x80, 0xa0, 0x90, 0xf0, 0x08, 0x0a, 0x09, 0x0f, // symbols 0- 7
+ 0x98, 0xda, 0xb9, 0x7f, 0x91, 0xd7, 0xb2, 0x78, // symbols 8-15
+ 0x28, 0xea, 0x49, 0x9f, 0x9a, 0xd4, 0xbd, 0x76, // symbols 16-23
+ 0x60, 0xb0, 0xc0, 0x20, 0x06, 0x0b, 0x0c, 0x02, // symbols 24-31
+ 0xc6, 0xfb, 0x1c, 0x42, 0xca, 0xf4, 0x1d, 0x46, // symbols 32-39
+ 0xd6, 0x8b, 0x3c, 0xc2, 0xcb, 0xf3, 0x1f, 0x4e, // symbols 40-47
+ 0xe0, 0x10, 0x50, 0xd0, 0x0e, 0x01, 0x05, 0x0d, // symbols 48-55
+ 0x5e, 0x21, 0xa5, 0x3d, 0x5b, 0x23, 0xaf, 0x3e, // symbols 56-63
+ 0xfe, 0x61, 0x75, 0x5d, 0x51, 0x27, 0xa2, 0x38, // symbols 64-71
+};
+
//##############################################################################
// class CenSymbol
//##############################################################################
@@ -48,7 +61,8 @@ CenSymbol CenSymbol::fromSymbol( TargetHandle_t i_mba, const CenRank & i_rank,
{
if ( TYPE_MBA != getTargetType(i_mba) )
{
- PRDF_ERR( PRDF_FUNC"i_mba is invalid" );
+ PRDF_ERR( PRDF_FUNC"i_mba is invalid: i_mba=0x%08x",
+ getHuid(i_mba) );
break;
}
@@ -124,9 +138,60 @@ CenSymbol CenSymbol::fromDimmDq( TargetHandle_t i_mba, const CenRank & i_rank,
//------------------------------------------------------------------------------
-int32_t CenSymbol::getWiringType( TARGETING::TargetHandle_t i_mba,
- const CenRank & i_rank,
- WiringType & o_type )
+CenSymbol CenSymbol::fromGalois( TargetHandle_t i_mba, const CenRank & i_rank,
+ uint8_t i_galois, uint8_t i_mask )
+{
+ #define PRDF_FUNC "[CenSymbol::fromGalois] "
+
+ CenSymbol o_symbol; // default contructor is invalid.
+
+ do
+ {
+ if ( TYPE_MBA != getTargetType(i_mba) )
+ {
+ PRDF_ERR( PRDF_FUNC"i_mba=0x%08x is invalid", getHuid(i_mba) );
+ break;
+ }
+
+ WiringType wiringType = WIRING_INVALID;
+ int32_t l_rc = getWiringType( i_mba, i_rank, wiringType );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC"getWiringType() failed" );
+ break;
+ }
+
+ // Get symbol from Galois field.
+ uint8_t symbol = SYMBOLS_PER_RANK;
+ for ( uint32_t i = 0; i < SYMBOLS_PER_RANK; i++ )
+ {
+ if ( symbol2Galois[i] == i_galois )
+ {
+ symbol = i;
+ break;
+ }
+ }
+
+ // Get pins from mask.
+ uint8_t pins = NO_SYMBOL_DQS;
+ if ( 0 != (i_mask & 0xaa) ) pins |= EVEN_SYMBOL_DQ;
+ if ( 0 != (i_mask & 0x55) ) pins |= ODD_SYMBOL_DQ;
+
+ // Create symbol object.
+ o_symbol = CenSymbol ( i_mba, i_rank, wiringType, symbol, pins,
+ isDramWidthX4(i_mba) );
+
+ } while (0);
+
+ return o_symbol;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+int32_t CenSymbol::getWiringType( TargetHandle_t i_mba, const CenRank & i_rank,
+ WiringType & o_type )
{
int32_t o_rc = SUCCESS;
@@ -138,6 +203,15 @@ int32_t CenSymbol::getWiringType( TARGETING::TargetHandle_t i_mba,
//------------------------------------------------------------------------------
+uint8_t CenSymbol::getDramPins() const
+{
+ uint32_t spd = iv_x4Dram ? SYMBOLS_PER_X4DRAM : SYMBOLS_PER_X8DRAM;
+
+ return iv_pins << (((spd - 1) - (iv_symbol % spd)) * DQS_PER_SYMBOL);
+}
+
+//------------------------------------------------------------------------------
+
uint8_t CenSymbol::cenDq2Symbol( uint8_t i_cenDq, uint8_t i_ps )
{
uint8_t sym = SYMBOLS_PER_RANK;
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
index e0d3e4659..d6f12864c 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
@@ -122,6 +122,19 @@ class CenSymbol
uint8_t i_portSlct );
/**
+ * @brief Creates a CenSymbol from a Galois field.
+ * @param i_mba The MBA target.
+ * @param i_rank The rank this symbol is on.
+ * @param i_galois The Galois field.
+ * @param i_mask The bit mask.
+ * @return A CenSymbol. Must call isValid() to determine if the function was
+ * successful in creating a valid object.
+ */
+ static CenSymbol fromGalois( TARGETING::TargetHandle_t i_mba,
+ const CenRank & i_rank, uint8_t i_galois,
+ uint8_t i_mask = 0 );
+
+ /**
* @brief Returns the dimm's wiring type.
* @param i_mba MBA Target handle.
* @param i_rank The rank this symbol is on.
@@ -141,7 +154,7 @@ class CenSymbol
/** @return This symbol's numerical value (0-71). */
uint8_t getSymbol() const { return iv_symbol; }
- /** @return The bad pins associated with this symbol. */
+ /** @return The bad pins associated with this symbol (2-bits). */
uint8_t getPins() const { return iv_pins; }
/** @return The even Centaur DQ of this symbol. */
@@ -153,6 +166,10 @@ class CenSymbol
/** @return The DRAM index for this symbol. */
uint8_t getDram() const { return symbol2Dram( iv_symbol, iv_x4Dram ); }
+ /** @return The bad pins associated with this symbol in relation to the DRAM
+ * (x4 mode is 4-bits, x8 mode is 8-bits,). */
+ uint8_t getDramPins() const;
+
/** @return rank associated with this symbol. */
CenRank getRank() const { return iv_rank; };
diff --git a/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C b/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C
index 21647ccea..7c02ceeac 100644
--- a/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C
+++ b/src/usr/diag/prdf/common/plugins/prdfCenLogParse.C
@@ -218,6 +218,90 @@ bool parseMemUeTable( uint8_t * i_buffer, uint32_t i_buflen,
//------------------------------------------------------------------------------
+bool parseMemCeTable( uint8_t * i_buffer, uint32_t i_buflen,
+ ErrlUsrParser & i_parser )
+{
+ using namespace CE_TABLE;
+
+ bool rc = true;
+
+ if ( NULL == i_buffer ) return false; // Something failed in parser.
+
+ const uint32_t entries = i_buflen / ENTRY_SIZE;
+
+ i_parser.PrintNumber( " MEM_CE_TABLE", "%d", entries );
+
+ const char * hh = " A Count Type";
+ const char * hd = "Rank Bank Row Column DRAM Pins";
+ i_parser.PrintString( hh, hd );
+ hh = " - ----- -------------";
+ hd = "---- ---- ------- ------ ---- ----";
+ i_parser.PrintString( hh, hd );
+
+ for ( uint32_t i = 0; i < entries; i++ )
+ {
+ uint32_t idx = i * ENTRY_SIZE;
+
+ uint32_t count = i_buffer[idx ]; // 8-bit
+ uint32_t type = i_buffer[idx+1] >> 4; // 4-bit
+
+ uint8_t active = (i_buffer[idx+2] >> 6) & 0x1; // 1-bit
+ uint8_t dram = i_buffer[idx+2] & 0x3f; // 6-bit
+
+ uint32_t dramPins = i_buffer[idx+3]; // 8-bit
+
+ uint32_t mrnk = (i_buffer[idx+4] >> 5) & 0x7; // 3-bit
+ uint32_t srnk = (i_buffer[idx+4] >> 2) & 0x7; // 3-bit
+ uint32_t svld = (i_buffer[idx+4] >> 1) & 0x1; // 1-bit
+
+ uint32_t row0 = i_buffer[idx+4] & 0x1;
+ uint32_t row1_8 = i_buffer[idx+5];
+ uint32_t row9_16 = i_buffer[idx+6];
+ uint32_t row = (row0 << 16) | (row1_8 << 8) | row9_16; // 17-bit
+
+ uint32_t bnk = i_buffer[idx+7] >> 4; // 4-bit
+
+ uint32_t col0_3 = i_buffer[idx+7] & 0xf;
+ uint32_t col4_11 = i_buffer[idx+8];
+ uint32_t col = (col0_3 << 8) | col4_11; // 12-bit
+
+ char active_char = ( 1 == active ) ? 'Y':'N';
+
+ const char * type_str = "UNKNOWN "; // 13 characters
+ switch ( type )
+ {
+ // TODO: RTC 67358 card type will be determined from wiring type.
+ // Also there will be string representation for dram.
+ // Currently we will use integer number.
+ default: ;
+ }
+
+ char rank_str[DATA_SIZE]; // 4 characters
+ if ( 1 == svld )
+ {
+ snprintf( rank_str, DATA_SIZE, "m%ds%d", mrnk, srnk );
+ }
+ else
+ {
+ snprintf( rank_str, DATA_SIZE, "m%d ", mrnk );
+ }
+
+ char header[HEADER_SIZE] = { '\0' };
+ snprintf( header, HEADER_SIZE, " %c 0x%02x %s", active_char,
+ count, type_str );
+
+ char data[DATA_SIZE] = { '\0' };
+ snprintf( data, DATA_SIZE, "%s 0x%01x 0x%05x 0x%03x %2d 0x%02x",
+ rank_str, bnk, row, col, dram, dramPins );
+
+ i_parser.PrintString( header, data );
+ }
+
+ return rc;
+}
+
+//------------------------------------------------------------------------------
+
bool parseDramRepairsData( uint8_t * i_buffer, uint32_t i_buflen,
ErrlUsrParser & i_parser )
{
diff --git a/src/usr/diag/prdf/common/plugins/prdfCenLogParse.H b/src/usr/diag/prdf/common/plugins/prdfCenLogParse.H
index c2695b10d..8a7c49391 100644
--- a/src/usr/diag/prdf/common/plugins/prdfCenLogParse.H
+++ b/src/usr/diag/prdf/common/plugins/prdfCenLogParse.H
@@ -62,6 +62,15 @@ bool parseMemUeTable( uint8_t * i_buffer, uint32_t i_buflen,
ErrlUsrParser & i_parser );
/**
+ * @brief Parses Memory CE table.
+ * @param i_buffer The data buffer.
+ * @param i_buflen The buffer length.
+ * @param i_parser The error log parser.
+ */
+bool parseMemCeTable( uint8_t * i_buffer, uint32_t i_buflen,
+ ErrlUsrParser & i_parser );
+
+/**
* @brief Parses DRAM Repairs data (actual chip/symbol marks and DRAM repairs in
* hardware).
* @param i_buffer The data buffer.
diff --git a/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C b/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C
index 3a39eb90b..71c693cb7 100644
--- a/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C
+++ b/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C
@@ -317,6 +317,10 @@ bool parseCaptureData( void * i_buffer, uint32_t i_buflen,
{
parseMemUeTable( sigData, sigDataSize, i_parser );
}
+ else if ( Util::hashString("MEM_CE_TABLE") == sigId )
+ {
+ parseMemCeTable( sigData, sigDataSize, i_parser );
+ }
else if ( Util::hashString("DRAM_REPAIRS_DATA") == sigId )
{
parseDramRepairsData( sigData, sigDataSize, i_parser );
diff --git a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
index d720639f8..4d40e287b 100644
--- a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
+++ b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
@@ -70,6 +70,18 @@ namespace UE_TABLE
} // namespace UE_TABLE
+namespace CE_TABLE
+{
+ enum
+ {
+ MAX_ENTRIES = 32, ///< Maximum number of entries allow in table.
+ ENTRY_SIZE = 9, ///< Number of bytes per entry.
+
+ MAX_SIZE = MAX_ENTRIES * ENTRY_SIZE, ///< Maximum table size.
+ };
+
+} // namespace UE_TABLE
+
namespace DQ_BITMAP
{
enum
diff --git a/src/usr/diag/prdf/common/prd_pegasus.mk b/src/usr/diag/prdf/common/prd_pegasus.mk
index 9843751be..5d7577c59 100755
--- a/src/usr/diag/prdf/common/prd_pegasus.mk
+++ b/src/usr/diag/prdf/common/prd_pegasus.mk
@@ -44,6 +44,7 @@ prd_pegasus_specific = \
prdfCenAddress.o \
prdfCenDqBitmap.o \
prdfCenMbaCaptureData.o \
+ prdfCenMbaCeTable.o \
prdfCenMbaTdCtlr.o \
prdfCenMbaTdCtlr_common.o \
prdfCenMbaThresholds_common.o \
OpenPOWER on IntegriCloud