Example #1
0
int32_t calloutBusInterface( ExtensibleChip * i_chip, PRDpriority i_priority,
                             TYPE i_busType, uint32_t i_busPos )
{
    #define PRDF_FUNC "[CalloutUtil::calloutBusInterface] "

    int32_t rc = SUCCESS;

    do
    {
        TargetHandle_t rxTrgt = NULL; TargetHandle_t txTrgt = NULL;

        rc = getBusEndpoints( i_chip, rxTrgt, txTrgt, i_busType, i_busPos );
        if ( SUCCESS != rc ) break;

        rc = calloutBusInterface( rxTrgt, txTrgt, i_priority );
        if ( SUCCESS != rc ) break;

    } while(0);

    if ( SUCCESS != rc )
    {
        PRDF_ERR( PRDF_FUNC "i_chip:0x%08x i_busType:%d i_busPos:%d "
                  "i_priority:%d", i_chip->GetId(), i_busType, i_busPos,
                  i_priority );
    }

    return rc;

    #undef PRDF_FUNC
}
Example #2
0
uint32_t ScomRegister::ForceRead() const
{
    #define PRDF_FUNC "[ScomRegister::ForceRead] "

    uint32_t o_rc = FAIL;

    do
    {
        // No read allowed if register access attribute is write-only or no
        // access.
        if ( ( ACCESS_NONE == iv_operationType ) &&
                ( ACCESS_WO == iv_operationType ) )
        {
            PRDF_ERR( PRDF_FUNC"Write-only register: 0x%08x 0x%016llx",
                      getChip()->GetId(), iv_scomAddress );
            break;
        }

        // Read hardware.
        o_rc = Access( readCache(), MopRegisterAccess::READ );
        if ( SUCCESS != o_rc )
        {
            // The read failed. Remove the entry from the cache so a subsequent
            // Read() will attempt to read from hardware again.
            flushCache( getChip() );
        }

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}
Example #3
0
int32_t mssIplUeIsolation( TargetHandle_t i_mba, const CenRank & i_rank,
                           CenDqBitmap & o_bitmap )
{
    #define PRDF_FUNC "[PlatServices::mssIplUeIsolation] "

    int32_t o_rc = SUCCESS;

    uint8_t data[PORT_SLCT_PER_MBA][DIMM_DQ_RANK_BITMAP_SIZE];

    errlHndl_t errl = NULL;
    PRD_FAPI_TO_ERRL( errl, mss_IPL_UE_isolation, getFapiTarget(i_mba),
                      i_rank.getMaster(), data );
    if ( NULL != errl )
    {
        PRDF_ERR( PRDF_FUNC"mss_IPL_UE_isolation() failed: MBA=0x%08x "
                  "rank=%d", getHuid(i_mba), i_rank.getMaster() );
        PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
        o_rc = FAIL;
    }
    else
    {
        o_bitmap = CenDqBitmap ( i_mba, i_rank, data );
    }

    return o_rc;

    #undef PRDF_FUNC
}
Example #4
0
TargetHandleList getConnectedDimms( TargetHandle_t i_mba,
                                    uint8_t i_port )
{
    #define PRDF_FUNC "[CalloutUtil::getConnectedDimms] "

    TargetHandleList o_list;

    TargetHandleList dimmList = getConnectedDimms( i_mba );

    for ( TargetHandleList::iterator dimmIt = dimmList.begin();
          dimmIt != dimmList.end(); dimmIt++)
    {
        uint8_t portSlct;
        int32_t l_rc = getMbaPort( *dimmIt, portSlct );
        if ( SUCCESS != l_rc )
        {
            PRDF_ERR( PRDF_FUNC "getMbaPort(0x%08x) failed",
                      getHuid(*dimmIt) );
            continue;
        }

        if ( portSlct == i_port )
        {
            o_list.push_back( *dimmIt );
        }
    }

    return o_list;

    #undef PRDF_FUNC
}
Example #5
0
/**
 * @brief  Plugin function called after analysis is complete but before PRD
 *         exits.
 * @param  i_mbaChip A Centaur MBA 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 PostAnalysis( ExtensibleChip * i_mbaChip,
                      STEP_CODE_DATA_STRUCT & i_sc )
{
    #define PRDF_FUNC "[Mba::PostAnalysis] "

    // Send command complete to MDIA.
    // This must be done in post analysis after attentions have been cleared.

    TargetHandle_t mbaTarget = i_mbaChip->GetChipHandle();
    CenMbaDataBundle * mbadb = getMbaDataBundle( i_mbaChip );

    if ( mbadb->iv_sendCmdCompleteMsg )
    {
        mbadb->iv_sendCmdCompleteMsg = false;

        int32_t l_rc = mdiaSendEventMsg( mbaTarget,
                                         mbadb->iv_cmdCompleteMsgData );
        if ( SUCCESS != l_rc )
        {
            PRDF_ERR( PRDF_FUNC"PlatServices::mdiaSendEventMsg() failed" );
        }
    }

    return SUCCESS; // Intentionally return SUCCESS for this plugin

    #undef PRDF_FUNC
}
Example #6
0
int32_t mdiaSendEventMsg( TargetHandle_t i_mbaTarget,
                          MDIA::MaintCommandEventType i_eventType )
{
    #define PRDF_FUNC "[PlatServices::mdiaSendCmdComplete] "

    int32_t o_rc = SUCCESS;

    do
    {
        if ( !isInMdiaMode() ) break; // no-op

        // Verify type.
        TYPE l_type = getTargetType(i_mbaTarget);
        if ( TYPE_MBA != l_type )
        {
            PRDF_ERR( PRDF_FUNC"unsupported target type %d", l_type );
            o_rc = FAIL;
            break;
        }

        // Send command complete to MDIA.
        MDIA::MaintCommandEvent l_mdiaEvent;

        l_mdiaEvent.target = i_mbaTarget;
        l_mdiaEvent.type = i_eventType;

        errlHndl_t errl = MDIA::processEvent( l_mdiaEvent );
        if ( NULL != errl )
        {
            PRDF_ERR( PRDF_FUNC"MDIA::processEvent() failed" );
            PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
            o_rc = FAIL;
            break;
        }

    } while (0);

    if ( SUCCESS != o_rc )
    {
        PRDF_ERR( PRDF_FUNC"Failed: i_target=0x%08x i_eventType=%d",
                  getHuid(i_mbaTarget), i_eventType );
    }

    return o_rc;

    #undef PRDF_FUNC
}
Example #7
0
errlHndl_t SimFspSyncSvc::processMfgTrace(msg_t *i_msg) const
{
    #define PRDF_FUNC "[SimFspSyncSvc::processMfgTrace]"
    PRDF_ENTER(PRDF_FUNC);

    errlHndl_t l_errLog = NULL;
    uint8_t l_mruListCount = 0;
    uint8_t  *l_extraData = NULL;

    do
    {
        l_extraData = reinterpret_cast <uint8_t *> (i_msg->extra_data);

        l_mruListCount = (i_msg->data[1] / sizeof(PfaMruListStruct));

        if(l_mruListCount > MruListLIMIT)
        {
            PRDF_ERR(PRDF_FUNC "Invalid MRU count: %d received from Hostboot"
                               " max expected count is: %d",
                               l_mruListCount, MruListLIMIT);

            /*@
             * @errortype
             * @refcode    LIC_REFCODE
             * @subsys     EPUB_FIRMWARE_SP
             * @reasoncode PRDF_INVALID_CONFIG
             *
             * @moduleid   PRDF_SYNC_SVC
             * @userdata1  MRU List Count
             * @userdata2  Max MRU Count
             * @userdata3  Line number in file
             * @devdesc    Received invalid MRU count in
             *             MnfgTrace message from Hostboot
             */
            PRDF_CREATE_ERRL(l_errLog,
                             ERRL_SEV_INFORMATIONAL,
                             ERRL_ETYPE_NOT_APPLICABLE,
                             SRCI_ERR_INFO,
                             SRCI_NO_ATTR,
                             PRDF_SYNC_SVC,
                             LIC_REFCODE,
                             PRDF_INVALID_CONFIG,
                             l_mruListCount,
                             MruListLIMIT,
                             __LINE__, 0);
            break;
        }

        if(NULL != l_extraData)
        {
            free(l_extraData);
        }

    }while(0);

    return l_errLog;
    #undef PRDF_FUNC
}
Example #8
0
uint32_t getIoOscPos( ExtensibleChip * i_chip,
                      STEP_CODE_DATA_STRUCT & io_sc)
{
    #define PRDF_FUNC "[PLL::getIoOscPos] "
    uint32_t o_oscPos = MAX_PCIE_OSC_PER_NODE;

    do
    {
        int32_t rc = SUCCESS;

        // START WORKAROUND
        // TODO: RTC 137711 - This redundant clock code only applies to Brazos
        //       systems. Unfortunately, this code made it into the common
        //       source and we ran into SW324506 where we are unable to SCOM
        //       PCIE_OSC_SWITCH during OP checkstop analysis. We should have
        //       a system attribute that tells us if redundant clock are enabled
        //       but for now just assume anything that is OPAL based will not
        //       have redundant clocks. Note that we still need this code in
        //       Hostboot (not HBRT) because Hostboot is still run on a Brazos
        //       system.
        if ( isHyprConfigOpal() )
        {
            o_oscPos = 0;
            break;
        }
        // END WORKAROUND

        SCAN_COMM_REGISTER_CLASS * pcieOscSwitchReg =
                i_chip->getRegister("PCIE_OSC_SWITCH");

        rc = pcieOscSwitchReg->Read();
        if (rc != SUCCESS)
        {
            PRDF_ERR(PRDF_FUNC "PCIE_OSC_SWITCH read failed"
                     "for 0x%08x", i_chip->GetId());
            break;
        }

        // [ 16 ] == 1    ( OSC 0 is active )
        // [ 16 ] == 0    ( OSC 1 is active )
        if(pcieOscSwitchReg->IsBitSet(16))
        {
            o_oscPos = 0;
        }
        else
        {
            o_oscPos = 1;
        }

    } while(0);

    return o_oscPos;

    #undef PRDF_FUNC
}
Example #9
0
int32_t getBusEndpoints( ExtensibleChip * i_chip,
                         TargetHandle_t & o_rxTrgt, TargetHandle_t & o_txTrgt,
                         TYPE i_busType, uint32_t i_busPos )
{
    #define PRDF_FUNC "[CalloutUtil::getBusEndpoints] "

    int32_t rc = SUCCESS;

    o_rxTrgt = NULL;
    o_txTrgt = NULL;

    TargetHandle_t chipTrgt = i_chip->GetChipHandle();
    TYPE           chipType = getTargetType(chipTrgt);

    if ( TYPE_PROC == chipType )
    {
        o_rxTrgt = getConnectedChild( chipTrgt, i_busType, i_busPos );

        if ( TYPE_ABUS == i_busType || TYPE_XBUS == i_busType )
        {
            o_txTrgt = getConnectedPeerTarget( o_rxTrgt );
        }
        else if ( TYPE_MCS == i_busType )
        {
            o_txTrgt = getConnectedChild( o_rxTrgt, TYPE_MEMBUF, 0 );
        }
    }
    else if ( TYPE_MCS == chipType )
    {
        o_rxTrgt = chipTrgt;
        o_txTrgt = getConnectedChild( o_rxTrgt, TYPE_MEMBUF, 0 );
    }
    else if ( TYPE_MEMBUF == chipType )
    {
        o_rxTrgt = chipTrgt;
        o_txTrgt = getConnectedParent( o_rxTrgt, TYPE_MCS );
    }

    // Note that all of the 'getConnected' functions above do proper parameter
    // checking and will return NULL if anything is wrong. So this is the only
    // NULL check we actually need in this function.

    if ( NULL == o_rxTrgt || NULL == o_txTrgt )
    {
        PRDF_ERR( PRDF_FUNC "i_chip:0x%08x o_rxTrgt:0x%08x o_txTrgt:0x%08x "
                  "i_busType:%d i_busPos:%d", getHuid(chipTrgt),
                  getHuid(o_rxTrgt), getHuid(o_txTrgt), i_busType, i_busPos );
        rc = FAIL;
    }

    return rc;

    #undef PRDF_FUNC
}
Example #10
0
void prdfAssert( const char * i_exp, const char * i_file, int i_line )
{
    PRDF_ERR( "prdfAssert(%s) in %s line %d", i_exp, i_file, i_line );

    errlHndl_t errl = NULL;

    /*@
     * @errortype
     * @subsys     EPUB_FIRMWARE_SP
     * @reasoncode PRDF_CODE_FAIL
     * @moduleid   PRDF_ASSERT
     * @userdata1  0
     * @userdata2  Line number of the assert
     * @userdata3  0
     * @userdata4  PRD Return code
     * @devdesc    PRD assert
     * @custDesc   An internal firmware fault.
     * @procedure  EPUB_PRC_SP_CODE
     */
    PRDF_CREATE_ERRL(errl,
                     ERRL_SEV_PREDICTIVE,         // error on diagnostic
                     ERRL_ETYPE_NOT_APPLICABLE,
                     SRCI_ERR_INFO,
                     SRCI_NO_ATTR,
                     PRDF_ASSERT,                 // module id
                     FSP_DEFAULT_REFCODE,         // refcode
                     PRDF_CODE_FAIL,              // Reason code
                     0,                           // user data word 1
                     i_line,                      // user data word 2
                     0,                           // user data word 3
                     PRD_ASSERT);                 // user data word 4

    PRDF_ADD_PROCEDURE_CALLOUT(errl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);
    PRDF_SET_RC(errl, PRD_ASSERT);
    PRDF_COLLECT_TRACE(errl, 256);
    PRDF_SET_TERM_STATE( errl );
    PRDF_COMMIT_ERRL(errl, ERRL_ACTION_SA);

    #ifdef  __HOSTBOOT_MODULE

    assert(0);

    #else

    const size_t sz_msg = 160;
    char msg[sz_msg];
    errlslen_t msize = snprintf( msg, sz_msg, "prdfAssert(%s) in %s line %d",
                                 i_exp, i_file, i_line );

    percAbend(PRDF_COMP_ID, msg, msize+1, 0, 0);
    abort();

    #endif
}
Example #11
0
/**
 * @brief  Plugin function called after analysis is complete but before PRD
 *         exits.
 * @param  i_chip    EQ chip.
 * @param  io_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 PostAnalysis( ExtensibleChip * i_chip,
                      STEP_CODE_DATA_STRUCT & io_sc )
{
#ifdef __HOSTBOOT_RUNTIME
    int32_t l_rc = restartTraceArray(i_chip->GetChipHandle());
    if (SUCCESS != l_rc)
    {
        PRDF_ERR( "[EQ PostAnalysis HUID: 0x%08x RestartTraceArray failed",
                  i_chip->GetId());
    }
#endif
    return SUCCESS;
} PRDF_PLUGIN_DEFINE(p9_eq, PostAnalysis);
Example #12
0
TargetHandleList getConnectedDimms( TargetHandle_t i_mba )
{
    TargetHandleList o_list;

    if ( TYPE_MBA != getTargetType(i_mba) )
    {
        PRDF_ERR( "[CalloutUtil::getConnectedDimms] Invalid target type: "
                  "HUID=0x%08x", getHuid(i_mba) );
    }
    else
        o_list = getConnected( i_mba, TYPE_DIMM );

    return o_list;
}
Example #13
0
TargetHandleList getConnectedDimms( TargetHandle_t i_mba,
                                    const CenRank & i_rank )
{
    #define PRDF_FUNC "[CalloutUtil::getConnectedDimms] "

    TargetHandleList o_list;

    if ( TYPE_MBA != getTargetType(i_mba) )
    {
        PRDF_ERR( PRDF_FUNC "Invalid target type: HUID=0x%08x", getHuid(i_mba) );
    }
    else
    {
        TargetHandleList dimmList = getConnected( i_mba, TYPE_DIMM );
        for ( TargetHandleList::iterator dimmIt = dimmList.begin();
              dimmIt != dimmList.end(); dimmIt++)
        {
            uint8_t dimmSlct;
            int32_t l_rc = getMbaDimm( *dimmIt, dimmSlct );
            if ( SUCCESS != l_rc )
            {
                PRDF_ERR( PRDF_FUNC "getMbaDimm(0x%08x) failed",
                          getHuid(*dimmIt) );
                continue;
            }

            if ( dimmSlct == i_rank.getDimmSlct() )
            {
                o_list.push_back( *dimmIt );
            }
        }
    }

    return o_list;

    #undef PRDF_FUNC
}
Example #14
0
uint32_t ScomRegister::Write()
{
    #define PRDF_FUNC "[ScomRegister::Write] "

    uint32_t o_rc = FAIL;

    do
    {
        // No write allowed if register access attribute is read-only or no
        // access.
        if ( ( ACCESS_NONE == iv_operationType ) &&
                 ( ACCESS_RO == iv_operationType ) )
        {
            PRDF_ERR( PRDF_FUNC"Read-only register: 0x%08x 0x%016llx",
                      getChip()->GetId(), iv_scomAddress );
            break;
        }

        // Query the cache for an existing entry.
        if ( !queryCache() )
        {
            // Something bad happened and there was nothing in the cache to
            // write to hardware.
            PRDF_ERR( PRDF_FUNC"No entry found in cache: 0x%08x 0x%016llx",
                      getChip()->GetId(), iv_scomAddress );
            break;
        }

        // Write hardware.
        o_rc = Access( readCache(), MopRegisterAccess::WRITE );

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}
Example #15
0
/**
 * @brief  Plugin to send a SKIP_MBA message for Memory Diagnositics.
 * @note   Does nothing in non-MDIA mode.
 * @note   Will stop any maintenance commands in progress.
 * @param  i_mbaChip A Centaur MBA chip.
 * @param  i_sc      The step code data struct.
 * @return SUCCESS.
 */
