summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfCenMbaDataBundle.H15
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C12
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.C109
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.H11
4 files changed, 141 insertions, 6 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfCenMbaDataBundle.H b/src/usr/diag/prdf/common/plat/mem/prdfCenMbaDataBundle.H
index 85ef296ed..89400e7ba 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfCenMbaDataBundle.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfCenMbaDataBundle.H
@@ -60,6 +60,10 @@ class MbaDataBundle : public DataBundle
#ifdef __HOSTBOOT_MODULE
delete iv_tdCtlr; iv_tdCtlr = nullptr;
#endif
+
+ #if defined(__HOSTBOOT_MODULE) && !defined(__HOSTBOOT_RUNTIME)
+ delete iv_sfCmd; iv_sfCmd = nullptr;
+ #endif
}
// Don't allow copy or assignment.
@@ -92,6 +96,17 @@ class MbaDataBundle : public DataBundle
MemTdCtlr<TARGETING::TYPE_MBA> * iv_tdCtlr = nullptr;
#endif
+
+ public: // instance variables
+
+ #if defined(__HOSTBOOT_MODULE) && !defined(__HOSTBOOT_RUNTIME)
+
+ /** Super fast commands during Memory Diagnostics require a cleanup after
+ * the command has finished. After starting the command, we have to store
+ * the command object until we get the command complete attention. */
+ mss_SuperFastRead * iv_sfCmd = nullptr;
+
+ #endif
};
/**
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C
index ba1eadd83..986edc20c 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C
@@ -109,6 +109,8 @@ uint32_t MemTdCtlr<T>::handleCmdComplete( STEP_CODE_DATA_STRUCT & io_sc )
}
// Inform MDIA the command has completed and PRD is starting analysis.
+ // If MDIA started the command, the reset message will do the cleanup
+ // for the super fast command.
o_rc = mdiaSendEventMsg( iv_chip->getTrgt(), MDIA::RESET_TIMER );
if ( SUCCESS != o_rc )
{
@@ -116,6 +118,16 @@ uint32_t MemTdCtlr<T>::handleCmdComplete( STEP_CODE_DATA_STRUCT & io_sc )
break;
}
+ // If PRD started a super fast command, this will do the cleanup for the
+ // super fast command.
+ o_rc = cleanupSfRead<T>( iv_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "cleanupSfRead(0x%08x) failed",
+ iv_chip->getHuid() );
+ break;
+ }
+
#endif
collectStateCaptureData( io_sc, TD_CTLR_DATA::START );
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
index 4701370fb..f556520ea 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
@@ -37,6 +37,7 @@
#include <prdfErrlUtil.H>
#include <prdfTrace.H>
+#include <prdfCenMbaDataBundle.H>
#include <prdfMemDqBitmap.H>
#include <prdfMemScrubUtils.H>
#include <prdfMfgThresholdMgr.H>
@@ -286,7 +287,7 @@ uint32_t startSfRead<TYPE_MCA>( ExtensibleChip * i_mcaChip,
.set_nce_soft_symbol_count_enable( mss::ON)
.set_nce_hard_symbol_count_enable( mss::ON);
- // Stop on hard CEs if MNFG CE checking is enable.
+ // Stop on hard CEs if MNFG CE checking is enabled.
if ( isMfgCeCheckingEnabled() ) stopCond.set_pause_on_nce_hard(mss::ON);
do
@@ -313,8 +314,8 @@ uint32_t startSfRead<TYPE_MCA>( ExtensibleChip * i_mcaChip,
// Start the super fast read command.
errlHndl_t errl;
- FAPI_INVOKE_HWP( errl, mss::memdiags::sf_read, fapiTrgt, stopCond, saddr );
-
+ FAPI_INVOKE_HWP( errl, mss::memdiags::sf_read, fapiTrgt, stopCond,
+ saddr );
if ( nullptr != errl )
{
PRDF_ERR( PRDF_FUNC "mss::memdiags::sf_read(0x%08x,%d) failed",
@@ -341,6 +342,14 @@ uint32_t startSfRead<TYPE_MCBIST>( ExtensibleChip * i_mcaChip,
return startSfRead<TYPE_MCA>( i_mcaChip, i_rank );
}
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t cleanupSfRead<TYPE_MCBIST>( ExtensibleChip * i_mcbChip )
+{
+ return SUCCESS; // Not needed for MCBIST commands.
+}
+
//##############################################################################
//## Centaur Maintenance Command wrappers
//##############################################################################
@@ -359,13 +368,50 @@ uint32_t startSfRead<TYPE_MBA>( ExtensibleChip * i_mbaChip,
{
#define PRDF_FUNC "[PlatServices::startSfRead<TYPE_MBA>] "
+ PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
+
PRDF_ASSERT( nullptr != i_mbaChip );
PRDF_ASSERT( TYPE_MBA == i_mbaChip->getType() );
uint32_t o_rc = SUCCESS;
+ // Get the MBA fapi target
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_mbaChip->getTrgt() );
+
+ // Get the stop conditions.
+ uint32_t stopCond = mss_MaintCmd::STOP_END_OF_RANK |
+ mss_MaintCmd::STOP_ON_MPE |
+ mss_MaintCmd::STOP_ON_UE |
+ mss_MaintCmd::STOP_ON_END_ADDRESS |
+ mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION;
+
+ // Stop on hard CEs if MNFG CE checking is enabled.
+ if ( isMfgCeCheckingEnabled() )
+ stopCond |= mss_MaintCmd::STOP_ON_HARD_NCE_ETE;
+
do
{
+ fapi2::buffer<uint64_t> saddr, eaddr, junk;
+
+ // Get the first address of the given rank.
+ o_rc = getMemAddrRange<TYPE_MBA>( i_mbaChip, i_rank, saddr, junk,
+ SLAVE_RANK );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
+ i_mbaChip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Get the last address of the chip.
+ o_rc = getMemAddrRange<TYPE_MBA>( i_mbaChip, junk, eaddr );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x) failed",
+ i_mbaChip->getHuid() );
+ break;
+ }
+
// Clear all of the counters and maintenance ECC attentions.
o_rc = prepareNextCmd<TYPE_MBA>( i_mbaChip );
if ( SUCCESS != o_rc )
@@ -375,8 +421,24 @@ uint32_t startSfRead<TYPE_MBA>( ExtensibleChip * i_mbaChip,
break;
}
- // Start the background scrub command.
- PRDF_ERR( PRDF_FUNC "function not implemented yet" ); // TODO RTC 157888
+ // Create the new command. Store a pointer to the command in the MBA
+ // data bundle so that we can call the cleanup function after the
+ // command has completed.
+ MbaDataBundle * db = getMbaDataBundle( i_mbaChip );
+ PRDF_ASSERT( nullptr == db->iv_sfCmd ); // Code bug.
+ db->iv_sfCmd = new mss_SuperFastRead { fapiTrgt, saddr, eaddr,
+ stopCond, false };
+
+ // Start the super fast read command.
+ errlHndl_t errl;
+ FAPI_INVOKE_HWP( errl, db->iv_sfCmd->setupAndExecuteCmd );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed",
+ i_mbaChip->getHuid(), i_rank.getKey() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
} while (0);
@@ -388,6 +450,43 @@ uint32_t startSfRead<TYPE_MBA>( ExtensibleChip * i_mbaChip,
//------------------------------------------------------------------------------
template<>
+uint32_t cleanupSfRead<TYPE_MBA>( ExtensibleChip * i_mbaChip )
+{
+ #define PRDF_FUNC "[PlatServices::cleanupSfRead<TYPE_MBA>] "
+
+ PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
+
+ PRDF_ASSERT( nullptr != i_mbaChip );
+ PRDF_ASSERT( TYPE_MBA == i_mbaChip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Cleanup the super fast read command, if it exists.
+ MbaDataBundle * db = getMbaDataBundle( i_mbaChip );
+ if ( nullptr != db->iv_sfCmd )
+ {
+ errlHndl_t errl;
+ FAPI_INVOKE_HWP( errl, db->iv_sfCmd->cleanupCmd );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "cleanupCmd() on 0x%08x failed",
+ i_mbaChip->getHuid() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL;
+ }
+
+ // Delete the command because we don't need it any more.
+ delete db->iv_sfCmd; db->iv_sfCmd = nullptr;
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t startVcmPhase1<TYPE_MBA>( ExtensibleChip * i_chip,
const MemRank & i_rank )
{
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
index 5455cd598..5c7a57772 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
@@ -114,7 +114,7 @@ bool isBroadcastModeCapable( ExtensibleChip * i_chip );
/**
* @brief Starts a super fast read command from the first address of the given
* rank to the end of memory.
- * @param i_chip MCA or MBA chip.
+ * @param i_chip MCBIST/MCA or MBA chip.
* @param i_rank Will start the command on the first address of this slave
* rank. To ensure the command is started on a master rank boundary,
* make sure the slave rank value is 0.
@@ -123,6 +123,15 @@ bool isBroadcastModeCapable( ExtensibleChip * i_chip );
template<TARGETING::TYPE T>
uint32_t startSfRead( ExtensibleChip * i_chip, const MemRank & i_rank );
+/**
+ * @brief If necessary, this will do the necessary cleanup for the superfast
+ * command when the command is complete.
+ * @param i_chip MCBIST or MBA chip.
+ * @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
+ */
+template<TARGETING::TYPE T>
+uint32_t cleanupSfRead( ExtensibleChip * i_chip );
+
} // end namespace PlatServices
} // end namespace PRDF
OpenPOWER on IntegriCloud