Ejemplo n.º 1
0
int32_t CenMbaTdCtlrCommon::setRtEteThresholds()
{
    #define PRDF_FUNC "[CenMbaTdCtlrCommon::setRtEteThresholds] "

    int32_t o_rc = SUCCESS;

    do
    {
        const char * reg_str = (0 == iv_mbaPos) ? "MBA0_MBSTR" : "MBA1_MBSTR";
        SCAN_COMM_REGISTER_CLASS * mbstr = iv_membChip->getRegister( reg_str );

        // MBSTR's content could be modified from cleanupCmd()
        // so we need to refresh
        o_rc = mbstr->ForceRead();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "ForceRead() failed on %s", reg_str );
            break;
        }

        uint16_t softIntCe = 0;
        o_rc = getScrubCeThreshold( iv_mbaChip, iv_rank, softIntCe );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "getScrubCeThreshold() failed." );
            break;
        }

        // Only care about retry CEs if there are a lot of them. So the
        // threshold will be high in the field. However, in MNFG the retry CEs
        // will be handled differently by putting every occurrence in the RCE
        // table and doing targeted diagnostics when needed.
        uint16_t retryCe = mfgMode() ? 1 : 2047;

        uint16_t hardCe = 1; // Always stop on first occurrence.

        mbstr->SetBitFieldJustified(  4, 12, softIntCe );
        mbstr->SetBitFieldJustified( 16, 12, softIntCe );
        mbstr->SetBitFieldJustified( 28, 12, hardCe    );
        mbstr->SetBitFieldJustified( 40, 12, retryCe   );

        // Set the per symbol counters to count hard CEs only. This is so that
        // when the scrub stops on the first hard CE, we can use the per symbol
        // counters to tell us which symbol reported the hard CE.
        mbstr->SetBitFieldJustified( 55, 3, 0x1 );

        o_rc = mbstr->Write();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str );
            break;
        }

    } while(0);

    return o_rc;

    #undef PRDF_FUNC
}
Ejemplo n.º 2
0
int32_t chnlCsCleanup( ExtensibleChip *i_mbChip,
                       STEP_CODE_DATA_STRUCT & i_sc )
{
    #define PRDF_FUNC "[MemUtils::chnlCsCleanup] "

    int32_t o_rc = SUCCESS;

    do
    {
        if( (  NULL == i_mbChip ) ||
            ( TYPE_MEMBUF != getTargetType( i_mbChip->GetChipHandle() )))
        {
            PRDF_ERR( PRDF_FUNC "Invalid parameters" );
            o_rc = FAIL; break;
        }

        if (( ! i_sc.service_data->IsUnitCS() ) ||
              (CHECK_STOP == i_sc.service_data->getPrimaryAttnType()) )
            break;

        CenMembufDataBundle * mbdb = getMembufDataBundle( i_mbChip );
        if ( !mbdb->iv_doChnlFailCleanup )
            break; // Cleanup has already been done.

        // Set it as SUE generation point.
        i_sc.service_data->SetFlag( ServiceDataCollector::UERE );

        ExtensibleChip * mcsChip = mbdb->getMcsChip();
        if ( NULL == mcsChip )
        {
            PRDF_ERR( PRDF_FUNC "MCS chip is NULL for Membuf:0x%08X",
                      i_mbChip->GetId() );
            o_rc = FAIL; break;
        }

        TargetHandle_t mcs = mcsChip->GetChipHandle();
        ExtensibleChip * procChip = NULL;
        uint8_t pos = getTargetPosition( mcs );
        TargetHandle_t proc = getParentChip ( mcs );

        if ( NULL == proc )
        {
            PRDF_ERR( PRDF_FUNC "Proc is NULL for Mcs:0x%08X", getHuid( mcs ) );
            o_rc = FAIL; break;
        }

        procChip = (ExtensibleChip *)systemPtr->GetChip( proc );

        if( NULL == procChip )
        {
            PRDF_ERR( PRDF_FUNC "Can not find Proc chip for HUID:0x%08X",
                      getHuid( proc) );
            o_rc = FAIL; break;
        }

        // This is a cleanup function. If we get any error from scom
        // operations, we will still continue with cleanup.
        SCAN_COMM_REGISTER_CLASS * l_tpMask =
              procChip->getRegister("TP_CHIPLET_FIR_MASK");
        o_rc |= l_tpMask->Read();
        if ( SUCCESS == o_rc )
        {
            // Bits 5-12 maps to attentions from MCS0-MCS7.
            l_tpMask->SetBit( 5 + pos );
            o_rc |= l_tpMask->Write();
        }

        // Mask attentions from the Centaur
        const char *iomcFirMask = ( pos < 4 )?
                                  "IOMCFIR_0_MASK_OR":"IOMCFIR_1_MASK_OR";

        SCAN_COMM_REGISTER_CLASS * iomcMask =
                                 procChip->getRegister( iomcFirMask);
        if ( pos >= 4 ) pos -= 4;

        // 8 bits are reserved for each Centaur in IOMCFIR.
        // There are total 4 ( for P system ) centaur supported
        // in MCS. Bits for first centaur starts from bit 8.

        iomcMask->SetBitFieldJustified( 8+ ( pos*8 ), 8, 0xff);

        o_rc |= iomcMask->Write();

        SCAN_COMM_REGISTER_CLASS * l_tpfirmask   = NULL;
        SCAN_COMM_REGISTER_CLASS * l_nestfirmask = NULL;
        SCAN_COMM_REGISTER_CLASS * l_memfirmask  = NULL;
        SCAN_COMM_REGISTER_CLASS * l_memspamask  = NULL;

        l_tpfirmask   = i_mbChip->getRegister("TP_CHIPLET_FIR_MASK");
        l_nestfirmask = i_mbChip->getRegister("NEST_CHIPLET_FIR_MASK");
        l_memfirmask  = i_mbChip->getRegister("MEM_CHIPLET_FIR_MASK");
        l_memspamask  = i_mbChip->getRegister("MEM_CHIPLET_SPA_MASK");

        l_tpfirmask->setAllBits();   o_rc |= l_tpfirmask->Write();
        l_nestfirmask->setAllBits(); o_rc |= l_nestfirmask->Write();
        l_memfirmask->setAllBits();  o_rc |= l_memfirmask->Write();
        l_memspamask->setAllBits();  o_rc |= l_memspamask->Write();


        for ( uint32_t i = 0; i < MAX_MBA_PER_MEMBUF; i++ )
        {
            ExtensibleChip * mbaChip = mbdb->getMbaChip( i );
            if( NULL != mbaChip )
            {
                TargetHandle_t mba = mbaChip->GetChipHandle();
                if ( NULL != mba )
                {
                    #if  defined(__HOSTBOOT_MODULE) && \
                        !defined(__HOSTBOOT_RUNTIME)
                    // This is very small platform specific code. So not
                    // creating a separate file for this.
                    int32_t l_rc = mdiaSendEventMsg( mba, MDIA::SKIP_MBA );
                    if ( SUCCESS != l_rc )
                    {
                        PRDF_ERR( PRDF_FUNC "mdiaSendEventMsg(0x%08x, SKIP_MBA) "
                                  "failed", getHuid( mba ) );
                        o_rc |= l_rc;
                    }
                    #else
                    int32_t l_rc = DEALLOC::mbaGard( mbaChip  );
                    if ( SUCCESS != l_rc )
                    {
                        PRDF_ERR( PRDF_FUNC "mbaGard failed. HUID: 0x%08x",
                                  getHuid( mba ) );
                        o_rc |= l_rc;
                    }
                    #endif // __HOSTBOOT_MODULE
                }
            }
        }

        // Clean up complete an is no longer required.
        mbdb->iv_doChnlFailCleanup = false;

    } while(0);

    return o_rc;

    #undef PRDF_FUNC
}
Ejemplo n.º 3
0
int32_t CenMbaTdCtlrCommon::prepareNextCmd( bool i_clearStats )
{
    #define PRDF_FUNC "[CenMbaTdCtlrCommon::prepareNextCmd] "

    int32_t o_rc = SUCCESS;

    do
    {
        //----------------------------------------------------------------------
        // Clean up previous command
        //----------------------------------------------------------------------

        o_rc = cleanupPrevCmd();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "cleanupPrevCmd() failed" );
            break;
        }

        //----------------------------------------------------------------------
        // Clear ECC counters
        //----------------------------------------------------------------------

        const char * reg_str = NULL;

        if ( i_clearStats )
        {
            reg_str = (0 == iv_mbaPos) ? "MBA0_MBSTR" : "MBA1_MBSTR";
            SCAN_COMM_REGISTER_CLASS * mbstr =
                                    iv_membChip->getRegister( reg_str );

            // MBSTR's content could be modified from cleanupCmd()
            // so we need to refresh
            o_rc = mbstr->ForceRead();
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "ForceRead() failed on %s", reg_str );
                break;
            }

            mbstr->SetBit(53); // Setting this bit clears all counters.

            o_rc = mbstr->Write();
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str );
                break;
            }

            // Hardware automatically clears bit 53, so flush this register out
            // of the register cache to avoid clearing the counters again with
            // a write from the out-of-date cached copy.
            RegDataCache & cache = RegDataCache::getCachedRegisters();
            cache.flush( iv_membChip, mbstr );
        }

        //----------------------------------------------------------------------
        // Clear ECC FIRs
        //----------------------------------------------------------------------

        reg_str = (0 == iv_mbaPos) ? "MBA0_MBSECCFIR_AND"
                                   : "MBA1_MBSECCFIR_AND";
        SCAN_COMM_REGISTER_CLASS * firand = iv_membChip->getRegister( reg_str );
        firand->setAllBits();

        // Clear all scrub MPE bits.
        // This will need to be done when starting a TD procedure or background
        // scrubbing. iv_rank may not be set when starting background scrubbing
        // and technically there should only be one of these MPE bits on at a
        // time so we should not have to worry about losing an attention by
        // clearing them all.
        firand->SetBitFieldJustified( 20, 8, 0 );

        // Clear scrub NCE, SCE, MCE, RCE, SUE, UE bits (36-41)
        firand->SetBitFieldJustified( 36, 6, 0 );

        o_rc = firand->Write();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "Write() failed on %s", reg_str );
            break;
        }

        SCAN_COMM_REGISTER_CLASS * spaAnd =
                                iv_mbaChip->getRegister("MBASPA_AND");
        spaAnd->setAllBits();

        // Clear threshold exceeded attentions
        spaAnd->SetBitFieldJustified( 1, 4, 0 );

        o_rc = spaAnd->Write();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "Write() failed on MBASPA_AND" );
            break;
        }

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}