summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2018-04-09 15:33:02 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-04-19 16:45:01 -0400
commit360d83a83ec25acbdb6b40e3c773e017c75b6cb4 (patch)
tree1f8fab4714fb56001a866a2601f722d50c2e910a
parentd81499bb6b6ed8614a88b2fab1ff1fb439771864 (diff)
downloadtalos-hostboot-360d83a83ec25acbdb6b40e3c773e017c75b6cb4.tar.gz
talos-hostboot-360d83a83ec25acbdb6b40e3c773e017c75b6cb4.zip
PRD: Generic PlatServices functions to start a command on rank
Change-Id: Id2c67e345936a4ed27b1c49f0feef776fe1bfcc6 RTC: 190428 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57150 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com> Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57131 CI-Ready: Zane C. Shelley <zshelle@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H7
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.C163
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices.H18
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.C155
-rw-r--r--src/usr/diag/prdf/plat/prdfPlatServices_ipl.H25
5 files changed, 362 insertions, 6 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H b/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H
index 142eac1ce..4b1fc07fb 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemAddress.H
@@ -43,6 +43,13 @@ namespace PRDF
class ExtensibleChip;
+/** Used to specify target address ranges for functions input. */
+enum AddrRangeType
+{
+ SLAVE_RANK, ///< Target slave rank only.
+ MASTER_RANK, ///< Target entire master rank.
+};
+
//------------------------------------------------------------------------------
// Class MemAddr
//------------------------------------------------------------------------------
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.C b/src/usr/diag/prdf/plat/prdfPlatServices.C
index 6e9c45c0c..29acee7e2 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.C
@@ -605,6 +605,70 @@ uint32_t startBgScrub<TYPE_MCBIST>( ExtensibleChip * i_mcaChip,
//------------------------------------------------------------------------------
+template<>
+uint32_t startTdScrub<TYPE_MCA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ AddrRangeType i_rangeType,
+ mss::mcbist::stop_conditions i_stopCond )
+{
+ #define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_MCA>] "
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MCA == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Set stop-on-AUE for all target scrubs. See explanation in startBgScrub()
+ // for the reasons why.
+ i_stopCond.set_pause_on_aue(mss::ON);
+
+ do
+ {
+ // Get the address range of the given rank.
+ mss::mcbist::address saddr, eaddr;
+ o_rc = getMemAddrRange<TYPE_MCA>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Get the MCBIST fapi target.
+ ExtensibleChip * mcbChip = getConnectedParent( i_chip, TYPE_MCBIST );
+ fapi2::Target<fapi2::TARGET_TYPE_MCBIST> fapiTrgt (mcbChip->getTrgt());
+
+ // Clear all of the counters and maintenance ECC attentions.
+ o_rc = prepareNextCmd<TYPE_MCBIST>( mcbChip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // Start targeted scrub command.
+ errlHndl_t errl = nullptr;
+ FAPI_INVOKE_HWP( errl, mss::memdiags::targeted_scrub, fapiTrgt,
+ i_stopCond, saddr, eaddr, mss::mcbist::NONE );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "mss::memdiags::targeted_scrub(0x%08x,0x%02x) "
+ "failed", mcbChip->getHuid(), i_rank.getKey() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
uint32_t __startTdScrub_mca( ExtensibleChip * i_mcaChip,
mss::mcbist::address i_saddr,
mss::mcbist::address i_eaddr,
@@ -844,6 +908,105 @@ uint32_t startBgScrub<TYPE_MBA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
+uint32_t startTdScrub<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ AddrRangeType i_rangeType,
+ uint32_t i_stopCond )
+{
+ #define PRDF_FUNC "[PlatServices::startTdScrub<TYPE_MBA>] "
+
+ #ifndef __HOSTBOOT_RUNTIME // IPL only
+ PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
+ #endif
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Make sure there is a command complete attention when the command stops.
+ i_stopCond |= mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION;
+
+ // Make sure the command stops on the end address if there are no errors.
+ i_stopCond |= mss_MaintCmd::STOP_ON_END_ADDRESS;
+
+ // IPL:
+ // IUEs (reported via RCE ETE) are reported as UEs during read operations.
+ // Therefore, we will treat IUEs like UEs for scrub operations simply to
+ // maintain consistency during all of Memory Diagnostics. Note that MDIA
+ // sets the threshold to 1 when it starts the first command on this MBA
+ // and that threshold should never change throughout all of Memory
+ // Diagnostics.
+ // Runtime:
+ // The runtime strategy for IUEs (reported via RCE ETE) is slightly
+ // different than IPL. For the most part we want to ignore them. However,
+ // we must have a threshold just incase they are causing problems. Note
+ // that the threshold this is set (field:2047, mnfg:1) when background
+ // scrubbing is started and that threshold should never change throughout
+ // all of runtime diagnostics.
+
+ i_stopCond |= mss_MaintCmd::STOP_ON_RETRY_CE_ETE;
+
+ // Default speed is to run as fast as possible.
+ mss_MaintCmd::TimeBaseSpeed cmdSpeed = mss_MaintCmd::FAST_MAX_BW_IMPACT;
+
+ #ifdef __HOSTBOOT_RUNTIME
+
+ // There is a Centaur bug preventing us from running at full speed because
+ // it will reduce mainline bandwidth to almost 10%. Customers won't like
+ // this. So we will have to use a slower speed.
+ if ( !enableFastBgScrub() ) cmdSpeed = mss_MaintCmd::FAST_MIN_BW_IMPACT;
+
+ #endif
+
+ do
+ {
+ // Get the address range of the given rank.
+ fapi2::buffer<uint64_t> saddr, eaddr;
+ o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Clear all of the counters and maintenance ECC attentions.
+ o_rc = prepareNextCmd<TYPE_MBA>( i_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // Get the MBA fapi target.
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() );
+
+ // Start the background scrub command.
+ mss_TimeBaseScrub cmd { fapiTrgt, saddr, eaddr, cmdSpeed,
+ i_stopCond, false };
+ errlHndl_t errl = nullptr;
+ FAPI_INVOKE_HWP( errl, cmd.setupAndExecuteCmd );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t startTpsRuntime<TYPE_MBA>( ExtensibleChip * i_mbaChip,
const MemRank & i_rank,
bool i_countAllCes )
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices.H b/src/usr/diag/prdf/plat/prdfPlatServices.H
index 0cf7119e8..0a3aa9b1c 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices.H
@@ -106,12 +106,6 @@ uint32_t putScom(TARGETING::TargetHandle_t i_target, BitString& io_bs,
//## Memory specific functions
//##############################################################################
-enum AddrRangeType
-{
- SLAVE_RANK, ///< Target slave rank only.
- MASTER_RANK, ///< Target entire master rank.
-};
-
/**
* @brief Returns the start and end address of the given rank.
* @note The end addresses returned from the MCBIST HWPs give a maximum
@@ -167,6 +161,18 @@ template<TARGETING::TYPE T>
uint32_t startBgScrub( ExtensibleChip * i_chip, const MemRank & i_rank );
/**
+ * @brief Starts a scrub command on the target rank.
+ * @param i_chip MCA or MBA chip.
+ * @param i_rank Target rank.
+ * @param i_rangeType See enum AddrRangeType.
+ * @param i_stopCond The stop conditions for the targeted scrub.
+ * @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
+ */
+template<TARGETING::TYPE TT, typename SCT>
+uint32_t startTdScrub( ExtensibleChip * i_chip, const MemRank & i_rank,
+ AddrRangeType i_rangeType, SCT i_stopCond );
+
+/**
* @brief Starts a targeted scrub command on the target rank for VCM phase 1.
* @param i_chip MCA or MBA chip.
* @param i_rank The rank to target.
diff --git a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
index 206deb85a..374b71bf1 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.C
@@ -486,6 +486,161 @@ uint32_t cleanupSfRead<TYPE_MBA>( ExtensibleChip * i_mbaChip )
//------------------------------------------------------------------------------
template<>
+uint32_t startTdSfRead<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ AddrRangeType i_rangeType,
+ uint32_t i_stopCond )
+{
+ #define PRDF_FUNC "[PlatServices::startTdSfRead<TYPE_MBA>] "
+
+ PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Make sure there is a command complete attention when the command stops.
+ i_stopCond |= mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION;
+
+ // Make sure the command stops on the end address if there are no errors.
+ i_stopCond |= mss_MaintCmd::STOP_ON_END_ADDRESS;
+
+ do
+ {
+ // Get the address range of the given rank.
+ fapi2::buffer<uint64_t> saddr, eaddr;
+ o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Clear all of the counters and maintenance ECC attentions.
+ o_rc = prepareNextCmd<TYPE_MBA>( i_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // Get the MBA fapi target.
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() );
+
+ // 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_chip );
+ PRDF_ASSERT( nullptr == db->iv_sfCmd ); // Code bug.
+ db->iv_sfCmd = new mss_SuperFastRead { fapiTrgt, saddr, eaddr,
+ i_stopCond, false };
+
+ // Start the super fast read command.
+ errlHndl_t errl = nullptr;
+ FAPI_INVOKE_HWP( errl, db->iv_sfCmd->setupAndExecuteCmd );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
+uint32_t startTdSteerCleanup<TYPE_MBA>( ExtensibleChip * i_chip,
+ const MemRank & i_rank,
+ AddrRangeType i_rangeType,
+ uint32_t i_stopCond )
+{
+ #define PRDF_FUNC "[PlatServices::startTdSteerCleanup<TYPE_MBA>] "
+
+ PRDF_ASSERT( isInMdiaMode() ); // MDIA must be running.
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MBA == i_chip->getType() );
+
+ uint32_t o_rc = SUCCESS;
+
+ // Make sure there is a command complete attention when the command stops.
+ i_stopCond |= mss_MaintCmd::ENABLE_CMD_COMPLETE_ATTENTION;
+
+ // Make sure the command stops on the end address if there are no errors.
+ i_stopCond |= mss_MaintCmd::STOP_ON_END_ADDRESS;
+
+ // Default speed is to run as fast as possible.
+ mss_MaintCmd::TimeBaseSpeed cmdSpeed = mss_MaintCmd::FAST_MAX_BW_IMPACT;
+
+ // IUEs (reported via RCE ETE) are reported as UEs during read operations.
+ // Therefore, we will treat IUEs like UEs for scrub operations simply to
+ // maintain consistency during all of Memory Diagnostics. Note that since we
+ // set the stop on RCE ETE flag, this requires a threshold in the MBSTR.
+ // Fortunately, MDIA sets the threshold to 1 when it starts the first
+ // command on this MBA and that threshold should never change throughout all
+ // of Memory Diagnostics.
+
+ i_stopCond |= mss_MaintCmd::STOP_ON_RETRY_CE_ETE;
+
+ do
+ {
+ // Get the address range of the given rank.
+ fapi2::buffer<uint64_t> saddr, eaddr;
+ o_rc = getMemAddrRange<TYPE_MBA>( i_chip, i_rank, saddr, eaddr,
+ i_rangeType );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMemAddrRange(0x%08x,0x%2x) failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ break;
+ }
+
+ // Clear all of the counters and maintenance ECC attentions.
+ o_rc = prepareNextCmd<TYPE_MBA>( i_chip );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "prepareNextCmd(0x%08x) failed",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // Get the MBA fapi target.
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> fapiTrgt ( i_chip->getTrgt() );
+
+ // Start the background scrub command.
+ mss_TimeBaseSteerCleanup cmd { fapiTrgt, saddr, eaddr, cmdSpeed,
+ i_stopCond, false };
+ errlHndl_t errl = nullptr;
+ FAPI_INVOKE_HWP( errl, cmd.setupAndExecuteCmd );
+ if ( nullptr != errl )
+ {
+ PRDF_ERR( PRDF_FUNC "setupAndExecuteCmd() on 0x%08x,0x%02x failed",
+ i_chip->getHuid(), i_rank.getKey() );
+ PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
+ o_rc = FAIL; break;
+ }
+
+ } while (0);
+
+ 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 61a5ef422..6bf884795 100644
--- a/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
+++ b/src/usr/diag/prdf/plat/prdfPlatServices_ipl.H
@@ -34,6 +34,7 @@
* is common between FSP and Hostboot should be in the respective common file.
*/
+#include <prdfMemAddress.H>
#include <diag/mdia/mdia.H>
//------------------------------------------------------------------------------
@@ -131,6 +132,30 @@ uint32_t startSfRead( ExtensibleChip * i_chip, const MemRank & i_rank );
template<TARGETING::TYPE T>
uint32_t cleanupSfRead( ExtensibleChip * i_chip );
+/**
+ * @brief Starts a super fast read command on the target rank.
+ * @param i_chip MBA chip.
+ * @param i_rank Target rank.
+ * @param i_rangeType See enum AddrRangeType.
+ * @param i_stopCond The stop conditions for the targeted scrub.
+ * @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
+ */
+template<TARGETING::TYPE TT, typename VT>
+uint32_t startTdSfRead( ExtensibleChip * i_chip, const MemRank & i_rank,
+ AddrRangeType i_rangeType, VT i_stopCond );
+
+/**
+ * @brief Starts a steer cleanup scrub command on the target rank.
+ * @param i_chip MBA chip.
+ * @param i_rank Target rank.
+ * @param i_rangeType See enum AddrRangeType.
+ * @param i_stopCond The stop conditions for the targeted scrub.
+ * @return Non-SUCCESS if an internal function fails, otherwise SUCCESS.
+ */
+template<TARGETING::TYPE TT, typename VT>
+uint32_t startTdSteerCleanup( ExtensibleChip * i_chip, const MemRank & i_rank,
+ AddrRangeType i_rangeType, VT i_stopCond );
+
} // end namespace PlatServices
} // end namespace PRDF
OpenPOWER on IntegriCloud