summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/plat/mem
diff options
context:
space:
mode:
authorCaleb Palmer <cnpalmer@us.ibm.com>2019-04-09 15:29:07 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2019-04-18 10:33:07 -0500
commit9d139bd7d99a87c6d11f6569482218badb49cc8b (patch)
treede94afe1294c8faa0acb828b21929746afa1482a /src/usr/diag/prdf/plat/mem
parent36a58f1f80473c1ee39e449c85f78ead269c0348 (diff)
downloadtalos-hostboot-9d139bd7d99a87c6d11f6569482218badb49cc8b.tar.gz
talos-hostboot-9d139bd7d99a87c6d11f6569482218badb49cc8b.zip
PRD: Axone/Explorer Misc Updates needed for TdCtlr/DataBundles
Change-Id: Ia769f949f984c810b998c19fd32c7c3af2e06244 RTC: 207388 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/75791 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Paul Greenwood <paul.greenwood@ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/76086 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>
Diffstat (limited to 'src/usr/diag/prdf/plat/mem')
-rwxr-xr-xsrc/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C24
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C127
-rw-r--r--src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H31
3 files changed, 178 insertions, 4 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C b/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C
index 0ae5cec80..869aa92e8 100755
--- a/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemIplCeStats.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2018 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -83,6 +83,19 @@ void MemIplCeStats<TYPE_MCA>::banAnalysis( uint8_t i_dimmSlct,
//------------------------------------------------------------------------------
template<>
+void MemIplCeStats<TYPE_MEM_PORT>::banAnalysis( uint8_t i_dimmSlct,
+ uint8_t i_portSlct )
+{
+ PRDF_ASSERT( i_dimmSlct < MAX_DIMM_PER_PORT );
+ PRDF_ASSERT( 0 == i_portSlct );
+
+ DimmKey banKey = { i_dimmSlct, i_portSlct };
+ iv_bannedAnalysis[banKey] = true;
+}
+
+//------------------------------------------------------------------------------
+
+template<>
void MemIplCeStats<TYPE_MBA>::banAnalysis( uint8_t i_dimmSlct )
{
// Two DIMMs per DIMM select on MBA.
@@ -101,6 +114,14 @@ void MemIplCeStats<TYPE_MCA>::banAnalysis( uint8_t i_dimmSlct )
banAnalysis( i_dimmSlct, 0 );
}
+//------------------------------------------------------------------------------
+
+template<>
+void MemIplCeStats<TYPE_MEM_PORT>::banAnalysis( uint8_t i_dimmSlct )
+{
+ // Only one DIMM per DIMM select on MEM_PORT.
+ banAnalysis( i_dimmSlct, 0 );
+}
//------------------------------------------------------------------------------
@@ -460,5 +481,6 @@ void MemIplCeStats<T>::addMruAndCommitErrl( const MemoryMru & i_memmru,
// need these templates to avoid linker errors
template class MemIplCeStats<TYPE_MCA>;
template class MemIplCeStats<TYPE_MBA>;
+template class MemIplCeStats<TYPE_MEM_PORT>;
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
index 9d8e00f50..5351b842a 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
+++ b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
@@ -188,6 +188,23 @@ uint32_t clearEccCounters<TYPE_MCA>( ExtensibleChip * i_chip )
}
template<>
+uint32_t clearEccCounters<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
+{
+ return __clearEccCounters<TYPE_OCMB_CHIP>( i_chip, "MCB_CNTL", 7 );
+}
+
+template<>
+uint32_t clearEccCounters<TYPE_MEM_PORT>( ExtensibleChip * i_chip )
+{
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+
+ ExtensibleChip * ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
+
+ return clearEccCounters<TYPE_OCMB_CHIP>( ocmbChip );
+}
+
+template<>
uint32_t clearEccCounters<TYPE_MBA>( ExtensibleChip * i_chip )
{
PRDF_ASSERT( nullptr != i_chip );
@@ -253,6 +270,53 @@ uint32_t clearEccFirs<TYPE_MCA>( ExtensibleChip * i_chip )
}
template<>
+uint32_t clearEccFirs<TYPE_OCMB_CHIP>( ExtensibleChip * i_chip )
+{
+ uint32_t o_rc = SUCCESS;
+
+ do
+ {
+ // Clear MCBISTFIR[5:9]
+ o_rc = __clearFir<TYPE_OCMB_CHIP>( i_chip, "MCBISTFIR_AND",
+ 0xf83fffffffffffffull );
+ if ( SUCCESS != o_rc ) break;
+
+ // Maintenance AUEs/IAUEs will be reported as system checkstops.
+ // Maintenance IMPEs will be reported as recoverable attentions at
+ // all times. Maintence IUEs will be masked during Memory
+ // Diagnostics and handled in the Targeted diagnostics code. After
+ // Memory Diagnostics, maintenance IUEs will be reported as
+ // recoverable in the field (no stop-on-error), but will remain
+ // masked if MNFG thresholds are enabled. In this case, the command
+ // will stop on RCE ETE in order to get a more accuracy callout. So
+ // clear RDFFIR[20:32,34:35,38] always and RDFFIR[37] in MNFG
+ // mode or during Memory Diagnostics.
+ uint64_t mask = 0xfffff0004dffffffull;
+ if ( mfgMode() ) mask &= 0xfffffffffbffffffull;
+ #ifndef __HOSTBOOT_RUNTIME
+ if ( isInMdiaMode() ) mask &= 0xfffffffffbffffffull;
+ #endif
+
+ o_rc = __clearFir<TYPE_OCMB_CHIP>( i_chip, "RDFFIR_AND", mask );
+ if ( SUCCESS != o_rc ) break;
+
+ } while(0);
+
+ return o_rc;
+}
+
+template<>
+uint32_t clearEccFirs<TYPE_MEM_PORT>( ExtensibleChip * i_chip )
+{
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+
+ ExtensibleChip * ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
+
+ return clearEccFirs<TYPE_OCMB_CHIP>( ocmbChip );
+}
+
+template<>
uint32_t clearEccFirs<TYPE_MBA>( ExtensibleChip * i_chip )
{
uint32_t o_rc = SUCCESS;
@@ -345,6 +409,69 @@ uint32_t checkEccFirs<TYPE_MCA>( ExtensibleChip * i_chip,
//------------------------------------------------------------------------------
template<>
+uint32_t checkEccFirs<TYPE_MEM_PORT>( ExtensibleChip * i_chip,
+ uint32_t & o_eccAttns )
+{
+ #define PRDF_FUNC "[checkEccFirs<TYPE_MEM_PORT>] "
+
+ uint32_t o_rc = SUCCESS;
+
+ o_eccAttns = MAINT_NO_ERROR;
+
+ PRDF_ASSERT( nullptr != i_chip );
+ PRDF_ASSERT( TYPE_MEM_PORT == i_chip->getType() );
+
+ ExtensibleChip * ocmbChip = getConnectedParent( i_chip, TYPE_OCMB_CHIP );
+
+ SCAN_COMM_REGISTER_CLASS * rdffir = ocmbChip->getRegister( "RDFFIR" );
+ SCAN_COMM_REGISTER_CLASS * mcbistfir = ocmbChip->getRegister( "MCBISTFIR" );
+
+ do
+ {
+ o_rc = rdffir->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on MCAECCFIR: i_chip=0x%08x",
+ i_chip->getHuid() );
+ break;
+ }
+
+ // We can assume that any chip mark placed by a maintenance command was
+ // done on the rank in which the command stopped. So we can blindly
+ // check all bits to determine if there was an MPE on the stopped rank.
+ if ( 0 != rdffir->GetBitFieldJustified(20,8) ) o_eccAttns |= MAINT_MPE;
+
+ if ( rdffir->IsBitSet(28) ) o_eccAttns |= MAINT_NCE;
+ if ( rdffir->IsBitSet(29) ) o_eccAttns |= MAINT_TCE;
+ if ( rdffir->IsBitSet(30) ) o_eccAttns |= MAINT_SCE;
+ if ( rdffir->IsBitSet(31) ) o_eccAttns |= MAINT_MCE;
+ if ( rdffir->IsBitSet(34) ) o_eccAttns |= MAINT_UE;
+ if ( rdffir->IsBitSet(37) ) o_eccAttns |= MAINT_IUE;
+ if ( rdffir->IsBitSet(39) ) o_eccAttns |= MAINT_IMPE;
+
+ o_rc = mcbistfir->Read();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Read() failed on MCBISTFIR: mcbChip=0x%08x",
+ ocmbChip->getHuid() );
+ break;
+ }
+
+ if ( mcbistfir->IsBitSet(5) ) o_eccAttns |= MAINT_HARD_NCE_ETE;
+ if ( mcbistfir->IsBitSet(6) ) o_eccAttns |= MAINT_SOFT_NCE_ETE;
+ if ( mcbistfir->IsBitSet(7) ) o_eccAttns |= MAINT_INT_NCE_ETE;
+ if ( mcbistfir->IsBitSet(8) ) o_eccAttns |= MAINT_RCE_ETE;
+
+ } while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+//------------------------------------------------------------------------------
+
+template<>
uint32_t checkEccFirs<TYPE_MBA>( ExtensibleChip * i_chip,
uint32_t & o_eccAttns )
{
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H b/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H
index ddc9b7390..e61389ea2 100644
--- a/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H
+++ b/src/usr/diag/prdf/plat/mem/prdfMemTdRankList.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2017 */
+/* Contributors Listed Below - COPYRIGHT 2013,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -80,8 +80,8 @@ class TdRankListEntry
private:
- ExtensibleChip * iv_chip = nullptr; ///< MCA or MBA chip.
- MemRank iv_rank = MemRank(0); ///< Any rank on the MCA or MBA.
+ ExtensibleChip * iv_chip = nullptr; ///< MCA, MBA, or MEM_PORT chip.
+ MemRank iv_rank = MemRank(0); ///< Any rank on the MCA/MBA/MEM_PORT
};
/**
@@ -183,6 +183,31 @@ inline TdRankList<TARGETING::TYPE_MCBIST>::TdRankList( ExtensibleChip * i_chip )
//------------------------------------------------------------------------------
template<>
+inline TdRankList<TARGETING::TYPE_OCMB_CHIP>::TdRankList(
+ ExtensibleChip * i_chip )
+{
+ using namespace TARGETING;
+ using namespace PlatServices;
+
+ PRDF_ASSERT( TYPE_OCMB_CHIP == i_chip->getType() );
+
+ ExtensibleChipList memPortChipList = getConnected( i_chip, TYPE_MEM_PORT );
+ for ( auto & memPortChip : memPortChipList )
+ {
+ std::vector<MemRank> rankList;
+ getSlaveRanks<TYPE_MEM_PORT>( memPortChip->getTrgt(), rankList );
+ PRDF_ASSERT( !rankList.empty() ); // target configured with no ranks
+
+ for ( auto & rank : rankList )
+ {
+ iv_list.push_back( TdRankListEntry(memPortChip, rank) );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+template<>
inline TdRankList<TARGETING::TYPE_MBA>::TdRankList( ExtensibleChip * i_chip )
{
using namespace TARGETING;
OpenPOWER on IntegriCloud