summaryrefslogtreecommitdiffstats
path: root/src/usr/diag/prdf/common/framework/config
diff options
context:
space:
mode:
authorChris Phan <cphan@us.ibm.com>2014-09-16 21:18:07 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-09-22 13:26:06 -0500
commitfe787082ffbf72795dc3c58d09e0a7ed45600da2 (patch)
treeae18464ab2b6abc2b79dc25273bef0714812e88a /src/usr/diag/prdf/common/framework/config
parent83e47c8df68c5736a8bb080d0a250df77c82f935 (diff)
downloadtalos-hostboot-fe787082ffbf72795dc3c58d09e0a7ed45600da2.tar.gz
talos-hostboot-fe787082ffbf72795dc3c58d09e0a7ed45600da2.zip
PRD: change osc callout and threshold design
Change-Id: Ib54734a1db5d17f4ea13ddd80f91fc4dae7aef3a CQ: SW278778 Backport: release-fips820 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13461 Tested-by: Jenkins Server Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: Zane Shelley <zshelle@us.ibm.com> Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13519
Diffstat (limited to 'src/usr/diag/prdf/common/framework/config')
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/config/prdfPllDomain.C157
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/config/prdfPllDomain.H30
2 files changed, 172 insertions, 15 deletions
diff --git a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C
index 4afa855a2..5b87ca01c 100755
--- a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C
+++ b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C
@@ -142,9 +142,11 @@ bool PllDomain::Query(ATTENTION_TYPE attentionType)
int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData,
ATTENTION_TYPE attentionType)
{
+ #define PRDF_FUNC "[PllDomain::Analyze] "
typedef ExtensibleChip * ChipPtr;
CcAutoDeletePointerVector<ChipPtr> chip(new ChipPtr[GetSize()]());
int count = 0;
+ bool oscSource[2] = { false, false };
int32_t rc = SUCCESS;
// Due to clock issues some chips may be moved to non-functional during
@@ -182,6 +184,25 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData,
(*l_captureFfdc)( l_chip,
PluginDef::bindParm<STEP_CODE_DATA_STRUCT &>(serviceData) );
}
+
+ // Only continue for pcie domain to get osc pos
+ if ( CLOCK_DOMAIN_IO != GetId() )
+ {
+ break;
+ }
+
+ // Figure out which pcie osc is active for this proc
+ uint32_t oscPos = getIoOscPos(l_chip, serviceData);
+
+ if ( oscPos < MAX_PCIE_OSC_PER_NODE )
+ {
+ oscSource[oscPos] = true;
+ }
+ else
+ {
+ PRDF_ERR(PRDF_FUNC"getOscPos returned error for chip: "
+ "0x%08x", l_chip->GetId());
+ }
}
else if ( !PlatServices::isFunctional(l_chip->GetChipHandle()) )
{
@@ -203,11 +224,17 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData,
farClockSource.Resolve(serviceData);
}
+ const uint32_t tmpCount = serviceData.service_data->getMruListSize();
+
// If only one detected the error, add it to the callout list.
- if ( 1 == count )
+ // Or if multiple chips report errors but no callout for PCIe case.
+ // This could happen for PCIe PLL since pcie clock resolution defer
+ // the osc callout to PllPcie chip plugin.
+ if (( 1 == count ) ||
+ (( 1 < count ) &&
+ ( 0 == tmpCount ) &&
+ ( CLOCK_DOMAIN_IO == GetId() )))
{
- const uint32_t tmpCount = serviceData.service_data->getMruListSize();
-
// Call this chip's CalloutPll plugin if it exists.
ExtensibleChipFunction * l_callout =
chip()[0]->getExtensibleFunction( CalloutPllFunc, true );
@@ -217,21 +244,88 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData,
PluginDef::bindParm<STEP_CODE_DATA_STRUCT &>(serviceData) );
}
- if ( tmpCount == serviceData.service_data->getMruListSize() )
+ // If CalloutPll plugin does not add anything new to the callout
+ // or for pcie io domain and only 1 proc reports error, then
+ // call it out in addition to the pcie osc already called out in
+ // CalloutPllFunc plugin
+ if (( tmpCount == serviceData.service_data->getMruListSize() ) ||
+ (( CLOCK_DOMAIN_IO == GetId() ) && ( 1 == count )))
{
// No additional callouts were made so add this chip to the list.
serviceData.service_data->SetCallout( chip()[0]->GetChipHandle());
}
}
- iv_threshold.Resolve(serviceData);
+ // PCIe domains uses two threshold resolutions one per osc
+ if ( CLOCK_DOMAIN_IO == GetId() )
+ {
+ if ( true == oscSource[0] )
+ {
+ iv_threshold.Resolve(serviceData);
+ }
+
+ if ( true == oscSource[1] )
+ {
+ iv_threshold2.Resolve(serviceData);
+ }
+
+ if (( false == oscSource[0] ) && ( false == oscSource[1] ))
+ {
+ PRDF_ERR(PRDF_FUNC"can't threshold IO domain due to no available "
+ "pcie osc source - count:%d, chip 0x%08x",
+ count, chip()[0]->GetId());
+ }
+ }
+ // Proc and mem domains only use one threshold resolution
+ else
+ {
+ iv_threshold.Resolve(serviceData);
+ }
+
// Test for threshold
if(serviceData.service_data->IsAtThreshold())
{
- // Mask in all chips in domain
- ExtensibleDomainFunction * l_mask = getExtensibleFunction("MaskPll");
- (*l_mask)(this,
+ // Only mask chips connected to fault pcie osc
+ if ( CLOCK_DOMAIN_IO == GetId() )
+ {
+ uint32_t oscPos = MAX_PCIE_OSC_PER_NODE;
+ if ( true == oscSource[0] )
+ {
+ // Mask pcie pll error in chips connected to pcie osc-0
+ oscPos = 0;
+ ExtensibleDomainFunction * l_mask =
+ getExtensibleFunction("MaskPllIo");
+ (*l_mask)(this,
+ PluginDef::bindParm<STEP_CODE_DATA_STRUCT&, uint32_t>
+ (serviceData, oscPos));
+ }
+
+ if ( true == oscSource[1] )
+ {
+ // Mask pcie pll error in chips connected to pcie osc-1
+ oscPos = 1;
+ ExtensibleDomainFunction * l_mask =
+ getExtensibleFunction("MaskPllIo");
+ (*l_mask)(this,
+ PluginDef::bindParm<STEP_CODE_DATA_STRUCT&, uint32_t>
+ (serviceData, oscPos));
+ }
+
+ if (( false == oscSource[0] ) && ( false == oscSource[1] ))
+ {
+ PRDF_ERR(PRDF_FUNC"can't mask pcie pll error due to no "
+ "available pcie osc source - count:%d, chip 0x%08x",
+ count, chip()[0]->GetId());
+ }
+ }
+ else
+ {
+ // Mask in all chips in domain
+ ExtensibleDomainFunction * l_mask =
+ getExtensibleFunction("MaskPll");
+ (*l_mask)(this,
PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(serviceData));
+ }
}
// Set Signature
serviceData.service_data->GetErrorSignature()->setChipId(chip()[0]->GetId());
@@ -259,6 +353,8 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData,
}
return rc;
+
+ #undef PRDF_FUNC
}
//------------------------------------------------------------------------------
@@ -314,18 +410,12 @@ int32_t PllDomain::MaskPll( ExtensibleDomain * i_domain,
{
PllDomain * l_domain = (PllDomain *) i_domain;
- const char * maskPllFuncName = "MaskPll";
- if ( CLOCK_DOMAIN_IO == l_domain->GetId() )
- {
- maskPllFuncName = "MaskPllIo";
- }
-
// Mask children chips.
for ( uint32_t i = 0; i < l_domain->GetSize(); i++ )
{
ExtensibleChip * l_chip = l_domain->LookUp(i);
ExtensibleChipFunction * l_mask =
- l_chip->getExtensibleFunction(maskPllFuncName);
+ l_chip->getExtensibleFunction("MaskPll");
(*l_mask)( l_chip,
PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_sc) );
}
@@ -347,5 +437,42 @@ PRDF_PLUGIN_DEFINE( PllDomain, MaskPll );
//------------------------------------------------------------------------------
+int32_t PllDomain::MaskPllIo( ExtensibleDomain * i_domain,
+ STEP_CODE_DATA_STRUCT & i_sc,
+ uint32_t i_oscPos )
+{
+ PllDomain * l_domain = (PllDomain *) i_domain;
+
+ // Mask children chips.
+ for ( uint32_t i = 0; i < l_domain->GetSize(); i++ )
+ {
+ ExtensibleChip * l_chip = l_domain->LookUp(i);
+ ExtensibleChipFunction * l_mask =
+ l_chip->getExtensibleFunction("MaskPllIo");
+
+ // io pcie domain needs osc pos info
+ (*l_mask)( l_chip,
+ PluginDef::bindParm<STEP_CODE_DATA_STRUCT&, uint32_t>
+ (i_sc, i_oscPos) );
+ }
+
+ // Mask children domains - not used in PCIe but leave it here for now
+ // This looks like a recursive call. It calls other domains of Mask.
+ ParentDomain<ExtensibleDomain>::iterator i;
+ for (i = l_domain->getBeginIterator(); i != l_domain->getEndIterator(); i++)
+ {
+ ExtensibleDomainFunction * l_mask =
+ (i->second)->getExtensibleFunction("MaskPll");
+ (*l_mask)( i->second,
+ PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_sc) );
+ }
+
+ return SUCCESS;
+}
+PRDF_PLUGIN_DEFINE( PllDomain, MaskPllIo );
+
+
+//------------------------------------------------------------------------------
+
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H
index 77ba5d841..11fea8d71 100755
--- a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H
+++ b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H
@@ -144,6 +144,18 @@ class PllDomain : public RuleChipDomain, public ExtensibleDomain,
static int32_t MaskPll( ExtensibleDomain * i_domain,
STEP_CODE_DATA_STRUCT & i_sc );
+ /**
+ * @brief Domain level plugin function used to mask PLL attentions in a
+ * domain and its subdomains.
+ * @param i_domain The target PLL domain.
+ * @param i_sc The step code data struct.
+ * @param i_oscPos osc position (only used by IO pcie domain)
+ * @return SUCCESS
+ */
+ static int32_t MaskPllIo( ExtensibleDomain * i_domain,
+ STEP_CODE_DATA_STRUCT & i_sc,
+ uint32_t i_oscPos );
+
protected:
/**
@@ -170,6 +182,12 @@ private: // Data
Resolution & iv_threshold;
+ // This resolution is used for the 2nd pcie osc only
+ // since the redundant pcie oscs are at the node
+ // level and can dynamically switch or config
+ // during the IPL
+ Resolution & iv_threshold2;
+
#ifndef __HOSTBOOT_MODULE
hwTableContent iv_dumpContent;
#endif
@@ -196,6 +214,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & clockSource,
farClockSource(clockSource),
iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1,
ThresholdResolution::cv_pllDefault,
+ i_mfgThresh ) ),
+ iv_threshold2( ResolutionFactory::Access().GetThresholdResolution( 1,
+ ThresholdResolution::cv_pllDefault,
i_mfgThresh ) )
{
InitChipPluginFuncs();
@@ -211,6 +232,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource,
farClockSource(clockSource),
iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1,
ThresholdResolution::cv_pllDefault,
+ i_mfgThresh ) ),
+ iv_threshold2( ResolutionFactory::Access().GetThresholdResolution( 1,
+ ThresholdResolution::cv_pllDefault,
i_mfgThresh ) )
{
InitChipPluginFuncs();
@@ -229,6 +253,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & clockSource,
iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1,
ThresholdResolution::cv_pllDefault,
i_mfgThresh ) ),
+ iv_threshold2( ResolutionFactory::Access().GetThresholdResolution( 1,
+ ThresholdResolution::cv_pllDefault,
+ i_mfgThresh ) ),
iv_dumpContent(i_hwdc)
{
InitChipPluginFuncs();
@@ -246,6 +273,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource,
iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1,
ThresholdResolution::cv_pllDefault,
i_mfgThresh ) ),
+ iv_threshold2( ResolutionFactory::Access().GetThresholdResolution( 1,
+ ThresholdResolution::cv_pllDefault,
+ i_mfgThresh ) ),
iv_dumpContent(i_hwdc)
{
InitChipPluginFuncs();
OpenPOWER on IntegriCloud