diff options
-rw-r--r-- | src/usr/diag/prdf/common/plat/mem/prdfCenMbaDataBundle.H | 15 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C | 12 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices_ipl.C | 109 | ||||
-rw-r--r-- | src/usr/diag/prdf/plat/prdfPlatServices_ipl.H | 11 |
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 |