diff options
22 files changed, 995 insertions, 218 deletions
diff --git a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C index 2eab1698c..478720324 100755 --- a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C +++ b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2003,2013 */ +/* COPYRIGHT International Business Machines Corp. 2003,2014 */ /* */ /* p1 */ /* */ @@ -36,6 +36,9 @@ #include <prdfPluginDef.H> #include <prdfGlobal.H> #include <iipSystem.h> +#include <UtilHash.H> + +using namespace TARGETING; namespace PRDF { @@ -114,6 +117,8 @@ 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 @@ -125,14 +130,38 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, for(unsigned int index = 0; index < GetSize(); ++index) { ExtensibleChip * l_chip = LookUp(index); - ExtensibleChipFunction * l_query = l_chip->getExtensibleFunction("QueryPll"); - bool atAttn; - rc = (*l_query)(l_chip,PluginDef::bindParm<bool &>(atAttn)); - if(atAttn == true) + bool atProcAttn = false; + bool atPciAttn = 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)); + } + + if(atProcAttn || atPciAttn) { + if( atProcAttn ) calloutProcOsc = true; + if( atPciAttn ) calloutPciOsc = true; + chip()[count] = LookUp(index); ++count; - l_chip->CaptureErrorData(serviceData.service_data->GetCaptureData()); + l_chip->CaptureErrorData( + serviceData.service_data->GetCaptureData()); + // Capture PllFIRs group + l_chip->CaptureErrorData( + serviceData.service_data->GetCaptureData(), + Util::hashString("PllFIRs")); } else if ( !PlatServices::isFunctional(l_chip->GetChipHandle()) ) { @@ -148,10 +177,13 @@ int32_t PllDomain::Analyze(STEP_CODE_DATA_STRUCT & serviceData, } // always suspect the clock source - closeClockSource.Resolve(serviceData); // dg06c - if(&closeClockSource != &farClockSource) + if( calloutPciOsc ) + { + closeClockSource.Resolve(serviceData); + } + if( calloutProcOsc ) { - farClockSource.Resolve(serviceData); // dg06c + farClockSource.Resolve(serviceData); } // If only one detected the error, add it to the callout list. diff --git a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H index 8e232604f..a17560fa2 100755 --- a/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H +++ b/src/usr/diag/prdf/common/framework/config/prdfPllDomain.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2006,2013 */ +/* COPYRIGHT International Business Machines Corp. 2006,2014 */ /* */ /* p1 */ /* */ @@ -47,54 +47,77 @@ class PllDomain : public RuleChipDomain, public ExtensibleDomain, #ifdef __HOSTBOOT_MODULE - /** @fn PllDomain - * @brief Constructor - * @param DOMAIN_ID - the domain ID - * @param Resolution to callout the correct clock source - * @param ThresholdResolution::ThresholdPolicy + /** + * @brief Constructor + * @param DOMAIN_ID the domain ID + * @param Resolution to callout the correct clock source + * @param ThresholdResolution::ThresholdPolicy */ PllDomain( DOMAIN_ID domain_id, Resolution & clockSource, const ThresholdResolution::ThresholdPolicy & i_mfgThresh ); + /** + * @brief Constructor + * @param DOMAIN_ID the domain ID + * @param Resolution to callout the correct second clock source + * @param Resolution to callout the correct clock source + * @param ThresholdResolution::ThresholdPolicy + */ + PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, + Resolution & clockSource, + const ThresholdResolution::ThresholdPolicy & i_mfgThresh ); + #else // not __HOSTBOOT_MODULE - /** @fn PllDomain - * @brief Constructor - * @param DOMAIN_ID - the domain ID - * @param Resolution to callout the correct clock source - * @param Dump content - * @param ThresholdResolution::ThresholdPolicy + /** + * @brief Constructor + * @param DOMAIN_ID the domain ID + * @param Resolution to callout the correct clock source + * @param Dump content + * @param ThresholdResolution::ThresholdPolicy */ PllDomain( DOMAIN_ID domain_id, Resolution & clockSource, hwTableContent i_hwdc, const ThresholdResolution::ThresholdPolicy & i_mfgThresh ); + /** + * @brief Constructor + * @param DOMAIN_ID the domain ID + * @param Resolution to callout the correct second clock source + * @param Resolution to callout the correct clock source + * @param Dump content + * @param ThresholdResolution::ThresholdPolicy + */ + PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, + Resolution & clockSource, + hwTableContent i_hwdc, + const ThresholdResolution::ThresholdPolicy & i_mfgThresh ); + #endif // not __HOSTBOOT_MODULE /** - Perform any initialization required by the hardware - @returns error code - @post PLL errors cleared in hardware. + * @brief Perform any initialization required by the hardware + * @returns error code + * @post PLL errors cleared in hardware. */ virtual int32_t Initialize(void); /** - Query if anything in this domain is at the attention type specified - @param Attention type to query for. (@see iipsdbug.h) - @returns [true|false] - @pre Initialize() - @post NONE + * @brief Query if anything in this domain is at the attention type specified + * @param Attention type to query for. (@see iipsdbug.h) + * @returns [true|false] + * @pre Initialize() */ virtual bool Query(ATTENTION_TYPE attentionType); /** - Analyze errors within the domain - @param service data collector - @param attentiont type (@see iipsdbug.h) - @returns service data collector - completed - @return return code - @pre Initialize(); Query() == true - @post domain element order may be modified. + * @brief Analyze errors within the domain + * @param service data collector + * @param attentiont type (@see iipsdbug.h) + * @returns service data collector - completed + * @return return code + * @pre Initialize(); Query() == true + * @post domain element order may be modified. */ virtual int32_t Analyze( STEP_CODE_DATA_STRUCT & serviceData, ATTENTION_TYPE attentionType ); @@ -122,10 +145,10 @@ class PllDomain : public RuleChipDomain, public ExtensibleDomain, protected: /** - Order the domain - with detecting element at the top - @param Attention type (@see iipsdbug.h) - @post domain elemenet order may be altered - @note this is called by Analyze() + * @brief Order the domain - with detecting element at the top + * @param Attention type (@see iipsdbug.h) + * @post domain elemenet order may be altered + * @note this is called by Analyze() */ virtual void Order(ATTENTION_TYPE attentionType); @@ -161,6 +184,19 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & clockSource, i_mfgThresh ) ) {} +inline +PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, + Resolution & clockSource, + const ThresholdResolution::ThresholdPolicy& i_mfgThresh) : + RuleChipDomain( domain_id, PllDomain::CONTAINER_SIZE ), + ExtensibleDomain("PllDomain"), + closeClockSource(secondClockSource), + farClockSource(clockSource), + iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1, + ThresholdResolution::cv_pllDefault, + i_mfgThresh ) ) +{} + #else // not __HOSTBOOT_MODULE inline @@ -177,6 +213,21 @@ PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & clockSource, iv_dumpContent(i_hwdc) {} +inline +PllDomain::PllDomain( DOMAIN_ID domain_id, Resolution & secondClockSource, + Resolution & clockSource, + hwTableContent i_hwdc, + const ThresholdResolution::ThresholdPolicy& i_mfgThresh) : + RuleChipDomain( domain_id, PllDomain::CONTAINER_SIZE ), + ExtensibleDomain("PllDomain"), + closeClockSource(secondClockSource), + farClockSource(clockSource), + iv_threshold( ResolutionFactory::Access().GetThresholdResolution( 1, + ThresholdResolution::cv_pllDefault, + i_mfgThresh ) ), + iv_dumpContent(i_hwdc) +{} + #endif // not __HOSTBOOT_MODULE //------------------------------------------------------------------------------ diff --git a/src/usr/diag/prdf/common/framework/resolution/prdfCallouts.H b/src/usr/diag/prdf/common/framework/resolution/prdfCallouts.H index 00914dd1c..dc6159cd1 100755 --- a/src/usr/diag/prdf/common/framework/resolution/prdfCallouts.H +++ b/src/usr/diag/prdf/common/framework/resolution/prdfCallouts.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2000,2013 */ +/* COPYRIGHT International Business Machines Corp. 2000,2014 */ /* */ /* p1 */ /* */ @@ -62,6 +62,14 @@ class PRDcallout iv_type(PRDcalloutData::TYPE_TARGET) { iv_meldValue.target = i_target; } + /** @brief Constructor from TargetHandle_t + * with clock type info + */ + PRDcallout( TARGETING::TargetHandle_t i_target, + PRDcalloutData::MruType i_type ) : + iv_type(i_type) + { iv_meldValue.target = i_target; } + /** @brief Constructor from MemoryMru */ PRDcallout( const MemoryMru & i_memmru ) : iv_type(PRDcalloutData::TYPE_MEMMRU) @@ -78,6 +86,8 @@ class PRDcallout switch ( iv_type ) { case PRDcalloutData::TYPE_TARGET: + case PRDcalloutData::TYPE_PROCCLK: + case PRDcalloutData::TYPE_PCICLK: iv_meldValue.target = PlatServices::getTarget(i_val); break; case PRDcalloutData::TYPE_MEMMRU: case PRDcalloutData::TYPE_SYMFRU: diff --git a/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C b/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C index de16a2b58..c86c929b8 100755 --- a/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C +++ b/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2001,2013 */ +/* COPYRIGHT International Business Machines Corp. 2001,2014 */ /* */ /* p1 */ /* */ @@ -43,31 +43,54 @@ int32_t ClockResolution::Resolve(STEP_CODE_DATA_STRUCT & serviceData) using namespace TARGETING; uint32_t l_rc = SUCCESS; - // Use clock routines for CLOCK_CARD types. - // FIXME: RTC: 51628 will address clock target issue - if ( (iv_targetType == TYPE_PROC) || (iv_targetType == TYPE_MEMBUF) ) + // callout clock osc + if ( (iv_targetType == TYPE_PROC) || + (iv_targetType == TYPE_PCI) || + (iv_targetType == TYPE_MEMBUF) ) { // Get clock card. - TargetHandle_t l_ptargetClock = PlatServices::getClockId( - iv_ptargetClock, - iv_targetType ); + TYPE oscType = (iv_targetType == TYPE_PCI) ? + TYPE_OSCPCICLK : TYPE_OSCREFCLK; - // Find mux if no clock card available. - if(NULL == l_ptargetClock) - { - l_ptargetClock = PlatServices::getClockMux(iv_ptargetClock); - } + TargetHandle_t l_ptargetClock = + PlatServices::getClockId(iv_ptargetClock, oscType); // Callout this chip if nothing else. + // FIXME - RTC: 91939 + // will re-write this block of code when + // we can get osc targets from targeting again. + // In the mean time, we don't want to call out the + // chip for this. if(NULL == l_ptargetClock) { - l_ptargetClock = iv_ptargetClock; - } + //l_ptargetClock = iv_ptargetClock; - //Just callout the clock source. - //There is no clock target now so we don't want to make - //any incorrect callout until it's implemented. - //serviceData.service_data->SetCallout(l_ptargetClock); + //in hostboot, getClockId() won't work + //so use the chip target and clock type + #ifdef __HOSTBOOT_MODULE + serviceData.service_data->SetCallout( + PRDcallout(iv_ptargetClock, + iv_targetType == TYPE_PCI ? + PRDcalloutData::TYPE_PCICLK : + PRDcalloutData::TYPE_PROCCLK)); + #endif + } + else + { + // callout the clock source + // HB does not have the osc target modeled + // so we need to use the proc target with + // osc clock type to call out + #ifndef __HOSTBOOT_MODULE + serviceData.service_data->SetCallout(l_ptargetClock); + #else + serviceData.service_data->SetCallout( + PRDcallout(l_ptargetClock, + iv_targetType == TYPE_PCI ? + PRDcalloutData::TYPE_PCICLK : + PRDcalloutData::TYPE_PROCCLK)); + #endif + } } // Get all connected chips for non-CLOCK_CARD types. else diff --git a/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.H b/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.H index eb1a08c0e..35772572c 100755 --- a/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.H +++ b/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2009,2013 */ +/* COPYRIGHT International Business Machines Corp. 2009,2014 */ /* */ /* p1 */ /* */ @@ -63,7 +63,6 @@ public: * @param[in] i_targetType type of target connected to clock source * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. */ - // FIXME: The default target type needs to be set to a PROC clock card. ClockResolution( TARGETING::TargetHandle_t i_pTargetHandle = NULL, TARGETING::TYPE i_targetType = TARGETING::TYPE_PROC ) : iv_ptargetClock( i_pTargetHandle ), diff --git a/src/usr/diag/prdf/common/framework/service/prdfRasServices_common.C b/src/usr/diag/prdf/common/framework/service/prdfRasServices_common.C index 657a99b27..9a9308f86 100644 --- a/src/usr/diag/prdf/common/framework/service/prdfRasServices_common.C +++ b/src/usr/diag/prdf/common/framework/service/prdfRasServices_common.C @@ -623,6 +623,20 @@ errlHndl_t ErrDataService::GenerateSrcPfa( ATTENTION_TYPE i_attnType, l_diagUpdate); } + else if(PRDcalloutData::TYPE_PROCCLK == thiscallout.getType() || + PRDcalloutData::TYPE_PCICLK == thiscallout.getType()) + { + // FIXME - RTC: 91939 + // Can't call out osc clock in hostboot as informational + // until the change from above story is in. + if( sdc.IsAtThreshold() ) + { + PRDF_ADD_CLOCK_CALLOUT(o_errl, + thiscallout.getTarget(), + thiscallout.getType(), + thispriority); + } + } else if ( PRDcalloutData::TYPE_MEMMRU == thiscallout.getType() ) { MemoryMru memMru (thiscallout.flatten()); diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C index 1b4adb88e..78b1690b5 100755 --- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C +++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C @@ -38,6 +38,7 @@ #include <algorithm> #include <fapi.H> #include <targeting/common/targetservice.H> +#include <targeting/common/utilFilter.H> // Pegasus includes #include <prdfCenAddress.H> @@ -1284,95 +1285,66 @@ uint8_t getRanksPerDimm( TargetHandle_t i_mba, uint8_t i_ds ) //## //############################################################################## -// FIXME: RTC: 51628 will address clock target issue -bool areClocksOn(TARGETING::TargetHandle_t i_pGivenTarget) -{ - bool o_clocksOn = false; - - #ifdef __HOSTBOOT_MODULE - - o_clocksOn = true; - - #else - - if ( NULL != i_pGivenTarget ) - { - errlHndl_t errl = NULL; - //errl =HWSV::hwsvClockQueryOn(i_pGivenTarget, - // HWSV::NO_MODE, o_clocksOn); - if ( NULL != errl ) - { - PRDF_ERR( "[areClocksOn] In areClocksOn failed" ); - PRDF_COMMIT_ERRL(errl, ERRL_ACTION_REPORT); - } - } - else - { - PRDF_ERR( "[areClocksOn] given target is null" ); - } - - #endif - - return o_clocksOn; -} - -//------------------------------------------------------------------------------ - -// FIXME: RTC: 51628 will address clock target issue TARGETING::TargetHandle_t getClockId(TARGETING::TargetHandle_t i_pGivenTarget, - TARGETING ::TYPE targetype) + TARGETING ::TYPE i_connType) { + #define PRDF_FUNC "[PlatServices::getClockId] " TargetHandleList l_clockCardlist; + TargetHandle_t l_target = i_pGivenTarget; TargetHandle_t o_pClockCardHandle = NULL; - return o_pClockCardHandle; -} - -//------------------------------------------------------------------------------ - -// FIXME: RTC: 51628 will address clock target issue -TARGETING::TargetHandle_t getClockMux(TARGETING::TargetHandle_t - i_pGivenTarget) -{ - //Modeling info of card and Clock mux is required - // PredicateCTM l_ClockMux(CLASS_UNIT,TYPE_CLOCK_MUX); - //defined for compilation - PredicateCTM l_ClockMux(CLASS_UNIT); - TargetHandle_t o_ptargetClockMux = NULL; - #if 0 do { - if(NULL != i_pGivenTarget) + // If membuf target, use the connected proc target + if(TYPE_MEMBUF == getTargetType(i_pGivenTarget)) { - TargetHandleList l_list; - if(TYPE_PROC==(i_pGivenTarget->getAttr<ATTR_TYPE>())) + l_target = getConnectedParent(i_pGivenTarget, TYPE_PROC); + if(NULL == l_target) { - targetService().getAssociated(l_list, - i_pGivenTarget, - TargetService::CHILD_BY_AFFINITY, - TargetService::ALL, - &l_ClockMux); - } - else - { - //TODO: If given target is not a proc how to query all mux units - // which relation to be used + PRDF_ERR(PRDF_FUNC"failed to get proc target " + "connected to membuf 0x%.8X", + getHuid(l_target)); + break; } + } - if (l_list.size() > 0) - { - // Pick out first item - o_ptargetClockMux = l_list[0]; - } + PredicateIsFunctional l_funcFilter; + PredicateCTM l_oscFilter(CLASS_CHIP, i_connType); + PredicateCTM l_peerFilter(CLASS_UNIT, + (i_connType == TYPE_OSCREFCLK ? + TYPE_REFCLKENDPT: TYPE_PCICLKENDPT)); + PredicatePostfixExpr l_funcAndOscFilter, l_funcAndPeerFilter; + l_funcAndOscFilter.push(&l_oscFilter).push(&l_funcFilter).And(); + l_funcAndPeerFilter.push(&l_peerFilter).push(&l_funcFilter).And(); + + //PROC <---> CLKTYPE <---> PEER <---> CLKTYPE <---> OSC + //Get the oscillators related to this proc + getPeerTargets( l_clockCardlist, // List of connected OSCs + l_target, // to this proc + // filter to get to clock endpoints + &l_funcAndPeerFilter/*&l_peerFilter*/, + // filter to get the driving OSC + &l_funcAndOscFilter/*&l_oscFilter*/); + + for(TargetHandleList::iterator l_itr = l_clockCardlist.begin(); + l_itr != l_clockCardlist.end(); + ++l_itr) + { + PRDF_TRAC(PRDF_FUNC"OSC 0x%.8X is connected to proc 0x%.8X", + getHuid(*l_itr), getHuid(l_target)); } - else + + if( 0 < l_clockCardlist.size()) { - PRDF_ERR("[getClockMux] given target is NULL"); + o_pClockCardHandle = l_clockCardlist[0]; } - }while(0); - #endif - return o_ptargetClockMux; + + } while(0); + + return o_pClockCardHandle; + + #undef PRDF_FUNC } //############################################################################## diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H index 05a8fae62..ba3bb7670 100755 --- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H +++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H @@ -386,34 +386,16 @@ int32_t getDimmSpareConfig( TARGETING::TargetHandle_t i_mba, CenRank i_rank, //############################################################################## /** - * @brief Queries if this chip's clocks are on. - * @param i_pTargetHandle Handle of a chip or any logical entity. - * @return TRUE if this chip's clocks are on, FALSE otherwise. - * @pre None. - * @post None. - */ -bool areClocksOn( TARGETING::TargetHandle_t i_pTargetHandle ); - -/** * @brief Gets handle of the clock card for the given target. - * @param i_pTargetHandle Handle of a functional unit. - * @param i_targetType Type of clock source desired. + * @param i_pTargetHandle Handle of a functional unit. + * @param i_peerType Type of peer clock source * @return Handle_t of clock source. * @pre None. * @post None. */ TARGETING::TargetHandle_t getClockId(TARGETING::TargetHandle_t - i_pTargetHandle,TARGETING::TYPE i_targetType); - -/** - * @brief Get TargetHandle_t of clock mux. - * @param i_pFabricHandle Handle of a fabric. - * @return Handle of clock mux. - * @pre Fabric must be a handle of a functioning fabric. - * @post None. - */ -TARGETING::TargetHandle_t getClockMux(TARGETING::TargetHandle_t - i_pFabricHandle); + i_pTargetHandle, + TARGETING::TYPE i_peerType); //############################################################################## //## MNFG Policy Flag Functions diff --git a/src/usr/diag/prdf/common/plat/pegasus/Ex.rule b/src/usr/diag/prdf/common/plat/pegasus/Ex.rule index 08b7acb4c..872374ca7 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/Ex.rule +++ b/src/usr/diag/prdf/common/plat/pegasus/Ex.rule @@ -5,7 +5,7 @@ # # IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2012,2013 +# COPYRIGHT International Business Machines Corp. 2012,2014 # # p1 # @@ -382,6 +382,26 @@ chip Ex name "Capture Data for L3 Trace Array"; capture group never; }; + + ############################################################################ + # EX Chiplet PLL Registers + ############################################################################ + + register EX_ERROR_REG + { + name "EH.TPCHIP.NET.PCBSLEX.TP_PCB_SLAVE_INST.ERROR_REG"; + scomaddr 0x100F001F; + capture group PllFIRs; + }; + + register EX_CONFIG_REG + { + name "EH.TPCHIP.NET.PCBSLEX.TP_PCB_SLAVE_INST.SLAVE_CONFIG_REG"; + scomaddr 0x100F001E; + capture group PllFIRs; + }; + + }; ############################################################################## diff --git a/src/usr/diag/prdf/common/plat/pegasus/Proc_acts_TP.rule b/src/usr/diag/prdf/common/plat/pegasus/Proc_acts_TP.rule index e3ea48274..567b87569 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/Proc_acts_TP.rule +++ b/src/usr/diag/prdf/common/plat/pegasus/Proc_acts_TP.rule @@ -267,7 +267,7 @@ group gTpLFir filter singlebit * These should never trigger directly themselves. * Should be handled by global PRD PLL code. */ - (TpLFir, bit(19)) ? threshold32pday; + (TpLFir, bit(19)) ? PllError; /** TP_LFIR[20] * Sbe indicated error_event0to4 enabled by mask bit 5 to 9 @@ -1151,6 +1151,13 @@ actionclass ThresholdNoCallout funccall("ClearServiceCallFlag"); }; +/** PLL error action */ +actionclass PllError +{ + capture(PllFIRs); + threshold32pday; +}; + # TOD Actions: # * Get SH Content for all TOD errors. # * Capture at least this chip TOD registers. diff --git a/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_ABUS.rule b/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_ABUS.rule index ed2b24d71..610dc691e 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_ABUS.rule +++ b/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_ABUS.rule @@ -5,7 +5,7 @@ # # IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2012,2013 +# COPYRIGHT International Business Machines Corp. 2012,2014 # # p1 # @@ -160,3 +160,21 @@ capture req nonzero("IOAFIR"); }; + ############################################################################ + # ABUS Chiplet PLL Registers + ############################################################################ + + register ABUS_ERROR_REG + { + name "EH.TPCHIP.NET.PCBSLAB.ERROR_REG"; + scomaddr 0x080F001F; + capture group PllFIRs; + }; + + register ABUS_CONFIG_REG + { + name "EH.TPCHIP.NET.PCBSLAB.SLAVE_CONFIG_REG"; + scomaddr 0x080F001E; + capture group PllFIRs; + }; + diff --git a/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PB.rule b/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PB.rule index 359df5ced..600bcfc93 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PB.rule +++ b/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PB.rule @@ -804,3 +804,21 @@ capture req nonzero("IOMCFIR_1"); }; + ############################################################################ + # PB Chiplet PLL Registers + ############################################################################ + + register PB_ERROR_REG + { + name "EH.TPCHIP.NET.PCBSLNEST.ERROR_REG"; + scomaddr 0x020F001F; + capture group PllFIRs; + }; + + register PB_CONFIG_REG + { + name "EH.TPCHIP.NET.PCBSLNEST.SLAVE_CONFIG_REG"; + scomaddr 0x020F001E; + capture group PllFIRs; + }; + diff --git a/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PCIE.rule b/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PCIE.rule index 5556c53c8..71aa714f8 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PCIE.rule +++ b/src/usr/diag/prdf/common/plat/pegasus/Proc_regs_PCIE.rule @@ -5,7 +5,7 @@ # # IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2012,2013 +# COPYRIGHT International Business Machines Corp. 2012,2014 # # p1 # @@ -263,3 +263,21 @@ capture req nonzero("IOPCIFIR_1"); }; + ############################################################################ + # PCIE Chiplet PLL Registers + ############################################################################ + + register PCI_ERROR_REG + { + name "EH.TPCHIP.NET.PCBSLPCI.ERROR_REG"; + scomaddr 0x090F001F; + capture group PllFIRs; + }; + + register PCI_CONFIG_REG + { + name "EH.TPCHIP.NET.PCBSLPCI.SLAVE_CONFIG_REG"; + scomaddr 0x090F001E; + capture group PllFIRs; + }; + diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenPll.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenPll.C index 51c51a2dd..8fbeb4cc0 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenPll.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenPll.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* COPYRIGHT International Business Machines Corp. 2012,2014 */ /* */ /* p1 */ /* */ @@ -131,22 +131,6 @@ int32_t MaskPll( ExtensibleChip * i_chip,void * unused) } PRDF_PLUGIN_DEFINE( Membuf, MaskPll ); -/** - * @brief Adds to the callout list for Centaur PLL errors. - * @param i_chip Centaur chip. - * @param i_sc The step code data struct. - * @return SUCCESS. - */ -int32_t CalloutPll( ExtensibleChip * i_chip, - STEP_CODE_DATA_STRUCT & i_sc ) -{ - // FIXME: RTC: 51628 will address clock target issue - // set Level 2 callout since we don't have clock target yet - i_sc.service_data->SetCallout( NextLevelSupport_ENUM ); - - return SUCCESS; -} -PRDF_PLUGIN_DEFINE( Membuf, CalloutPll ); } // end namespace Membuf diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfP8DataBundle.H b/src/usr/diag/prdf/common/plat/pegasus/prdfP8DataBundle.H new file mode 100644 index 000000000..41758d909 --- /dev/null +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfP8DataBundle.H @@ -0,0 +1,120 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfP8DataBundle.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013,2014 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __prdfP8DataBundle_H +#define __prdfP8DataBundle_H + +/** @file prdfP8DataBundle.H + * @brief Contains the data bundle for a P8 MCS object. + */ + +#include <iipSystem.h> +#include <prdfExtensibleChip.H> +#include <prdfGlobal.H> +#include <prdfPlatServices.H> +//#include <prdfTrace.H> + +namespace PRDF +{ + +/** + * @brief The P8 data bundle. + */ +class P8DataBundle : public DataBundle +{ + public: // functions + + /* + * @brief Proc PLL chiplet types + */ + enum ChipletType + { + ABUS, + EX, + PB, + }; + + /* + * @brief Proc PLL Error Reg data structure + */ + struct PllErrReg + { + ExtensibleChip * chip; + ChipletType type; + SCAN_COMM_REGISTER_CLASS * errReg; + SCAN_COMM_REGISTER_CLASS * configReg; + PllErrReg() : chip(NULL), errReg(NULL), configReg(NULL) {} + }; + + typedef std::vector<PllErrReg> ProcPllErrRegList; + typedef ProcPllErrRegList::iterator ProcPllErrRegListIter; + + + /** + * @brief Constructor. + * @param i_chip The P8 chip. + */ + explicit P8DataBundle( ExtensibleChip * i_chip ) + {} + + /** + * @brief Destructor. + */ + ~P8DataBundle() {} + + /** + * @brief get a list of Proc PLL Error reg data + * @return returns a list of Proc PLL Error reg data + */ + ProcPllErrRegList & getProcPllErrRegList() + { + return iv_procPllErrRegList; + } + + private: // functions + + P8DataBundle( const P8DataBundle & ); + const P8DataBundle & operator=( const P8DataBundle & ); + + private: // instance variables + + ProcPllErrRegList iv_procPllErrRegList; + +}; + +//------------------------------------------------------------------------------ + +/** + * @brief Wrapper function for the P8DataBundle. + * @param i_chip The P8 chip. + * @return This P8's data bundle. + */ +inline P8DataBundle * getDataBundle( ExtensibleChip * i_chip ) +{ + return static_cast<P8DataBundle *>(i_chip->getDataBundle()); +} + +} // end namespace PRDF + +#endif // __prdfP8DataBundle_H + diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C b/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C index d63dd4686..afa833aa7 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfP8Pll.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* COPYRIGHT International Business Machines Corp. 2012,2014 */ /* */ /* p1 */ /* */ @@ -32,22 +32,91 @@ #include <prdfBitString.H> #include <iipscr.h> #include <prdfPlatServices.H> +#include <prdfErrlUtil.H> +#include <iipSystem.h> +#include <prdfGlobal_common.H> +#include <prdfP8DataBundle.H> + +using namespace TARGETING; namespace PRDF { +using namespace PlatServices; + namespace Proc { enum { - PLL_DETECT_P8 = 19, //Bit position of the error bit. + // 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, + PB_DMI_RIGHT_PLL_ERROR = 25, // Venice only + PB_DMI_LEFT_PLL_ERROR = 26, // Venice and Murano }; /** - * @brief Query the PLL chip for a PLL error on P8 Plugin - * @param i_chip P8 chip + * @brief this is to get a list of pll error + * register data to work on + * @param i_chip P8 chip + * @param o_pllErrRegList Pll Err Reg list + * @note + */ +void GetProcPllErrRegList(ExtensibleChip * i_chip, + P8DataBundle::ProcPllErrRegList& o_pllErrRegList) +{ + #define PRDF_FUNC "[Proc::GetProcPllErrRegList] " + o_pllErrRegList.clear(); + P8DataBundle::PllErrReg entry; + + do + { + // PB + entry.chip = i_chip; + entry.type = P8DataBundle::PB; + entry.errReg = i_chip->getRegister("PB_ERROR_REG"); + entry.configReg = i_chip->getRegister("PB_CONFIG_REG"); + o_pllErrRegList.push_back( entry ); + + // ABUS + entry.chip = i_chip; + entry.type = P8DataBundle::ABUS; + entry.errReg = i_chip->getRegister("ABUS_ERROR_REG"); + entry.configReg = i_chip->getRegister("ABUS_CONFIG_REG"); + o_pllErrRegList.push_back( entry ); + + // EX + TargetHandleList exList = getConnected( + i_chip->GetChipHandle(), TYPE_EX); + ExtensibleChip * exChip; + + TargetHandleList::iterator itr = exList.begin(); + for( ; itr != exList.end(); ++itr) + { + PRDF_DTRAC(PRDF_FUNC"EX: 0x%.8X", getHuid(*itr)); + exChip = (ExtensibleChip *)systemPtr->GetChip( *itr ); + if( NULL == exChip ) continue; + + entry.chip = exChip; + entry.type = P8DataBundle::EX; + entry.errReg = exChip->getRegister("EX_ERROR_REG"); + entry.configReg = exChip->getRegister("EX_CONFIG_REG"); + o_pllErrRegList.push_back( entry ); + } + + } while(0); + + #undef PRDF_FUNC +} + +/** + * @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 @@ -55,11 +124,15 @@ enum int32_t QueryPll( ExtensibleChip * i_chip, bool & o_result) { + #define PRDF_FUNC "[Proc::QueryPll] " + 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"); + SCAN_COMM_REGISTER_CLASS * TP_LFIR = + i_chip->getRegister("TP_LFIR"); + SCAN_COMM_REGISTER_CLASS * TP_LFIRmask = + i_chip->getRegister("TP_LFIR_MASK"); do { @@ -70,40 +143,236 @@ int32_t QueryPll( ExtensibleChip * i_chip, if (rc != SUCCESS) break; if(TP_LFIR->IsBitSet(PLL_DETECT_P8) && - !(TP_LFIRmask->IsBitSet(PLL_DETECT_P8))) + !TP_LFIRmask->IsBitSet(PLL_DETECT_P8)) { 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, QueryPll ); + /** - * @brief Clear the PLL error for P8 Plugin + * @brief Query the PLL chip for a Proc PLL error * @param i_chip P8 chip - * @param i_sc The step code data struct + * @param o_result set to true in the presence of PLL error * @returns Failure or Success of query. * @note */ +int32_t QueryProcPll( ExtensibleChip * i_chip, + bool & o_result) +{ + #define PRDF_FUNC "[Proc::QueryProcPll] " + + 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"); + MODEL procModel = getProcModel( i_chip->GetChipHandle() ); + + do + { + rc = TP_LFIR->Read(); + if (rc != SUCCESS) break; + + rc = TP_LFIRmask->Read(); + if (rc != SUCCESS) break; + + // First check for LFIR + if( !(TP_LFIR->IsBitSet(PLL_DETECT_P8) && + !(TP_LFIRmask->IsBitSet(PLL_DETECT_P8))) ) + { + break; + } + + // Next check for the error reg bits in the chiplets + P8DataBundle * procdb = getDataBundle( i_chip ); + P8DataBundle::ProcPllErrRegList & procPllErrRegList = + procdb->getProcPllErrRegList(); + + // Always get a list here since this is the entry point + GetProcPllErrRegList( i_chip, procPllErrRegList ); + + P8DataBundle::ProcPllErrRegListIter itr = procPllErrRegList.begin(); + for( ; itr != procPllErrRegList.end(); ++itr) + { + rc = (*itr).errReg->Read(); + if (rc != SUCCESS) break; + + rc = (*itr).configReg->Read(); + if (rc != SUCCESS) break; + + if( P8DataBundle::PB == (*itr).type ) + { + if(( (*itr).errReg->IsBitSet(PB_DMI_LEFT_PLL_ERROR) && + !(*itr).configReg->IsBitSet(PLL_ERROR_MASK) ) || + (( MODEL_VENICE == procModel) && + ( (*itr).errReg->IsBitSet(PB_DMI_RIGHT_PLL_ERROR) && + !(*itr).configReg->IsBitSet(PLL_ERROR_MASK) ))) + { + o_result = true; + break; + } + } + else if((*itr).errReg->IsBitSet(PLL_ERROR_BIT) && + !(*itr).configReg->IsBitSet(PLL_ERROR_MASK)) + { + o_result = true; + 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, 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 * TP_LFIR = + i_chip->getRegister("TP_LFIR"); + SCAN_COMM_REGISTER_CLASS * TP_LFIRmask = + i_chip->getRegister("TP_LFIR_MASK"); + SCAN_COMM_REGISTER_CLASS * pciErrReg = + i_chip->getRegister("PCI_ERROR_REG"); + SCAN_COMM_REGISTER_CLASS * pciConfigReg = + i_chip->getRegister("PCI_CONFIG_REG"); + + do + { + rc = TP_LFIR->Read(); + if (rc != SUCCESS) break; + + rc = TP_LFIRmask->Read(); + if (rc != SUCCESS) break; + + rc = pciErrReg->Read(); + if (rc != SUCCESS) break; + + rc = pciConfigReg->Read(); + if (rc != SUCCESS) break; + + if(TP_LFIR->IsBitSet(PLL_DETECT_P8) && + !TP_LFIRmask->IsBitSet(PLL_DETECT_P8) && + 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 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 ClearPll( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & i_sc) { + #define PRDF_FUNC "[Proc::ClearPll] " + int32_t rc = SUCCESS; if (CHECK_STOP != i_sc.service_data->GetAttentionType()) { - SCAN_COMM_REGISTER_CLASS * TP_LFIR = i_chip->getRegister("TP_LFIR_AND"); + // Clear proc osc error reg bits + P8DataBundle * procdb = getDataBundle( i_chip ); + P8DataBundle::ProcPllErrRegList & procPllErrRegList = + procdb->getProcPllErrRegList(); + if( procPllErrRegList.empty() ) + { + GetProcPllErrRegList( i_chip, procPllErrRegList ); + } + + P8DataBundle::ProcPllErrRegListIter itr = procPllErrRegList.begin(); + for( ; itr != procPllErrRegList.end(); ++itr) + { + (*itr).errReg->ClearBit(PLL_ERROR_BIT); + if( P8DataBundle::PB == (*itr).type ) + { + (*itr).errReg->ClearBit(PB_DMI_LEFT_PLL_ERROR); + } + rc |= (*itr).errReg->Write(); + } + + // Clear pci osc error reg bit + SCAN_COMM_REGISTER_CLASS * pciErrReg = + i_chip->getRegister("PCI_ERROR_REG"); + pciErrReg->ClearBit(PLL_ERROR_BIT); + rc |= pciErrReg->Write(); + + // Clear TP_LFIR + SCAN_COMM_REGISTER_CLASS * TP_LFIR = + i_chip->getRegister("TP_LFIR_AND"); TP_LFIR->setAllBits(); TP_LFIR->ClearBit(PLL_DETECT_P8); - rc = TP_LFIR->Write(); + rc |= TP_LFIR->Write(); + + // 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(); + } + + if( rc != SUCCESS ) + { + PRDF_ERR(PRDF_FUNC"failed for proc: 0x%.8X", + i_chip->GetId()); } return rc; + #undef PRDF_FUNC } PRDF_PLUGIN_DEFINE( Proc, ClearPll ); @@ -116,34 +385,111 @@ PRDF_PLUGIN_DEFINE( Proc, ClearPll ); */ int32_t MaskPll( ExtensibleChip * i_chip,void * unused) { + #define PRDF_FUNC "[Proc::MaskPll] " + int32_t rc = SUCCESS; - SCAN_COMM_REGISTER_CLASS * tpmask_or = i_chip->getRegister("TP_LFIR_MASK_OR"); - tpmask_or->clearAllBits(); - tpmask_or->SetBit(PLL_DETECT_P8); - rc = tpmask_or->Write(); + MODEL procModel = getProcModel( i_chip->GetChipHandle() ); + // fence off proc osc error reg bits + P8DataBundle * procdb = getDataBundle( i_chip ); + P8DataBundle::ProcPllErrRegList & procPllErrRegList = + procdb->getProcPllErrRegList(); + if( procPllErrRegList.empty() ) + { + GetProcPllErrRegList( i_chip, procPllErrRegList ); + } + + P8DataBundle::ProcPllErrRegListIter itr = procPllErrRegList.begin(); + for( ; itr != procPllErrRegList.end(); ++itr) + { + // Error is already fenced + if( (*itr).configReg->IsBitSet(PLL_ERROR_MASK) ) + { + continue; + } + + bool needMask = false; + if( P8DataBundle::PB == (*itr).type ) + { + if( ((*itr).errReg->IsBitSet(PB_DMI_LEFT_PLL_ERROR)) || + (( MODEL_VENICE == procModel) && + ( (*itr).errReg->IsBitSet(PB_DMI_RIGHT_PLL_ERROR))) ) + { + (*itr).configReg->SetBit(PLL_ERROR_MASK); + needMask = true; + } + } + else if( (*itr).errReg->IsBitSet(PLL_ERROR_BIT) ) + { + (*itr).configReg->SetBit(PLL_ERROR_MASK); + needMask = true; + } + + if( needMask ) + { + rc |= (*itr).configReg->Write(); + } + } + + // fence off pci osc error reg bit + SCAN_COMM_REGISTER_CLASS * pciErrReg = + i_chip->getRegister("PCI_ERROR_REG"); + SCAN_COMM_REGISTER_CLASS * pciConfigReg = + i_chip->getRegister("PCI_CONFIG_REG"); + + if(pciErrReg->IsBitSet(PLL_ERROR_BIT) && + !pciConfigReg->IsBitSet(PLL_ERROR_MASK)) + { + pciConfigReg->SetBit(PLL_ERROR_MASK); + rc |= pciConfigReg->Write(); + } + + // 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 + + if( rc != SUCCESS ) + { + PRDF_ERR(PRDF_FUNC"failed for proc: 0x%.8X", + i_chip->GetId()); + } + return rc; + #undef PRDF_FUNC } PRDF_PLUGIN_DEFINE( Proc, MaskPll ); /** - * @brief Adds to the callout list for P8 PLL errors. - * @param i_chip P8 chip. - * @param i_sc The step code data struct. + * @brief Optional plugin function called after analysis is complete but + * before PRD exits. + * @param i_chip P8 chip. + * @param i_sc The step code data struct. + * @note This is especially useful for any analysis that still needs to be + * done after the framework clears the FIR bits that were at attention. * @return SUCCESS. */ -int32_t CalloutPll( ExtensibleChip * i_chip, - STEP_CODE_DATA_STRUCT & i_sc ) +int32_t PllPostAnalysis( ExtensibleChip * i_chip, + STEP_CODE_DATA_STRUCT & i_sc ) { - // FIXME: RTC: 51628 will address clock target issue - // set Level 2 callout since we don't have clock target yet - i_sc.service_data->SetCallout( NextLevelSupport_ENUM ); + #define PRDF_FUNC "[Proc::PllPostAnalysis] " + + // Need to clear the PLL Err Reg list so it can + // be populated with fresh data on the next analysis + P8DataBundle * procdb = getDataBundle( i_chip ); + P8DataBundle::ProcPllErrRegList & procPllErrRegList = + procdb->getProcPllErrRegList(); + procPllErrRegList.clear(); return SUCCESS; + #undef PRDF_FUNC } -PRDF_PLUGIN_DEFINE( Proc, CalloutPll ); - +PRDF_PLUGIN_DEFINE( Proc, PllPostAnalysis ); } // end namespace Proc diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfP8Proc.C b/src/usr/diag/prdf/common/plat/pegasus/prdfP8Proc.C index f39cefbb5..8557867de 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfP8Proc.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfP8Proc.C @@ -31,6 +31,7 @@ #include <prdfPluginMap.H> #include <prdfLaneRepair.H> #include <prdfPhbUtils.H> +#include <prdfP8DataBundle.H> using namespace TARGETING; @@ -55,6 +56,7 @@ namespace Proc */ int32_t Initialize( ExtensibleChip * i_chip ) { + i_chip->getDataBundle() = new P8DataBundle( i_chip ); return SUCCESS; } PRDF_PLUGIN_DEFINE( Proc, Initialize ); diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C b/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C index 747f71e87..cffc861c0 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfPegasusConfigurator.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* COPYRIGHT International Business Machines Corp. 2012,2014 */ /* */ /* p1 */ /* */ @@ -43,9 +43,13 @@ #include <iipSystem.h> #include <prdrLoadChipCache.H> // To flush chip-file cache. +using namespace TARGETING; + namespace PRDF { +using namespace PlatServices; + //------------------------------------------------------------------------------ // Resolution for no chips at attention. @@ -298,34 +302,50 @@ void PegasusConfigurator::addChipsToPllDomain( ScanFacility & i_scanFac, ResolutionFactory & i_resFac) { - using namespace TARGETING; - do { uint32_t l_node = _getNodePosition(i_pTarget); - // Fabric PLL - only one per node as all fabs on node have same clock source + // Fabric PLL - only one per node as all fabs + // on node have same clock source if(NULL != io_pllDomains) { if(NULL == (*io_pllDomains)[l_node]) { - if((CLOCK_DOMAIN_FAB == i_domainId) || - (CLOCK_DOMAIN_MEMBUF == i_domainId)) + if(CLOCK_DOMAIN_FAB == i_domainId) { - Resolution & l_clock =(CLOCK_DOMAIN_FAB == i_domainId) ? - i_resFac.GetClockResolution(i_pTarget, TYPE_PROC) : - i_resFac.GetClockResolution(i_pTarget, TYPE_MEMBUF); + Resolution & procClock = i_resFac.GetClockResolution( + i_pTarget, TYPE_PROC); + Resolution & ioClock = i_resFac.GetClockResolution( + i_pTarget, TYPE_PCI); #ifdef __HOSTBOOT_MODULE (*io_pllDomains)[l_node] = new PllDomain( - i_domainId, l_clock, + i_domainId, ioClock, procClock, ThresholdResolution::cv_pllDefault ); #else (*io_pllDomains)[l_node] = new PllDomain( - i_domainId, l_clock, CONTENT_HW, + i_domainId, ioClock, procClock, + CONTENT_HW, ThresholdResolution::cv_pllDefault ); #endif } + else if(CLOCK_DOMAIN_MEMBUF == i_domainId) + { + Resolution & clock = i_resFac.GetClockResolution( + i_pTarget, TYPE_MEMBUF); + + #ifdef __HOSTBOOT_MODULE + (*io_pllDomains)[l_node] = new PllDomain( + i_domainId, clock, + ThresholdResolution::cv_pllDefault ); + #else + (*io_pllDomains)[l_node] = new PllDomain( + i_domainId, clock, CONTENT_HW, + ThresholdResolution::cv_pllDefault ); + #endif + } + else { PRDF_ERR( "[addChipsToPllDomain] Unsupported PLL Domain: " diff --git a/src/usr/diag/prdf/common/plugins/prdfCalloutsData.H b/src/usr/diag/prdf/common/plugins/prdfCalloutsData.H index dbe792464..63f9747bb 100644 --- a/src/usr/diag/prdf/common/plugins/prdfCalloutsData.H +++ b/src/usr/diag/prdf/common/plugins/prdfCalloutsData.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2013 */ +/* COPYRIGHT International Business Machines Corp. 2013,2014 */ /* */ /* p1 */ /* */ @@ -51,6 +51,8 @@ enum MruType TYPE_TARGET, TYPE_MEMMRU, TYPE_SYMFRU, + TYPE_PROCCLK, + TYPE_PCICLK, }; } // end namespace PRDcalloutData diff --git a/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C b/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C index cff6134f2..30bbd4bf3 100644 --- a/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C +++ b/src/usr/diag/prdf/common/plugins/prdfLogParse_common.C @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2003,2013 */ +/* COPYRIGHT International Business Machines Corp. 2003,2014 */ /* */ /* p1 */ /* */ @@ -496,6 +496,8 @@ bool parsePfaData( void * i_buffer, uint32_t i_buflen, break; case PRDcalloutData::TYPE_TARGET: + case PRDcalloutData::TYPE_PROCCLK: + case PRDcalloutData::TYPE_PCICLK: strcat( data, "(HUID)" ); i_parser.PrintString( header, data ); break; diff --git a/src/usr/diag/prdf/prdfErrlUtil.H b/src/usr/diag/prdf/prdfErrlUtil.H index a307ba9d6..c9eec1dfd 100644 --- a/src/usr/diag/prdf/prdfErrlUtil.H +++ b/src/usr/diag/prdf/prdfErrlUtil.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2002,2013 */ +/* COPYRIGHT International Business Machines Corp. 2002,2014 */ /* */ /* p1 */ /* */ @@ -207,6 +207,15 @@ (void)(i_diag_need) /** + * @brief Add clock callout + */ +#define PRDF_ADD_CLOCK_CALLOUT(io_errl, i_target, i_clockType, i_priority) \ + io_errl->addClockCallout(i_target, \ + (PRDcalloutData::TYPE_PROCCLK == i_clockType) ? \ + HWAS::OSCREFCLK_TYPE : HWAS::OSCPCICLK_TYPE, \ + (const HWAS::callOutPriority)i_priority); + +/** * @brief Process's pending deconfig and GARD service actions * and thencommits and deletes the error log. */ diff --git a/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H b/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H index 8f22a2863..0bb1abd3b 100755 --- a/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H +++ b/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H @@ -5,7 +5,7 @@ /* */ /* IBM CONFIDENTIAL */ /* */ -/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* COPYRIGHT International Business Machines Corp. 2012,2014 */ /* */ /* p1 */ /* */ @@ -62,10 +62,138 @@ class PTPLFIR:public CxxTest::TestSuite //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(); + } + + void TestPllAtThreshold(void) + { + PRDS_BEGIN("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(); } }; |