diff options
| author | Chris Phan <cphan@us.ibm.com> | 2014-09-16 21:18:07 -0500 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-09-22 13:26:06 -0500 |
| commit | fe787082ffbf72795dc3c58d09e0a7ed45600da2 (patch) | |
| tree | ae18464ab2b6abc2b79dc25273bef0714812e88a /src/usr/diag/prdf/common/framework/config | |
| parent | 83e47c8df68c5736a8bb080d0a250df77c82f935 (diff) | |
| download | talos-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-x | src/usr/diag/prdf/common/framework/config/prdfPllDomain.C | 157 | ||||
| -rwxr-xr-x | src/usr/diag/prdf/common/framework/config/prdfPllDomain.H | 30 |
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(); |

