summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C54
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H19
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H17
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C16
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTps.H3
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C139
6 files changed, 199 insertions, 49 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
index 23e97f0d2..b394b8408 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
@@ -28,15 +28,8 @@
// Platform includes
#include <prdfMemAddress.H>
#include <prdfMemCaptureData.H>
-#include <prdfMemMark.H>
#include <prdfP9McaDataBundle.H>
-#ifdef __HOSTBOOT_RUNTIME
- #include <prdfMemTps.H>
- #include <prdfMemVcm.H>
- #include <prdfP9McbistDataBundle.H>
-#endif
-
using namespace TARGETING;
namespace PRDF
@@ -94,17 +87,13 @@ void calloutMemUe<TYPE_MBA>( ExtensibleChip * i_chip, const MemRank & i_rank,
//------------------------------------------------------------------------------
-#ifdef __HOSTBOOT_RUNTIME
-
-template<TARGETING::TYPE T>
-uint32_t __addVcmEvent( ExtensibleChip * i_chip, const MemRank & i_rank,
- const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc );
+#ifdef __HOSTBOOT_MODULE
template<>
-uint32_t __addVcmEvent<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- const MemMark & i_mark,
- STEP_CODE_DATA_STRUCT & io_sc )
+uint32_t addVcmEvent<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ const MemMark & i_mark,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
PRDF_ASSERT( TYPE_MCA == i_chip->getType() );
@@ -119,10 +108,10 @@ uint32_t __addVcmEvent<TYPE_MCA>( ExtensibleChip * i_chip,
/* TODO: RTC 144083
template<>
-uint32_t __addVcmEvent<TYPE_MBA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- const MemMark & i_mark,
- STEP_CODE_DATA_STRUCT & io_sc )
+uint32_t addVcmEvent<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ const MemMark & i_mark,
+ STEP_CODE_DATA_STRUCT & io_sc )
{
PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
@@ -138,16 +127,13 @@ uint32_t __addVcmEvent<TYPE_MBA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
-#ifdef __HOSTBOOT_RUNTIME
+#ifdef __HOSTBOOT_MODULE
-template<TARGETING::TYPE T>
-uint32_t __addTpsEvent( ExtensibleChip * i_chip, const MemRank & i_rank,
- STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps = false );
template<>
-uint32_t __addTpsEvent<TYPE_MCA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps )
+uint32_t addTpsEvent<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps )
{
PRDF_ASSERT( TYPE_MCA == i_chip->getType() );
@@ -163,9 +149,9 @@ uint32_t __addTpsEvent<TYPE_MCA>( ExtensibleChip * i_chip,
/* TODO: RTC 144083
template<>
-uint32_t __addTpsEvent<TYPE_MBA>( ExtensibleChip * i_chip,
- const MemRank & i_rank,
- STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps )
+uint32_t addTpsEvent<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps )
{
PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
@@ -243,10 +229,10 @@ uint32_t analyzeFetchMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
io_sc.service_data->SetCallout( mm );
// Add a VCM request to the TD queue.
- o_rc = __addVcmEvent<T>( i_chip, i_rank, chipMark, io_sc );
+ o_rc = addVcmEvent<T>( i_chip, i_rank, chipMark, io_sc );
if ( SUCCESS != o_rc )
{
- PRDF_ERR( PRDF_FUNC "__addVcmEvent() failed: i_chip=0x%08x "
+ PRDF_ERR( PRDF_FUNC "addVcmEvent() failed: i_chip=0x%08x "
"i_rank=%d,%d", i_chip->getHuid(), i_rank.getMaster(),
i_rank.getSlave() );
break;
@@ -311,10 +297,10 @@ uint32_t analyzeFetchUe( ExtensibleChip * i_chip,
// Add a TPS request to the TD queue and ban any further TPS requests
// for this rank.
- o_rc = __addTpsEvent<T>( i_chip, rank, io_sc, true );
+ o_rc = addTpsEvent<T>( i_chip, rank, io_sc, true );
if ( SUCCESS != o_rc )
{
- PRDF_ERR( PRDF_FUNC "__addTpsEvent() failed: i_chip=0x%08x "
+ PRDF_ERR( PRDF_FUNC "addTpsEvent() failed: i_chip=0x%08x "
"rank=%d,%d", i_chip->getHuid(), rank.getMaster(),
rank.getSlave() );
// NOTE: We are not adding a break here because we still want to do
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
index 00dbd33e5..52240465d 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
@@ -33,6 +33,13 @@
// Platform includes
#include <prdfMemRank.H>
#include <prdfPlatServices.H>
+#include <prdfMemMark.H>
+
+#ifdef __HOSTBOOT_MODULE
+ #include <prdfMemTps.H>
+ #include <prdfMemVcm.H>
+ #include <prdfP9McbistDataBundle.H>
+#endif
namespace PRDF
{
@@ -72,6 +79,18 @@ template<TARGETING::TYPE T, typename D>
uint32_t analyzeFetchUe( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc );
+#ifdef __HOSTBOOT_MODULE
+
+template<TARGETING::TYPE T>
+uint32_t addVcmEvent( ExtensibleChip * i_chip, const MemRank & i_rank,
+ const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc );
+
+template<TARGETING::TYPE T>
+uint32_t addTpsEvent( ExtensibleChip * i_chip, const MemRank & i_rank,
+ STEP_CODE_DATA_STRUCT & io_sc, bool i_banTps = false );
+
+#endif
+
} // end namespace MemEcc
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
index 59cf8c5d8..e493e0c51 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
@@ -75,23 +75,25 @@ class MemTdCtlr
*/
uint32_t handleCmdComplete( STEP_CODE_DATA_STRUCT & io_sc );
- #ifdef __HOSTBOOT_RUNTIME
/**
* @brief Adds a new TD procedure to the queue.
*
- * This is only supported during runtime. It is used to process TD requests
- * during analysis of attentions other than the command complete attention
- * (i.e. memory CEs and UEs). If there isn't a current TD procedure in
- * progress, this function will stop background scrubbing and start this new
- * procedure. Otherwise, this new procedure is simply added to the queue.
+ * During runtime, this is used to process TD requests during analysis of
+ * attentions other than the command complete attention (i.e. memory CEs
+ * and UEs). If there isn't a current TD procedure in progress, this
+ * function will stop background scrubbing and start this new procedure.
+ * Otherwise, this new procedure is simply added to the queue.
*
- * It is possible that some of the other attentions my occur during the IPL
+ * It is possible that some of the other attentions may occur during the IPL
* after Hostboot has been flushed from the cache to system memory. At that
* point we don't have time to complete a TD procedure. Therefore, the
* requests will be ignored. Any chip marks placed during this time will be
* redetected when the runtime TD controller is initialized.
*
+ * During IPL, this will simply add a new procedure to the queue, since we
+ * know TD will already be in progress when this is called.
+ *
* @note Initializes the TD controller, if needed.
* @param io_sc The step code data struct.
* @param i_entry The new TD queue entry.
@@ -100,7 +102,6 @@ class MemTdCtlr
uint32_t handleTdEvent( STEP_CODE_DATA_STRUCT & io_sc,
TdEntry * i_entry );
- #endif
private:
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
index e10a0595e..06993bdb7 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
@@ -48,6 +48,22 @@ using namespace PlatServices;
//------------------------------------------------------------------------------
template <TARGETING::TYPE T>
+uint32_t MemTdCtlr<T>::handleTdEvent( STEP_CODE_DATA_STRUCT & io_sc,
+ TdEntry * i_entry )
+{
+ #define PRDF_FUNC "[MemTdCtlr::handleTdEvent] "
+
+ // Add this entry to the queue.
+ iv_queue.push( i_entry );
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template <TARGETING::TYPE T>
uint32_t MemTdCtlr<T>::defaultStep( STEP_CODE_DATA_STRUCT & io_sc )
{
#define PRDF_FUNC "[MemTdCtlr::defaultStep] "
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTps.H b/src/usr/diag/prdf/plat/mem/prdfMemTps.H
index 924f55c94..ef2fd6368 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTps.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTps.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -34,7 +34,6 @@
namespace PRDF
{
-// TODO: RTC 157889 Actual implementation of this procedure will be done later.
/** @brief Two-Phase Scrub procedure. */
template <TARGETING::TYPE T>
class TpsEvent : public TdEntry
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C
index e18269c97..3a4f0a714 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTps_ipl.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -26,16 +26,23 @@
/** @file prdfMemTps_ipl.C */
// Platform includes
+#include <prdfMemEccAnalysis.H>
+#include <prdfMemIplCeStats.H>
+#include <prdfMemMark.H>
+#include <prdfMemScrubUtils.H>
#include <prdfMemTps.H>
+#include <prdfP9McaExtraSig.H>
+#include <prdfPlatServices.H>
using namespace TARGETING;
namespace PRDF
{
+using namespace PlatServices;
+
//------------------------------------------------------------------------------
-// TODO: RTC 157608 Actual implementation of this procedure will be done later.
template<>
uint32_t TpsEvent<TYPE_MCA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc,
bool & o_done )
@@ -43,10 +50,132 @@ uint32_t TpsEvent<TYPE_MCA>::nextStep( STEP_CODE_DATA_STRUCT & io_sc,
#define PRDF_FUNC "[TpsEvent<TYPE_MCA>::nextStep] "
uint32_t o_rc = SUCCESS;
-
o_done = true;
-
- PRDF_ERR( PRDF_FUNC "function not implemented yet" );
+ MemIplCeStats<TYPE_MCA> ceStats( iv_chip );
+
+ do
+ {
+ //only done in MNFG IPL CE Handling mode
+ PRDF_ASSERT( isMfgCeCheckingEnabled() );
+
+ //phase 0
+ if ( TD_PHASE_0 == iv_phase )
+ {
+ //start TPS phase 1
+ o_rc = startTpsPhase1<TYPE_MCA>( iv_chip, iv_rank );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Call to 'startTpsPhase1 failed on chip: "
+ "0x%08x", iv_chip->getHuid() );
+ break;
+ }
+ iv_phase = TD_PHASE_1;
+
+ }
+ //phase 1/2
+ else
+ {
+ //collect the CE statistics for later analysis use
+ o_rc = ceStats.collectStats( iv_rank );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Call to 'ceStats.collectStats' failed "
+ "on chip: 0x%08x", iv_chip->getHuid() );
+ break;
+ }
+
+ //get the ecc attentions
+ uint32_t eccAttns;
+ o_rc = checkEccFirs<TYPE_MCA>( iv_chip, eccAttns );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Call to 'checkEccFirs' failed on chip: "
+ "0x%08x", iv_chip->getHuid() );
+ break;
+ }
+
+ //if there was a UE or IUE
+ if ( (eccAttns & MAINT_UE) || (eccAttns & MAINT_IUE) )
+ {
+ //UE
+ if ( eccAttns & MAINT_UE )
+ {
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_MaintUE );
+ }
+ //IUE
+ else
+ {
+ io_sc.service_data->setSignature( iv_chip->getHuid(),
+ PRDFSIG_MaintIUE );
+ }
+
+ //Add the rank to the callout list
+ MemoryMru memmru(iv_chip->getTrgt(), iv_rank,
+ MemoryMruData::CALLOUT_RANK);
+ io_sc.service_data->SetCallout( memmru );
+
+ //Make the error log predictive
+ io_sc.service_data->setServiceCall();
+
+ //Abort this procedure
+ o_done = true;
+ }
+ //else if there was an MPE
+ else if ( eccAttns & MAINT_MPE )
+ {
+ //Add the mark to the callout list
+ MemMark chipMark;
+ o_rc = MarkStore::readChipMark<TYPE_MCA>( iv_chip, iv_rank,
+ chipMark );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "readChipMark<T>(0x%08x,%d) failed",
+ iv_chip->getHuid(), iv_rank.getMaster() );
+ break;
+ }
+
+ MemoryMru memmru( iv_chip->getTrgt(), iv_rank,
+ chipMark.getSymbol() );
+ io_sc.service_data->SetCallout( memmru );
+
+ //Add a VCM procedure to the queue
+ MemEcc::addVcmEvent<TYPE_MCA>( iv_chip, iv_rank, chipMark,
+ io_sc );
+
+ //Abort this procedure
+ o_done = true;
+ }
+ else
+ {
+ //Add the rank to the callout list
+ MemoryMru memmru(iv_chip->getTrgt(), iv_rank,
+ MemoryMruData::CALLOUT_RANK);
+ io_sc.service_data->SetCallout( memmru );
+
+ //phase 1
+ if ( TD_PHASE_1 == iv_phase )
+ {
+ //Start TPS phase 2
+ o_rc = startTpsPhase2<TYPE_MCA>( iv_chip, iv_rank );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Call to 'startTpsPhase2 failed on "
+ "chip: 0x%08x", iv_chip->getHuid() );
+ break;
+ }
+ iv_phase = TD_PHASE_2;
+ }
+ //phase 2
+ else
+ {
+ //Abort this procedure
+ o_done = true;
+ }
+ }
+ }
+
+ }while(0);
return o_rc;
OpenPOWER on IntegriCloud