diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2016-09-20 10:45:03 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-09-22 10:54:17 -0400 |
commit | c3e8041de1c99af5f9ced249e0c471b10b504e69 (patch) | |
tree | 49e1c476cdb90ac00a122276b9e798de35822b56 /src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C | |
parent | 35947c5fc61541987c6acae263752a8593615ff1 (diff) | |
download | talos-hostboot-c3e8041de1c99af5f9ced249e0c471b10b504e69.tar.gz talos-hostboot-c3e8041de1c99af5f9ced249e0c471b10b504e69.zip |
PRD: create utility to query maintenance ECC FIRs
Change-Id: I2689c66b700614b6cc0caaba70af4a8e3834dcf5
RTC: 161234
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29956
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30032
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C')
-rw-r--r-- | src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C index 40399336e..6a8a740d4 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C @@ -244,5 +244,134 @@ uint32_t clearEccFirs<TYPE_MBA>( ExtensibleChip * i_chip ) return o_rc; } +//------------------------------------------------------------------------------ + +template<> +uint32_t checkEccFirs<TYPE_MCA>( ExtensibleChip * i_chip, + uint32_t & o_eccAttns ) +{ + #define PRDF_FUNC "[checkEccFirs<TYPE_MCA>] " + + uint32_t o_rc = SUCCESS; + + o_eccAttns = MAINT_NO_ERROR; + + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MCA == i_chip->getTrgtType() ); + + ExtensibleChip * mcbChip = getConnectedParent( i_chip, TYPE_MCBIST ); + PRDF_ASSERT( nullptr != mcbChip ); + + SCAN_COMM_REGISTER_CLASS * mcaeccfir = i_chip->getRegister( "MCAECCFIR" ); + SCAN_COMM_REGISTER_CLASS * mcbistfir = mcbChip->getRegister( "MCBISTFIR" ); + + do + { + o_rc = mcaeccfir->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 != mcaeccfir->GetBitFieldJustified(20,8) ) + o_eccAttns |= MAINT_MPE; + + if ( mcaeccfir->IsBitSet(30) ) o_eccAttns |= MAINT_SCE; + if ( mcaeccfir->IsBitSet(31) ) o_eccAttns |= MAINT_MCE; + if ( mcaeccfir->IsBitSet(34) ) o_eccAttns |= MAINT_UE; + if ( mcaeccfir->IsBitSet(37) ) o_eccAttns |= MAINT_IUE; + if ( mcaeccfir->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", + mcbChip->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 ) +{ + #define PRDF_FUNC "[checkEccFirs<TYPE_MBA>] " + + uint32_t o_rc = SUCCESS; + + o_eccAttns = MAINT_NO_ERROR; + + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MBA == i_chip->getTrgtType() ); + + ExtensibleChip * membChip = getConnectedParent( i_chip, TYPE_MEMBUF ); + PRDF_ASSERT( nullptr != membChip ); + + uint32_t pos = getTargetPosition( i_chip->getTrgt() ); + const char * reg = (0 == pos) ? "MBA0_MBSECCFIR" : "MBA1_MBSECCFIR"; + + SCAN_COMM_REGISTER_CLASS * mbseccfir = membChip->getRegister( reg ); + SCAN_COMM_REGISTER_CLASS * mbspa = i_chip->getRegister( "MBASPA" ); + + do + { + o_rc = mbseccfir->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on %s: membChip=0x%08x", + reg, membChip->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. + if ( 0 != mbseccfir->GetBitFieldJustified(20,8) ) + o_eccAttns |= MAINT_MPE; + + if ( mbseccfir->IsBitSet(37) ) o_eccAttns |= MAINT_SCE; + if ( mbseccfir->IsBitSet(38) ) o_eccAttns |= MAINT_MCE; + if ( mbseccfir->IsBitSet(41) ) o_eccAttns |= MAINT_UE; + + o_rc = mbspa->Read(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC "Read() failed on MBASPA: i_chip=0x%08x", + i_chip->getHuid() ); + break; + } + + if ( mbspa->IsBitSet(1) ) o_eccAttns |= MAINT_HARD_NCE_ETE; + if ( mbspa->IsBitSet(2) ) o_eccAttns |= MAINT_SOFT_NCE_ETE; + if ( mbspa->IsBitSet(3) ) o_eccAttns |= MAINT_INT_NCE_ETE; + if ( mbspa->IsBitSet(4) ) o_eccAttns |= MAINT_RCE_ETE; + + } while(0); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + } // end namespace PRDF |