summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
diff options
context:
space:
mode:
authorCaleb Palmer <cnpalmer@us.ibm.com>2016-08-26 13:50:04 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-09-20 16:47:29 -0400
commit41c9a48acc1bd50d2fe3f0185cf8cf805d299af0 (patch)
tree8967dc668d36cacb74699403a961a5d7db4c3a11 /src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
parentd5de7972297a818670c0987b59a4f4cb398f1cd7 (diff)
downloadtalos-hostboot-41c9a48acc1bd50d2fe3f0185cf8cf805d299af0.tar.gz
talos-hostboot-41c9a48acc1bd50d2fe3f0185cf8cf805d299af0.zip
PRD: Enable background scrubbing
Change-Id: I3a92fbb75bc8642f79e8aca571078baee8d4f532 RTC: 147390 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28186 Tested-by: Jenkins Server <pfd-jenkins+hostboot@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/29179 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.C312
1 files changed, 312 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
new file mode 100644
index 000000000..c64e668d9
--- /dev/null
+++ b/src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C
@@ -0,0 +1,312 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/diag/prdf/plat/mem/prdfMemScrubUtils.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+/** @file prdfMemScrubUtils.C
+ * @brief Define the functionality necessary to start initial background scrub
+ */
+
+// Framework includes
+#include <prdfMemScrubUtils.H>
+#include <prdfExtensibleChip.H>
+#include <prdfGlobal.H>
+#include <prdfPlatServices.H>
+#include <prdfTrace.H>
+#include <fapi2.H>
+#include <prdfTargetServices.H>
+#include <prdfRegisterCache.H>
+#include <lib/mcbist/memdiags.H>
+
+using namespace TARGETING;
+
+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;
+
+ SCAN_COMM_REGISTER_CLASS * mcbFirAnd =
+ i_mcbChip->getRegister("MCBISTFIR_AND");
+ mcbFirAnd->setAllBits();
+
+ mcbFirAnd->ClearBit(10); // Maint cmd complete
+ mcbFirAnd->ClearBit(12); // Maint cmd WAT workaround for sf commands
+
+ if ( SUCCESS != mcbFirAnd->Write() )
+ {
+ PRDF_ERR ( PRDF_FUNC "Write() failed on MCBISTFIR_AND" );
+ o_rc = FAIL;
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+int32_t clearCmdCompleteAttn<TYPE_MBA>(ExtensibleChip* i_mbaChip)
+{
+ #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)
+
+ if ( SUCCESS != mbaSpaAnd->Write() )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on MBASPA_AND" );
+ o_rc = FAIL;
+ }
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+int32_t clearEccCounters<TYPE_MCBIST>(ExtensibleChip* i_mcbChip)
+{
+ #define PRDF_FUNC "[PRDF::clearEccCounters<TYPE_MCBIST>] "
+ int32_t o_rc = SUCCESS;
+
+ do
+ {
+ SCAN_COMM_REGISTER_CLASS * mcbcntl =
+ i_mcbChip->getRegister( "MCB_CNTL" );
+
+ o_rc = mcbcntl->ForceRead();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "ForceRead() failed on MCB_CNTL" );
+ break;
+ }
+
+ mcbcntl->SetBit(7); // Setting this bit clears all counters.
+
+ o_rc = mcbcntl->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on MCB_CNTL" );
+ break;
+ }
+
+ // Hardware automatically clears bit 7, 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 );
+
+ } while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+int32_t clearEccCounters<TYPE_MBA>(ExtensibleChip* i_mbaChip)
+{
+ #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 );
+
+ // 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;
+ }
+
+ mbstr->SetBit(53); // Setting this bit clears all counters.
+
+ o_rc = mbstr->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str );
+ break;
+ }
+
+ // 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 );
+
+ } while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+int32_t clearEccFirs<TYPE_MCBIST>(ExtensibleChip* i_mcbChip)
+{
+ #define PRDF_FUNC "[PRDF::clearEccFirs<TYPE_MCBIST>] "
+
+ int32_t o_rc = SUCCESS;
+
+ TARGETING::TargetHandle_t mcbTrgt = i_mcbChip->GetChipHandle();
+
+ do
+ {
+ //clear MCBISTFIR - bits 5-9
+ SCAN_COMM_REGISTER_CLASS * mcbFirAnd =
+ i_mcbChip->getRegister("MCBISTFIR_AND");
+ mcbFirAnd->setAllBits();
+
+ mcbFirAnd->SetBitFieldJustified( 5, 5, 0 );
+
+ o_rc = mcbFirAnd->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on MCBISTFIR_AND" );
+ break;
+ }
+
+ //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;
+ }
+ }
+
+ } while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+template<>
+int32_t clearEccFirs<TYPE_MBA>(ExtensibleChip* i_mbaChip)
+{
+ #define PRDF_FUNC "[PRDF::clearEccFirs<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_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;
+ }
+
+ SCAN_COMM_REGISTER_CLASS * spaAnd =
+ i_mbaChip->getRegister("MBASPA_AND");
+ spaAnd->setAllBits();
+
+ // Clear threshold exceeded attentions
+ spaAnd->SetBitFieldJustified( 1, 4, 0 );
+
+ o_rc = spaAnd->Write();
+ if ( SUCCESS != o_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "Write() failed on MBASPA_AND" );
+ break;
+ }
+
+ } while(0);
+
+ return o_rc;
+
+ #undef PRDF_FUNC
+}
+
+} //end namespace PRDF
OpenPOWER on IntegriCloud