int32_t SkipMbaMsg( ExtensibleChip * i_mbaChip, STEP_CODE_DATA_STRUCT & i_sc )
{
    #define PRDF_FUNC "[Mba::SkipMbaMsg] "

    int32_t l_rc = SUCCESS;

    TargetHandle_t mbaTrgt = i_mbaChip->GetChipHandle();

    l_rc = mdiaSendEventMsg( mbaTrgt, MDIA::SKIP_MBA );
    if ( SUCCESS != l_rc )
    {
        PRDF_ERR( PRDF_FUNC"mdiaSendEventMsg(0x%08x, SKIP_MBA) failed",
                  getHuid(mbaTrgt) );
        // Keep going.
    }

    return SUCCESS; // Intentionally return SUCCESS for this plugin

    #undef PRDF_FUNC
}
Example #16
0
int32_t mssRestoreDramRepairs( TargetHandle_t i_mbaTarget,
                               uint8_t & o_repairedRankMask,
                               uint8_t & o_badDimmMask )
{
    int32_t o_rc = SUCCESS;

    errlHndl_t errl = NULL;

    PRD_FAPI_TO_ERRL( errl, mss_restore_DRAM_repairs,
                      fapi::Target(fapi::TARGET_TYPE_MBA_CHIPLET, i_mbaTarget),
                      o_repairedRankMask, o_badDimmMask );

    if ( NULL != errl )
    {
        PRDF_ERR( "[PlatServices::mssRestoreDramRepairs] "
                  "mss_restore_dram_repairs() failed. HUID: 0x%08x",
                  getHuid(i_mbaTarget) );
        PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT );
        o_rc = FAIL;
    }

    return o_rc;
}
Example #17
0
int32_t isPllUnlockCausedByPciOscFo( ExtensibleChip * i_chip,
                                     uint32_t i_activeOscPos,
                                     bool & o_pciOscSwitchCausedPllError )
{
    #define PRDF_FUNC "Proc::isPllUnlockCausedByPciOscFo "
    int32_t o_rc = SUCCESS;
    o_pciOscSwitchCausedPllError = false;

    #ifndef __HOSTBOOT_MODULE

    do
    {
        uint32_t u32Data = 0;
        o_rc = getCfam( i_chip, 0x00002819, u32Data );

        if( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "PCI Status register Read failed 0x%08x",
                      i_chip->GetId() );
            break;
        }

        uint32_t pciOscMask = ( 0 == i_activeOscPos ) ? 0x00000C00 : 0x00000300;

        if( !(u32Data & pciOscMask) )
        {
            // PLL unlock error has occurred due to problem in secondary or
            // backup pci osc.
            o_pciOscSwitchCausedPllError = true;
        }
    }while(0);

    #endif
    #undef PRDF_FUNC

    return o_rc;
}
Example #18
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;
}
Example #19
0
int32_t cleanupSecondaryFirBits( ExtensibleChip * i_chip,
                       TYPE i_busType,
                       uint32_t i_busPos )
{
    int32_t l_rc = SUCCESS;
    TargetHandle_t mcsTgt = NULL;
    TargetHandle_t mbTgt = NULL;
    ExtensibleChip * mcsChip = NULL;
    ExtensibleChip * mbChip = NULL;

    //In case of spare deployed attention for DMI bus, we need to clear
    // secondary MBIFIR[10] and MCIFIR[10] bits.
    do
    {
        if ( i_busType == TYPE_MCS )
        {
            mcsTgt = getConnectedChild( i_chip->GetChipHandle(),
                                        TYPE_MCS,
                                        i_busPos);
            if (!mcsTgt) break;
            mcsChip = ( ExtensibleChip * )systemPtr->GetChip( mcsTgt );
            if (!mcsChip) break;
            mbChip =  getMcsDataBundle( mcsChip )->getMembChip();
            if (!mbChip) break;
            mbTgt =   mbChip->GetChipHandle();
            if (!mbTgt) break;
        }
        else if ( i_busType == TYPE_MEMBUF )
        {
            mbTgt = i_chip->GetChipHandle();
            if (!mbTgt) break;
            mcsChip = getMembufDataBundle( i_chip )->getMcsChip();
            if (!mcsChip) break;
            mcsTgt  = mcsChip->GetChipHandle();
            if (!mcsTgt) break;
            mbChip = i_chip;
        }
        else
        {
            // We only need to clean secondary FIR bits for DMI bus
            l_rc = SUCCESS;
            break;
        }

        SCAN_COMM_REGISTER_CLASS * mciAnd = mcsChip->getRegister("MCIFIR_AND");
        SCAN_COMM_REGISTER_CLASS * mbiAnd = mbChip->getRegister( "MBIFIR_AND");

        mciAnd->setAllBits(); mciAnd->ClearBit(10);
        mbiAnd->setAllBits(); mbiAnd->ClearBit(10);

        l_rc  = mciAnd->Write();
        l_rc |= mbiAnd->Write();

        if ( SUCCESS != l_rc )
        {
            PRDF_ERR( "[cleanupSecondaryFirBits] Write() failed on "
                      "MCIFIR/MBIFIR: MCS=0x%08x MEMB=0x%08x",
                      mcsChip->GetId(), mbChip->GetId() );
            break;
        }

    } while (0);

    return l_rc;
}
Example #20
0
/**
 * @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 );
        bool pllUnlockDuetoOscSwitch;
        rc = isPllUnlockCausedByPciOscFo( i_chip, oscPos,
                                          pllUnlockDuetoOscSwitch );

        if( SUCCESS != rc )
        {
            PRDF_ERR( PRDF_FUNC "PCI Osc switch analysis failed" );
            break;
        }

        if( pllUnlockDuetoOscSwitch )
        {
            // PLL unlock has occurred due to PCI OSC switchover. We can ignore
            // this error. It shall be handled seprately as PC OSC switchover
            // event.
            break;
        }

        // 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
}
Example #21
0
/**
  * @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,
                 uint32_t i_oscPos )
{
    #define PRDF_FUNC "[Proc::MaskPllIo] "

    int32_t rc = SUCCESS;

    do
    {
        if (CHECK_STOP == i_sc.service_data->getPrimaryAttnType())
        {
            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);
            rc = pciConfigReg->Write();
            if (rc != SUCCESS)
            {
                PRDF_ERR(PRDF_FUNC "PCI_CONFIG_REG write failed"
                         "for chip: 0x%08x",
                         i_chip->GetId());
            }
        }

        // Since TP_LFIR bit is the collection of all of the
        // pll error reg bits, we can't mask it or we will not
        // see any PLL errors reported from the error regs

    } while(0);

    return rc;

    #undef PRDF_FUNC
}
Example #22
0
/**
  * @brief  Clear the PLL error for P8 Plugin
  * @param  i_chip P8 chip
  * @param  i_sc   The step code data struct
  * @returns Failure or Success of query.
  */
