summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/common/plat
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2013-04-27 22:12:56 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-06-11 09:11:25 -0500
commit25a05966a93786736212b4f35aa84929423a48e4 (patch)
tree3be7d985ec3938b43671ff01e93ff8db5eae9de1 /src/usr/diag/prdf/common/plat
parentbb2e9e1adac63e8b12c881b546b757f8d8de5697 (diff)
downloadtalos-hostboot-25a05966a93786736212b4f35aa84929423a48e4.tar.gz
talos-hostboot-25a05966a93786736212b4f35aa84929423a48e4.zip
PRD: TD controller for MDIA
Change-Id: I6453a1fef37cbd7f9d3c105af8349688ad62c0c2 RTC: 22866 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4248 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/4935
Diffstat (limited to 'src/usr/diag/prdf/common/plat')
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/Mba.rule24
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule32
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C20
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H20
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H6
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C36
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H8
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C76
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H11
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H48
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C104
-rw-r--r--src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H212
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C40
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H15
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C3
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H3
16 files changed, 570 insertions, 88 deletions
diff --git a/src/usr/diag/prdf/common/plat/pegasus/Mba.rule b/src/usr/diag/prdf/common/plat/pegasus/Mba.rule
index d09d63997..438f483be 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/Mba.rule
+++ b/src/usr/diag/prdf/common/plat/pegasus/Mba.rule
@@ -44,6 +44,8 @@ chip Mba
dump DUMP_CONTENT_HWSUPERNOVA;
scomlen 64;
+.include "prdfCenMbaExtraSig.H";
+
#############################################################################
# #
# ###### #
@@ -120,6 +122,13 @@ chip Mba
capture group FirRegs;
};
+ register MBADDRPHYFIR_AND
+ {
+ name "DPHY01.PHY01_DDRPHY_FIR_REG_AND";
+ scomaddr 0x800200910301143F;
+ capture group never;
+ };
+
register MBADDRPHYFIR_MASK
{
name "DPHY01.PHY01_DDRPHY_FIR_MASK_REG";
@@ -190,11 +199,17 @@ chip Mba
name "MBU.MBA01.MBA_MCBIST.SCOMFIR.MBSPAQ";
scomaddr 0x03010611;
reset (&, 0x03010612);
- #FIXME : There is no OR register for mask. Is it right to use mask register value
mask (|, 0x03010614);
capture group FirRegs;
};
+ register MBASPA_AND
+ {
+ name "MBU.MBA01.MBA_MCBIST.SCOMFIR.MBSPAQ_AND";
+ scomaddr 0x03010612;
+ capture group never;
+ };
+
register MBASPA_MASK
{
name "MBU.MBA01.MBA_MCBIST.SCOMFIR.MBSPAMSKQ";
@@ -221,7 +236,6 @@ chip Mba
capture group CerrRegs;
};
-
register DDRPHY_APB_FIR_ERR0_P0
{
name "DPHY01.DDRPHY_APB_FIR_ERR0_P0";
@@ -796,5 +810,9 @@ group gMbaSpa attntype SPECIAL filter singlebit
################################################################################
/** Analyze maintenance command complete */
-actionclass analyzeMaintCmdComplete { funccall("MaintCmdComplete"); };
+actionclass analyzeMaintCmdComplete
+{
+ funccall("MaintCmdComplete"); # Must be called last so return code can be
+ # passed on to rule code.
+};
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 668f49be3..7bf027415 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
@@ -228,6 +228,13 @@
capture group FirRegs;
};
+ register MBSECC01FIR_AND
+ {
+ name "MBU.MBS.ECC01.MBECCFIR_AND";
+ scomaddr 0x02011441;
+ capture group never;
+ };
+
register MBSECC01FIR_MASK
{
name "MBU.MBS.ECC01.MBECCFIR_MASK";
@@ -269,6 +276,13 @@
capture group FirRegs;
};
+ register MBSECC23FIR_AND
+ {
+ name "MBU.MBS.ECC23.MBECCFIR_AND";
+ scomaddr 0x02011481;
+ capture group never;
+ };
+
register MBSECC23FIR_MASK
{
name "MBU.MBS.ECC23.MBECCFIR_MASK";
@@ -599,3 +613,21 @@
capture group default;
};
+ ############################################################################
+ # NEST Chiplet memory scrub/read threshold register
+ ############################################################################
+
+ register MBSTR_0
+ {
+ name "MBU.MBS.MCBISTS01.SCOMFIR.MBSTRQ";
+ scomaddr 0x02011655;
+ capture group default;
+ };
+
+ register MBSTR_1
+ {
+ name "MBU.MBS.MCBISTS23.SCOMFIR.MBSTRQ";
+ scomaddr 0x02011755;
+ capture group default;
+ };
+
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C
index 39917a826..a7ca03cb7 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C
@@ -27,6 +27,7 @@
#include <iipServiceDataCollector.h>
#include <prdfCenAddress.H>
+#include <prdfCenMarkstore.H>
#include <prdfPlatServices.H>
#include <prdfTrace.H>
@@ -49,6 +50,25 @@ void defaultError( STEP_CODE_DATA_STRUCT & i_sc )
//------------------------------------------------------------------------------
+void calloutMark( TargetHandle_t i_mba, const CenRank & i_rank,
+ const CenMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc,
+ PRDpriority i_priority )
+{
+ if ( i_mark.getCM().isValid() )
+ {
+ MemoryMru memmru ( i_mba, i_rank, i_mark.getCM() );
+ io_sc.service_data->SetCallout( memmru, i_priority );
+ }
+
+ if ( i_mark.getSM().isValid() )
+ {
+ MemoryMru memmru ( i_mba, i_rank, i_mark.getSM() );
+ io_sc.service_data->SetCallout( memmru, i_priority );
+ }
+}
+
+//------------------------------------------------------------------------------
+
TargetHandleList getConnectedDimms( TargetHandle_t i_mba,
const CenRank & i_rank )
{
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H
index ff4f97baf..0bf1a6863 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H
@@ -24,15 +24,18 @@
#ifndef prdfCalloutUtil_H
#define prdfCalloutUtil_H
-#include <prdfPlatServices.H>
-
/** @file prdfCalloutUtil.H
* @brief Utility functions for common, non-trivial callouts.
*/
+#include <prdfPlatServices.H>
+
+#include <prdfCallouts.H>
+
namespace PRDF
{
+class CenMark;
class CenRank;
struct STEP_CODE_DATA_STRUCT;
@@ -48,6 +51,19 @@ namespace CalloutUtil
void defaultError( STEP_CODE_DATA_STRUCT & i_sc );
/**
+ * @brief Will add a MemoryMru to the callout list for the chip mark and symbol
+ * mark, if they exist.
+ * @param i_mba Target MBA.
+ * @param i_rank Target rank.
+ * @param i_mark Target mark.
+ * @param io_sc The step code data struct.
+ * @param i_priority Callout priority (default MRU_MED).
+ */
+void calloutMark( TARGETING::TargetHandle_t i_mba, const CenRank & i_rank,
+ const CenMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc,
+ PRDpriority i_priority = MRU_MED );
+
+/**
* @param i_mba The target MBA.
* @param i_rank The target rank.
* @return A list of DIMMs connected to the MBA and rank.
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H
index 8d31d928b..4360da5b2 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H
@@ -48,6 +48,12 @@ enum
SYMBOLS_PER_BYTE = 4,
DQS_PER_SYMBOL = 2,
DQS_PER_BYTE = SYMBOLS_PER_BYTE * DQS_PER_SYMBOL,
+
+ SYMBOLS_PER_X8DRAM = 4,
+ SYMBOLS_PER_X4DRAM = 2,
+
+ X8DRAMS_PER_RANK = SYMBOLS_PER_RANK / SYMBOLS_PER_X8DRAM,
+ X4DRAMS_PER_RANK = SYMBOLS_PER_RANK / SYMBOLS_PER_X4DRAM,
};
} // 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
index 8b0e920d8..48ea97c00 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C
@@ -228,6 +228,42 @@ int32_t CenDqBitmap::setEccSpare( uint8_t i_pins )
//------------------------------------------------------------------------------
+int32_t CenDqBitmap::isDramSpareAvailable( uint8_t i_portSlct,
+ bool & o_available )
+{
+ #define PRDF_FUNC "[CenDqBitmap::isDramSpareAvailable] "
+
+ int32_t o_rc = SUCCESS;
+
+ o_available = false;
+
+ 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) )
+ {
+ // TODO: RTC 68096 Need to add x4 ECC support.
+ }
+ else
+ {
+ o_available =
+ ( 0 == iv_data[i_portSlct][DIMM_DQ_RANK_BITMAP_SIZE-1] );
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
void CenDqBitmap::getCaptureData( CaptureData & o_cd ) const
{
uint8_t rank = iv_rank.flatten();
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H
index 834c3bb01..4762caecd 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H
@@ -114,6 +114,14 @@ class CenDqBitmap
int32_t setEccSpare( uint8_t i_pins );
/**
+ * @brief Queries for DRAM spare status.
+ * @param i_portSlct The target port.
+ * @param o_available TRUE if the spare is available, FALSE if it is used.
+ * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise.
+ */
+ int32_t isDramSpareAvailable( uint8_t i_portSlct, bool & o_available );
+
+ /**
* @brief Adds the bitmaps for both ports to the capture data.
* @param o_cd Capture data struct.
*/
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C
index 0d03876ab..c73efc43f 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C
@@ -22,19 +22,22 @@
/* IBM_PROLOG_END_TAG */
/** @file prdfCenMba.C
- * @brief Contains all the plugin code for the PRD Centaur MBA
+ * @brief Contains all common plugin code for the Centaur MBA
*/
+// Framework includes
#include <iipServiceDataCollector.h>
-#include <prdfCalloutUtil.H>
#include <prdfExtensibleChip.H>
#include <prdfPlatServices.H>
#include <prdfPluginMap.H>
-#include <prdfCenAddress.H>
+// Pegasus includes
+#include <prdfCalloutUtil.H>
#include <prdfCenMbaCaptureData.H>
#include <prdfCenMbaDataBundle.H>
+using namespace TARGETING;
+
namespace PRDF
{
@@ -78,71 +81,32 @@ int32_t MaintCmdComplete( ExtensibleChip * i_mbaChip,
{
#define PRDF_FUNC "[Mba::MaintCmdComplete] "
- using namespace TARGETING;
-
int32_t l_rc = SUCCESS;
- TargetHandle_t mbaTarget = i_mbaChip->GetChipHandle();
-
- do
- {
- #ifdef __HOSTBOOT_MODULE
-
- if ( isInMdiaMode() )
- {
- // Immediately inform mdia that the command
- // has finished.
-
- l_rc = mdiaSendEventMsg( mbaTarget, MDIA::RESET_TIMER );
-
- if(l_rc)
- {
- PRDF_ERR( PRDF_FUNC"PlatServices::mdiaSendEventMsg() failed" );
- // keep going
- }
-
- // Determine for mdia whether or not the command
- // finished at the end of the last rank or if
- // the command will need to be restarted.
- // Tuck this away until PostAnalysis.
-
- CenAddr startAddr, endAddr;
- l_rc = getCenMaintStartAddr( i_mbaChip, startAddr );
- l_rc |= getCenMaintEndAddr( i_mbaChip, endAddr );
- if ( SUCCESS != l_rc )
- {
- PRDF_ERR( PRDF_FUNC"cenGetMbaAddr() failed" );
- break;
- }
-
- CenMbaDataBundle * mbadb = getMbaDataBundle( i_mbaChip );
- mbadb->iv_sendCmdCompleteMsg = true;
- mbadb->iv_cmdCompleteMsgData =
- startAddr == endAddr ? MDIA::COMMAND_COMPLETE
- : MDIA::COMMAND_STOPPED;
-
- // Do not commit error log for a successful command complete.
- if ( MDIA::COMMAND_COMPLETE == mbadb->iv_cmdCompleteMsgData )
- i_sc.service_data->DontCommitErrorLog();
- }
-
- #endif // __HOSTBOOT_MODULE
-
- // Get DRAM repairs capture data
- CenMbaCaptureData::addDramRepairsData( mbaTarget, i_sc );
- } while (0);
+ TargetHandle_t mbaTarget = i_mbaChip->GetChipHandle();
+ CenMbaDataBundle * mbadb = getMbaDataBundle( i_mbaChip );
+ // Tell the TD controller that a maintenance command complete occurred.
+ l_rc = mbadb->iv_tdCtlr.handleCmdCompleteEvent( i_sc );
if ( SUCCESS != l_rc )
{
- PRDF_ERR( PRDF_FUNC"failed on MBA 0x%08x", getHuid(mbaTarget) );
+ PRDF_ERR( PRDF_FUNC"Failed: i_mbaChip=0x%08x", getHuid(mbaTarget) );
CalloutUtil::defaultError( i_sc );
}
- return l_rc;
+ // Gather capture data even if something failed above.
+ // NOTE: There is no need to capture if the maintenance command complete was
+ // successful with no errors because the error log will not be
+ // committed.
+ if ( !i_sc.service_data->IsDontCommitErrl() )
+ CenMbaCaptureData::addDramRepairsData( mbaTarget, i_sc );
+
+ return PRD_NO_CLEAR_FIR_BITS; // FIR bits are cleared by this plugin
#undef PRDF_FUNC
}
PRDF_PLUGIN_DEFINE( Mba, MaintCmdComplete );
} // end namespace Mba
+
} // end namespace PRDF
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 a239ad48d..fe2eb5c4c 100644
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H
@@ -28,11 +28,15 @@
* @brief Contains the common data bundle for a Centaur MBA object.
*/
+// Framework includes
#include <iipSystem.h>
#include <prdfExtensibleChip.H>
#include <prdfGlobal.H>
#include <prdfPlatServices.H>
+// Pegasus includes
+#include <prdfCenMbaTdCtlr.H>
+
namespace PRDF
{
@@ -48,7 +52,7 @@ class CenMbaDataBundleCommon : public DataBundle
* @param i_mbaChip The MBA chip.
*/
explicit CenMbaDataBundleCommon( ExtensibleChip * i_mbaChip ) :
- iv_mbaChip(i_mbaChip), iv_membChip(NULL)
+ iv_mbaChip(i_mbaChip), iv_membChip(NULL), iv_tdCtlr(i_mbaChip)
{}
/**
@@ -83,6 +87,11 @@ class CenMbaDataBundleCommon : public DataBundle
ExtensibleChip * iv_mbaChip; ///< This MBA chip
ExtensibleChip * iv_membChip; ///< The connected MEMBUF chip
+
+ public: // instance variables
+
+ CenMbaTdCtlr iv_tdCtlr; ///< Targeted Diagnostics Controller
+
};
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H
new file mode 100644
index 000000000..3fa49f259
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H
@@ -0,0 +1,48 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.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 __prdfCenMbaExtraSig_H
+#define __prdfCenMbaExtraSig_H
+
+#include <prdrSignatures.H>
+
+PRDR_ERROR_SIGNATURE(MaintCmdComplete_ERROR, 0xeeee0000, "",
+ "ERROR: maint cmd complete analysis failed" );
+
+PRDR_ERROR_SIGNATURE(StartVcmPhase1, 0xffff0000, "", "Starting VCM phase 1");
+PRDR_ERROR_SIGNATURE(StartVcmPhase2, 0xffff0001, "", "Starting VCM phase 2");
+PRDR_ERROR_SIGNATURE(StartDsdPhase1, 0xffff0002, "", "Starting DSD phase 1");
+PRDR_ERROR_SIGNATURE(StartDsdPhase2, 0xffff0003, "", "Starting DSD phase 2");
+
+PRDR_ERROR_SIGNATURE(MaintUE, 0xffff0010, "", "Maintenance UE");
+
+PRDR_ERROR_SIGNATURE(VcmVerified, 0xffff0020, "", "VCM: verified");
+PRDR_ERROR_SIGNATURE(VcmFalseAlarm, 0xffff0021, "", "VCM: false alarm");
+PRDR_ERROR_SIGNATURE(VcmBadSpare, 0xffff0022, "", "VCM: bad DRAM spare");
+PRDR_ERROR_SIGNATURE(VcmMarksUnavail, 0xffff0023, "",
+ "VCM: No more marks available");
+
+PRDR_ERROR_SIGNATURE(DsdDramSpared, 0xffff0030, "", "DSD: DRAM spared");
+PRDR_ERROR_SIGNATURE(DsdBadSpare, 0xffff0031, "", "DSD: DRAM spare is bad");
+
+#endif // __prdfCenMbaExtraSig_H
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C
new file mode 100644
index 000000000..1e7a0ed7c
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C
@@ -0,0 +1,104 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.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 <prdfCenMbaTdCtlr_common.H>
+
+using namespace TARGETING;
+
+namespace PRDF
+{
+
+using namespace PlatServices;
+
+//------------------------------------------------------------------------------
+
+int32_t CenMbaTdCtlrCommon::cleanupPrevCmd()
+{
+ #define PRDF_FUNC "[CenMbaTdCtlrCommon::cleanupPrevCmd] "
+
+ int32_t o_rc = SUCCESS;
+
+ // Clean up the current maintenance command. This must be done whenever
+ // maintenance command will no longer be executed.
+ if ( NULL != iv_mssCmd )
+ {
+ o_rc = iv_mssCmd->cleanupCmd();
+ if ( SUCCESS != o_rc )
+ PRDF_ERR( PRDF_FUNC"cleanupCmd() failed" );
+
+ delete iv_mssCmd; iv_mssCmd = NULL;
+ }
+
+ // Clear the command complete attention. This must be done before starting
+ // the next maintenance command.
+ SCAN_COMM_REGISTER_CLASS * firand = iv_mbaChip->getRegister("MBASPA_AND");
+ firand->setAllBits();
+
+ firand->ClearBit(0); // Maintenance command complete
+ firand->ClearBit(8); // Maintenance command complete (DD1.0 workaround)
+
+ int32_t l_rc = firand->Write();
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC"Write() failed on MBASPA_AND" );
+ o_rc = FAIL;
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+int32_t CenMbaTdCtlrCommon::chipMarkCleanup()
+{
+ #define PRDF_FUNC "[CenMbaTdCtlrCommon::chipMarkCleanup] "
+
+ int32_t o_rc = SUCCESS;
+
+ do
+ {
+ SCAN_COMM_REGISTER_CLASS * ddrPhyAndFir =
+ iv_mbaChip->getRegister( "MBADDRPHYFIR_AND" );
+ ddrPhyAndFir->setAllBits();
+
+ ddrPhyAndFir->ClearBit(50); // Calibration Error RE 0
+ ddrPhyAndFir->ClearBit(58); // Calibration Error RE 1
+
+ o_rc = ddrPhyAndFir->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC"Write() failed on MBADDRPHYFIR_AND" );
+ break;
+ }
+
+ } while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+} // end namespace PRDF
+
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H
new file mode 100644
index 000000000..5107dc7f5
--- /dev/null
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H
@@ -0,0 +1,212 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.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 prdfCenMbaTdCtlr_common.H
+ * @brief The common implementation of the MBA TD Controller.
+ */
+
+#ifndef __prdfCenMbaTdCtlr_common_H
+#define __prdfCenMbaTdCtlr_common_H
+
+// Framework includes
+#include <iipServiceDataCollector.h>
+#include <prdf_types.h>
+#include <prdfPlatServices.H>
+
+// Pegasus includes
+#include <prdfCenAddress.H>
+#include <prdfCenConst.H>
+#include <prdfCenMarkstore.H>
+#include <prdfCenMbaExtraSig.H>
+
+namespace PRDF
+{
+
+class ExtensibleChip;
+
+/**
+ * @brief A state machine for memory targeted diagnostics.
+ */
+class CenMbaTdCtlrCommon
+{
+ public: // functions
+
+ /**
+ * @brief Constructor
+ *
+ * This constructor will be called in the MBA data bundle code. Therefore,
+ * no register reads/writes can be done in this constructor. Anything needed
+ * to initialize the instance variables that requires register reads/writes
+ * or is non-trivial should be done in initialize().
+ *
+ * @param i_mbaChip An MBA chip.
+ */
+ explicit CenMbaTdCtlrCommon( ExtensibleChip * i_mbaChip ) :
+ iv_mbaChip(i_mbaChip), iv_initialized(false), iv_rank(), iv_mark(),
+ iv_mssCmd(NULL)
+ {}
+
+ /** @brief Destructor */
+ ~CenMbaTdCtlrCommon()
+ {
+ delete iv_mssCmd; iv_mssCmd = NULL;
+ }
+
+ /**
+ * @brief Determines and executes the next course of action after a
+ * maintenance command complete attention.
+ * @note Initializes the TD controller, if needed.
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t handleCmdCompleteEvent( STEP_CODE_DATA_STRUCT & io_sc ) = 0;
+
+ protected: // functions
+
+ /**
+ * @brief Initializes the TD controller and sets appropriate information
+ * in the hardware, if needed.
+ *
+ * Since the TD controller constructor will only be called in the MBA data
+ * bundle, register reads/writes can NOT be done in the constructor.
+ * Instead, anything needed to initialize the instance variables that
+ * requires register reads/writes or is non-trivial should be done in
+ * this function.
+ *
+ * @note Should be called at the beginning of every public function to
+ * ensure the TD controller is initialized.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t initialize() = 0;
+
+ /**
+ * @brief Analyzes a non-TD command complete event.
+ *
+ * A maintenance command has completed but no TD are in progress. This
+ * function will check for any ECC errors, unverified chip marks from a
+ * reset/reload, etc. and starts any TD procedures, if necessary.
+ *
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t analyzeCmdComplete( STEP_CODE_DATA_STRUCT & io_sc ) = 0;
+
+ /**
+ * @brief Analyzes VCM Phase 1 results and moves state machine.
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t analyzeVcmPhase1( STEP_CODE_DATA_STRUCT & io_sc ) = 0;
+
+ /**
+ * @brief Analyzes VCM Phase 2 results and moves state machine.
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t analyzeVcmPhase2( STEP_CODE_DATA_STRUCT & io_sc ) = 0;
+
+ /**
+ * @brief Analyzes DSD Phase 1 results and moves state machine.
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t analyzeDsdPhase1( STEP_CODE_DATA_STRUCT & io_sc ) = 0;
+
+ /**
+ * @brief Analyzes DSD Phase 2 results and moves state machine.
+ * @param io_sc The step code data struct.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t analyzeDsdPhase2( STEP_CODE_DATA_STRUCT & io_sc ) = 0;
+
+ /**
+ * @brief Starts VCM Phase 1.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t startVcmPhase1() = 0;
+
+ /**
+ * @brief Starts VCM Phase 2.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t startVcmPhase2() = 0;
+
+ /**
+ * @brief Starts DSD Phase 1.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t startDsdPhase1() = 0;
+
+ /**
+ * @brief Starts DSD Phase 2.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t startDsdPhase2() = 0;
+
+ /**
+ * @return TRUE if currently running a targeted diagnositics procedure,
+ * FALSE otherwise.
+ */
+ virtual bool isInTdMode() = 0;
+
+ /**
+ * @brief Calls the cleanupCmd() function of the command that had just
+ * completed.
+ * @note This function will clear the maintenance command complete
+ * attention. So for FSP attentions, the SDC needs to be synched
+ * before calling this function just in case there is a
+ * reset/reload.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t cleanupPrevCmd();
+
+ /**
+ * @brief Clears FIR bits that may have been a side-effect of a chip mark
+ * placed by hardware.
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+ virtual int32_t chipMarkCleanup();
+
+ protected: // instance variables
+
+ /** The memory controller chip that this TD controller acts on. */
+ ExtensibleChip * iv_mbaChip;
+
+ /** Indicates if TD controller is initialized. */
+ bool iv_initialized;
+
+ /** The current rank that is being targeted for diagnostics. */
+ CenRank iv_rank;
+
+ /** The current mark that is being targeted for diagnostics. */
+ CenMark iv_mark;
+
+ /** Current maintenance command */
+ PlatServices::mss_MaintCmdWrapper * iv_mssCmd;
+
+}; // CenMbaTdCtlrCommon
+
+} // end namespace PRDF
+
+#endif // __prdfCenMbaTdCtlr_common_H
+
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
index 38edaea21..57eaf1322 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C
@@ -60,29 +60,17 @@ CenSymbol CenSymbol::fromSymbol( TargetHandle_t i_mba, const CenRank & i_rank,
break;
}
- if ( SYMBOLS_PER_RANK <= i_symbol )
- {
- PRDF_ERR( PRDF_FUNC"i_symbol is invalid" );
- break;
- }
-
if ( BOTH_SYMBOL_DQS < i_pins )
{
PRDF_ERR( PRDF_FUNC"i_pins is invalid" );
break;
}
- o_symbol = CenSymbol ( i_mba, i_rank, wiringType, i_symbol, i_pins );
+ o_symbol = CenSymbol ( i_mba, i_rank, wiringType, i_symbol, i_pins,
+ isDramWidthX4(i_mba) );
} while (0);
- if ( !o_symbol.isValid() )
- {
- PRDF_ERR( PRDF_FUNC"Failed: i_mba=0x%08x i_rank=%d i_symbol=%d "
- "i_pins=%d", getHuid(i_mba), i_rank.flatten(), i_symbol,
- i_pins );
- }
-
return o_symbol;
#undef PRDF_FUNC
@@ -124,17 +112,11 @@ CenSymbol CenSymbol::fromDimmDq( TargetHandle_t i_mba, const CenRank & i_rank,
uint8_t pins = (0 == (i_dimmDq & ODD_SYMBOL_DQ)) ? EVEN_SYMBOL_DQ :
ODD_SYMBOL_DQ;
- o_symbol = CenSymbol ( i_mba, i_rank, wiringType, symbol, pins );
+ o_symbol = CenSymbol ( i_mba, i_rank, wiringType, symbol, pins,
+ isDramWidthX4(i_mba) );
} while (0);
- if ( !o_symbol.isValid() )
- {
- PRDF_ERR( PRDF_FUNC"Failed: i_mba=0x%08x i_rank=%d i_dimmDq=%d "
- "i_portSlct=%d", getHuid(i_mba), i_rank.flatten(), i_dimmDq,
- i_portSlct );
- }
-
return o_symbol;
#undef PRDF_FUNC
@@ -205,6 +187,20 @@ uint8_t CenSymbol::symbol2PortSlct( uint8_t i_symbol )
//------------------------------------------------------------------------------
+uint8_t CenSymbol::symbol2Dram( uint8_t i_symbol, bool isX4Dram )
+{
+ uint8_t dram = isX4Dram ? X4DRAMS_PER_RANK : X8DRAMS_PER_RANK;
+
+ if ( SYMBOLS_PER_RANK > i_symbol )
+ {
+ dram = i_symbol / (isX4Dram ? SYMBOLS_PER_X4DRAM : SYMBOLS_PER_X8DRAM);
+ }
+
+ return dram;
+}
+
+//------------------------------------------------------------------------------
+
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 0bfc86dfd..a43700e87 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H
@@ -81,9 +81,10 @@ class CenSymbol
* @brief Constructor from components
*/
CenSymbol( TARGETING::TargetHandle_t i_mba, CenRank i_rank,
- WiringType i_wiringType, uint8_t i_symbol, uint8_t i_pins ) :
+ WiringType i_wiringType, uint8_t i_symbol, uint8_t i_pins,
+ bool i_x4Dram ) :
iv_mbaTarget(i_mba), iv_rank(i_rank), iv_wiringType(i_wiringType),
- iv_symbol(i_symbol), iv_pins(i_pins)
+ iv_symbol(i_symbol), iv_pins(i_pins), iv_x4Dram(i_x4Dram)
{}
public: // functions
@@ -148,6 +149,12 @@ class CenSymbol
/** @return The port select for this symbol. */
uint8_t getPortSlct() const { return symbol2PortSlct( iv_symbol ); }
+ /** @return The DRAM index for this symbol. */
+ uint8_t getDram() const { return symbol2Dram( iv_symbol, iv_x4Dram ); }
+
+ /** @return TRUE this symbol is on a x4 DRAM, FALSE otherwise. */
+ bool isX4Dram() const { return iv_x4Dram; }
+
/** @return The symbol of the given Centaur DQ and port select. */
static uint8_t cenDq2Symbol( uint8_t i_CenDq, uint8_t i_ps );
@@ -157,6 +164,9 @@ class CenSymbol
/** @return The port select for given symbol. */
static uint8_t symbol2PortSlct( uint8_t i_symbol );
+ /** @return The DRAM index for the given symbol. */
+ static uint8_t symbol2Dram( uint8_t i_symbol, bool isX4Dram );
+
/**
* @brief Overrides the '<' operator.
* @param i_symbol The symbol to compare with.
@@ -199,6 +209,7 @@ class CenSymbol
WiringType iv_wiringType; ///< This symbol's wiring type.
uint8_t iv_symbol; ///< This symbol's numerical value.
uint8_t iv_pins; ///< See enum DqMask.
+ bool iv_x4Dram; ///< TRUE x4 DRAM, FALSE x8 DRAM.
};
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C
index 177a64d91..6c4e7a736 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C
@@ -203,8 +203,7 @@ MemoryMru::MemoryMru( TARGETING::TargetHandle_t i_mbaTarget,
iv_memMruMeld.s.rank = iv_rank.flatten();
iv_memMruMeld.s.symbol = iv_symbol.getSymbol();
iv_memMruMeld.s.pins = iv_symbol.getPins();
- //TODO: RTC 68096 Add support for DRAM spare
- iv_memMruMeld.s.dramSpared = 0;
+ iv_memMruMeld.s.dramSpared = 0; // manually set by setDramSpared()
iv_memMruMeld.s.wiringType = iv_symbol.getWiringType();
// If the code gets to this point the MemoryMru is valid.
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H
index a1cb63ab0..448649385 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H
@@ -71,6 +71,9 @@ class MemoryMru
MemoryMru( TARGETING::TargetHandle_t i_mbaTarget, const CenRank & i_rank,
MemoryMruData::Callout i_specialCallout );
+ /** @brief Indicates that the symbol actually resides on the DRAM spare. */
+ void setDramSpared() { iv_memMruMeld.s.dramSpared = 1; }
+
public: // functions
/** @return The 32-bit representation of this MemoryMru. */
OpenPOWER on IntegriCloud