From ad8ec727bc7f5c641c92e274829cc89f6e0e7f1f Mon Sep 17 00:00:00 2001 From: Zane Shelley Date: Sat, 31 Mar 2018 16:00:01 -0500 Subject: PRD: super fast read command support for MBA Change-Id: Ie7cf3910e177056bdabf68ee6d0e66f8ec130b7d RTC: 190428 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56551 Tested-by: Jenkins Server Reviewed-by: Caleb N. Palmer Reviewed-by: Benjamin J. Weisenbeck Reviewed-by: Brian J. Stegmiller Reviewed-by: Zane C. Shelley Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56890 CI-Ready: Zane C. Shelley Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: Zane C. Shelley --- .../prdf/common/plat/mem/prdfCenMbaDataBundle.H | 15 +++ src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C | 12 +++ src/usr/diag/prdf/plat/prdfPlatServices_ipl.C | 109 ++++++++++++++++++++- src/usr/diag/prdf/plat/prdfPlatServices_ipl.H | 11 ++- 4 files changed, 141 insertions(+), 6 deletions(-) (limited to 'src/usr') 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. @@ -91,6 +95,17 @@ class MbaDataBundle : public DataBundle /** The Targeted Diagnostics controller. */ MemTdCtlr * 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::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::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( 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 #include +#include #include #include #include @@ -286,7 +287,7 @@ uint32_t startSfRead( 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( 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( ExtensibleChip * i_mcaChip, return startSfRead( i_mcaChip, i_rank ); } +//------------------------------------------------------------------------------ + +template<> +uint32_t cleanupSfRead( ExtensibleChip * i_mcbChip ) +{ + return SUCCESS; // Not needed for MCBIST commands. +} + //############################################################################## //## Centaur Maintenance Command wrappers //############################################################################## @@ -359,13 +368,50 @@ uint32_t startSfRead( ExtensibleChip * i_mbaChip, { #define PRDF_FUNC "[PlatServices::startSfRead] " + 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 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 saddr, eaddr, junk; + + // Get the first address of the given rank. + o_rc = getMemAddrRange( 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( 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( i_mbaChip ); if ( SUCCESS != o_rc ) @@ -375,8 +421,24 @@ uint32_t startSfRead( 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); @@ -387,6 +449,43 @@ uint32_t startSfRead( ExtensibleChip * i_mbaChip, //------------------------------------------------------------------------------ +template<> +uint32_t cleanupSfRead( ExtensibleChip * i_mbaChip ) +{ + #define PRDF_FUNC "[PlatServices::cleanupSfRead] " + + 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( 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 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 +uint32_t cleanupSfRead( ExtensibleChip * i_chip ); + } // end namespace PlatServices } // end namespace PRDF -- cgit v1.2.1