summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/plat/cen
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2018-04-23 22:05:54 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-04-27 21:29:33 -0400
commit06d556e9b03c86d451b3a383f12834cb88302ae1 (patch)
tree08204a2d2c034a278e064c5640742311d4fdcb5e /src/usr/diag/prdf/plat/cen
parent9e489a4e55630ff825726262406d394da68f2626 (diff)
downloadtalos-hostboot-06d556e9b03c86d451b3a383f12834cb88302ae1.tar.gz
talos-hostboot-06d556e9b03c86d451b3a383f12834cb88302ae1.zip
PRD: L4 line delete
Change-Id: I41ddf8520c3124d2e9dabcbcae766d2e74239e56 RTC: 187477 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57707 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: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Squashed: I97a883994a99823c605c6a4af15a5d8bf7b575c6 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57883 CI-Ready: Zane C. Shelley <zshelle@us.ibm.com> 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/cen')
-rw-r--r--src/usr/diag/prdf/plat/cen/prdfCenMembuf.C293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/usr/diag/prdf/plat/cen/prdfCenMembuf.C b/src/usr/diag/prdf/plat/cen/prdfCenMembuf.C
index bcc13efc9..112a9d157 100644
--- a/src/usr/diag/prdf/plat/cen/prdfCenMembuf.C
+++ b/src/usr/diag/prdf/plat/cen/prdfCenMembuf.C
@@ -28,6 +28,7 @@
#include <prdfExtensibleChip.H>
#include <prdfPluginDef.H>
#include <prdfPluginMap.H>
+#include <UtilHash.H> // for Util::hashString
// Platform includes
@@ -41,6 +42,298 @@ using namespace PlatServices;
namespace cen_centaur
{
+//##############################################################################
+//
+// MBSFIR
+//
+//##############################################################################
+
+/**
+ * @brief Captures trapped address for L4 cache ECC errors.
+ * @param i_chip Centaur chip
+ * @param io_sc Step code data struct
+ * @return SUCCESS always
+ * @note This function also reset ECC trapped address regsiters so that HW can
+ * capture address for next L4 ecc error.
+ */
+int32_t CaptureL4CacheErr( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[CaptureL4CacheErr] "
+
+ do
+ {
+ i_chip->CaptureErrorData( io_sc.service_data->GetCaptureData(),
+ Util::hashString( "L4CacheErr" ) );
+
+ // NOTE: FW should write on MBCELOG so that HW can capture
+ // address for next L4 CE error.
+
+ // NOTE: Line delete feature for L4 cache is not available yet, but if
+ // it is ever supported, we need to make sure following should be the
+ // order of events:
+ // 1. Capture group of registers associated with group L4CacheErr
+ // 2. do L4 line delete.
+ // 3. clear register MBCELOG
+
+ // If we clear register MBCELOG before doing line delete, it is possible
+ // that hardware procedures shall run into erroneous scenarios. One
+ // probable order of events from PRDF's perspective which can cause
+ // this is below:
+ // 1. Receives an attention due to failure at cache address X.
+ // 2. captures all relevant register including MBCELOG.
+ // 3. cleares MBCELOG - i.e. failed address info is lost. HW populates
+ // this register with another L4 CE address say Y.
+ // 4. requestes HWP for line delete operation on address X but it
+ // actually deletes Y. It's because MBCELOG now contains address Y.
+
+ SCAN_COMM_REGISTER_CLASS * mbcelogReg = i_chip->getRegister("MBCELOG");
+ mbcelogReg->clearAllBits();
+
+ if ( SUCCESS != mbcelogReg->Write() )
+ {
+ PRDF_ERR( PRDF_FUNC "MBCELOG write failed for 0x%08x",
+ i_chip->GetId() );
+ break;
+ }
+
+ } while (0);
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( cen_centaur, CaptureL4CacheErr );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Clears MBS secondary FIR bits which may come up because of primary
+ * MBS/MBI FIR bits.
+ * @param i_chip Centaur chip
+ * @param io_sc Step code data struct
+ * @return SUCCESS always
+ */
+int32_t ClearMbsSecondaryBits( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[ClearMbsSecondaryBits] "
+
+ int32_t l_rc = SUCCESS;
+
+ do
+ {
+ SCAN_COMM_REGISTER_CLASS * mbsFir = i_chip->getRegister("MBSFIR");
+ SCAN_COMM_REGISTER_CLASS * mbsFirMask =
+ i_chip->getRegister("MBSFIR_MASK");
+ SCAN_COMM_REGISTER_CLASS * mbsFirAnd =
+ i_chip->getRegister("MBSFIR_AND");
+ l_rc = mbsFir->Read();
+ l_rc |= mbsFirMask->Read();
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "MBSFIR/MBSFIR_MASK read failed for 0x%08x",
+ i_chip->GetId() );
+ break;
+ }
+
+ mbsFirAnd->setAllBits();
+
+ if ( mbsFir->IsBitSet(26) &&
+ mbsFir->IsBitSet(9) && !mbsFirMask->IsBitSet(9) )
+ {
+ mbsFirAnd->ClearBit(26);
+ }
+
+ if ( mbsFir->IsBitSet(3) || mbsFir->IsBitSet(4) )
+ {
+ SCAN_COMM_REGISTER_CLASS * mbiFir = i_chip->getRegister("MBIFIR");
+ SCAN_COMM_REGISTER_CLASS * mbiFirMask =
+ i_chip->getRegister("MBIFIR_MASK");
+ l_rc = mbiFir->Read();
+ l_rc |= mbiFirMask->Read();
+ if ( SUCCESS != l_rc )
+ {
+ // Do not break from here, just print error trace. If there are
+ // other secondary bits ( e.g. 26, 27 ), we want to clear them.
+ PRDF_ERR( PRDF_FUNC "MBIFIR/MASK read failed for 0x%08x",
+ i_chip->GetId() );
+ }
+ else if ( mbiFir->IsBitSet(0) && !mbiFirMask->IsBitSet(0) )
+ {
+ mbsFirAnd->ClearBit(3);
+ mbsFirAnd->ClearBit(4);
+ }
+ }
+
+ l_rc = mbsFirAnd->Write();
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "MBSFIR_AND write failed for 0x%08x",
+ i_chip->GetId() );
+ break;
+ }
+
+ } while (0);
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( cen_centaur, ClearMbsSecondaryBits );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Mask MBS secondary FIR bits which may come up because of L4 UE.
+ * @param i_chip Centaur chip
+ * @param io_sc Step code data struct
+ * @return SUCCESS always
+ */
+int32_t MaskMbsSecondaryBits( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MaskMbsSecondaryBits] "
+
+ int32_t l_rc = SUCCESS;
+
+ do
+ {
+ SCAN_COMM_REGISTER_CLASS * mbsFirMaskOr =
+ i_chip->getRegister("MBSFIR_MASK_OR");
+ mbsFirMaskOr->SetBit(27);
+ l_rc = mbsFirMaskOr->Write();
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "MBSFIR_MASK_OR write failedfor 0x%08x",
+ i_chip->GetId() );
+ break;
+ }
+
+ } while (0);
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( cen_centaur, MaskMbsSecondaryBits );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Clears MBACAL secondary FIR bits which may come up because of MBSFIR.
+ * @param i_chip Centaur chip
+ * @param io_sc Step code data struct
+ * @return SUCCESS always
+
+ */
+int32_t ClearMbaCalSecondaryBits( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[ClearMbaCalSecondaryBits] "
+
+ int32_t l_rc = SUCCESS;
+
+ do
+ {
+ SCAN_COMM_REGISTER_CLASS * mbsFir = i_chip->getRegister("MBSFIR");
+ SCAN_COMM_REGISTER_CLASS * mbsFirMask =
+ i_chip->getRegister("MBSFIR_MASK");
+ l_rc = mbsFir->Read();
+ l_rc |= mbsFirMask->Read();
+ if ( SUCCESS != l_rc )
+ {
+ PRDF_ERR( PRDF_FUNC "MBSFIR/MBSFIR_MASK read failed for 0x%08x",
+ i_chip->GetId() );
+ break;
+ }
+
+ for ( auto & mbaChip : getConnected(i_chip, TYPE_MBA) )
+ {
+ SCAN_COMM_REGISTER_CLASS * mbaCalFir =
+ mbaChip->getRegister("MBACALFIR");
+
+ if ( SUCCESS != mbaCalFir->Read() )
+ {
+ // Do not break. Just print error trace and look for
+ // other MBA.
+ PRDF_ERR( PRDF_FUNC "MBACALFIR read failed for 0x%08x",
+ mbaChip->GetId() );
+ continue;
+ }
+
+ if ( !( mbaCalFir->IsBitSet(10) || mbaCalFir->IsBitSet(14) ) )
+ continue;
+
+ SCAN_COMM_REGISTER_CLASS * mbaCalAndFir =
+ mbaChip->getRegister("MBACALFIR_AND");
+
+ mbaCalAndFir->setAllBits();
+
+ mbaCalAndFir->ClearBit(10);
+ mbaCalAndFir->ClearBit(14);
+
+ l_rc = mbaCalAndFir->Write();
+ if ( SUCCESS != l_rc )
+ {
+ // Do not break. Just print error trace and look for
+ // other MBA.
+ PRDF_ERR( PRDF_FUNC "MBACALFIR_AND write failed for 0x%08x",
+ mbaChip->GetId() );
+ }
+ }
+
+ } while (0);
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( cen_centaur, ClearMbaCalSecondaryBits );
+
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Mask MBACAL secondary FIR bits which may come up because of L4 UE.
+ * @param i_chip Centaur chip
+ * @param io_sc Step code data struct
+ * @return SUCCESS always
+ */
+int32_t MaskMbaCalSecondaryBits( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[MaskMbaCalSecondaryBits] "
+
+ int32_t l_rc = SUCCESS;
+
+ do
+ {
+ for ( auto & mbaChip : getConnected(i_chip, TYPE_MBA) )
+ {
+ SCAN_COMM_REGISTER_CLASS * mbaCalFirMaskOr =
+ mbaChip->getRegister("MBACALFIR_MASK_OR");
+
+ mbaCalFirMaskOr->SetBit(9);
+ mbaCalFirMaskOr->SetBit(15);
+ l_rc = mbaCalFirMaskOr->Write();
+ if ( SUCCESS != l_rc )
+ {
+ // Do not break. Just print error trace and look for other MBA.
+ PRDF_ERR( PRDF_FUNC "MBACALFIR_MASK_OR write failed for 0x%08x",
+ mbaChip->GetId() );
+ }
+ }
+
+ } while (0);
+
+ return SUCCESS;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( cen_centaur, MaskMbaCalSecondaryBits );
+
+//------------------------------------------------------------------------------
+
} // end namespace cen_centaur
} // end namespace PRDF
OpenPOWER on IntegriCloud