summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaleb Palmer <cnpalmer@us.ibm.com>2017-10-30 14:56:06 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2017-11-01 15:17:47 -0400
commit7f4fb82f60a51dc3742e11022867114b76cfb41d (patch)
tree5d2c820a9fa77bc713677ea313ad56530ec179b8
parentac21d7508c5457d0524dafa256f1b4d781ba2f69 (diff)
downloadtalos-hostboot-7f4fb82f60a51dc3742e11022867114b76cfb41d.tar.gz
talos-hostboot-7f4fb82f60a51dc3742e11022867114b76cfb41d.zip
PRD: Fix infinite loop when handling MPEs
Change-Id: I905e0deb0bc4a014b1c1c93dcac07a811843ae08 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/49013 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/49077 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@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>
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C26
-rw-r--r--src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H12
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H5
3 files changed, 31 insertions, 12 deletions
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
index 18cc52c6d..2af940211 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.C
@@ -294,22 +294,34 @@ uint32_t iuePortFail<TYPE_MCA>( ExtensibleChip * i_chip,
template<TARGETING::TYPE T, typename D>
uint32_t addVcmEvent( ExtensibleChip * i_chip, const MemRank & i_rank,
- const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc )
+ const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc,
+ bool i_isFetch )
{
PRDF_ASSERT( T == i_chip->getType() );
+ uint32_t o_rc = SUCCESS;
+
D db = static_cast<D>(i_chip->getDataBundle());
TdEntry * entry = new VcmEvent<T>( i_chip, i_rank, i_mark );
- return db->getTdCtlr()->handleTdEvent( io_sc, entry );
+ // We only want to call handleTdEvent for fetch attentions, if we do it in
+ // other cases we will hit an infinite loop, so we just add the entry to the
+ // queue instead.
+ if ( i_isFetch )
+ o_rc = db->getTdCtlr()->handleTdEvent( io_sc, entry );
+ else
+ db->getTdCtlr()->pushToQueue( entry );
+
+ return o_rc;
}
template
uint32_t addVcmEvent<TYPE_MCA, McaDataBundle *>( ExtensibleChip * i_chip,
const MemRank & i_rank,
const MemMark & i_mark,
- STEP_CODE_DATA_STRUCT & io_sc);
+ STEP_CODE_DATA_STRUCT & io_sc,
+ bool i_isFetch);
#endif
@@ -342,7 +354,7 @@ uint32_t addTpsEvent<TYPE_MCA, McaDataBundle *>( ExtensibleChip * i_chip,
template<TARGETING::TYPE T, typename D>
uint32_t handleMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
- STEP_CODE_DATA_STRUCT & io_sc )
+ STEP_CODE_DATA_STRUCT & io_sc, bool i_isFetch )
{
#define PRDF_FUNC "[MemEcc::handleMpe] "
@@ -373,7 +385,7 @@ uint32_t handleMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
#ifdef __HOSTBOOT_RUNTIME
// Add a VCM request to the TD queue.
- o_rc = addVcmEvent<T,D>( i_chip, i_rank, chipMark, io_sc );
+ o_rc = addVcmEvent<T,D>( i_chip, i_rank, chipMark, io_sc, i_isFetch );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "addVcmEvent() failed: i_chip=0x%08x "
@@ -393,7 +405,7 @@ uint32_t handleMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
// To resolve template linker errors.
template
uint32_t handleMpe<TYPE_MCA, McaDataBundle *>( ExtensibleChip * i_chip,
- const MemRank & i_rank, STEP_CODE_DATA_STRUCT & io_sc );
+ const MemRank & i_rank, STEP_CODE_DATA_STRUCT & io_sc, bool i_isFetch );
//------------------------------------------------------------------------------
@@ -439,7 +451,7 @@ uint32_t analyzeFetchMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
D db = static_cast<D>(i_chip->getDataBundle());
db->iv_ueTable.addEntry( UE_TABLE::FETCH_MPE, addr );
- o_rc = MemEcc::handleMpe<T,D>( i_chip, i_rank, io_sc );
+ o_rc = MemEcc::handleMpe<T,D>( i_chip, i_rank, io_sc, true );
if ( SUCCESS != o_rc )
{
PRDF_ERR( PRDF_FUNC "handleMpe<T>(0x%08x, 0x%02x) failed",
diff --git a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
index 2c93e0cb1..5a48cf951 100644
--- a/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
+++ b/src/usr/diag/prdf/common/plat/mem/prdfMemEccAnalysis.H
@@ -107,14 +107,15 @@ uint32_t handleMemIue( ExtensibleChip * i_chip, const MemRank & i_rank,
/**
* @brief Handles a MPE attention.
- * @param i_chip MCA or MBA.
- * @param i_rank Target rank.
- * @param io_sc The step code data struct.
+ * @param i_chip MCA or MBA.
+ * @param i_rank Target rank.
+ * @param io_sc The step code data struct.
+ * @param i_isFetch Whether this is a fetch attn or not.
* @return Non-SUCCESS if an interal function fails, SUCCESS otherwise.
*/
template<TARGETING::TYPE T, typename D>
uint32_t handleMpe( ExtensibleChip * i_chip, const MemRank & i_rank,
- STEP_CODE_DATA_STRUCT & io_sc );
+ STEP_CODE_DATA_STRUCT & io_sc, bool i_isFetch = false );
/**
* @brief Analyzes a fetch MPE attention.
@@ -203,7 +204,8 @@ uint32_t maskMemPort( ExtensibleChip * i_chip );
template<TARGETING::TYPE T, typename D>
uint32_t addVcmEvent( ExtensibleChip * i_chip, const MemRank & i_rank,
- const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc );
+ const MemMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc,
+ bool i_isFetch = false );
template<TARGETING::TYPE T, typename D>
uint32_t addTpsEvent( ExtensibleChip * i_chip, const MemRank & i_rank,
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
index e49112cb0..33f3187ea 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.H
@@ -102,6 +102,11 @@ class MemTdCtlr
uint32_t handleTdEvent( STEP_CODE_DATA_STRUCT & io_sc,
TdEntry * i_entry );
+ /**
+ * @brief Pushes a new TdEntry to the back of iv_queue.
+ * @param i_entry The new TD queue entry.
+ */
+ void pushToQueue( TdEntry * i_entry ) { iv_queue.push(i_entry); }
private:
OpenPOWER on IntegriCloud