void FabricDomain::SortForRecov() { using namespace PluginDef; SYSTEM_DEBUG_CLASS sysdbug; uint32_t l_sev[GetSize()]; std::fill(&l_sev[0], &l_sev[GetSize()], 0); // Loop through all chips. for ( uint32_t i = 0; i < GetSize(); ++i ) { RuleChip * l_fabChip = LookUp(i); TARGETING::TargetHandle_t l_pchipHandle = l_fabChip->GetChipHandle(); //check if chip has an attention which has not been analyzed as yet if( sysdbug.isActiveAttentionPending( l_pchipHandle, RECOVERABLE ) ) { // Find severity level. ExtensibleChipFunction * l_extFunc = l_fabChip->getExtensibleFunction( "CheckForRecoveredSev"); (*l_extFunc)(l_fabChip, bindParm<uint32_t &>( l_sev[i] )); } } // Find item with highest severity. MoveToFront(std::distance(&l_sev[0], std::max_element(&l_sev[0], &l_sev[GetSize()], __prdfFabricDomain::lessThanOperator)) ); }
void FabricDomain::SortForRecov() { using namespace PluginDef; SYSTEM_DEBUG_CLASS sysdbug; uint32_t l_sev[GetSize()]; std::fill(&l_sev[0], &l_sev[GetSize()], 0); // Loop through all chips. for (uint32_t i = 0; i < GetSize(); ++i) { RuleChip * l_fabChip = LookUp(i); TARGETING::TargetHandle_t l_pchipHandle = l_fabChip->GetChipHandle(); if (sysdbug.IsAttentionActive(l_pchipHandle)) // If at attention, check. { if (RECOVERABLE == sysdbug.GetAttentionType( l_pchipHandle)) { // Recovered, set sev 1. l_sev[i] = 1; } else if (CHECK_STOP == sysdbug.GetAttentionType(l_pchipHandle)) { // Check for recovered error at checkstop. ExtensibleChipFunction * l_extFunc = l_fabChip->getExtensibleFunction("CheckForRecovered"); bool l_hasRer = false; (*l_extFunc)(l_fabChip, bindParm<bool &>(l_hasRer)); if (l_hasRer) { // Has a recovered error, sev 1. l_sev[i] = 1; } } // Find real severity level. if (0 != l_sev[i]) { ExtensibleChipFunction * l_extFunc = l_fabChip->getExtensibleFunction( "CheckForRecoveredSev"); uint32_t l_cSev = 1; (*l_extFunc)(l_fabChip, bindParm<uint32_t &>(l_cSev)); l_sev[i] = l_cSev; } } } // Find item with highest severity. MoveToFront(std::distance(&l_sev[0], std::max_element(&l_sev[0], &l_sev[GetSize()], __prdfFabricDomain::lessThanOperator)) ); //pw03 }
void FabricDomain::Order(ATTENTION_TYPE attentionType) { using PluginDef::bindParm; if (attentionType == MACHINE_CHECK) { SortForXstop(); } else if (attentionType == RECOVERABLE) { SortForRecov(); } else // Recovered or Special { SYSTEM_DEBUG_CLASS sysdbug; for (int32_t i = (GetSize() - 1); i >= 0; --i) //pw03 { RuleChip * l_fabChip = LookUp(i); TARGETING::TargetHandle_t l_pchipHandle = l_fabChip->GetChipHandle(); if ((sysdbug.IsAttentionActive(l_pchipHandle)) && (sysdbug.GetAttentionType(l_pchipHandle ) == attentionType)) { MoveToFront(i); //pw03 break; } } } }
void FabricDomain::Order(ATTENTION_TYPE attentionType) { if (attentionType == MACHINE_CHECK) { SortForXstop(); } else if (attentionType == RECOVERABLE) { SortForRecov(); } else // Recovered or Special { SYSTEM_DEBUG_CLASS sysdbug; for (int32_t i = (GetSize() - 1); i >= 0; --i) { RuleChip * l_fabChip = LookUp(i); TARGETING::TargetHandle_t l_pchipHandle = l_fabChip->GetChipHandle(); bool l_analysisPending = sysdbug.isActiveAttentionPending(l_pchipHandle, attentionType ); if ( l_analysisPending ) { MoveToFront(i); break; } } } }
bool PllDomain::Query(ATTENTION_TYPE attentionType) { bool atAttn = false; // System always checks for RE's first, even if there is an XSTOP // So we only need to check for PLL errors on RECOVERABLE type if(attentionType == RECOVERABLE) { // check sysdbug for attention first SYSTEM_DEBUG_CLASS sysdbug; for(unsigned int index = 0; (index < GetSize()) && (atAttn == false); ++index) { if(sysdbug.IsAttentionActive(LookUp(index)->GetChipHandle())) { ExtensibleChip * l_chip = LookUp(index); ExtensibleChipFunction * l_query = l_chip->getExtensibleFunction("QueryPll"); 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 ) { PRDF_ERR( "prdfPllDomain::Query() Power Fault detected!" ); break; } else if(SUCCESS != rc) { PRDF_ERR( "prdfPllDomain::Query() SCOM fail. RC=%x", rc ); } } } } return(atAttn); }
bool RuleChipDomain::Query( ATTENTION_TYPE i_attnType ) { bool o_rc = false; using PluginDef::bindParm; SYSTEM_DEBUG_CLASS sysdbug; for ( uint32_t i = 0; i < GetSize(); i++ ) { RuleChip * chip = LookUp(i); TARGETING::TargetHandle_t l_pchipHandle = LookUp(i)->GetChipHandle(); if ( sysdbug.isActiveAttentionPending( l_pchipHandle, i_attnType ) ) { // If the attention type is a checkstop, check if the chip is // reporting based on an externally signaled error condition. If // so, ignore this chip (the chip reporting the checkstop will // be found later). const char * funcName; switch(i_attnType) { case CHECK_STOP: case UNIT_CS: funcName = "IgnoreCheckstopAttn"; break; case RECOVERABLE: funcName = "IgnoreRecoveredAttn"; break; case SPECIAL: funcName = "IgnoreSpecialAttn"; break; default: continue; } ExtensibleChipFunction * ef = chip->getExtensibleFunction( funcName, true ); bool ignore = false; (*ef)( chip, bindParm<bool &, const ATTENTION_TYPE> (ignore, i_attnType) ); if ( ignore ) continue; o_rc = true; break; } } return o_rc; }
void RuleChipDomain::Order( ATTENTION_TYPE i_attnType ) { using PluginDef::bindParm; SYSTEM_DEBUG_CLASS sysdbug; const char * funcName; //mp01 a for ( int32_t i = (GetSize() - 1); i >= 0; i-- ) { RuleChip * chip = LookUp(i); TARGETING::TargetHandle_t l_pchipHandle = LookUp(i)->GetChipHandle(); if ( sysdbug.isActiveAttentionPending( l_pchipHandle, i_attnType ) ) { switch(i_attnType) { case CHECK_STOP: case UNIT_CS: funcName = "IgnoreCheckstopAttn"; break; case RECOVERABLE: funcName = "IgnoreRecoveredAttn"; break; case SPECIAL: funcName = "IgnoreSpecialAttn"; break; default: continue; } ExtensibleChipFunction * ef = chip->getExtensibleFunction( funcName, true ); bool ignore = false; (*ef)( chip, bindParm<bool &, const ATTENTION_TYPE> (ignore, i_attnType) ); if ( ignore ) continue; MoveToFront(i); break; } } }
inline bool DomainContainer<T>::Query(ATTENTION_TYPE attentionType) // DG03 { bool rc = false; SYSTEM_DEBUG_CLASS sysdebug; unsigned int size = GetSize(); for(unsigned int i = 0;(i < size) && (rc == false);i++) { TARGETING::TargetHandle_t l_pchipHandle = LookUp(i)->GetChipHandle(); if(sysdebug.IsAttentionActive(l_pchipHandle) == true) { if(sysdebug.GetAttentionType(l_pchipHandle) == attentionType) rc = true; } } return(rc); }
// Determine the proper sorting for a checkstop based on: // 1. Find only a single chip with an internal checkstop // 2. Graph reduction algorithm // 3. WOF/TOD counters void FabricDomain::SortForXstop() { using namespace PluginDef; using namespace TARGETING; uint32_t l_internalOnlyCount = 0; int l_chip = 0; uint64_t l_externalDrivers[GetSize()]; uint64_t l_wofValues[GetSize()]; bool l_internalCS[GetSize()]; union { uint64_t * u; CPU_WORD * c; } ptr; // zs01 SYSTEM_DEBUG_CLASS sysDebug; TargetHandle_t node = NULL; if( false == isSmpCoherent() ) { // Before node stitching, any system CS is only limited // to a node. ATTN will only pass us proc chips belonging // to a single node. In this scenario, we should only consider // chips belonging to one node. TargetHandle_t proc = sysDebug.getTargetWithAttn( TYPE_PROC, MACHINE_CHECK); node = getConnectedParent( proc, TYPE_NODE); if( NULL == node ) { // We should never reach here. Even if we reach here, as this is // XSTOP, we would like to go ahead with analysis to have as much // data as possible. So just print a trace. PRDF_ERR("[FabricDomain::SortForXstop] Node is Null"); } } // Get internal setting and external driver list for each chip. for(uint32_t i = 0; i < GetSize(); ++i) { l_externalDrivers[i] = 0; l_wofValues[i] = 0; RuleChip * l_fabChip = LookUp(i); // if it is a node check stop, limit the scope of sorting only to the // node which is causing ATTN to invoke PRD. if ( ( NULL != node ) && ( node != getConnectedParent( l_fabChip->GetChipHandle(), TYPE_NODE) )) continue; ptr.u = &l_externalDrivers[i]; // zs01 BitString l_externalChips(GetSize(), ptr.c); // zs01 TargetHandleList l_tmpList; // Call "GetCheckstopInfo" plugin. ExtensibleChipFunction * l_extFunc = l_fabChip->getExtensibleFunction("GetCheckstopInfo"); (*l_extFunc)(l_fabChip, bindParm<bool &, TargetHandleList &, uint64_t &> (l_internalCS[i], l_tmpList, l_wofValues[i] ) ); // Update bit buffer. for (TargetHandleList::iterator j = l_tmpList.begin(); j != l_tmpList.end(); ++j) { for (uint32_t k = 0; k < GetSize(); k++) if ((*j) == LookUp(k)->GetChipHandle()) l_externalChips.Set(k); }; // Check if is internal. if (l_internalCS[i]) { l_internalOnlyCount++; l_chip = i; } } // Check if we are done... only one with an internal error. if (1 == l_internalOnlyCount) { MoveToFront(l_chip); //pw03 return; } else if (0 == l_internalOnlyCount) { // TODO : add trace here... continue with analysis to determine // which chip origined though. } // --- Do graph reduction --- // Currently does not do cycle elimination. // Get initial list (all chips). BIT_STRING_BUFFER_CLASS l_current(GetSize()); l_current.Pattern(0,GetSize(),0xFFFFFFFF, 32); // turn on all bits. // Do reduction. // When done, l_prev will have the minimal list. BIT_STRING_BUFFER_CLASS l_prev(GetSize()); l_prev.Clear(); while ((!(l_current == l_prev)) && (!l_current.IsZero())) { l_prev = l_current; l_current.Clear(); for (uint32_t i = 0; i < GetSize(); i++) { if (l_prev.IsSet(i)) // skip if this chip isn't in the pool. for (uint32_t j = 0; j < GetSize(); j++) { ptr.u = &l_externalDrivers[i]; // zs01 if ( BitString(GetSize(), ptr.c).IsSet(j) ) // zs01 l_current.Set(j); } } } // Hopefully, we got just one chip left... if (1 == l_prev.GetSetCount()) { // Now find it. for (uint32_t i = 0; i < GetSize(); i++) if ((l_prev.IsSet(i)) && (l_internalCS[i] || (0 == l_internalOnlyCount))) { MoveToFront(i); //pw03 return; } } // --- Do WOF compare --- uint32_t l_minWof = 0; for (uint32_t i = 0; i < GetSize(); i++) { // Search for minimum WOF value. if (l_wofValues[i] < l_wofValues[l_minWof]) // Only choose chips with internal checkstop, // unless no internals. if ((l_internalCS[i] || (0 == l_internalOnlyCount))) l_minWof = i; } MoveToFront(l_minWof); //pw03 return; };
errlHndl_t main( ATTENTION_VALUE_TYPE i_attentionType, const AttnList & i_attnList ) { PRDF_ENTER( "PRDF::main() Global attnType=%04X", i_attentionType ); // will unlock when going out of scope PRDF_SYSTEM_SCOPELOCK; g_prd_errlHndl = NULL; uint32_t rc = SUCCESS; // clears all the chips saved to stack during last analysis ServiceDataCollector::clearChipStack(); if(( g_initialized == false)&&(NULL ==systemPtr)) { g_prd_errlHndl = noLock_initialize(); if(g_prd_errlHndl != NULL) rc = PRD_NOT_INITIALIZED; } ServiceDataCollector serviceData; STEP_CODE_DATA_STRUCT sdc; sdc.service_data = &serviceData; SYSTEM_DEBUG_CLASS sysdebug; sysdebug.Reinitialize(i_attnList); //Refresh sysdebug with latest Attn data //////////////////////////////////////////////////////////////////////////// // Normalize global attn type (ie 11,12,13,....) to (CHECKSTOP, RECOVERED, // SPECIAL..) //////////////////////////////////////////////////////////////////////////// if ( i_attentionType == INVALID_ATTENTION_TYPE || i_attentionType >= END_ATTENTION_TYPE ) { rc = PRD_INVALID_ATTENTION_TYPE; PRDF_ERR( "PrdMain: Invalid attention type! Global:%x", i_attentionType ); i_attentionType = RECOVERABLE; // This will prevent RAS service problems } // link to the right service Generator ServiceGeneratorClass & serviceGenerator = ServiceGeneratorClass::ThisServiceGenerator(); // Initialize the SDC error log. Required for GenerateSrcPfa() call below. serviceGenerator.createInitialErrl( i_attentionType ); // check for something wrong if ( g_initialized == false || rc != SUCCESS || systemPtr == NULL ) { if(rc == SUCCESS) { rc = PRD_NOT_INITIALIZED; } PRDF_ERR("PrdMain: PRD failed. RC=%x",rc ); // we are not going to do an analysis - so fill out the Service Data (serviceData.GetErrorSignature())->setSigId(rc); serviceData.SetCallout(SP_CODE); serviceData.SetThresholdMaskId(0); // Sets AT_THRESHOLD, DEGRADED, // SERVICE_CALL } else // do the analysis { // flush Cache so that SCR reads access hardware RegDataCache::getCachedRegisters().flush(); serviceData.SetAttentionType(i_attentionType); // capture time of day serviceGenerator.SetErrorTod( i_attentionType, serviceData ); if(serviceGenerator.QueryLoggingBufferFull()) { serviceData.SetFlooding(); } int32_t analyzeRc = systemPtr->Analyze(sdc, i_attentionType); // flush Cache to free up the memory RegDataCache::getCachedRegisters().flush(); ScanFacility & l_scanFac = ScanFacility::Access(); //delete all the wrapper register objects since these were created //just for plugin code l_scanFac.ResetPluginRegister(); SystemSpecific::postAnalysisWorkarounds(sdc); if(analyzeRc != SUCCESS && g_prd_errlHndl == NULL) { // We have a bad RC, but no error log - Fill out SDC and have // service generator make one (serviceData.GetErrorSignature())->setErrCode( (uint16_t)analyzeRc ); serviceData.SetCallout(SP_CODE); serviceData.SetServiceCall(); // We don't want to gard unless we have a good // return code serviceData.Gard(GardAction::NoGard); } } if(g_prd_errlHndl != NULL) { PRDF_INF("PRDTRACE: PrdMain: g_prd_errlHndl != NULL"); PRDF_ADD_PROCEDURE_CALLOUT( g_prd_errlHndl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE ); // This forces any previous errls to be committed g_prd_errlHndl = NULL; // pw 597903 -- Don't GARD if we got a global error. serviceData.Gard(GardAction::NoGard); } g_prd_errlHndl = serviceGenerator.GenerateSrcPfa( i_attentionType, serviceData ); // Sleep for 20msec to let attention lines settle if we are at threshold. if ( (g_prd_errlHndl == NULL) && serviceData.IsAtThreshold() ) { PlatServices::milliSleep( 0, 20 ); } RasServices::SetTerminateOnCheckstop(true); PRDF_EXIT( "PRDF::main()" ); return(g_prd_errlHndl.release()); }
int32_t System::Analyze(STEP_CODE_DATA_STRUCT & serviceData, ATTENTION_TYPE attentionType) { #define PRDF_FUNC "[System::Analyze] " SYSTEM_DEBUG_CLASS sysdebug; Domain * domainAtAttentionPtr = NULL; ServiceDataCollector * l_saved_sdc = NULL; ServiceDataCollector * l_temp_sdc = NULL; int32_t rc = (prioritizedDomains.empty() ? NO_DOMAINS_IN_SYSTEM : SUCCESS); int32_t l_saved_rc = 0; int32_t l_primaryRc = 0; if(rc == SUCCESS) { // IF machine check then check for recoverable errors first // otherwise just check for the given type of attention ATTENTION_TYPE startAttention = attentionType; if((attentionType == MACHINE_CHECK) || (attentionType == UNIT_CS)) startAttention = RECOVERABLE; ATTENTION_TYPE atnType = startAttention; for( atnType = startAttention; domainAtAttentionPtr == NULL && atnType >= attentionType ; --atnType) { DomainContainerType::iterator domainIterator; for( domainIterator = prioritizedDomains.begin(); domainIterator != prioritizedDomains.end() && domainAtAttentionPtr == NULL; ) { bool l_continueInDomain = false; domainAtAttentionPtr = ((*domainIterator)->Query(atnType)) ? (*domainIterator) : NULL; if(domainAtAttentionPtr != NULL) { serviceData.service_data->SetCauseAttentionType(atnType); rc = domainAtAttentionPtr->Analyze(serviceData, atnType); if((rc == PRD_SCAN_COMM_REGISTER_ZERO) || (rc == PRD_POWER_FAULT) ) { // save sdc, and continue if(l_saved_sdc == NULL) { l_saved_sdc = new ServiceDataCollector( *serviceData.service_data); l_saved_rc = rc; } if( ( PRD_SCAN_COMM_REGISTER_ZERO == rc ) && ( serviceData.service_data->isPrimaryPass() ) && serviceData.service_data->isSecondaryErrFound() ) { //So, the chip was reporting attention but none of //the FIR read had any Primary bit set. But some //secondary bits are on though. So, we would like //to investigate if there are other chips in //the domain which are reporting primary attention. l_continueInDomain = true; serviceData.service_data->clearSecondaryErrFlag(); } domainAtAttentionPtr = NULL; if(rc == PRD_POWER_FAULT) { PRDF_ERR( PRDF_FUNC"Power Fault detected!" ); break; } } else if ( ( attentionType == MACHINE_CHECK ) && ( atnType != MACHINE_CHECK ) ) { // We were asked to analyze MACHINE XTOP, but we found // another attention and did analyze that. In this case // we want to add additional signature of MACHINE XSTOP // attention to error log. // l_temp_sdc is not NULL. It is a code bug. Do not do // anything for error isolation pass. if ( NULL != l_temp_sdc ) { PRDF_ERR( PRDF_FUNC"l_temp_sdc is not NULL" ); continue; } // Do a setup for error isolation pass for MACHINE // XTOP. In this pass, we are only interested in // error signature. domainAtAttentionPtr = NULL; l_temp_sdc = new ServiceDataCollector ( *serviceData.service_data ); // Set up Error Isolation Pass Flag. serviceData.service_data->setIsolationOnlyPass(); // Set the outer for loop iteration variable atnType so // that we analyze MACHINE XSTOP in next iteration. atnType = MACHINE_CHECK + 1; // save primary rc. l_primaryRc = rc; break; } } // end domainAtAttentionPtr != NULL //so if a chip of a domain is at attention and gave us dd02, we //would like to see other chips of the domain before moving on //to next domain. if( !l_continueInDomain ) { domainIterator++; } } // end inner for loop } // end outer for loop // if ptr is NULL && we don't have a saved SDC than we have noAttns // if ptr is NULL && we have a saved SDC then we have an attn with no-bits-on // otherwise we are done - aready did the analysis if ( domainAtAttentionPtr == NULL) { if(l_saved_sdc == NULL) { rc = noAttnResolution.Resolve(serviceData); } else { *serviceData.service_data = *l_saved_sdc; sysdebug.CalloutThoseAtAttention(serviceData); rc = l_saved_rc; } } // l_temp_sdc will not be NULL if we go to ERROR ISOLATION ONLY PASS. // In that case get the secondary signature and update this. if ( NULL != l_temp_sdc ) { // Merge SUE flag if( serviceData.service_data->IsSUE() ) { l_temp_sdc->SetSUE(); } // We are having only one secondary signature. Secondary signature // here is mainly used for XSTOP error. XSTOP error can only happen // on Fabric domain. For fabric domain, we use Fabric sorting which // will give us first chip which is root cause for the XSTOP error. // So signature we get after fabric sorting is enough for FFDC // perspective. l_temp_sdc->AddSignatureList( *( serviceData.service_data->GetErrorSignature() )); // merge debug scom data from the two analysis l_temp_sdc->GetCaptureData().mergeData( serviceData.service_data->GetCaptureData()); // merge trace array data from the two analysis l_temp_sdc->getTraceArrayData().mergeData( serviceData.service_data->getTraceArrayData()); *serviceData.service_data = *l_temp_sdc; delete l_temp_sdc; // We will discard any error we get in ERROR ISOLATION ONLY PASS, // and restore rc found in primary pass. rc = l_primaryRc; } if(l_saved_sdc != NULL) delete l_saved_sdc; //dg05a } #undef PRDF_FUNC return(rc); }
errlHndl_t main( ATTENTION_VALUE_TYPE i_attentionType, const AttnList & i_attnList ) { PRDF_ENTER( "PRDF::main() Global attnType=%04X", i_attentionType ); // These have to be outside of system scope lock errlHndl_t retErrl = NULL; bool initiateHwudump = false; TARGETING::TargetHandle_t dumpTrgt = NULL; errlHndl_t dumpErrl = NULL; uint32_t dumpErrlActions = 0; { // system scope lock starts ------------------------------------------ // will unlock when going out of scope PRDF_SYSTEM_SCOPELOCK; g_prd_errlHndl = NULL; uint32_t rc = SUCCESS; // clears all the chips saved to stack during last analysis ServiceDataCollector::clearChipStack(); if(( g_initialized == false)&&(NULL ==systemPtr)) { g_prd_errlHndl = noLock_initialize(); if(g_prd_errlHndl != NULL) rc = PRD_NOT_INITIALIZED; } ServiceDataCollector serviceData; STEP_CODE_DATA_STRUCT sdc; sdc.service_data = &serviceData; SYSTEM_DEBUG_CLASS sysdebug; sysdebug.Reinitialize(i_attnList); //Refresh sysdebug with latest Attn data //////////////////////////////////////////////////////////////////////////// // Normalize global attn type (ie 11,12,13,....) to (CHECKSTOP, RECOVERED, // SPECIAL..) //////////////////////////////////////////////////////////////////////////// if ( i_attentionType == INVALID_ATTENTION_TYPE || i_attentionType >= END_ATTENTION_TYPE ) { rc = PRD_INVALID_ATTENTION_TYPE; PRDF_ERR( "PrdMain: Invalid attention type! Global:%x", i_attentionType ); i_attentionType = RECOVERABLE; // This will prevent RAS service problems } // link to the right service Generator ServiceGeneratorClass & serviceGenerator = ServiceGeneratorClass::ThisServiceGenerator(); // Initialize the SDC error log. Required for GenerateSrcPfa() call below. serviceGenerator.createInitialErrl( i_attentionType ); // check for something wrong if ( g_initialized == false || rc != SUCCESS || systemPtr == NULL ) { if(rc == SUCCESS) { rc = PRD_NOT_INITIALIZED; } PRDF_ERR("PrdMain: PRD failed. RC=%x",rc ); // we are not going to do an analysis - so fill out the Service Data (serviceData.GetErrorSignature())->setSigId(rc); serviceData.SetCallout(SP_CODE); serviceData.SetCallout( NextLevelSupport_ENUM, MRU_LOW ); serviceData.SetThresholdMaskId(0); // Sets AT_THRESHOLD, DEGRADED, // SERVICE_CALL } else // do the analysis { // flush Cache so that SCR reads access hardware RegDataCache::getCachedRegisters().flush(); serviceData.setPrimaryAttnType(i_attentionType); // Set the time in which PRD handled the error. Timer timeOfError; PlatServices::getCurrentTime( timeOfError ); serviceData.SetTOE( timeOfError ); ServiceDataCollector l_tempSdc = serviceData; l_tempSdc.setPrimaryPass(); sdc.service_data = &l_tempSdc; int32_t analyzeRc = systemPtr->Analyze( sdc, i_attentionType ); if( PRD_SCAN_COMM_REGISTER_ZERO == analyzeRc ) { // So, the first pass has failed. Hence, there are no primary // bits set. We must start second pass to see if there are any //secondary bits set. sdc.service_data = &serviceData; #if !defined(__HOSTBOOT_MODULE) && !defined(__HOSTBOOT_RUNTIME) ForceSyncAnalysis( l_tempSdc ); // save SDC till end of primary pass #endif // starting the second pass PRDF_INF( "PRDF::main() No bits found set in first pass," " starting second pass" ); sysdebug.initAttnPendingtatus( ); //for the second pass if( l_tempSdc.isSecondaryErrFound() ) { sdc.service_data->setSecondaryErrFlag(); } analyzeRc = systemPtr->Analyze( sdc, i_attentionType ); // merging capture data of primary pass with capture data of // secondary pass for better FFDC. serviceData.GetCaptureData().mergeData( l_tempSdc.GetCaptureData()); #if !defined(__HOSTBOOT_MODULE) && !defined(__HOSTBOOT_RUNTIME) // save SDC till end of secondary pass ForceSyncAnalysis( serviceData ); #endif } else { serviceData = l_tempSdc; sdc.service_data = &serviceData; } // flush Cache to free up the memory RegDataCache::getCachedRegisters().flush(); ScanFacility & l_scanFac = ScanFacility::Access(); //delete all the wrapper register objects since these were created //just for plugin code l_scanFac.ResetPluginRegister(); if(analyzeRc != SUCCESS && g_prd_errlHndl == NULL) { (serviceData.GetErrorSignature())->setErrCode( (uint16_t)analyzeRc ); serviceData.SetCallout(SP_CODE); serviceData.SetCallout( NextLevelSupport_ENUM, MRU_LOW ); serviceData.SetServiceCall(); // We don't want to gard unless we have a good // return code serviceData.Gard(GardAction::NoGard); } } if(g_prd_errlHndl != NULL) { PRDF_INF("PRDTRACE: PrdMain: g_prd_errlHndl != NULL"); PRDF_ADD_PROCEDURE_CALLOUT( g_prd_errlHndl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE ); // This is a precautionary step. There is a possibilty that if // severity for g_prd_errlHndl is Predictve and there is only // EPUB_PRC_SP_CODE callout than it will be changed to tracing event. // So adding EPUB_PRC_LVL_SUPP to avoid this. PRDF_ADD_PROCEDURE_CALLOUT( g_prd_errlHndl, SRCI_PRIORITY_LOW, EPUB_PRC_LVL_SUPP ); // This forces any previous errls to be committed g_prd_errlHndl = NULL; // pw 597903 -- Don't GARD if we got a global error. serviceData.Gard(GardAction::NoGard); } g_prd_errlHndl = serviceGenerator.GenerateSrcPfa( i_attentionType, serviceData, initiateHwudump, dumpTrgt, dumpErrl, dumpErrlActions); // Sleep for 20msec to let attention lines settle if we are at threshold. if ( (g_prd_errlHndl == NULL) && serviceData.IsAtThreshold() ) { PlatServices::milliSleep( 0, 20 ); } retErrl = g_prd_errlHndl.release(); } // system scope lock ends ------------------------------------------ if ( true == initiateHwudump ) { PlatServices::initiateUnitDump( dumpTrgt, dumpErrl, dumpErrlActions ); } PRDF_EXIT( "PRDF::main()" ); return retErrl; }