summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.C
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/prdf/common/plat/pegasus/prdfCenMbaCeTable.C
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/prdf/common/plat/pegasus/prdfCenMbaCeTable.C')
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCeTable.C237
1 files changed, 237 insertions, 0 deletions
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
+
OpenPOWER on IntegriCloud