diff options
author | Chris Phan <cphan@us.ibm.com> | 2014-09-14 08:43:05 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-09-17 10:53:56 -0500 |
commit | 982f36dabb04e3f8bafcd41892f2d318cdf24dbc (patch) | |
tree | 37c9cde3e81b1b6e17e6bf0b0a56b3211b79a75d /src/usr/diag | |
parent | 3f018e5e0d7d409832b99fe062647428eb253c81 (diff) | |
download | talos-hostboot-982f36dabb04e3f8bafcd41892f2d318cdf24dbc.tar.gz talos-hostboot-982f36dabb04e3f8bafcd41892f2d318cdf24dbc.zip |
PRD: fix PLL threshold being used by both Proc and PCIe PLL errors
Change-Id: Iecac321abe107850ea080cc380927db6cd68dff8
CQ: SW278456
Backport: release-fips811
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13366
Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com>
Tested-by: Jenkins Server
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/13419
Diffstat (limited to 'src/usr/diag')
-rwxr-xr-x | src/usr/diag/prdf/common/framework/config/prdfPllDomain.C | 83 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/framework/config/prdfPllDomain.H | 29 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/iipconst.h | 5 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C | 180 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C | 299 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C | 46 | ||||
-rw-r--r-- | src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.H | 10 | ||||
-rwxr-xr-x | src/usr/diag/prdf/common/prd_pegasus.mk | 1 | ||||
-rwxr-xr-x | src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H | 166 |
9 files changed, 617 insertions, 202 deletions
diff --git a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C index 30f3bb318..9e4576d8f 100755 --- a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C +++ b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C @@ -50,6 +50,30 @@ using namespace PlatServices; //------------------------------------------------------------------------------ +void PllDomain::InitChipPluginFuncs() +{ + if ( CLOCK_DOMAIN_IO == GetId() ) + { + QueryPllFunc = "QueryPllIo"; + CapturePllFunc = "capturePllFfdcIo"; + CalloutPllFunc = "CalloutPllIo"; + MaskPllFunc = "MaskPllIo"; + ClearPllFunc = "ClearPllIo"; + PostAnalysisPllFunc = "PllPostAnalysisIo"; + } + else + { + QueryPllFunc = "QueryPll"; + CapturePllFunc = "capturePllFfdc"; + CalloutPllFunc = "CalloutPll"; + MaskPllFunc = "MaskPll"; + ClearPllFunc = "ClearPll"; + PostAnalysisPllFunc = "PllPostAnalysis"; + } +} + +//------------------------------------------------------------------------------ + int32_t PllDomain::Initialize(void) { @@ -94,7 +118,7 @@ bool PllDomain::Query(ATTENTION_TYPE attentionType) { ExtensibleChip * l_chip = LookUp(index); ExtensibleChipFunction * l_query = - l_chip->getExtensibleFunction("QueryPll"); + l_chip->getExtensibleFunction(QueryPllFunc); int32_t rc = (*l_query)(l_chip,PluginDef::bindParm<bool &>(atAttn)); // if rc then scom read failed - Error log has already been generated if( PRD_POWER_FAULT == rc ) @@ -122,8 +146,6 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, CcAutoDeletePointerVector<ChipPtr> chip(new ChipPtr[GetSize()]()); int count = 0; int32_t rc = SUCCESS; - bool calloutProcOsc = false; - bool calloutPciOsc = false; // Due to clock issues some chips may be moved to non-functional during // analysis. In this case, these chips will need to be removed from their @@ -135,30 +157,14 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, for(unsigned int index = 0; index < GetSize(); ++index) { ExtensibleChip * l_chip = LookUp(index); - bool atProcAttn = false; - bool atPciAttn = false; + bool atAttn = false; - if( CLOCK_DOMAIN_FAB == GetId() ) - { - ExtensibleChipFunction * queryProc = - l_chip->getExtensibleFunction("QueryProcPll"); - rc |= (*queryProc)(l_chip,PluginDef::bindParm<bool &>(atProcAttn)); - ExtensibleChipFunction * queryPci = - l_chip->getExtensibleFunction("QueryPciPll"); - rc |= (*queryPci)(l_chip,PluginDef::bindParm<bool &>(atPciAttn)); - } - else - { - ExtensibleChipFunction * l_query = - l_chip->getExtensibleFunction("QueryPll"); - rc |= (*l_query)(l_chip,PluginDef::bindParm<bool &>(atProcAttn)); - } + ExtensibleChipFunction * l_query = + l_chip->getExtensibleFunction(QueryPllFunc); + rc |= (*l_query)(l_chip,PluginDef::bindParm<bool &>(atAttn)); - if(atProcAttn || atPciAttn) + if ( atAttn ) { - if( atProcAttn ) calloutProcOsc = true; - if( atPciAttn ) calloutPciOsc = true; - chip()[count] = LookUp(index); ++count; l_chip->CaptureErrorData( @@ -170,7 +176,7 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, // Call this chip's capturePllFfdc plugin if it exists. ExtensibleChipFunction * l_captureFfdc = - l_chip->getExtensibleFunction("capturePllFfdc", true); + l_chip->getExtensibleFunction(CapturePllFunc, true); if ( NULL != l_captureFfdc ) { (*l_captureFfdc)( l_chip, @@ -191,11 +197,8 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, } // always suspect the clock source - if( calloutPciOsc ) - { - closeClockSource.Resolve(serviceData); - } - if( calloutProcOsc ) + closeClockSource.Resolve(serviceData); + if(&closeClockSource != &farClockSource) { farClockSource.Resolve(serviceData); } @@ -207,7 +210,7 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, // Call this chip's CalloutPll plugin if it exists. ExtensibleChipFunction * l_callout = - chip()[0]->getExtensibleFunction( "CalloutPll", true ); + chip()[0]->getExtensibleFunction( CalloutPllFunc, true ); if ( NULL != l_callout ) { (*l_callout)( chip()[0], @@ -250,7 +253,7 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, ExtensibleChip * l_chip = chip()[i]; // Send any special messages indicating there was a PLL error. ExtensibleChipFunction * l_pllPostAnalysis = - l_chip->getExtensibleFunction("PllPostAnalysis", true); + l_chip->getExtensibleFunction(PostAnalysisPllFunc, true); (*l_pllPostAnalysis)(l_chip, PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(serviceData)); } @@ -272,12 +275,18 @@ int32_t PllDomain::ClearPll( ExtensibleDomain * i_domain, { PllDomain * l_domain = (PllDomain *) i_domain; + const char * clearPllFuncName = "ClearPll"; + if ( CLOCK_DOMAIN_IO == l_domain->GetId() ) + { + clearPllFuncName = "ClearPllIo"; + } + // Clear children chips. for ( uint32_t i = 0; i < l_domain->GetSize(); i++ ) { ExtensibleChip * l_chip = l_domain->LookUp(i); ExtensibleChipFunction * l_clear = - l_chip->getExtensibleFunction("ClearPll"); + l_chip->getExtensibleFunction(clearPllFuncName); (*l_clear)( l_chip, PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_sc) ); } @@ -305,12 +314,18 @@ 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("MaskPll"); + l_chip->getExtensibleFunction(maskPllFuncName); (*l_mask)( l_chip, PluginDef::bindParm<STEP_CODE_DATA_STRUCT&>(i_sc) ); } diff --git a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H index 189809058..77ba5d841 100755 --- a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H +++ b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H @@ -155,6 +155,12 @@ protected: virtual void Order(ATTENTION_TYPE attentionType); private: // functions + + /** + * @brief initialize pll chip plugin function names + */ + virtual void InitChipPluginFuncs(); + private: // Data enum { CONTAINER_SIZE = 8 }; @@ -168,6 +174,13 @@ private: // Data hwTableContent iv_dumpContent; #endif + const char * QueryPllFunc; + const char * CapturePllFunc; + const char * CalloutPllFunc; + const char * MaskPllFunc; + const char * ClearPllFunc; + const char * PostAnalysisPllFunc; + }; //------------------------------------------------------------------------------ @@ -184,7 +197,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & clockSource, iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1, ThresholdResolution::cv_pllDefault, i_mfgThresh ) ) -{} +{ + InitChipPluginFuncs(); +} inline PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, @@ -197,7 +212,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1, ThresholdResolution::cv_pllDefault, i_mfgThresh ) ) -{} +{ + InitChipPluginFuncs(); +} #else // not __HOSTBOOT_MODULE @@ -213,7 +230,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & clockSource, ThresholdResolution::cv_pllDefault, i_mfgThresh ) ), iv_dumpContent(i_hwdc) -{} +{ + InitChipPluginFuncs(); +} inline PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, @@ -228,7 +247,9 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, ThresholdResolution::cv_pllDefault, i_mfgThresh ) ), iv_dumpContent(i_hwdc) -{} +{ + InitChipPluginFuncs(); +} #endif // not __HOSTBOOT_MODULE diff --git a/src/usr/diag/prdf/common/iipconst.h b/src/usr/diag/prdf/common/iipconst.h index c485d63e8..a1780dba0 100755 --- a/src/usr/diag/prdf/common/iipconst.h +++ b/src/usr/diag/prdf/common/iipconst.h @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2002,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] 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. */ @@ -79,6 +81,7 @@ enum DOMAIN_ID CLOCK_DOMAIN_FAB = 0x90, CLOCK_DOMAIN_MCS = 0x91, CLOCK_DOMAIN_MEMBUF = 0x92, + CLOCK_DOMAIN_IO = 0x93, END_DOMAIN_ID }; diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C b/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C index da76a52c3..027b427a4 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C @@ -210,63 +210,6 @@ int32_t QueryProcPll( ExtensibleChip * i_chip, PRDF_PLUGIN_DEFINE( Proc, QueryProcPll ); /** - * @brief Query the PLL chip for a PCI PLL error - * @param i_chip P8 Pci chip - * @param o_result set to true in the presence of PLL error - * @returns Failure or Success of query. - */ -int32_t QueryPciPll( ExtensibleChip * i_chip, - bool & o_result) -{ - #define PRDF_FUNC "[Proc::QueryPciPll] " - - int32_t rc = SUCCESS; - o_result = false; - - SCAN_COMM_REGISTER_CLASS * pciErrReg = - i_chip->getRegister("PCI_ERROR_REG"); - SCAN_COMM_REGISTER_CLASS * pciConfigReg = - i_chip->getRegister("PCI_CONFIG_REG"); - - do - { - rc = pciErrReg->Read(); - if (rc != SUCCESS) - { - PRDF_ERR(PRDF_FUNC"PCI_ERROR_REG read failed" - "for 0x%08x", i_chip->GetId()); - break; - } - - rc = pciConfigReg->Read(); - if (rc != SUCCESS) - { - PRDF_ERR(PRDF_FUNC"PCI_CONFIG_REG read failed" - "for 0x%08x", i_chip->GetId()); - break; - } - - if(pciErrReg->IsBitSet(PLL_ERROR_BIT) && - !pciConfigReg->IsBitSet(PLL_ERROR_MASK)) - { - o_result = true; - } - - } while(0); - - if( rc != SUCCESS ) - { - PRDF_ERR(PRDF_FUNC"failed for proc: 0x%.8X", - i_chip->GetId()); - } - - return rc; - - #undef PRDF_FUNC -} -PRDF_PLUGIN_DEFINE( Proc, QueryPciPll ); - -/** * @brief Query the PLL chip for a PLL error on P8 * @param i_chip P8 Pci chip * @param o_result set to true in the presence of PLL error @@ -304,16 +247,13 @@ int32_t QueryPll( ExtensibleChip * i_chip, break; } - if( ! (TP_LFIR->IsBitSet(PLL_DETECT_P8) && - !TP_LFIRmask->IsBitSet(PLL_DETECT_P8)) ) + if (( TP_LFIRmask->IsBitSet(PLL_DETECT_P8) ) || + ( ! TP_LFIR->IsBitSet(PLL_DETECT_P8) )) { // if global pll bit is not set, break out break; } - rc = QueryPciPll( i_chip, o_result ); - if ((rc != SUCCESS) || (true == o_result)) break; - rc = QueryProcPll( i_chip, o_result ); if ((rc != SUCCESS) || (true == o_result)) break; @@ -376,24 +316,12 @@ int32_t ClearPll( ExtensibleChip * i_chip, } } - // Clear pci osc error reg bit - SCAN_COMM_REGISTER_CLASS * pciErrReg = - i_chip->getRegister("PCI_ERROR_REG"); - pciErrReg->ClearBit(PLL_ERROR_BIT); - tmpRC = pciErrReg->Write(); - if (tmpRC != SUCCESS) - { - PRDF_ERR(PRDF_FUNC"PCI_ERROR_REG write failed" - "for chip: 0x%08x", i_chip->GetId()); - rc |= tmpRC; - } - // Clear TP_LFIR - SCAN_COMM_REGISTER_CLASS * TP_LFIR = + SCAN_COMM_REGISTER_CLASS * TP_LFIRand = i_chip->getRegister("TP_LFIR_AND"); - TP_LFIR->setAllBits(); - TP_LFIR->ClearBit(PLL_DETECT_P8); - tmpRC = TP_LFIR->Write(); + TP_LFIRand->setAllBits(); + TP_LFIRand->ClearBit(PLL_DETECT_P8); + tmpRC = TP_LFIRand->Write(); if (tmpRC != SUCCESS) { PRDF_ERR(PRDF_FUNC"TP_LFIR_AND write failed" @@ -435,93 +363,43 @@ int32_t MaskPll( ExtensibleChip * i_chip, if (CHECK_STOP != i_sc.service_data->GetAttentionType()) { - bool maskProcPllErr = false; - bool maskPciPllErr = false; - const SDC_MRU_LIST & l_mrus = i_sc.service_data->GetMruList(); int32_t tmpRC = SUCCESS; - for ( uint32_t i = 0; i < l_mrus.size(); i++ ) + P8DataBundle * procdb = getDataBundle( i_chip ); + P8DataBundle::ProcPllErrRegList & procPllErrRegList = + procdb->getProcPllErrRegList(); + if( procPllErrRegList.empty() ) { - if((PRDcalloutData::TYPE_PROCCLK == - l_mrus[i].callout.getType()) || - ((PRDcalloutData::TYPE_TARGET == - l_mrus[i].callout.getType()) && - (TYPE_OSCREFCLK == - getTargetType(l_mrus[i].callout.getTarget())))) - { - maskProcPllErr = true; - } - else if((PRDcalloutData::TYPE_PCICLK == - l_mrus[i].callout.getType()) || - ((PRDcalloutData::TYPE_TARGET == - l_mrus[i].callout.getType()) && - (TYPE_OSCPCICLK == - getTargetType(l_mrus[i].callout.getTarget())))) - { - maskPciPllErr = true; - } + GetProcPllErrRegList( i_chip, procPllErrRegList ); } - // fence off proc osc error reg bits - if(true == maskProcPllErr) + for(P8DataBundle::ProcPllErrRegListIter itr = + procPllErrRegList.begin(); + itr != procPllErrRegList.end(); ++itr) { - P8DataBundle * procdb = getDataBundle( i_chip ); - P8DataBundle::ProcPllErrRegList & procPllErrRegList = - procdb->getProcPllErrRegList(); - if( procPllErrRegList.empty() ) - { - GetProcPllErrRegList( i_chip, procPllErrRegList ); - } - - for(P8DataBundle::ProcPllErrRegListIter itr = - procPllErrRegList.begin(); - itr != procPllErrRegList.end(); ++itr) + // Error is already fenced + if( (*itr).configReg->IsBitSet(PLL_ERROR_MASK) ) { - // Error is already fenced - if( (*itr).configReg->IsBitSet(PLL_ERROR_MASK) ) - { - continue; - } - - (*itr).configReg->SetBit(PLL_ERROR_MASK); - - tmpRC = (*itr).configReg->Write(); - if (tmpRC != SUCCESS) - { - PRDF_ERR(PRDF_FUNC"CONFIG_REG write failed" - "for chip: 0x%08x, type: 0x%08x", - (*itr).chip->GetId(), (*itr).type); - rc |= tmpRC; - } + continue; } - // Need to clear the PLL Err Reg list so it can - // be populated with fresh data on the next analysis - // can do this in error case to save some space - procPllErrRegList.clear(); - - } - - // fence off pci osc error reg bit - if(true == maskPciPllErr) - { - SCAN_COMM_REGISTER_CLASS * pciConfigReg = - i_chip->getRegister("PCI_CONFIG_REG"); + (*itr).configReg->SetBit(PLL_ERROR_MASK); - if(!pciConfigReg->IsBitSet(PLL_ERROR_MASK)) + tmpRC = (*itr).configReg->Write(); + if (tmpRC != SUCCESS) { - pciConfigReg->SetBit(PLL_ERROR_MASK); - tmpRC = pciConfigReg->Write(); - if (tmpRC != SUCCESS) - { - PRDF_ERR(PRDF_FUNC"PCI_CONFIG_REG write failed" - "for chip: 0x%08x", - i_chip->GetId()); - rc |= tmpRC; - } + PRDF_ERR(PRDF_FUNC"CONFIG_REG write failed" + "for chip: 0x%08x, type: 0x%08x", + (*itr).chip->GetId(), (*itr).type); + rc |= tmpRC; } } + // Need to clear the PLL Err Reg list so it can + // be populated with fresh data on the next analysis + // can do this in error case to save some space + procPllErrRegList.clear(); + // Since TP_LFIR bit is the collection of all of the // pll error reg bits, we can't mask it or we will not // see any PLL errors reported from the error regs diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C b/src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C new file mode 100755 index 000000000..b1a02aa03 --- /dev/null +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C @@ -0,0 +1,299 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2014 */ +/* [+] 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 prdfP8PLL.C + * @brief chip Plug-in code for proc pll pcie support + */ + +#include <iipServiceDataCollector.h> +#include <prdfExtensibleChip.H> +#include <prdfPluginMap.H> +#include <prdfBitString.H> +#include <iipscr.h> +#include <prdfPlatServices.H> +#include <prdfErrlUtil.H> +#include <iipSystem.h> +#include <prdfGlobal_common.H> +#include <prdfP8DataBundle.H> +#include <UtilHash.H> + +using namespace TARGETING; + +namespace PRDF +{ + +using namespace PlatServices; + +namespace Proc +{ + +enum +{ + // All of the chiplet PLL_ERROR bits below + // are collected in this TP_LFIR bit + PLL_DETECT_P8 = 19, + // Chiplet PLL_ERROR mask and error bits + PLL_ERROR_MASK = 12, + PLL_ERROR_BIT = 25, +}; + +/** + * @brief Query the PLL chip for a PCI PLL error + * @param i_chip P8 Pci chip + * @param o_result set to true in the presence of PLL error + * @returns Failure or Success of query. + */ +int32_t QueryPciPll( ExtensibleChip * i_chip, + bool & o_result) +{ + #define PRDF_FUNC "[Proc::QueryPciPll] " + + int32_t rc = SUCCESS; + o_result = false; + + SCAN_COMM_REGISTER_CLASS * pciErrReg = + i_chip->getRegister("PCI_ERROR_REG"); + SCAN_COMM_REGISTER_CLASS * pciConfigReg = + i_chip->getRegister("PCI_CONFIG_REG"); + + do + { + rc = pciErrReg->Read(); + if (rc != SUCCESS) + { + PRDF_ERR(PRDF_FUNC"PCI_ERROR_REG read failed" + "for 0x%08x", i_chip->GetId()); + break; + } + + rc = pciConfigReg->Read(); + if (rc != SUCCESS) + { + PRDF_ERR(PRDF_FUNC"PCI_CONFIG_REG read failed" + "for 0x%08x", i_chip->GetId()); + break; + } + + if(pciErrReg->IsBitSet(PLL_ERROR_BIT) && + !pciConfigReg->IsBitSet(PLL_ERROR_MASK)) + { + o_result = true; + } + + } while(0); + + if( rc != SUCCESS ) + { + PRDF_ERR(PRDF_FUNC"failed for proc: 0x%.8X", + i_chip->GetId()); + } + + return rc; + + #undef PRDF_FUNC +} +PRDF_PLUGIN_DEFINE( Proc, QueryPciPll ); + +/** + * @brief Query the PLL chip for a PLL error on P8 + * @param i_chip P8 Pci chip + * @param o_result set to true in the presence of PLL error + * @returns Failure or Success of query. + * @note + */ +int32_t QueryPllIo( ExtensibleChip * i_chip, + bool & o_result) +{ + #define PRDF_FUNC "[Proc::QueryPllIo] " + + int32_t rc = SUCCESS; + o_result = false; + + SCAN_COMM_REGISTER_CLASS * TP_LFIR = + i_chip->getRegister("TP_LFIR"); + SCAN_COMM_REGISTER_CLASS * TP_LFIRmask = + i_chip->getRegister("TP_LFIR_MASK"); + + do + { + rc = TP_LFIR->Read(); + if (rc != SUCCESS) + { + PRDF_ERR(PRDF_FUNC"TP_LFIR read failed" + "for 0x%08x", i_chip->GetId()); + break; + } + + rc = TP_LFIRmask->Read(); + if (rc != SUCCESS) + { + PRDF_ERR(PRDF_FUNC"TP_LFIR_MASK read failed" + "for 0x%08x", i_chip->GetId()); + break; + } + + if (( TP_LFIRmask->IsBitSet(PLL_DETECT_P8) ) || + ( ! TP_LFIR->IsBitSet(PLL_DETECT_P8) )) + { + // if global pll bit is not set, break out + break; + } + + rc = QueryPciPll( i_chip, o_result ); + if ((rc != SUCCESS) || (true == o_result)) break; + + } while(0); + + if( rc != SUCCESS ) + { + PRDF_ERR(PRDF_FUNC"failed for proc: 0x%.8X", + i_chip->GetId()); + } + + return rc; + + #undef PRDF_FUNC +} +PRDF_PLUGIN_DEFINE( Proc, QueryPllIo ); + + +/** + * @brief Clear the PLL error for P8 Plugin + * @param i_chip P8 chip + * @param i_sc The step code data struct + * @returns Failure or Success of query. + */ +int32_t ClearPllIo( ExtensibleChip * i_chip, + STEP_CODE_DATA_STRUCT & i_sc) +{ + #define PRDF_FUNC "[Proc::ClearPllIo] " + + int32_t rc = SUCCESS; + + if (CHECK_STOP != i_sc.service_data->GetAttentionType()) + { + // Clear pci osc error reg bit + int32_t tmpRC = SUCCESS; + SCAN_COMM_REGISTER_CLASS * pciErrReg = + i_chip->getRegister("PCI_ERROR_REG"); + pciErrReg->ClearBit(PLL_ERROR_BIT); + tmpRC = pciErrReg->Write(); + if (tmpRC != SUCCESS) + { + PRDF_ERR(PRDF_FUNC"PCI_ERROR_REG write failed" + "for chip: 0x%08x", i_chip->GetId()); + rc |= tmpRC; + } + + // Clear TP_LFIR + SCAN_COMM_REGISTER_CLASS * TP_LFIRand = + i_chip->getRegister("TP_LFIR_AND"); + TP_LFIRand->setAllBits(); + TP_LFIRand->ClearBit(PLL_DETECT_P8); + tmpRC = TP_LFIRand->Write(); + if (tmpRC != SUCCESS) + { + PRDF_ERR(PRDF_FUNC"TP_LFIR_AND write failed" + "for chip: 0x%08x", i_chip->GetId()); + rc |= tmpRC; + } + } + + if( rc != SUCCESS ) + { + PRDF_ERR(PRDF_FUNC"failed for proc: 0x%.8X", + i_chip->GetId()); + } + + return rc; + + #undef PRDF_FUNC +} +PRDF_PLUGIN_DEFINE( Proc, ClearPllIo ); + +/** + * @brief Mask the PLL error for P8 Plugin + * @param i_chip P8 chip + * @param i_sc The step code data struct + * @returns Failure or Success of query. + * @note + */ +int32_t MaskPllIo( ExtensibleChip * i_chip, + STEP_CODE_DATA_STRUCT & i_sc ) +{ + #define PRDF_FUNC "[Proc::MaskPllIo] " + + int32_t rc = SUCCESS; + + if (CHECK_STOP != i_sc.service_data->GetAttentionType()) + { + // fence off pci osc error reg bit + SCAN_COMM_REGISTER_CLASS * pciConfigReg = + i_chip->getRegister("PCI_CONFIG_REG"); + + if(!pciConfigReg->IsBitSet(PLL_ERROR_MASK)) + { + pciConfigReg->SetBit(PLL_ERROR_MASK); + rc = pciConfigReg->Write(); + if (rc != SUCCESS) + { + PRDF_ERR(PRDF_FUNC"PCI_CONFIG_REG write failed" + "for chip: 0x%08x", + i_chip->GetId()); + } + } + + // Since TP_LFIR bit is the collection of all of the + // pll error reg bits, we can't mask it or we will not + // see any PLL errors reported from the error regs + + } // if not checkstop + + return rc; + + #undef PRDF_FUNC +} +PRDF_PLUGIN_DEFINE( Proc, MaskPllIo ); + +/** + * @brief capture additional PLL FFDC + * @param i_chip P8 chip + * @param i_sc service data collector + * @returns Success + */ +int32_t capturePllFfdcIo( ExtensibleChip * i_chip, + STEP_CODE_DATA_STRUCT & io_sc ) +{ + // Add FSI status reg + captureFsiStatusReg( i_chip, io_sc ); + + return SUCCESS; +} +PRDF_PLUGIN_DEFINE( Proc, capturePllFfdcIo ); + +} // end namespace Proc + +} // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C b/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C index 0ab803b6b..a9a6a9ef3 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C @@ -120,6 +120,7 @@ errlHndl_t PegasusConfigurator::build() uint32_t l_maxNodeCount = _getMaxNumNodes(); // PLL domains PllDomainList l_fabricPllDomains(l_maxNodeCount, NULL); + PllDomainList l_pciePllDomains(l_maxNodeCount, NULL); PllDomainList l_membPllDomains( l_maxNodeCount, NULL); do @@ -135,7 +136,8 @@ errlHndl_t PegasusConfigurator::build() errl = addDomainChips( TYPE_MBA, l_mbaDomain ); if ( NULL != errl ) break; - errl = addDomainChips( TYPE_PROC, l_procDomain, &l_fabricPllDomains ); + errl = addDomainChips( TYPE_PROC, l_procDomain, + &l_fabricPllDomains, &l_pciePllDomains ); if ( NULL != errl ) break; errl = addDomainChips( TYPE_EX, l_exDomain ); @@ -155,7 +157,9 @@ errlHndl_t PegasusConfigurator::build() // Add domains to domain list. NOTE: Order is important because this is // the order the domains will be analyzed. - addPllDomainsToSystem( l_fabricPllDomains, l_membPllDomains ); + addPllDomainsToSystem( l_fabricPllDomains, + l_pciePllDomains, + l_membPllDomains ); //MemBuf domain added after PLL domain sysDmnLst.push_back( l_membufDomain ); @@ -211,7 +215,8 @@ errlHndl_t PegasusConfigurator::build() errlHndl_t PegasusConfigurator::addDomainChips( TARGETING::TYPE i_type, RuleChipDomain * io_domain, - PllDomainList * io_pllDomains ) + PllDomainList * io_pllDomains, + PllDomainList * io_pllDomains2) { using namespace TARGETING; int32_t l_rc = SUCCESS; @@ -259,7 +264,6 @@ errlHndl_t PegasusConfigurator::addDomainChips( TARGETING::TYPE i_type, { delete chip; break; - } sysChipLst.push_back( chip ); io_domain->AddChip( chip ); @@ -274,6 +278,12 @@ errlHndl_t PegasusConfigurator::addDomainChips( TARGETING::TYPE i_type, *itr, scanFac, resFac); + addChipsToPllDomain(CLOCK_DOMAIN_IO, + io_pllDomains2, + chip, + *itr, + scanFac, + resFac); break; case TYPE_MEMBUF: addChipsToPllDomain(CLOCK_DOMAIN_MEMBUF, @@ -319,15 +329,28 @@ void PegasusConfigurator::addChipsToPllDomain( Resolution & procClock = i_resFac.GetClockResolution( i_pTarget, TYPE_PROC); + #ifdef __HOSTBOOT_MODULE + (*io_pllDomains)[l_node] = new PllDomain( + i_domainId, procClock, + ThresholdResolution::cv_mnfgDefault ); + #else + (*io_pllDomains)[l_node] = new PllDomain( + i_domainId, procClock, + CONTENT_HW, + ThresholdResolution::cv_mnfgDefault ); + #endif + } + else if(CLOCK_DOMAIN_IO == i_domainId) + { Resolution & ioClock = i_resFac.GetClockResolution( i_pTarget, TYPE_PCI); #ifdef __HOSTBOOT_MODULE (*io_pllDomains)[l_node] = new PllDomain( - i_domainId, ioClock, procClock, + i_domainId, ioClock, ThresholdResolution::cv_mnfgDefault ); #else (*io_pllDomains)[l_node] = new PllDomain( - i_domainId, ioClock, procClock, + i_domainId, ioClock, CONTENT_HW, ThresholdResolution::cv_mnfgDefault ); #endif @@ -347,7 +370,6 @@ void PegasusConfigurator::addChipsToPllDomain( ThresholdResolution::cv_mnfgDefault ); #endif } - else { PRDF_ERR( "[addChipsToPllDomain] Unsupported PLL Domain: " @@ -364,6 +386,7 @@ void PegasusConfigurator::addChipsToPllDomain( void PegasusConfigurator::addPllDomainsToSystem( PllDomainList & i_fabricPllDomains, + PllDomainList & i_pciePllDomains, PllDomainList & i_membPllDomains) { uint32_t l_maxNodeCount = _getMaxNumNodes(); @@ -377,6 +400,15 @@ void PegasusConfigurator::addPllDomainsToSystem( } } + //Add PCIe Pll Domains to the system. + for(uint32_t n = 0; n < l_maxNodeCount; ++n) + { + if(NULL != i_pciePllDomains[n]) + { + sysDmnLst.push_back(i_pciePllDomains[n]); + } + } + //Add Membuf Pll Domains to the system. for(uint32_t n = 0; n < l_maxNodeCount; ++n) { diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.H b/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.H index cb6b9f33b..3f8fbfd4c 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] 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. */ @@ -80,11 +82,13 @@ class PegasusConfigurator : public Configurator * @parm i_type The specified target type. * @parm io_domain The associated domain. * @parm io_pllDomains The associated PLL domain (optional for some) + * @parm io_pllDomains2 The associated PLL domain (optional for some) * @return error log handle */ errlHndl_t addDomainChips( TARGETING::TYPE i_type, RuleChipDomain * io_domain, - PllDomainList * io_pllDomains = NULL ); + PllDomainList * io_pllDomains = NULL, + PllDomainList * io_pllDomains2 = NULL); /** * @brief Add chip to its Pll Domain. @@ -106,10 +110,12 @@ class PegasusConfigurator : public Configurator /** * @brief Add Pll Domains to the System. * @param i_fabricPllDomains - List of Fabric Pll Domains + * @param i_pciePllDomains - List of Pcie Pll Domains * @param i_membPllDomains - List of Membuf Pll Domains */ void addPllDomainsToSystem( PllDomainList & i_fabricPllDomains, + PllDomainList & i_pciePllDomains, PllDomainList & i_membPllDomains ); private: // data diff --git a/src/usr/diag/prdf/common/prd_pegasus.mk b/src/usr/diag/prdf/common/prd_pegasus.mk index b78e5b1d3..8cec3d691 100755 --- a/src/usr/diag/prdf/common/prd_pegasus.mk +++ b/src/usr/diag/prdf/common/prd_pegasus.mk @@ -29,6 +29,7 @@ PRDF_RULE_PLUGINS_PEGASUS += prdfPlatP8Ex.o PRDF_RULE_PLUGINS_PEGASUS += prdfP8Ex.o PRDF_RULE_PLUGINS_PEGASUS += prdfP8Mcs.o PRDF_RULE_PLUGINS_PEGASUS += prdfP8Pll.o +PRDF_RULE_PLUGINS_PEGASUS += prdfP8PllPcie.o PRDF_RULE_PLUGINS_PEGASUS += prdfCenMba.o PRDF_RULE_PLUGINS_PEGASUS += prdfPlatCenMba.o PRDF_RULE_PLUGINS_PEGASUS += prdfCenMembuf.o diff --git a/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H b/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H index 8588f7439..c54f64ead 100755 --- a/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H +++ b/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H @@ -5,7 +5,9 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* [+] 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. */ @@ -44,7 +46,7 @@ class PTPLFIR:public CxxTest::TestSuite void TestRecoverable(void) { - PRDS_BEGIN("PLL in MNFG mode"); + PRDS_BEGIN("PCI PLL"); PRDS_ERROR_ENTRY("NODE{0}:PROC{0}", PRDF::RECOVERABLE); @@ -121,7 +123,87 @@ class PTPLFIR:public CxxTest::TestSuite void TestPllAtThreshold(void) { - PRDS_BEGIN("PLL At Threshold"); + PRDS_BEGIN("PCI PLL At Threshold"); + + PRDS_ERROR_ENTRY("NODE{0}:PROC{0}", PRDF::RECOVERABLE); + + PRDS_EXPECTED_SIGNATURE("NODE{0}:PROC{0}",0x00ed0000 ); + + //GLOBAL_RE_FIR + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x570F001B, 0x4000000000000000); + + //TP_CHIPLET_RE_FIR + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x01040001, 0x4000000000000000); + + //TP_LFIR + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x0104000a, 0x0000100000000000); + + //TP_LFIR_ACT1 + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x01040011, 0xFFFFFFFFFFFFFFFF); + + + // ############ PLL regs ########### + + // PCI_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x090F001F, + 0x0000004000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x090F001F, + //0x0000000000000001); + + // PCI_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x090F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x090F001E, + //0x0008000000000001); + + // PB_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x020F001F, + 0x0000006000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x020F001F, + //0x0000000000000001); + + // PB_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x020F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x020F001E, + //0x0008000000000001); + + // ABUS_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x080F001F, + 0x0000004000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x080F001F, + //0x0000000000000001); + + // ABUS_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x080F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x080F001E, + //0x0008000000000001); + + // EX_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}:EX{4}", 0x100F001F, + 0x0000004000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}:EX{4}", 0x100F001F, + //0x0000000000000001); + + // EX_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}:EX{4}", 0x100F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}:EX{4}", 0x100F001E, + //0x0008000000000001); + + + PRDS_START_SIM(); + + PRDS_END(); + } + + + // test Proc PLL error ------------------------- + + void TestProcPll(void) + { + PRDS_BEGIN("Proc PLL"); PRDS_ERROR_ENTRY("NODE{0}:PROC{0}", PRDF::RECOVERABLE); @@ -144,7 +226,84 @@ class PTPLFIR:public CxxTest::TestSuite // PCI_ERROR_REG PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x090F001F, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x090F001F, + //0x0000000000000001); + + // PCI_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x090F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x090F001E, + //0x0008000000000001); + + // PB_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x020F001F, + 0x0000006000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x020F001F, + //0x0000000000000001); + + // PB_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x020F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x020F001E, + //0x0008000000000001); + + // ABUS_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x080F001F, 0x0000004000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x080F001F, + //0x0000000000000001); + + // ABUS_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x080F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x080F001E, + //0x0008000000000001); + + // EX_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}:EX{4}", 0x100F001F, + 0x0000004000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}:EX{4}", 0x100F001F, + //0x0000000000000001); + + // EX_CONFIG_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}:EX{4}", 0x100F001E, + 0x0000000000000001); + //PRDS_SCR_EXPECT("NODE{0}:PROC{0}:EX{4}", 0x100F001E, + //0x0008000000000001); + + + PRDS_START_SIM(); + + PRDS_END(); + } + + void TestProcPllAtThreshold(void) + { + PRDS_BEGIN("Proc PLL At Threshold"); + + PRDS_ERROR_ENTRY("NODE{0}:PROC{0}", PRDF::RECOVERABLE); + + PRDS_EXPECTED_SIGNATURE("NODE{0}:PROC{0}",0x00ed0000 ); + + //GLOBAL_RE_FIR + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x570F001B, 0x4000000000000000); + + //TP_CHIPLET_RE_FIR + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x01040001, 0x4000000000000000); + + //TP_LFIR + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x0104000a, 0x0000100000000000); + + //TP_LFIR_ACT1 + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x01040011, 0xFFFFFFFFFFFFFFFF); + + + // ############ PLL regs ########### + + // PCI_ERROR_REG + PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x090F001F, + 0x0000000000000001); //PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x090F001F, //0x0000000000000001); @@ -196,5 +355,6 @@ class PTPLFIR:public CxxTest::TestSuite PRDS_END(); } + }; #endif |