Exemplo n.º 1
0
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))
               );
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
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;
            }
        }
    }
}
Exemplo n.º 4
0
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;
            }
        }
    }
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
        }
    }
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
// 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;

};
Exemplo n.º 10
0
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());
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
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;
}