Example #1
0
int32_t checkMcsChannelFail( ExtensibleChip * i_mcsChip,
                             STEP_CODE_DATA_STRUCT & io_sc )
{
    #define PRDF_FUNC "[MemUtils::checkMcsChannelFail] "

    int32_t o_rc = SUCCESS;

    do
    {
        // Skip if already handling unit checkstop.
        if ( io_sc.service_data->GetFlag(ServiceDataCollector::UNIT_CS) )
            break;

        // Must be an MCS.
        if ( TYPE_MCS != getTargetType(i_mcsChip->GetChipHandle()) )
        {
            PRDF_ERR( PRDF_FUNC "i_mcsChip is not TYPE_MCS" );
            o_rc = FAIL; break;
        }

        // Check MCIFIR[31] for presence of channel fail.
        SCAN_COMM_REGISTER_CLASS * mcifir = i_mcsChip->getRegister("MCIFIR");
        o_rc = mcifir->Read();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "Read() failed on MCIFIR" );
            break;
        }

        if ( !mcifir->IsBitSet(31) ) break; // No channel fail, so exit.

        // Set unit checkstop flag and cause attention type.
        io_sc.service_data->SetFlag(ServiceDataCollector::UNIT_CS);
        io_sc.service_data->setSecondaryAttnType(UNIT_CS);
        io_sc.service_data->SetThresholdMaskId(0);

        // Indicate that cleanup is required.
        P8McsDataBundle * mcsdb = getMcsDataBundle( i_mcsChip );
        ExtensibleChip * membChip = mcsdb->getMembChip();
        if ( NULL == membChip )
        {
            PRDF_ERR( PRDF_FUNC "getMembChip() returned NULL" );
            o_rc = FAIL; break;
        }
        CenMembufDataBundle * mbdb = getMembufDataBundle( membChip );
        mbdb->iv_doChnlFailCleanup = true;

    } while (0);

    if ( SUCCESS != o_rc )
    {
        PRDF_ERR( PRDF_FUNC "Failed: i_mcsChip=0x%08x", i_mcsChip->GetId() );
    }

    return o_rc;

    #undef PRDF_FUNC
}
Example #2
0
/**
 * @brief  Handles Max Spares Exceeded attentions on the MCS.
 *
 * This function will first check for channel fail conditions on the MCS side of
 * the bus, handle the attention, then do channel fail cleanup if needed. It
 * would be preferred that the channel fail handling would be done in a more
 * generic way, like it is done on the MCS and MEMBUF pre/post analysis
 * functions. Unfortunately, the IOMCFIRs are not on the MCS chiplet, which
 * complicates things. Fortunately, the only attentions on the IOMCFIRs that are
 * hardwired to channel fail are the Max Spares Exceeded attentions. Therefore,
 * we can deal with the channel fail handling within this attention.
 *
 * @param  i_procChip A PROC chip.
 * @param  i_sc       The step code data struct.
 * @param  i_mcsPos   The MCS position.
 * @return SUCCESS always.
 */
int32_t maxSparesExceeded_MCS( ExtensibleChip * i_procChip,
                               STEP_CODE_DATA_STRUCT & i_sc,
                               uint32_t i_mcsPos )
{
    #define PRDF_FUNC "[Proc::maxSparesExceeded_MCS] "

    int32_t l_rc = SUCCESS;

    TargetHandle_t procTrgt = i_procChip->GetChipHandle();
    TargetHandle_t mcsTrgt  = NULL;
    ExtensibleChip * mcsChip  = NULL;
    ExtensibleChip * membChip = NULL;

    do
    {
        // Get the connected MCS chip
        mcsTrgt = getConnectedChild( procTrgt, TYPE_MCS, i_mcsPos );
        if ( NULL == mcsTrgt )
        {
            PRDF_ERR( PRDF_FUNC"getConnectedChild() returned NULL" );
            l_rc = FAIL; break;
        }

        mcsChip = (ExtensibleChip *)systemPtr->GetChip( mcsTrgt );
        if ( NULL == mcsChip )
        {
            PRDF_ERR( PRDF_FUNC"GetChip() returned NULL" );
            l_rc = FAIL; break;
        }

        // Check for channel fails on the MCS side of this bus.
        l_rc = MemUtils::checkMcsChannelFail( mcsChip, i_sc );
        if ( SUCCESS != l_rc )
        {
            PRDF_ERR( PRDF_FUNC"checkMcsChannelFail() failed" );
            break;
        }

        // Do additional bus analysis.
        l_rc = handleLaneRepairEvent( i_procChip, TYPE_MCS, i_mcsPos, i_sc,
                                      false );
        if ( SUCCESS != l_rc )
        {
            PRDF_ERR( PRDF_FUNC"handleLaneRepairEvent() failed" );
            break;
        }

        // Get the connected MEMBUF chip.
        P8McsDataBundle * mcsdb = getMcsDataBundle( mcsChip );
        membChip = mcsdb->getMembChip();
        if ( NULL == membChip )
        {
            PRDF_ERR( PRDF_FUNC"getMembChip() returned NULL" );
            l_rc = FAIL; break;
        }

        // Do channel fail cleanup.
        l_rc = MemUtils::chnlCsCleanup( membChip, i_sc );
        if ( SUCCESS != l_rc )
        {
            PRDF_ERR( PRDF_FUNC"chnlCsCleanup() failed" );
            break;
        }

    } while (0);

    if ( SUCCESS != l_rc )
    {
        PRDF_ERR( PRDF_FUNC"Failed: i_procChip=0x%08x i_mcsPos=%d",
                  i_procChip->GetId(), i_mcsPos );
        CalloutUtil::defaultError( i_sc );
    }

    return SUCCESS; // Always return SUCCESS

    #undef PRDF_FUNC
}