int32_t ClearPllIo( ExtensibleChip * i_chip,
                        STEP_CODE_DATA_STRUCT & i_sc)
{
    #define PRDF_FUNC "[Proc::ClearPllIo] "

    int32_t rc = SUCCESS;

    if (CHECK_STOP != i_sc.service_data->getPrimaryAttnType())
    {
        // Clear pci osc error reg bit
        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;
        }

        if( pciErrReg->IsBitSet( PLL_ERROR_BIT ) )
        {
            pciErrReg->clearAllBits();
            pciErrReg->SetBit(PLL_ERROR_BIT);
            tmpRC = pciErrReg->Write();

            if ( SUCCESS != tmpRC )
            {
                PRDF_ERR( PRDF_FUNC "Write() failed on PCI Error register: "
                          "proc=0x%08x", i_chip->GetId() );
                rc |= tmpRC;
            }
        }

        // Clear TP_LFIR
        SCAN_COMM_REGISTER_CLASS * TP_LFIRand =
                   i_chip->getRegister("TP_LFIR_AND");
        TP_LFIRand->setAllBits();
        TP_LFIRand->ClearBit(PLL_DETECT_P8);
        tmpRC = TP_LFIRand->Write();
        if (tmpRC != SUCCESS)
        {
            PRDF_ERR(PRDF_FUNC "TP_LFIR_AND write failed"
                     "for chip: 0x%08x", i_chip->GetId());
            rc |= tmpRC;
        }

        SCAN_COMM_REGISTER_CLASS * oscCerrReg =
                i_chip->getRegister("OSCERR");

        tmpRC = oscCerrReg->Read();
        if (tmpRC != SUCCESS)
        {
            PRDF_ERR(PRDF_FUNC "OSCERR read failed"
                     "for 0x%08x", i_chip->GetId());
            rc |= tmpRC;
        }
        oscCerrReg->ClearBit(4);
        oscCerrReg->ClearBit(5);
        tmpRC = oscCerrReg->Write();
        if (tmpRC != SUCCESS)
        {
            PRDF_ERR(PRDF_FUNC "oscCerrReg write failed"
                     "for chip: 0x%08x", i_chip->GetId());
            rc |= tmpRC;
        }

    }

    if( rc != SUCCESS )
    {
        PRDF_ERR(PRDF_FUNC "failed for proc: 0x%.8X",
                 i_chip->GetId());
    }

    return rc;

    #undef PRDF_FUNC
}
Example #23
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);
}
Example #24
0
int32_t calloutBusInterface( TargetHandle_t i_rxTrgt, TargetHandle_t i_txTrgt,
                             PRDpriority i_priority )
{
    #define PRDF_FUNC "[CalloutUtil::calloutBusInterface] "

    int32_t rc = SUCCESS;

    do
    {
        // Check for valid targets.
        if ( NULL == i_rxTrgt || NULL == i_txTrgt )
        {
            PRDF_ERR( PRDF_FUNC "Given target(s) are NULL" );
            rc = FAIL; break;
        }

        // Get the HWAS bus type.
        HWAS::busTypeEnum hwasType;

        TYPE rxType = getTargetType(i_rxTrgt);
        TYPE txType = getTargetType(i_txTrgt);

        if ( TYPE_ABUS == rxType && TYPE_ABUS == txType )
        {
            hwasType = HWAS::A_BUS_TYPE;
        }
        else if ( TYPE_XBUS == rxType && TYPE_XBUS == txType )
        {
            hwasType = HWAS::X_BUS_TYPE;
        }
        else if ( (TYPE_MCS    == rxType && TYPE_MEMBUF == txType) ||
                  (TYPE_MEMBUF == rxType && TYPE_MCS    == txType) )
        {
            hwasType = HWAS::DMI_BUS_TYPE;
        }
        else
        {
            PRDF_ERR( PRDF_FUNC "Unsupported target types" );
            rc = FAIL; break;
        }

        // Get the global error log.
        errlHndl_t errl = NULL;
        errl = ServiceGeneratorClass::ThisServiceGenerator().getErrl();
        if ( NULL == errl )
        {
            PRDF_ERR( PRDF_FUNC "Failed to get the global error log" );
            rc = FAIL; break;
        }

        // Callout this bus interface.
        PRDF_ADD_BUS_CALLOUT( errl, i_rxTrgt, i_txTrgt, hwasType, i_priority );

    } while(0);

    if ( SUCCESS != rc )
    {
        PRDF_ERR( PRDF_FUNC "i_rxTrgt:0x%08x i_txTrgt:0x%08x i_priority:%d",
                  getHuid(i_rxTrgt), getHuid(i_txTrgt), i_priority );
    }

    return rc;

    #undef PRDF_FUNC
}
Example #25
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());
}
Example #26
0
int32_t handleLaneRepairEvent( ExtensibleChip * i_chip,
                               TYPE i_busType,
                               uint32_t i_busPos,
                               STEP_CODE_DATA_STRUCT & i_sc,
                               bool i_spareDeployed )
{
    #define PRDF_FUNC "[LaneRepair::handleLaneRepairEvent] "

    int32_t l_rc = SUCCESS;
    TargetHandle_t rxBusTgt = NULL;
    TargetHandle_t txBusTgt = NULL;
    bool thrExceeded = true;
    std::vector<uint8_t> rx_lanes;
    std::vector<uint8_t> rx_vpdLanes;
    std::vector<uint8_t> tx_vpdLanes;
    BitStringBuffer l_vpdLaneMap0to63(64);
    BitStringBuffer l_vpdLaneMap64to127(64);
    BitStringBuffer l_newLaneMap0to63(64);
    BitStringBuffer l_newLaneMap64to127(64);

    do
    {
        #ifdef __HOSTBOOT_MODULE
        if ( CHECK_STOP == i_sc.service_data->GetAttentionType() )
        {
            // This would only happen on OpenPOWER machines when we are doing
            // the post IPL analysis. In this case, we do not have the FFDC to
            // query the IO registers so simply set service call and skip
            // everything else.
            i_sc.service_data->SetServiceCall();
            return SUCCESS;
        }
        #endif

        // Get the RX and TX targets.
        l_rc = CalloutUtil::getBusEndpoints( i_chip, rxBusTgt, txBusTgt,
                                             i_busType, i_busPos );
        if ( SUCCESS != l_rc )
        {
            PRDF_ERR( PRDF_FUNC "getBusEndpoints() failed" );
            break;
        }

        // Call io_read_erepair
        l_rc = readErepair(rxBusTgt, rx_lanes);
        if (SUCCESS != l_rc)
        {
            PRDF_ERR( PRDF_FUNC "readErepair() failed: rxBusTgt=0x%08x",
                      getHuid(rxBusTgt) );
            break;
        }

        // Add newly failed lanes to capture data
        for (std::vector<uint8_t>::iterator lane = rx_lanes.begin();
             lane != rx_lanes.end(); ++lane)
        {
            PRDF_INF( PRDF_FUNC "New failed lane on RX HUID 0x%08x: %d",
                      getHuid(rxBusTgt), *lane);
            if (*lane < 64)
                l_newLaneMap0to63.Set(*lane);
            else if (*lane < 127)
                l_newLaneMap64to127.Set(*lane - 64);
            else
            {
                PRDF_ERR( PRDF_FUNC "Invalid lane number %d: rxBusTgt=0x%08x",
                          *lane, getHuid(rxBusTgt) );
                l_rc = FAIL; break;
            }
        }
        if ( SUCCESS != l_rc ) break;

        // Add failed lane capture data to errorlog
        i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(),
                                ( Util::hashString("ALL_FAILED_LANES_0TO63") ^
                                  i_chip->getSignatureOffset() ),
                                l_newLaneMap0to63);
        i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(),
                                ( Util::hashString("ALL_FAILED_LANES_64TO127") ^
                                  i_chip->getSignatureOffset() ),
                                l_newLaneMap64to127);

        if (!mfgMode()) // Don't read/write VPD in mfg mode
        {
            // Read Failed Lanes from VPD
            l_rc = getVpdFailedLanes(rxBusTgt, rx_vpdLanes, tx_vpdLanes);
            if (SUCCESS != l_rc)
            {
                PRDF_ERR( PRDF_FUNC "getVpdFailedLanes() failed: "
                          "rxBusTgt=0x%08x", getHuid(rxBusTgt) );
                break;
            }

            // Add VPD lanes to capture data
            for (std::vector<uint8_t>::iterator lane = rx_vpdLanes.begin();
                 lane != rx_vpdLanes.end(); ++lane)
            {
                if (*lane < 64)
                    l_vpdLaneMap0to63.Set(*lane);
                else if (*lane < 127)
                    l_vpdLaneMap64to127.Set(*lane - 64);
                else
                {
                    PRDF_ERR( PRDF_FUNC "Invalid VPD lane number %d: "
                              "rxBusTgt=0x%08x", *lane, getHuid(rxBusTgt) );
                    l_rc = FAIL; break;
                }
            }
            if ( SUCCESS != l_rc ) break;

            // Add failed lane capture data to errorlog
            i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(),
                                ( Util::hashString("VPD_FAILED_LANES_0TO63") ^
                                  i_chip->getSignatureOffset() ),
                                l_vpdLaneMap0to63);
            i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(),
                               ( Util::hashString("VPD_FAILED_LANES_64TO127") ^
                                 i_chip->getSignatureOffset() ),
                               l_vpdLaneMap64to127);

            if (i_spareDeployed)
            {
                // Call Erepair to update VPD
                l_rc = setVpdFailedLanes(rxBusTgt, txBusTgt,
                                         rx_lanes, thrExceeded);
                if (SUCCESS != l_rc)
                {
                    PRDF_ERR( PRDF_FUNC "setVpdFailedLanes() failed: "
                              "rxBusTgt=0x%08x txBusTgt=0x%08x",
                              getHuid(rxBusTgt), getHuid(txBusTgt) );
                    break;
                }
                if( thrExceeded )
                {
                    i_sc.service_data->SetErrorSig(
                                            PRDFSIG_ERepair_FWThrExceeded );
                }
            }
        }

        if (i_spareDeployed && !thrExceeded)
        {
            // Update lists of lanes from VPD
            rx_vpdLanes.clear(); tx_vpdLanes.clear();
            l_rc = getVpdFailedLanes(rxBusTgt, rx_vpdLanes, tx_vpdLanes);
            if (SUCCESS != l_rc)
            {
                PRDF_ERR( PRDF_FUNC "getVpdFailedLanes() before power down "
                          "failed: rxBusTgt=0x%08x", getHuid(rxBusTgt) );
                break;
            }

            // Power down all lanes that have been saved in VPD
            l_rc = powerDownLanes(rxBusTgt, rx_vpdLanes, tx_vpdLanes);
            if (SUCCESS != l_rc)
            {
                PRDF_ERR( PRDF_FUNC "powerDownLanes() failed: rxBusTgt=0x%08x",
                          getHuid(rxBusTgt) );
                break;
            }
        }
        else
        {
            // Make predictive
            i_sc.service_data->SetServiceCall();
        }
    } while (0);

    // Clear FIRs
    if (rxBusTgt)
    {
        l_rc |= erepairFirIsolation(rxBusTgt);
        l_rc |= clearIOFirs(rxBusTgt);
    }

    if ( i_spareDeployed )
    {
        l_rc |= cleanupSecondaryFirBits( i_chip, i_busType, i_busPos );
    }

    // This return code gets returned by the plugin code back to the rule code.
    // So, we do not want to give a return code that the rule code does not
    // understand. So far, there is no need return a special code, so always
    // return SUCCESS.
    if ( SUCCESS != l_rc )
    {
        PRDF_ERR( PRDF_FUNC "i_chip: 0x%08x i_busType:%d i_busPos:%d",
                  i_chip->GetId(), i_busType, i_busPos );

        i_sc.service_data->SetErrorSig( PRDFSIG_ERepair_ERROR );
        CalloutUtil::defaultError( i_sc );
    }

    return SUCCESS;

    #undef PRDF_FUNC
}
Example #27
0
errlHndl_t noLock_initialize()
{
    #define PRDF_FUNC "PRDF::noLock_initialize() "

    PRDF_ENTER( PRDF_FUNC );

    g_prd_errlHndl = NULL; // This forces any previous errls to be committed

    // Synchronize SCOM access to hardware
    // Start un-synchronized so hardware is accessed
    RegDataCache::getCachedRegisters().flush();

    if(g_initialized == true && systemPtr != NULL)
    {
        // This means we are being re-initialized (and we were in a good state)
        // so Clean up in preparation for re-build
        unInitialize();
    }

    if(g_initialized == false)
    {
        // Initialize the Service Generator
        ServiceGeneratorClass & serviceGenerator =
                    ServiceGeneratorClass::ThisServiceGenerator();
        serviceGenerator.Initialize();

        // Perform platform specific initialization.
        initPlatSpecific();

        CcAutoDeletePointer<Configurator> configuratorPtr
            (SystemSpecific::getConfiguratorPtr());

        errlHndl_t l_errBuild = configuratorPtr->build();//build object model
        if( NULL != l_errBuild )
        {
            //there is some problem in building RuleMetaData object
            g_prd_errlHndl = l_errBuild;

            //object model is either not build or at best incomplete.We must
            // clean this up .The easiest way is to delete the system which in
            //in turn shall clean up the constituents.
            delete systemPtr;
            systemPtr = NULL;
            g_initialized = false;
            PRDF_ERR(PRDF_FUNC"failed to buid object model");
        }
        //systemPtr is populated in configurator
        else if( systemPtr != NULL )
        {
            systemPtr->Initialize(); // Hardware initialization
            g_initialized = true;
        }

        // Flush rule table cache since objects are all built.
        Prdr::LoadChipCache::flushCache();
    }

    PRDF_EXIT( PRDF_FUNC );

    return (g_prd_errlHndl.release());

    #undef PRDF_FUNC
}