summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C')
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
index a34e4f199..4e49e423e 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_ipl.C
@@ -30,7 +30,11 @@
#include <prdfMemTdCtlr.H>
// Platform includes
+#include <prdfMemMark.H>
+#include <prdfMemoryMru.H>
#include <prdfMemScrubUtils.H>
+#include <prdfMemVcm_ipl.H>
+#include <prdfP9McaExtraSig.H>
using namespace TARGETING;
@@ -99,6 +103,174 @@ uint32_t MemTdCtlr<T>::defaultStep( STEP_CODE_DATA_STRUCT & io_sc )
//------------------------------------------------------------------------------
+template <TARGETING::TYPE T>
+uint32_t __checkEcc( ExtensibleChip * i_chip, const MemRank & i_rank,
+ TdQueue & io_queue, bool & o_errorsFound,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[__checkEcc] "
+
+ uint32_t o_rc = SUCCESS;
+
+ o_errorsFound = true; // Assume true for unless nothing found.
+
+ TargetHandle_t trgt = i_chip->getTrgt();
+ HUID huid = i_chip->getHuid();
+
+ do
+ {
+ // Check for ECC errors.
+ uint32_t eccAttns = 0;
+ o_rc = checkEccFirs<T>( i_chip, eccAttns );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "checkEccFirs<T>(0x%08x) failed", huid );
+ break;
+ }
+
+ if ( 0 != (eccAttns & MAINT_UE) )
+ {
+ // Add the signature to the multi-signature list. Also, since
+ // this will be a predictive callout, change the primary
+ // signature as well.
+ io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintUE );
+ io_sc.service_data->setSignature( huid, PRDFSIG_MaintUE );
+
+ // Add the rank to the callout list.
+ MemoryMru mm { trgt, i_rank, MemoryMruData::CALLOUT_RANK };
+ io_sc.service_data->SetCallout( mm );
+
+ // Make the error log predictive.
+ io_sc.service_data->setServiceCall();
+ }
+ else if ( 0 != (eccAttns & MAINT_MPE) )
+ {
+ io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintMPE );
+
+ // Read the chip mark from markstore.
+ MemMark chipMark;
+ o_rc = MarkStore::readChipMark<T>( i_chip, i_rank, chipMark );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "readChipMark<T>(0x%08x,%d) failed",
+ huid, i_rank.getMaster() );
+ break;
+ }
+
+ // If the chip mark is not valid, then somehow the chip mark was
+ // placed on a rank other than the rank in which the command
+ // stopped. This would most likely be a code bug.
+ PRDF_ASSERT( chipMark.isValid() );
+
+ // Add the mark to the callout list.
+ MemoryMru mm { trgt, i_rank, chipMark.getSymbol() };
+ io_sc.service_data->SetCallout( mm );
+
+ // Add a new VCM procedure to the queue.
+ TdEntry * e = new VcmEvent<T>{ i_chip, i_rank };
+ io_queue.push( e );
+ }
+ else if ( isMfgCeCheckingEnabled() &&
+ (0 != (eccAttns & MAINT_HARD_NCE_ETE)) )
+ {
+ io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintHARD_CTE );
+
+ // TODO RTC 136128
+ // - Query the per-symbol counters for the hard CE symbol (there
+ // should be only one).
+ // - Add the symbol to the callout list (via MemoryMru).
+ // - Add a TPS procedure to the queue.
+ }
+ else // Nothing found.
+ {
+ o_errorsFound = false;
+ }
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template <>
+uint32_t MemTdCtlr<TYPE_MCBIST>::checkEcc( bool & o_errorsFound,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MemTdCtlr<TYPE_MCBIST>::checkEcc] "
+
+ uint32_t o_rc = SUCCESS;
+
+ o_errorsFound = false;
+
+ MemRank rank = iv_stoppedRank.getRank();
+
+ do
+ {
+ // Get all ports in which the command was run.
+ std::vector<ExtensibleChip *> portList;
+ o_rc = getMcbistMaintPort( iv_chip, portList );
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "getMcbistMaintPort(0x%08x) failed",
+ iv_chip->getHuid() );
+ break;
+ }
+
+ // Check each MCA for ECC errors.
+ for ( auto & mcaChip : portList )
+ {
+ bool errorsFound;
+ uint32_t l_rc = __checkEcc<TYPE_MCA>( mcaChip, rank, iv_queue,
+ errorsFound, io_sc );
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "__checkEcc<TYPE_MCA>(0x%08x,%d) failed",
+ mcaChip->getHuid(), rank.getMaster() );
+ o_rc |= l_rc; continue; // Try the other MCAs.
+ }
+
+ if ( errorsFound ) o_errorsFound = true;
+ }
+ if ( SUCCESS != o_rc ) break;
+
+ } while (0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template <>
+uint32_t MemTdCtlr<TYPE_MBA>::checkEcc( bool & o_errorsFound,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MemTdCtlr<TYPE_MBA>::checkEcc] "
+
+ uint32_t o_rc = SUCCESS;
+
+ o_errorsFound = false;
+
+ MemRank rank = iv_stoppedRank.getRank();
+
+ o_rc = __checkEcc<TYPE_MBA>( iv_chip, rank, iv_queue, o_errorsFound, io_sc);
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "__checkEcc<TYPE_MBA>(0x%08x,%d) failed",
+ iv_chip->getHuid(), rank.getMaster() );
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
// Avoid linker errors with the template.
template class MemTdCtlr<TYPE_MCBIST>;
template class MemTdCtlr<TYPE_MBA>;
OpenPOWER on IntegriCloud