summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2013-05-05 16:39:07 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-06-11 09:10:52 -0500
commitaad40c5ff3cfea7c2901a2f96f6fe4c2c8568f9b (patch)
treeeb377b4aba02b8c13451f81bd189ddeacdf95aa8 /src/usr/diag/prdf
parent3c953d5b070d51e9e246a4cf74d540620efafd2f (diff)
downloadtalos-hostboot-aad40c5ff3cfea7c2901a2f96f6fe4c2c8568f9b.tar.gz
talos-hostboot-aad40c5ff3cfea7c2901a2f96f6fe4c2c8568f9b.zip
PRD: simplified interface for [g|s]etBadDqBitmap functions
Change-Id: Id3ce782ab0a523affff3018445e521bec62df2e3 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4371 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: Zane Shelley <zshelle@us.ibm.com> Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4933
Diffstat (limited to 'src/usr/diag/prdf')
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/iipCaptureData.h26
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/register/prdfCaptureData.C14
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C74
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H32
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C11
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdf_ras_services.C1
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H10
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C257
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H140
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C3
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C23
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H18
-rwxr-xr-xsrc/usr/diag/prdf/common/prd_pegasus.mk1
-rw-r--r--src/usr/diag/prdf/plat/pegasus/prdfDramRepairs.C74
14 files changed, 545 insertions, 139 deletions
diff --git a/src/usr/diag/prdf/common/framework/register/iipCaptureData.h b/src/usr/diag/prdf/common/framework/register/iipCaptureData.h
index bcf4c7ad2..5f9316fac 100755
--- a/src/usr/diag/prdf/common/framework/register/iipCaptureData.h
+++ b/src/usr/diag/prdf/common/framework/register/iipCaptureData.h
@@ -82,6 +82,32 @@
#include <prdfPlatServices.H>
#include <functional> // @jl04 a Needed for the unary function in new predicate.
+#ifdef __HOSTBOOT_MODULE
+
+ // FIXME: RTC 73204 was opened to add support for these in hostboot. They will
+ // need to be removed once the issue has been resolved.
+ #ifndef htonl
+ #define htonl(foo) (foo)
+ #endif
+
+ #ifndef htons
+ #define htons(foo) (foo)
+ #endif
+
+ #ifndef ntohl
+ #define ntohl(foo) (foo)
+ #endif
+
+ #ifndef ntohs
+ #define ntohs(foo) (foo)
+ #endif
+
+#else
+
+ #include <netinet/in.h>
+
+#endif
+
namespace PRDF
{
diff --git a/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C b/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C
index 1c4c2219f..0431cf87e 100755
--- a/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C
+++ b/src/usr/diag/prdf/common/framework/register/prdfCaptureData.C
@@ -29,20 +29,6 @@
// Includes
//----------------------------------------------------------------------
-#ifdef __HOSTBOOT_MODULE
-
-// For hostboot, these are no-ops
-#define htonl(foo) (foo)
-#define htons(foo) (foo)
-#define ntohl(foo) (foo)
-#define ntohs(foo) (foo)
-
-#else
-
-// for hton funcs.
-#include <netinet/in.h>
-
-#endif
#include <iipbits.h>
#include <prdfHomRegisterAccess.H> // dg06a
#include <prdfScomRegister.H>
diff --git a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
index 140beebbd..654c4b4a8 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
+++ b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
@@ -38,7 +38,7 @@
#include <prdfErrlUtil.H>
#include <prdfCenAddress.H>
-#include <prdfCenConst.H>
+#include <prdfCenDqBitmap.H>
#include <dimmBadDqBitmapFuncs.H> // for dimm[S|G]etBadDqBitmap()
@@ -244,52 +244,72 @@ int32_t erepairFirIsolation(TargetHandle_t i_rxBusTgt)
//## Memory specific functions
//##############################################################################
-int32_t getBadDqBitmap( TargetHandle_t i_mbaTarget, const uint8_t i_portSlct,
- const uint8_t i_dimmSlct, const uint8_t i_rankSlct,
- uint8_t (&o_data)[DIMM_DQ_RANK_BITMAP_SIZE] )
+int32_t getBadDqBitmap( TargetHandle_t i_mba, const CenRank & i_rank,
+ CenDqBitmap & o_bitmap )
{
+ #define PRDF_FUNC "[PlatServices::getBadDqBitmap] "
+
int32_t o_rc = SUCCESS;
- errlHndl_t errl = NULL;
+ uint8_t data[PORT_SLCT_PER_MBA][DIMM_DQ_RANK_BITMAP_SIZE];
- PRD_FAPI_TO_ERRL( errl, dimmGetBadDqBitmap, getFapiTarget(i_mbaTarget),
- i_portSlct, i_dimmSlct, i_rankSlct, o_data );
+ for ( int32_t ps = 0; ps < PORT_SLCT_PER_MBA; ps++ )
+ {
+ errlHndl_t errl = NULL;
+ PRD_FAPI_TO_ERRL( errl, dimmGetBadDqBitmap, getFapiTarget(i_mba),
+ ps, i_rank.getDimmSlct(), i_rank.getRankSlct(),
+ data[ps] );
+ if ( NULL != errl )
+ {
+ PRDF_ERR( PRDF_FUNC"dimmGetBadDqBitmap() failed: MBA=0x%08x "
+ "ps=%d ds=%d rs=%d", getHuid(i_mba), ps,
+ i_rank.getDimmSlct(), i_rank.getRankSlct() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
+ }
- if ( NULL != errl )
+ if ( SUCCESS == o_rc )
{
- PRDF_ERR( "[PlatServices::getBadDqBitmap] dimmGetBadDqBitmap() failed. "
- "HUID: 0x%08x port: %d DIMM: %d rank: %d",
- getHuid(i_mbaTarget), i_portSlct, i_dimmSlct, i_rankSlct );
- PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
- o_rc = FAIL;
+ o_bitmap = CenDqBitmap ( i_mba, i_rank, data );
}
return o_rc;
+
+ #undef PRDF_FUNC
}
//------------------------------------------------------------------------------
-int32_t setBadDqBitmap( TargetHandle_t i_mbaTarget, const uint8_t i_portSlct,
- const uint8_t i_dimmSlct, const uint8_t i_rankSlct,
- const uint8_t (&i_data)[DIMM_DQ_RANK_BITMAP_SIZE] )
+int32_t setBadDqBitmap( TargetHandle_t i_mba, const CenRank & i_rank,
+ const CenDqBitmap & i_bitmap )
{
- int32_t o_rc = SUCCESS;
+ #define PRDF_FUNC "[PlatServices::setBadDqBitmap] "
- errlHndl_t errl = NULL;
+ int32_t o_rc = SUCCESS;
- PRD_FAPI_TO_ERRL( errl, dimmSetBadDqBitmap, getFapiTarget(i_mbaTarget),
- i_portSlct, i_dimmSlct, i_rankSlct, i_data );
+ const uint8_t (&data)[PORT_SLCT_PER_MBA][DIMM_DQ_RANK_BITMAP_SIZE]
+ = i_bitmap.getData();
- if ( NULL != errl )
+ for ( int32_t ps = 0; ps < PORT_SLCT_PER_MBA; ps++ )
{
- PRDF_ERR( "[PlatServices::getBadDqBitmap] dimmSetBadDqBitmap() failed. "
- "HUID: 0x%08x ps: %d ds: %d rs: %d",
- getHuid(i_mbaTarget), i_portSlct, i_dimmSlct, i_rankSlct );
- PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
- o_rc = FAIL;
+ errlHndl_t errl = NULL;
+ PRD_FAPI_TO_ERRL( errl, dimmSetBadDqBitmap, getFapiTarget(i_mba),
+ ps, i_rank.getDimmSlct(), i_rank.getRankSlct(),
+ data[ps] );
+ if ( NULL != errl )
+ {
+ PRDF_ERR( PRDF_FUNC"dimmSetBadDqBitmap() failed: MBA=0x%08x "
+ "ps=%d ds=%d rs=%d", getHuid(i_mba), ps,
+ i_rank.getDimmSlct(), i_rank.getRankSlct() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ }
}
return o_rc;
+
+ #undef PRDF_FUNC
}
//------------------------------------------------------------------------------
@@ -367,7 +387,6 @@ int32_t mssGetSteerMux( TargetHandle_t i_mbaTarget, uint8_t i_rank,
}
return o_rc;
-
}
//------------------------------------------------------------------------------
@@ -393,7 +412,6 @@ int32_t mssSetSteerMux( TargetHandle_t i_mbaTarget, uint8_t i_rank,
}
return o_rc;
-
}
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H
index 50e27a8d0..1cccfa675 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H
+++ b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H
@@ -38,6 +38,7 @@
#include <prdfTargetServices.H> // must include all common targeting code
+#include <prdfCenConst.H>
#include <prdfTimer.H>
#include <dimmConsts.H> // for DIMM_DQ_RANK_BITMAP_SIZE
@@ -54,6 +55,7 @@
namespace PRDF
{
+class CenDqBitmap;
class CenRank;
namespace PlatServices
@@ -190,34 +192,24 @@ int32_t erepairFirIsolation(TARGETING::TargetHandle_t i_rxBusTgt);
//##############################################################################
/**
- * @brief Reads the bad DQ bitmap attribute.
+ * @brief Reads the bad DQ bitmap attribute for both ports of the target rank.
* @param i_mbaTarget A MBA target.
- * @param i_portSlct Port select (0-1).
- * @param i_dimmSlct DIMM select (0-1).
- * @param i_rankSlct Rank select (0-3).
- * @param o_data The return data array.
+ * @param i_rank Target rank.
+ * @param o_bitmap DQ bitmap container.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
-int32_t getBadDqBitmap( TARGETING::TargetHandle_t i_mbaTarget,
- const uint8_t i_portSlct,
- const uint8_t i_dimmSlct,
- const uint8_t i_rankSlct,
- uint8_t (&o_data)[DIMM_DQ_RANK_BITMAP_SIZE] );
+int32_t getBadDqBitmap( TARGETING::TargetHandle_t i_mba, const CenRank & i_rank,
+ CenDqBitmap & o_bitmap );
/**
- * @brief Writes the bad DQ bitmap attribute.
+ * @brief Writes the bad DQ bitmap attribute for both ports of the target rank.
* @param i_mbaTarget A MBA target.
- * @param i_portSlct Port select (0-1).
- * @param i_dimmSlct DIMM select (0-1).
- * @param i_rankSlct Rank select (0-3).
- * @param i_data The input data array.
+ * @param i_rank Target rank.
+ * @param i_bitmap DQ bitmap container.
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
-int32_t setBadDqBitmap( TARGETING::TargetHandle_t i_mbaTarget,
- const uint8_t i_portSlct,
- const uint8_t i_dimmSlct,
- const uint8_t i_rankSlct,
- const uint8_t (&i_data)[DIMM_DQ_RANK_BITMAP_SIZE] );
+int32_t setBadDqBitmap( TARGETING::TargetHandle_t i_mba, const CenRank & i_rank,
+ const CenDqBitmap & i_bitmap );
/**
* @brief Invokes the get mark store hardware procedure.
diff --git a/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C b/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C
index 74fb4f752..f822fb992 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C
+++ b/src/usr/diag/prdf/common/framework/service/prdfServiceDataCollector.C
@@ -30,17 +30,6 @@
//------------------------------------------------------------------------------
#include <string.h> // for memcpy
#define prdfServiceDataCollector_C
-
-#ifdef __HOSTBOOT_MODULE
- // these are no-ops in HB
- #define htonl(foo) (foo)
- #define htons(foo) (foo)
- #define ntohl(foo) (foo)
- #define ntohs(foo) (foo)
-#else
- #include <netinet/in.h>
-#endif
-
#include <iipServiceDataCollector.h>
#include <prdfPlatServices.H>
#include <prdfTrace.H>
diff --git a/src/usr/diag/prdf/common/framework/service/prdf_ras_services.C b/src/usr/diag/prdf/common/framework/service/prdf_ras_services.C
index f67bc886f..48b60467a 100755
--- a/src/usr/diag/prdf/common/framework/service/prdf_ras_services.C
+++ b/src/usr/diag/prdf/common/framework/service/prdf_ras_services.C
@@ -49,7 +49,6 @@
#include <iipSystem.h> //For RemoveStoppedChips
#ifdef __HOSTBOOT_MODULE
- #define htonl(foo) (foo) // no-op for HB
#include <stdio.h>
#else
#include <srcisrc.H>
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H
index b4f1806d5..8d31d928b 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H
@@ -37,13 +37,17 @@ namespace PRDF
enum
{
- PORT_SLCT_PER_MBA = 2,
- MAX_DIMM_SLCT_PER_MBA = 2,
+ PORT_SLCT_PER_MBA = 2,
+ MAX_DIMM_SLCT_PER_MBA = 2,
MAX_RANKS_PER_DIMM_SLCT = 4,
- MAX_RANKS_PER_MBA = MAX_DIMM_SLCT_PER_MBA * MAX_RANKS_PER_DIMM_SLCT,
+ MAX_RANKS_PER_MBA = MAX_DIMM_SLCT_PER_MBA * MAX_RANKS_PER_DIMM_SLCT,
SYMBOLS_PER_RANK = 72,
DQS_PER_DIMM = 72,
+
+ SYMBOLS_PER_BYTE = 4,
+ DQS_PER_SYMBOL = 2,
+ DQS_PER_BYTE = SYMBOLS_PER_BYTE * DQS_PER_SYMBOL,
};
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C
new file mode 100644
index 000000000..8b0e920d8
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C
@@ -0,0 +1,257 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.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 */
+
+/** @file prdfCenDqBitmap.C */
+
+#include <prdfCenDqBitmap.H>
+
+#include <UtilHash.H>
+#include <iipServiceDataCollector.h>
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+int32_t CenDqBitmap::badDqs( uint8_t i_portSlct, bool & o_badDqs ) const
+{
+ #define PRDF_FUNC "[CenDqBitmap::badDqs] "
+
+ int32_t o_rc = SUCCESS;
+
+ o_badDqs = false;
+
+ do
+ {
+ if ( PORT_SLCT_PER_MBA <= i_portSlct )
+ {
+ PRDF_ERR( PRDF_FUNC"Invalid parameter: i_portSlct=%d", i_portSlct );
+ o_rc = FAIL; break;
+ }
+
+ for ( uint32_t j = 0; j < DIMM_DQ_RANK_BITMAP_SIZE; j++ )
+ {
+ if ( 0 != iv_data[i_portSlct][j] )
+ {
+ o_badDqs = true;
+ break;
+ }
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+int32_t CenDqBitmap::setDq( uint8_t i_dq, uint8_t i_portSlct )
+{
+ #define PRDF_FUNC "[CenDqBitmap::setDq] "
+
+ int32_t o_rc = SUCCESS;
+
+ do
+ {
+ if ( DQS_PER_DIMM <= i_dq )
+ {
+ PRDF_ERR( PRDF_FUNC"Invalid parameter: i_dq=%d", i_dq );
+ o_rc = FAIL; break;
+ }
+
+ if ( PORT_SLCT_PER_MBA <= i_portSlct )
+ {
+ PRDF_ERR( PRDF_FUNC"Invalid parameter: i_portSlct=%d", i_portSlct );
+ o_rc = FAIL; break;
+ }
+
+ uint8_t byteIdx = i_dq / DQS_PER_BYTE;
+ uint8_t bitIdx = i_dq % DQS_PER_BYTE;
+
+ uint32_t shift = (DQS_PER_BYTE-1) - bitIdx; // 0-7
+ iv_data[i_portSlct][byteIdx] |= 0x01 << shift;
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+int32_t CenDqBitmap::setSymbol( uint8_t i_symbol, uint8_t i_pins )
+{
+ #define PRDF_FUNC "[CenDqBitmap::setSymbol] "
+
+ int32_t o_rc = SUCCESS;
+
+ do
+ {
+ uint8_t evenDq = CenSymbol::symbol2CenDq( i_symbol );
+ uint8_t portSlct = CenSymbol::symbol2PortSlct( i_symbol );
+ if ( DQS_PER_DIMM <= evenDq || PORT_SLCT_PER_MBA <= portSlct )
+ {
+ PRDF_ERR( PRDF_FUNC"Invalid parameter: i_symbol=%d", i_symbol );
+ o_rc = FAIL; break;
+ }
+
+ uint8_t byteIdx = evenDq / DQS_PER_BYTE;
+ uint8_t bitIdx = evenDq % DQS_PER_BYTE;
+
+ i_pins &= 0x3; // limit to 2 bits
+ uint32_t shift = (((DQS_PER_BYTE-1) - bitIdx) % 2) * 2; // 0,2,4,6
+ iv_data[portSlct][byteIdx] |= i_pins << shift;
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+int32_t CenDqBitmap::setDram( uint8_t i_symbol, uint8_t i_pins )
+{
+ #define PRDF_FUNC "[CenDqBitmap::setDram] "
+
+ int32_t o_rc = SUCCESS;
+
+ do
+ {
+ uint8_t evenDq = CenSymbol::symbol2CenDq( i_symbol );
+ uint8_t portSlct = CenSymbol::symbol2PortSlct( i_symbol );
+ if ( DQS_PER_DIMM <= evenDq || PORT_SLCT_PER_MBA <= portSlct )
+ {
+ PRDF_ERR( PRDF_FUNC"Invalid parameter: i_symbol=%d", i_symbol );
+ o_rc = FAIL; break;
+ }
+
+ uint8_t byteIdx = evenDq / DQS_PER_BYTE;
+ uint8_t bitIdx = evenDq % DQS_PER_BYTE;
+
+ if ( isDramWidthX4(iv_mba) )
+ {
+ i_pins &= 0xf; // limit to 4 bits
+ uint32_t shift = (((DQS_PER_BYTE-1) - bitIdx) % 4) * 4; // 0,4
+ iv_data[portSlct][byteIdx] |= i_pins << shift;
+ }
+ else
+ {
+ i_pins &= 0xff; // limit to 8 bits
+ iv_data[portSlct][byteIdx] |= i_pins;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+int32_t CenDqBitmap::setDramSpare( uint8_t i_portSlct, uint8_t i_pins )
+{
+ #define PRDF_FUNC "[CenDqBitmap::setDramSpare] "
+
+ int32_t o_rc = SUCCESS;
+
+ do
+ {
+ if ( PORT_SLCT_PER_MBA <= i_portSlct )
+ {
+ PRDF_ERR( PRDF_FUNC"Invalid parameter: i_portSlct=%d", i_portSlct );
+ 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;
+ }
+ else
+ {
+ i_pins &= 0xff; // limit to 8 bits
+ iv_data[i_portSlct][DIMM_DQ_RANK_BITMAP_SIZE-1] |= i_pins;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+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);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+void CenDqBitmap::getCaptureData( CaptureData & o_cd ) const
+{
+ uint8_t rank = iv_rank.flatten();
+ size_t sz_rank = sizeof(rank);
+
+ size_t sz_capData = sz_rank + sizeof(iv_data);
+
+ // Adjust the size for endianess.
+ const size_t sz_word = sizeof(CPU_WORD);
+ sz_capData = ((sz_capData + sz_word-1) / sz_word) * sz_word;
+
+ uint8_t capData[sz_capData];
+ memset( capData, 0x00, sz_capData );
+
+ capData[0] = rank;
+ memcpy( &capData[1], iv_data, sizeof(iv_data) );
+
+ // Fix endianess issues with non PPC machines.
+ for ( uint32_t i = 0; i < (sz_capData/sz_word); i++ )
+ ((CPU_WORD*)capData)[i] = htonl(((CPU_WORD*)capData)[i]);
+
+ BIT_STRING_ADDRESS_CLASS bs ( 0, sz_capData*8, (CPU_WORD *) &capData );
+ o_cd.Add( iv_mba, Util::hashString("MBA_BAD_DQ_BITMAP"), bs );
+}
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H
new file mode 100644
index 000000000..834c3bb01
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H
@@ -0,0 +1,140 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.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 */
+
+/** @file prdfCenDqBitmap.H */
+
+#ifndef __prdfCenDqBitmap_H
+#define __prdfCenDqBitmap_H
+
+#include <prdfPlatServices.H>
+
+#include <prdfCenAddress.H>
+#include <prdfCenConst.H>
+
+namespace PRDF
+{
+
+class CaptureData;
+
+/**
+ * @brief Container for DIMM's Centaur DQ bitmap.
+ */
+class CenDqBitmap
+{
+ public: // constructors
+
+ /** @brief Default constructor */
+ CenDqBitmap()
+ {
+ memset( iv_data, 0x00, sizeof(iv_data) );
+ }
+
+ /** @brief Constructor from components */
+ CenDqBitmap( TARGETING::TargetHandle_t i_mba, const CenRank & i_rank,
+ const uint8_t (&i_d)[PORT_SLCT_PER_MBA][DIMM_DQ_RANK_BITMAP_SIZE] ) :
+ iv_mba(i_mba), iv_rank(i_rank)
+ {
+ memcpy( iv_data, i_d, sizeof(iv_data) );
+ }
+
+ public: // functions
+
+ /**
+ * @brief Queries the given port to determine if there are any bad DQs
+ * present.
+ * @param i_portSlct The target port.
+ * @param o_badDqs TRUE if there are bad DQS present the given port,
+ * FALSE otherwise.
+ * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise.
+ */
+ int32_t badDqs( uint8_t i_portSlct, bool & o_badDqs ) const;
+
+ /**
+ * @brief Sets the specified Centaur DQ.
+ * @param i_dq The target Centaur DQ.
+ * @param i_portSlct The target port.
+ * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise.
+ */
+ int32_t setDq( uint8_t i_dq, uint8_t i_portSlct );
+
+ /**
+ * @brief Sets the specified symbol.
+ * @param i_symbol The target symbol.
+ * @param i_pins Optional 2-bit value of the symbol's pins. The default
+ * is to set both pins.
+ * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise.
+ */
+ int32_t setSymbol( uint8_t i_symbol, uint8_t i_pins = 0x3 );
+
+ /**
+ * @brief Sets the specified DRAM.
+ * @param i_symbol A symbol on the target DRAM.
+ * @param i_pins Optional 8-bit (x8 mode) or 4-bit (x4 mode) value of the
+ * DRAM's pins. The default is to set all pins.
+ * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise.
+ */
+ int32_t setDram( uint8_t i_symbol, uint8_t i_pins = 0xff );
+
+ /**
+ * @brief Sets the DRAM spare on the specified port.
+ * @param i_portSlct The target port.
+ * @param i_pins Optional 8-bit (x8 mode) or 4-bit (x4 mode) value of
+ * the DRAM's pins. The default is to set all pins.
+ * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise.
+ */
+ int32_t setDramSpare( uint8_t i_portSlct, uint8_t i_pins = 0xff );
+
+ /**
+ * @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.
+ * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise.
+ */
+ int32_t setEccSpare( uint8_t i_pins );
+
+ /**
+ * @brief Adds the bitmaps for both ports to the capture data.
+ * @param o_cd Capture data struct.
+ */
+ void getCaptureData( CaptureData & o_cd ) const;
+
+ /** @return A reference to the data array. */
+ const uint8_t (&getData()const)[PORT_SLCT_PER_MBA][DIMM_DQ_RANK_BITMAP_SIZE]
+ {
+ return iv_data;
+ }
+
+ private: // instance variables
+
+ TARGETING::TargetHandle_t iv_mba; ///< Target MBA
+ CenRank iv_rank; ///< Target rank
+
+ /** A bitmap of all bad DQs for each port. */
+ uint8_t iv_data[PORT_SLCT_PER_MBA][DIMM_DQ_RANK_BITMAP_SIZE];
+};
+
+} // end namespace PRDF
+
+#endif // __prdfCenDqBitmap_H
+
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C
index efe490b65..0e55bd69f 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaCaptureData.C
@@ -32,9 +32,6 @@
#include <prdfDramRepairUsrData.H>
#include <iipServiceDataCollector.h>
#include <prdf_ras_services.H>
-#ifdef __HOSTBOOT_MODULE
- #define htonl(foo) (foo) // no-op for HB
-#endif
namespace PRDF
{
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
index 1c196b16c..fe28589ba 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
@@ -160,14 +160,6 @@ int32_t CenSymbol::getWiringType( TARGETING::TargetHandle_t i_mba,
//------------------------------------------------------------------------------
-uint8_t CenSymbol::getPortSlct() const
-{
- return ( ((iv_symbol <= 3) || ((8 <= iv_symbol) && (iv_symbol <= 39)))
- ? 1 : 0 );
-}
-
-//------------------------------------------------------------------------------
-
uint8_t CenSymbol::cenDq2Symbol( uint8_t i_cenDq, uint8_t i_ps )
{
uint8_t sym = SYMBOLS_PER_RANK;
@@ -202,6 +194,21 @@ uint8_t CenSymbol::symbol2CenDq( uint8_t i_symbol )
//------------------------------------------------------------------------------
+uint8_t CenSymbol::symbol2PortSlct( uint8_t i_symbol )
+{
+ uint8_t portSlct = PORT_SLCT_PER_MBA;
+
+ if ( SYMBOLS_PER_RANK > i_symbol )
+ {
+ portSlct = ( ((i_symbol <= 3) || ((8 <= i_symbol) && (i_symbol <= 39)))
+ ? 1 : 0 );
+ }
+
+ return portSlct;
+}
+
+//------------------------------------------------------------------------------
+
int32_t CenSymbol::getSymbol( const CenRank & i_rank, WiringType i_wiringType,
uint8_t i_dimmDq, uint8_t i_portSlct,
uint8_t & o_symbol )
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
index 66744996f..ccd1f8ec4 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
@@ -42,6 +42,7 @@
namespace PRDF
{
+
/**
* @brief Container for a memory symbol.
*/
@@ -137,18 +138,21 @@ class CenSymbol
/** @return The bad pins associated with this symbol. */
uint8_t getPins() const { return iv_pins; }
- /**
- * @brief Returns this symbol's port select.
- * @return Port select.
- */
- uint8_t getPortSlct() const;
+ /** @return The even Centaur DQ of this symbol. */
+ uint8_t getEvenDq() const { return symbol2CenDq( iv_symbol ); }
- /** @return The symbol of this Cen DQ. */
+ /** @return The port select for this symbol. */
+ uint8_t getPortSlct() const { return symbol2PortSlct( iv_symbol ); }
+
+ /** @return The symbol of the given Centaur DQ and port select. */
static uint8_t cenDq2Symbol( uint8_t i_CenDq, uint8_t i_ps );
- /** @return The first Cen DQ in this symbol. */
+ /** @return The even Centaur DQ of the given symbol. */
static uint8_t symbol2CenDq( uint8_t i_symbol );
+ /** @return The port select for given symbol. */
+ static uint8_t symbol2PortSlct( uint8_t i_symbol );
+
/**
* @brief Overrides the '<' operator.
* @param i_symbol The symbol to compare with.
diff --git a/src/usr/diag/prdf/common/prd_pegasus.mk b/src/usr/diag/prdf/common/prd_pegasus.mk
index 8ea8860ce..ade450c4b 100755
--- a/src/usr/diag/prdf/common/prd_pegasus.mk
+++ b/src/usr/diag/prdf/common/prd_pegasus.mk
@@ -40,6 +40,7 @@ PRDF_RULE_PLUGINS_PEGASUS_WSIM = \
prd_pegasus_specific = \
prdfCalloutUtil.o \
prdfCenAddress.o \
+ prdfCenDqBitmap.o \
prdfCenSymbol.o \
prdfLineDelete.o \
prdfPegasusConfigurator.o \
diff --git a/src/usr/diag/prdf/plat/pegasus/prdfDramRepairs.C b/src/usr/diag/prdf/plat/pegasus/prdfDramRepairs.C
index 25745ee21..8e4e95de9 100644
--- a/src/usr/diag/prdf/plat/pegasus/prdfDramRepairs.C
+++ b/src/usr/diag/prdf/plat/pegasus/prdfDramRepairs.C
@@ -31,6 +31,8 @@
#include <prdfErrlUtil.H>
#include "common/prdfEnums.H"
#include "common/plat/pegasus/prdfCenMbaCaptureData.H"
+#include "common/plat/pegasus/prdfCalloutUtil.H"
+#include "common/plat/pegasus/prdfCenDqBitmap.H"
#include "common/plat/pegasus/prdfCenSymbol.H"
#include "common/plat/pegasus/prdfMemoryMru.H"
#include "framework/service/prdfPlatServices.H"
@@ -317,6 +319,9 @@ bool processBadDimms(TargetHandle_t i_mba, uint8_t i_badDimmMask)
bool processDq(TargetHandle_t i_mba)
{
+ using namespace TARGETING;
+ using namespace PlatServices;
+
PRDF_DENTER("processDq: %p", i_mba);
// callout any dimms on the argument MBA
@@ -324,65 +329,46 @@ bool processDq(TargetHandle_t i_mba)
uint64_t calloutCount = 0;
- // get all the dimms connected to this MBA
-
- TARGETING::TargetHandleList dimms = PlatServices::getConnected(
- i_mba, TARGETING::TYPE_DIMM);
-
- TargetHandleList::iterator dit = dimms.end();
-
- // call them out if they have any bad dq
-
- while(dit-- != dimms.begin())
+ for ( uint32_t r = 0; r < MAX_RANKS_PER_MBA; r++ )
{
- uint8_t port = 0, dimm = 0;
+ CenRank rank ( r );
+ CenDqBitmap bitmap;
- if(SUCCESS != PlatServices::getMbaPort(*dit, port))
+ if ( SUCCESS != getBadDqBitmap(i_mba, rank, bitmap) )
{
- // skip this dimm
- continue;
+ continue; // skip this rank
}
- if(SUCCESS != PlatServices::getMbaDimm(*dit, dimm))
+ for ( uint32_t p = 0; p < PORT_SLCT_PER_MBA; p++ )
{
- // skip this dimm
- continue;
- }
-
- bool badDq = false;
- uint8_t bitmap[DIMM_DQ_RANK_BITMAP_SIZE];
+ bool badDqs = false;
+ if ( SUCCESS != bitmap.badDqs(p, badDqs) )
+ {
+ continue; // skip this DIMM
+ }
- uint64_t rankNumber = DIMM_DQ_MAX_DIMM_RANKS;
+ if ( !badDqs )
+ {
+ continue; // skip this DIMM
+ }
- while(rankNumber-- && !badDq)
- {
- if(SUCCESS != PlatServices::getBadDqBitmap(
- i_mba,
- port,
- dimm,
- rankNumber,
- bitmap))
+ TargetHandleList list = CalloutUtil::getConnectedDimms( i_mba,
+ rank, p );
+ if ( 0 == list.size() )
{
- // skip this rank
+ PRDF_ERR( "[processDq] bad bits present but no connected "
+ "DIMM: MBA=0x%08x rank=%d port=%d", getHuid(i_mba),
+ rank.flatten(), p );
continue;
}
- uint8_t * it = bitmap + DIMM_DQ_RANK_BITMAP_SIZE;
-
- while(!badDq && it-- != bitmap)
+ for ( TargetHandleList::iterator i = list.begin();
+ i < list.end(); i++ )
{
- if(*it)
- {
- badDq = true;
- }
+ ++calloutCount;
+ commitRestoreCallout( &addDimmCallout, *i, i_mba );
}
}
-
- if(badDq)
- {
- ++calloutCount;
- commitRestoreCallout( &addDimmCallout, *dit, i_mba );
- }
}
PRDF_DEXIT("processDq: bad dq dimm count: %d", calloutCount);
OpenPOWER on IntegriCloud