diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2016-09-12 12:26:37 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-09-20 16:49:27 -0400 |
commit | cac04c08e0961e57519c67765c6e1d747f36ba67 (patch) | |
tree | 84a4982b5228418a5ecb6d5f991238b24357d094 /src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C | |
parent | 2428ea76bd997fed3d9b5438251b29254455c2e3 (diff) | |
download | talos-hostboot-cac04c08e0961e57519c67765c6e1d747f36ba67.tar.gz talos-hostboot-cac04c08e0961e57519c67765c6e1d747f36ba67.zip |
PRD: add MCA support to start/stop background scrubbing
Change-Id: I4ba78f7621c5d6374bd01aa0d91ee46137c0b22c
Squashed: I9a02f087c402e5fcd07534c88fcc049a7cdd8626
Squashed: I1c06f78196db1979d28cbf7c4cd49d384939a849
Squashed: I29e2ccc0ec83d0cdc9412dbd71feff4b3ce27db3
RTC: 160719
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29525
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: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29964
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 | 292 |
1 files changed, 114 insertions, 178 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C index c64e668d9..40399336e 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C @@ -44,24 +44,25 @@ namespace PRDF { using namespace PlatServices; -template<> -int32_t clearCmdCompleteAttn<TYPE_MCBIST>(ExtensibleChip* i_mcbChip) -{ - #define PRDF_FUNC "[PRDF::clearCmdCompleteAttn<TYPE_MCBIST>] " +//------------------------------------------------------------------------------ - int32_t o_rc = SUCCESS; +template<TARGETING::TYPE T> +uint32_t __clearFir( ExtensibleChip * i_chip, const char * i_firAnd, + uint64_t i_pattern ) +{ + #define PRDF_FUNC "[__clearFir] " - SCAN_COMM_REGISTER_CLASS * mcbFirAnd = - i_mcbChip->getRegister("MCBISTFIR_AND"); - mcbFirAnd->setAllBits(); + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( T == i_chip->getTrgtType() ); - mcbFirAnd->ClearBit(10); // Maint cmd complete - mcbFirAnd->ClearBit(12); // Maint cmd WAT workaround for sf commands + SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( i_firAnd ); + reg->SetBitFieldJustified( 0, 64, i_pattern ); - if ( SUCCESS != mcbFirAnd->Write() ) + uint32_t o_rc = reg->Write(); + if ( SUCCESS != o_rc ) { - PRDF_ERR ( PRDF_FUNC "Write() failed on MCBISTFIR_AND" ); - o_rc = FAIL; + PRDF_ERR( PRDF_FUNC "Write() failed on %s: i_chip=0x%08x", + i_firAnd, i_chip->getHuid() ); } return o_rc; @@ -69,62 +70,73 @@ int32_t clearCmdCompleteAttn<TYPE_MCBIST>(ExtensibleChip* i_mcbChip) #undef PRDF_FUNC } +//------------------------------------------------------------------------------ + template<> -int32_t clearCmdCompleteAttn<TYPE_MBA>(ExtensibleChip* i_mbaChip) +uint32_t clearCmdCompleteAttn<TYPE_MCBIST>( ExtensibleChip * i_chip ) { - #define PRDF_FUNC "[PRDF::clearCmdCompleteAttn<TYPE_MBA>] " - - int32_t o_rc = SUCCESS; - - SCAN_COMM_REGISTER_CLASS * mbaSpaAnd = i_mbaChip->getRegister("MBASPA_AND"); - mbaSpaAnd->setAllBits(); - - mbaSpaAnd->ClearBit(0); // Maint cmd complete - mbaSpaAnd->ClearBit(8); // Maint cmd complete (DD1.0 workaround) + // Clear MCBISTFIR[10,12]. + return __clearFir<TYPE_MCBIST>( i_chip, "MCBISTFIR_AND", + 0xffd7ffffffffffffull ); +} - if ( SUCCESS != mbaSpaAnd->Write() ) - { - PRDF_ERR( PRDF_FUNC "Write() failed on MBASPA_AND" ); - o_rc = FAIL; - } +template<> +uint32_t clearCmdCompleteAttn<TYPE_MCA>( ExtensibleChip * i_chip ) +{ + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MCA == i_chip->getTrgtType() ); - return o_rc; + ExtensibleChip * mcbChip = getConnectedParent( i_chip, TYPE_MCBIST ); - #undef PRDF_FUNC + return clearCmdCompleteAttn<TYPE_MCBIST>( mcbChip ); } template<> -int32_t clearEccCounters<TYPE_MCBIST>(ExtensibleChip* i_mcbChip) +uint32_t clearCmdCompleteAttn<TYPE_MBA>( ExtensibleChip * i_chip ) { - #define PRDF_FUNC "[PRDF::clearEccCounters<TYPE_MCBIST>] " - int32_t o_rc = SUCCESS; + // Clear MBASPA[0,8]. + return __clearFir<TYPE_MBA>( i_chip, "MBASPA_AND", 0x7f7fffffffffffffull ); +} + +//------------------------------------------------------------------------------ + +template<TARGETING::TYPE T> +uint32_t __clearEccCounters( ExtensibleChip * i_chip, const char * i_reg, + uint32_t i_bit ) +{ + #define PRDF_FUNC "[__clearEccCounters] " + + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( T == i_chip->getTrgtType() ); + + uint32_t o_rc = SUCCESS; do { - SCAN_COMM_REGISTER_CLASS * mcbcntl = - i_mcbChip->getRegister( "MCB_CNTL" ); - - o_rc = mcbcntl->ForceRead(); + SCAN_COMM_REGISTER_CLASS * reg = i_chip->getRegister( i_reg ); + o_rc = reg->ForceRead(); // force required if ( SUCCESS != o_rc ) { - PRDF_ERR( PRDF_FUNC "ForceRead() failed on MCB_CNTL" ); + PRDF_ERR( PRDF_FUNC "ForceRead() failed on %s: i_chip=0x%08x", + i_reg, i_chip->getHuid() ); break; } - mcbcntl->SetBit(7); // Setting this bit clears all counters. + reg->SetBit( i_bit ); // Setting this bit clears all counters. - o_rc = mcbcntl->Write(); + o_rc = reg->Write(); if ( SUCCESS != o_rc ) { - PRDF_ERR( PRDF_FUNC "Write() failed on MCB_CNTL" ); + PRDF_ERR( PRDF_FUNC "Write() failed on %s: i_chip=0x%08x", + i_reg, i_chip->getHuid() ); break; } - // Hardware automatically clears bit 7, so flush this register out + // Hardware automatically clears this bit. So flush this register out // of the register cache to avoid clearing the counters again with // a write from the out-of-date cached copy. RegDataCache & cache = RegDataCache::getCachedRegisters(); - cache.flush( i_mcbChip, mcbcntl ); + cache.flush( i_chip, reg ); } while(0); @@ -134,179 +146,103 @@ int32_t clearEccCounters<TYPE_MCBIST>(ExtensibleChip* i_mcbChip) } template<> -int32_t clearEccCounters<TYPE_MBA>(ExtensibleChip* i_mbaChip) +uint32_t clearEccCounters<TYPE_MCBIST>( ExtensibleChip * i_chip ) { - #define PRDF_FUNC "[PRDF::clearEccCounters<TYPE_MBA>] " - int32_t o_rc = SUCCESS; - const char* reg_str = nullptr; - - TARGETING::TargetHandle_t mbaTrgt = i_mbaChip->GetChipHandle(); - - do - { - - uint32_t mbaPos = getTargetPosition(mbaTrgt); - reg_str = (0 == mbaPos) ? "MBA0_MBSTR" : "MBA1_MBSTR"; - SCAN_COMM_REGISTER_CLASS * mbstr = i_mbaChip->getRegister( reg_str ); + return __clearEccCounters<TYPE_MCBIST>( i_chip, "MCB_CNTL", 7 ); +} - // MBSTR's content could be modified from cleanupCmd() - // so we need to refresh - o_rc = mbstr->ForceRead(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "ForceRead() failed on %s", reg_str ); - break; - } +template<> +uint32_t clearEccCounters<TYPE_MCA>( ExtensibleChip * i_chip ) +{ + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MCA == i_chip->getTrgtType() ); - mbstr->SetBit(53); // Setting this bit clears all counters. + ExtensibleChip * mcbChip = getConnectedParent( i_chip, TYPE_MCBIST ); - o_rc = mbstr->Write(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str ); - break; - } + return clearEccCounters<TYPE_MCBIST>( mcbChip ); +} - // Hardware automatically clears bit 53, so flush this register out - // of the register cache to avoid clearing the counters again with - // a write from the out-of-date cached copy. - RegDataCache & cache = RegDataCache::getCachedRegisters(); - cache.flush( i_mbaChip, mbstr ); +template<> +uint32_t clearEccCounters<TYPE_MBA>( ExtensibleChip * i_chip ) +{ + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MBA == i_chip->getTrgtType() ); - } while(0); + ExtensibleChip * membChip = getConnectedParent( i_chip, TYPE_MEMBUF ); - return o_rc; + uint32_t pos = getTargetPosition( i_chip->getTrgt() ); + const char * reg = (0 == pos) ? "MBA0_MBSTR" : "MBA1_MBSTR"; - #undef PRDF_FUNC + return __clearEccCounters<TYPE_MEMBUF>( membChip, reg, 53 ); } +//------------------------------------------------------------------------------ + template<> -int32_t clearEccFirs<TYPE_MCBIST>(ExtensibleChip* i_mcbChip) +uint32_t clearEccFirs<TYPE_MCBIST>( ExtensibleChip * i_chip ) { - #define PRDF_FUNC "[PRDF::clearEccFirs<TYPE_MCBIST>] " - - int32_t o_rc = SUCCESS; - - TARGETING::TargetHandle_t mcbTrgt = i_mcbChip->GetChipHandle(); + uint32_t o_rc = SUCCESS; do { - //clear MCBISTFIR - bits 5-9 - SCAN_COMM_REGISTER_CLASS * mcbFirAnd = - i_mcbChip->getRegister("MCBISTFIR_AND"); - mcbFirAnd->setAllBits(); - - mcbFirAnd->SetBitFieldJustified( 5, 5, 0 ); + // Clear MCBISTFIR[5:9] + o_rc = __clearFir<TYPE_MCBIST>( i_chip, "MCBISTFIR_AND", + 0xf83fffffffffffffull ); + if ( SUCCESS != o_rc ) break; - o_rc = mcbFirAnd->Write(); - if ( SUCCESS != o_rc ) + for ( uint32_t p = 0; p < MAX_PORT_PER_MCBIST; p++ ) { - PRDF_ERR( PRDF_FUNC "Write() failed on MCBISTFIR_AND" ); - break; - } + ExtensibleChip * mcaChip = getConnectedChild( i_chip, TYPE_MCA, p ); + if ( nullptr == mcaChip ) continue; - //clear MCAECCFIR - bits 20-34, 36-37, and 39 - //iterate through all MCAs - for ( uint32_t mcaPos = 0; mcaPos < MAX_PORT_PER_MCBIST ; mcaPos++ ) - { - TargetHandle_t mcaTrgt = - getConnectedChild( mcbTrgt, TYPE_MCA, mcaPos ); - if ( nullptr == mcaTrgt ) - { - PRDF_ERR ( PRDF_FUNC "Failed to get mcaTrgt" ); - continue; - } - ExtensibleChip * mcaChip = - (ExtensibleChip*)systemPtr->GetChip(mcaTrgt); - - SCAN_COMM_REGISTER_CLASS * mcaEccFirAnd = - mcaChip->getRegister("MCAECCFIR_AND"); - mcaEccFirAnd->setAllBits(); - - mcaEccFirAnd->SetBitFieldJustified( 20, 15, 0 ); - mcaEccFirAnd->SetBitFieldJustified( 36, 2, 0 ); - mcaEccFirAnd->ClearBit(39); - - o_rc = mcaEccFirAnd->Write(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "Write() failed on MCAECCFIR_AND" ); - break; - } + // Clear MCAECCFIR[20:34,36:37,39] + o_rc = __clearFir<TYPE_MCA>( mcaChip, "MCAECCFIR_AND", + 0xfffff00012ffffffull ); + if ( SUCCESS != o_rc ) break; } } while(0); return o_rc; - - #undef PRDF_FUNC } template<> -int32_t clearEccFirs<TYPE_MBA>(ExtensibleChip* i_mbaChip) +uint32_t clearEccFirs<TYPE_MCA>( ExtensibleChip * i_chip ) { - #define PRDF_FUNC "[PRDF::clearEccFirs<TYPE_MBA>] " + PRDF_ASSERT( nullptr != i_chip ); + PRDF_ASSERT( TYPE_MCA == i_chip->getTrgtType() ); - int32_t o_rc = SUCCESS; - const char* reg_str = nullptr; + ExtensibleChip * mcbChip = getConnectedParent( i_chip, TYPE_MCBIST ); - TARGETING::TargetHandle_t mbaTrgt = i_mbaChip->GetChipHandle(); + return clearEccFirs<TYPE_MCBIST>( mcbChip ); +} + +template<> +uint32_t clearEccFirs<TYPE_MBA>( ExtensibleChip * i_chip ) +{ + uint32_t o_rc = SUCCESS; do { - uint32_t mbaPos = getTargetPosition(mbaTrgt); - reg_str = (0 == mbaPos) ? "MBA0_MBSECCFIR_AND" - : "MBA1_MBSECCFIR_AND"; - - TargetHandle_t membTrgt = getConnectedParent(mbaTrgt, TYPE_MEMBUF); - if (nullptr == membTrgt) - { - PRDF_ERR ( PRDF_FUNC "Failed to get membTrgt" ); - o_rc = FAIL; - break; - } - ExtensibleChip * membChip = - (ExtensibleChip*)systemPtr->GetChip(membTrgt); - SCAN_COMM_REGISTER_CLASS * firand = membChip->getRegister(reg_str); - firand->setAllBits(); - - // Clear all scrub MPE bits. - // This will need to be done when starting a TD procedure or bg - // scrubbing. rank may not be set when starting background scrubbing - // and technically there should only be one of the MPE bits on at a - // time so we should not have to worry about losing an attention by - // clearing them all. - firand->SetBitFieldJustified( 20, 8, 0 ); - - // Clear scrub NCE, SCE, MCE, RCE, SUE, UE bits (36-41) - firand->SetBitFieldJustified( 36, 6, 0 ); - - o_rc = firand->Write(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str ); - break; - } + ExtensibleChip * membChip = getConnectedParent( i_chip, TYPE_MEMBUF ); - SCAN_COMM_REGISTER_CLASS * spaAnd = - i_mbaChip->getRegister("MBASPA_AND"); - spaAnd->setAllBits(); + uint32_t pos = getTargetPosition( i_chip->getTrgt() ); + const char * reg = (0 == pos) ? "MBA0_MBSECCFIR_AND" + : "MBA1_MBSECCFIR_AND"; - // Clear threshold exceeded attentions - spaAnd->SetBitFieldJustified( 1, 4, 0 ); + // Clear MBSECCFIR[20:27,36:41] + o_rc = __clearFir<TYPE_MEMBUF>( membChip, reg, 0xfffff00ff03fffffull ); + if ( SUCCESS != o_rc ) break; - o_rc = spaAnd->Write(); - if ( SUCCESS != o_rc ) - { - PRDF_ERR( PRDF_FUNC "Write() failed on MBASPA_AND" ); - break; - } + // Clear MBASPA[1:4] + o_rc = __clearFir<TYPE_MBA>( i_chip, "MBASPA_AND", + 0x87ffffffffffffffull ); + if ( SUCCESS != o_rc ) break; } while(0); return o_rc; - - #undef PRDF_FUNC } -} //end namespace PRDF +} // end namespace PRDF + |