summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChris Phan <cphan@us.ibm.com>2014-09-16 21:18:07 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-09-22 13:26:06 -0500
commitfe787082ffbf72795dc3c58d09e0a7ed45600da2 (patch)
treeae18464ab2b6abc2b79dc25273bef0714812e88a /src
parent83e47c8df68c5736a8bb080d0a250df77c82f935 (diff)
downloadtalos-hostboot-fe787082ffbf72795dc3c58d09e0a7ed45600da2.tar.gz
talos-hostboot-fe787082ffbf72795dc3c58d09e0a7ed45600da2.zip
PRD: change osc callout and threshold design
Change-Id: Ib54734a1db5d17f4ea13ddd80f91fc4dae7aef3a CQ: SW278778 Backport: release-fips820 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13461 Tested-by: Jenkins Server Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: Zane Shelley <zshelle@us.ibm.com> Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13519
Diffstat (limited to 'src')
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/config/prdfPllDomain.C157
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/config/prdfPllDomain.H30
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C25
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C32
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H34
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfTargetServices.C26
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfTargetServices.H4
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/Proc.rule11
-rwxr-xr-xsrc/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C105
-rw-r--r--src/usr/diag/prdf/common/plugins/prdfParserEnums.H2
-rw-r--r--src/usr/diag/prdf/framework/service/prdfPlatServices.C77
-rwxr-xr-xsrc/usr/diag/prdf/test/prdfTest_ProcTpLFir.H12
12 files changed, 458 insertions, 57 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();
diff --git a/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C b/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C
index 0bffe92c5..3ee6b3e4d 100755
--- a/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C
+++ b/src/usr/diag/prdf/common/framework/resolution/prdfClockResolution.C
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2001,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. */
@@ -45,15 +47,13 @@ int32_t ClockResolution::Resolve(STEP_CODE_DATA_STRUCT & serviceData)
uint32_t l_rc = SUCCESS;
// callout clock osc
if ( (iv_targetType == TYPE_PROC) ||
- (iv_targetType == TYPE_PCI) ||
(iv_targetType == TYPE_MEMBUF) )
{
- // Get clock card.
- TYPE oscType = (iv_targetType == TYPE_PCI) ?
- TYPE_OSCPCICLK : TYPE_OSCREFCLK;
-
+ // even though we pass in pos=0 for systemref clk,
+ // getActiveRefClk will make sure it returns the active osc.
TargetHandle_t l_ptargetClock =
- PlatServices::getClockId(iv_ptargetClock, oscType);
+ PlatServices::getActiveRefClk(iv_ptargetClock,
+ TYPE_OSCREFCLK, 0);
// Callout this chip if nothing else.
if(NULL == l_ptargetClock)
@@ -70,11 +70,16 @@ int32_t ClockResolution::Resolve(STEP_CODE_DATA_STRUCT & serviceData)
#else
serviceData.service_data->SetCallout(
PRDcallout(l_ptargetClock,
- iv_targetType == TYPE_PCI ?
- PRDcalloutData::TYPE_PCICLK :
- PRDcalloutData::TYPE_PROCCLK));
+ PRDcalloutData::TYPE_PROCCLK));
#endif
}
+ else if (iv_targetType == TYPE_PCI)
+ {
+ // The PCIe OSC callout is being done inside
+ // chip plugins (prdfP8PllPcie) since the connected
+ // OSC can dynamically change and requires
+ // reading chip reg to figure out.
+ }
// Get all connected chips for non-CLOCK_CARD types.
else
{
diff --git a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
index a564c8c5c..18023a4a7 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
+++ b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
@@ -108,6 +108,38 @@ fapi::Target getFapiTarget( TARGETING::TargetHandle_t i_target )
//## Processor specific functions
//##############################################################################
+uint32_t getIoOscPos( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc)
+{
+ #define PRDF_FUNC "[PlatServices::getIoOscPos] "
+ uint32_t o_oscPos = MAX_PCIE_OSC_PER_NODE;
+
+ do
+ {
+ uint32_t u32Data = 0;
+
+ int32_t tmpRc = getCfam( i_chip, io_sc, 0x2819, u32Data );
+
+ if ( SUCCESS != tmpRc )
+ {
+ PRDF_ERR( PRDF_FUNC"getCfam of 0x2819 returned error for "
+ "chip 0x%08x", i_chip->GetId() );
+ break;
+ }
+
+ // 2819 [ 16 ] == 1 ( OSC 0 is active )
+ // 2819 [ 16 ] == 0 ( OSC 1 is active )
+ uint32_t tmpData = ( u32Data >> 15 ) & 0x1;
+ o_oscPos = (tmpData == 1 ? 0:1);
+
+ } while(0);
+
+ return o_oscPos;
+
+ #undef PRDF_FUNC
+}
+
+
//##############################################################################
//## Lane Repair functions
//##############################################################################
diff --git a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H
index 57a455751..75825400f 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H
+++ b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.H
@@ -162,6 +162,15 @@ void initiateUnitDump( TARGETING::TargetHandle_t i_target,
*/
void collectSBE_FFDC(TARGETING::TargetHandle_t i_procTarget);
+/**
+ * @brief get the active pcie osc pos for this proc
+ * @param i_chip P8 chip
+ * @param i_sc service data collector
+ * @return active osc position
+ */
+uint32_t getIoOscPos( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc );
+
//##############################################################################
//## Lane Repair functions
//##############################################################################
@@ -500,6 +509,31 @@ mss_MaintCmdWrapper * createMssCmd( mss_MaintCmdWrapper::CmdType i_cmdType,
void captureFsiStatusReg( ExtensibleChip * i_chip,
STEP_CODE_DATA_STRUCT & io_sc );
+/**
+ * @brief get cfam data
+ * @param i_chip Extensible chip
+ * @param i_sc service data collector
+ * @param i_addr address
+ * @param o_data returned data
+ * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
+ */
+int32_t getCfam( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ const uint32_t i_addr,
+ uint32_t & o_data);
+
+/**
+ * @brief get sysref clk target for the given proc target.
+ * @param i_procTarget proc target.
+ * @param i_peerType Type of peer clock source
+ * @param i_oscPos OSC position (0 or 1)
+ * @return Handle_t of systemref clock target.
+ */
+TARGETING::TargetHandle_t getActiveRefClk(
+ TARGETING::TargetHandle_t i_procTarget,
+ TARGETING::TYPE i_connType,
+ uint32_t i_oscPos);
+
} // end namespace PlatServices
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C
index fc8eea822..2cb06d287 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C
+++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.C
@@ -890,6 +890,8 @@ uint32_t getTargetPosition( TARGETING::TargetHandle_t i_target )
{
case TYPE_PROC:
case TYPE_OSC:
+ case TYPE_OSCPCICLK:
+ case TYPE_OSCREFCLK:
{
uint16_t tmpPos = 0;
if ( !i_target->tryGetAttr<ATTR_POSITION>(tmpPos) )
@@ -1300,15 +1302,24 @@ uint8_t getRanksPerDimm( TargetHandle_t i_mba, uint8_t i_ds )
TARGETING::TargetHandle_t getClockId(TARGETING::TargetHandle_t
i_pGivenTarget,
- TARGETING ::TYPE i_connType)
+ TARGETING ::TYPE i_connType,
+ uint32_t i_oscPos)
{
#define PRDF_FUNC "[PlatServices::getClockId] "
+
TargetHandleList l_clockCardlist;
TargetHandle_t l_target = i_pGivenTarget;
TargetHandle_t o_pClockCardHandle = NULL;
do
{
+ if ( i_oscPos >= MAX_PCIE_OSC_PER_NODE )
+ {
+ PRDF_ERR(PRDF_FUNC"target: 0x%.8X - invalid "
+ "i_oscPos: %d", getHuid(i_pGivenTarget), i_oscPos);
+ break;
+ }
+
// If membuf target, use the connected proc target
if(TYPE_MEMBUF == getTargetType(i_pGivenTarget))
{
@@ -1344,13 +1355,14 @@ TARGETING::TargetHandle_t getClockId(TARGETING::TargetHandle_t
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));
- }
+ PRDF_TRAC(PRDF_FUNC"OSC 0x%.8X, pos: %d is connected to "
+ "proc 0x%.8X, inputOscPos: %d", getHuid(*l_itr),
+ getTargetPosition(*l_itr), getHuid(l_target), i_oscPos);
- if( 0 < l_clockCardlist.size())
- {
- o_pClockCardHandle = l_clockCardlist[0];
+ if ( i_oscPos == getTargetPosition(*l_itr) )
+ {
+ o_pClockCardHandle = *l_itr;
+ }
}
} while(0);
diff --git a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H
index cbb965b8e..ff3a34a05 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H
+++ b/src/usr/diag/prdf/common/framework/service/prdfTargetServices.H
@@ -374,13 +374,15 @@ uint8_t getRanksPerDimm( TARGETING::TargetHandle_t i_mbaTarget, uint8_t i_ds );
* @brief Gets handle of the clock card for the given target.
* @param i_pTargetHandle Handle of a functional unit.
* @param i_peerType Type of peer clock source
+ * @param i_oscPos OSC position (0 or 1)
* @return Handle_t of clock source.
* @pre None.
* @post None.
*/
TARGETING::TargetHandle_t getClockId(TARGETING::TargetHandle_t
i_pTargetHandle,
- TARGETING::TYPE i_peerType);
+ TARGETING::TYPE i_peerType,
+ uint32_t i_oscPos);
//##############################################################################
//## MNFG Policy Flag Functions
diff --git a/src/usr/diag/prdf/common/plat/pegasus/Proc.rule b/src/usr/diag/prdf/common/plat/pegasus/Proc.rule
index dfbedfb1f..8c97fcbe0 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/Proc.rule
+++ b/src/usr/diag/prdf/common/plat/pegasus/Proc.rule
@@ -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.
@@ -160,6 +162,13 @@ chip Proc
capture group never;
};
+ register PCIE_OSC_SWITCH
+ {
+ name "TPC.FSI.FSI_MAILBOX.FSXCOMP.FSXLOG.SNS1LTH";
+ scomaddr 0x00002819;
+ capture group never;
+ };
+
};
##############################################################################
diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C b/src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C
index b1a02aa03..a27e4bc57 100755
--- a/src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C
+++ b/src/usr/diag/prdf/common/plat/pegasus/prdfP8PllPcie.C
@@ -199,6 +199,15 @@ int32_t ClearPllIo( ExtensibleChip * i_chip,
int32_t tmpRC = SUCCESS;
SCAN_COMM_REGISTER_CLASS * pciErrReg =
i_chip->getRegister("PCI_ERROR_REG");
+
+ tmpRC = pciErrReg->Read();
+ if (tmpRC != SUCCESS)
+ {
+ PRDF_ERR(PRDF_FUNC"PCI_ERROR_REG read failed"
+ "for chip: 0x%08x", i_chip->GetId());
+ rc |= tmpRC;
+ }
+
pciErrReg->ClearBit(PLL_ERROR_BIT);
tmpRC = pciErrReg->Write();
if (tmpRC != SUCCESS)
@@ -238,22 +247,55 @@ 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
+ * @param i_oscPos active osc position
* @returns Failure or Success of query.
* @note
*/
int32_t MaskPllIo( ExtensibleChip * i_chip,
- STEP_CODE_DATA_STRUCT & i_sc )
+ STEP_CODE_DATA_STRUCT & i_sc,
+ uint32_t i_oscPos )
{
#define PRDF_FUNC "[Proc::MaskPllIo] "
int32_t rc = SUCCESS;
- if (CHECK_STOP != i_sc.service_data->GetAttentionType())
+ do
{
+ if (CHECK_STOP == i_sc.service_data->GetAttentionType())
+ {
+ break;
+ }
+
+ if ( i_oscPos >= MAX_PCIE_OSC_PER_NODE )
+ {
+ PRDF_ERR(PRDF_FUNC"invalid oscPos: %d for chip: "
+ "0x%08x", i_oscPos, i_chip->GetId());
+ rc = FAIL;
+ break;
+ }
+
+ uint32_t oscPos = getIoOscPos( i_chip, i_sc );
+
+ if ( oscPos != i_oscPos )
+ {
+ PRDF_DTRAC(PRDF_FUNC"skip masking for chip: 0x%08x, "
+ "oscPos: %d, i_oscPos: %d",
+ i_chip->GetId(), oscPos, i_oscPos);
+ break;
+ }
+
// fence off pci osc error reg bit
SCAN_COMM_REGISTER_CLASS * pciConfigReg =
i_chip->getRegister("PCI_CONFIG_REG");
+ rc = pciConfigReg->Read();
+ if (rc != SUCCESS)
+ {
+ PRDF_ERR(PRDF_FUNC"PCI_CONFIG_REG read failed"
+ "for 0x%08x", i_chip->GetId());
+ break;
+ }
+
if(!pciConfigReg->IsBitSet(PLL_ERROR_MASK))
{
pciConfigReg->SetBit(PLL_ERROR_MASK);
@@ -270,7 +312,7 @@ int32_t MaskPllIo( ExtensibleChip * i_chip,
// 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
+ } while(0);
return rc;
@@ -285,7 +327,7 @@ PRDF_PLUGIN_DEFINE( Proc, MaskPllIo );
* @returns Success
*/
int32_t capturePllFfdcIo( ExtensibleChip * i_chip,
- STEP_CODE_DATA_STRUCT & io_sc )
+ STEP_CODE_DATA_STRUCT & io_sc )
{
// Add FSI status reg
captureFsiStatusReg( i_chip, io_sc );
@@ -294,6 +336,61 @@ int32_t capturePllFfdcIo( ExtensibleChip * i_chip,
}
PRDF_PLUGIN_DEFINE( Proc, capturePllFfdcIo );
+/**
+ * @brief calling out active pcie osc connected to this proc
+ * @param i_chip P8 chip
+ * @param i_sc service data collector
+ * @returns Success
+ */
+int32_t CalloutPllIo( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[Proc::CalloutPllIo] "
+
+ int32_t rc = SUCCESS;
+
+ do
+ {
+ uint32_t oscPos = getIoOscPos( i_chip, io_sc );
+
+ // oscPos will be checked inside getClockId and in case
+ // a connected osc is not found, will use the proc target
+ // this is the hostboot path since it's used the proc
+ // target and clock type.
+ TargetHandle_t connectedOsc = getClockId( i_chip->GetChipHandle(),
+ TYPE_OSCPCICLK,
+ oscPos );
+
+ if ( NULL == connectedOsc )
+ {
+ PRDF_ERR(PRDF_FUNC"Failed to get connected PCIe OSC for "
+ "chip 0x%08x, oscPos: %d",i_chip->GetId(), oscPos );
+ connectedOsc = i_chip->GetChipHandle();
+ }
+
+ PRDF_DTRAC(PRDF_FUNC"PCIe OSC: 0x%08x connected to "
+ "proc: 0x%08x", getHuid(connectedOsc), i_chip->GetId());
+
+ // 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
+ io_sc.service_data->SetCallout(connectedOsc);
+ #else
+ io_sc.service_data->SetCallout(
+ PRDcallout(connectedOsc,
+ PRDcalloutData::TYPE_PCICLK));
+ #endif
+
+ } while(0);
+
+ return rc;
+
+ #undef PRDF_FUNC
+}
+PRDF_PLUGIN_DEFINE( Proc, CalloutPllIo );
+
} // end namespace Proc
} // end namespace PRDF
diff --git a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
index 73c7d3895..bcab4da4c 100644
--- a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
+++ b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H
@@ -67,6 +67,8 @@ enum PositionBounds
MAX_DIMM_PER_PORT = 2,
MAX_L4_PER_MEMBUF = 1,
+ MAX_PCIE_OSC_PER_NODE = 2,
+
INVALID_POSITION_BOUND = 0xffffffff,
};
diff --git a/src/usr/diag/prdf/framework/service/prdfPlatServices.C b/src/usr/diag/prdf/framework/service/prdfPlatServices.C
index 1c7eddc76..cb20e8a44 100644
--- a/src/usr/diag/prdf/framework/service/prdfPlatServices.C
+++ b/src/usr/diag/prdf/framework/service/prdfPlatServices.C
@@ -267,10 +267,14 @@ bool isSmpCoherent() { return false; }
//## util functions
//##############################################################################
-void captureFsiStatusReg( ExtensibleChip * i_chip,
- STEP_CODE_DATA_STRUCT & io_sc )
+int32_t getCfam( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc,
+ const uint32_t i_addr,
+ uint32_t & o_data)
{
- #define PRDF_FUNC "[PlatServices::captureFsiStatusReg] "
+ #define PRDF_FUNC "[PlatServices::getCfam] "
+
+ int32_t rc = SUCCESS;
do
{
@@ -293,36 +297,83 @@ void captureFsiStatusReg( ExtensibleChip * i_chip,
errlHndl_t errH = NULL;
ecmdDataBufferBase cfamData(32);
- uint32_t u32Data = 0;
PRD_FAPI_TO_ERRL(errH,
fapiGetCfamRegister,
- PlatServices::getFapiTarget(i_chip->GetChipHandle()),
- 0x00001007,
+ PlatServices::getFapiTarget(l_procTgt),
+ i_addr,
cfamData);
- if(errH)
+ if ( NULL == errH )
{
- PRDF_ERR( PRDF_FUNC"chip: 0x%.8X, failed to get "
- "CFAM_FSI_STATUS: 0x%X",
- i_chip->GetId(), cfamData.getWord( 0 ) );
+ o_data = cfamData.getWord(0);
+ }
+ else
+ {
+ rc = FAIL;
+ PRDF_ERR( PRDF_FUNC"chip: 0x%.8X, failed to get cfam address: "
+ "0x%X", i_chip->GetId(), i_addr );
PRDF_COMMIT_ERRL(errH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);
break;
}
- u32Data = cfamData.getWord(0);
+
+ } while(0);
+
+
+ return rc;
+
+ #undef PRDF_FUNC
+}
+
+void captureFsiStatusReg( ExtensibleChip * i_chip,
+ STEP_CODE_DATA_STRUCT & io_sc )
+{
+ #define PRDF_FUNC "[PlatServices::captureFsiStatusReg] "
+
+ uint32_t u32Data = 0;
+ int32_t rc = getCfam( i_chip, io_sc, 0x00001007, u32Data );
+
+ if ( SUCCESS == rc )
+ {
BIT_STRING_ADDRESS_CLASS bs (0, 32, (CPU_WORD *) &u32Data);
io_sc.service_data->GetCaptureData().Add(
i_chip->GetChipHandle(),
( Util::hashString("CFAM_FSI_STATUS") ^
i_chip->getSignatureOffset() ),
- bs);
- } while(0);
+ bs);
+ }
+
+ // only get this for proc chip
+ if ( TYPE_PROC == getTargetType(i_chip->GetChipHandle()) )
+ {
+ rc = getCfam( i_chip, io_sc, 0x00002819, u32Data );
+
+ if ( SUCCESS == rc )
+ {
+ BIT_STRING_ADDRESS_CLASS bs (0, 32, (CPU_WORD *) &u32Data);
+
+ io_sc.service_data->GetCaptureData().Add(
+ i_chip->GetChipHandle(),
+ ( Util::hashString("PCIE_OSC_SWITCH") ^
+ i_chip->getSignatureOffset() ),
+ bs);
+ }
+ }
#undef PRDF_FUNC
}
+TARGETING::TargetHandle_t getActiveRefClk(TARGETING::TargetHandle_t
+ i_procTarget,
+ TARGETING::TYPE i_connType,
+ uint32_t i_oscPos)
+{
+ return PlatServices::getClockId( i_procTarget,
+ i_connType,
+ i_oscPos );
+}
} // end namespace PlatServices
diff --git a/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H b/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H
index c54f64ead..2bd7140fb 100755
--- a/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H
+++ b/src/usr/diag/prdf/test/prdfTest_ProcTpLFir.H
@@ -81,7 +81,7 @@ class PTPLFIR:public CxxTest::TestSuite
// PB_ERROR_REG
PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x020F001F,
- 0x0000006000000001);
+ 0x0000000000000001);
//PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x020F001F,
//0x0000000000000001);
@@ -93,7 +93,7 @@ class PTPLFIR:public CxxTest::TestSuite
// ABUS_ERROR_REG
PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x080F001F,
- 0x0000004000000001);
+ 0x0000000000000001);
//PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x080F001F,
//0x0000000000000001);
@@ -105,7 +105,7 @@ class PTPLFIR:public CxxTest::TestSuite
// EX_ERROR_REG
PRDS_SCR_WRITE("NODE{0}:PROC{0}:EX{4}", 0x100F001F,
- 0x0000004000000001);
+ 0x0000000000000001);
//PRDS_SCR_EXPECT("NODE{0}:PROC{0}:EX{4}", 0x100F001F,
//0x0000000000000001);
@@ -158,7 +158,7 @@ class PTPLFIR:public CxxTest::TestSuite
// PB_ERROR_REG
PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x020F001F,
- 0x0000006000000001);
+ 0x0000000000000001);
//PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x020F001F,
//0x0000000000000001);
@@ -170,7 +170,7 @@ class PTPLFIR:public CxxTest::TestSuite
// ABUS_ERROR_REG
PRDS_SCR_WRITE("NODE{0}:PROC{0}", 0x080F001F,
- 0x0000004000000001);
+ 0x0000000000000001);
//PRDS_SCR_EXPECT("NODE{0}:PROC{0}", 0x080F001F,
//0x0000000000000001);
@@ -182,7 +182,7 @@ class PTPLFIR:public CxxTest::TestSuite
// EX_ERROR_REG
PRDS_SCR_WRITE("NODE{0}:PROC{0}:EX{4}", 0x100F001F,
- 0x0000004000000001);
+ 0x0000000000000001);
//PRDS_SCR_EXPECT("NODE{0}:PROC{0}:EX{4}", 0x100F001F,
//0x0000000000000001);
OpenPOWER on IntegriCloud