Beispiel #1
0
    /** brief handle chip attentions
     *
     *  @param[in] i_proc - processor chip id at attention
     *                      XSCOM chip id based on devtree defn
     *  @param[in] i_ipollStatus - processor chip Ipoll status
     *  @param[in] i_ipollMask   - processor chip Ipoll mask
     *  @return 0 on success else return code
     */
    int handleAttns(uint64_t i_proc,
                    uint64_t i_ipollStatus,
                    uint64_t i_ipollMask)
    {
        ATTN_SLOW(ENTER_MRK"ATTN_RT::handleAttns RtProc: %llx"
                  ", ipollMask: %llx, ipollStatus: %llx",
                  i_proc, i_ipollMask, i_ipollStatus);

        int rc = 0;
        errlHndl_t err = NULL;
        AttentionList attentions;
        MemOps & memOps = getMemOps();
        uint64_t l_iprScomData = 0;


        do
        {
            // Convert chipIds to HB targets
            TargetHandle_t proc = NULL;
            err = RT_TARG::getHbTarget(i_proc, proc);
            if(err)
            {
                ATTN_ERR("ATTN_RT::handleAttns getHbTarget "
                   "returned error for RtProc: %llx", i_proc);
                rc = EINVAL;
                break;
            }

            err = Singleton<Service>::instance().handleAttentions(proc);
            if(err)
            {
                ATTN_ERR("ATTN_RT::handleAttns service::handleAttentions "
                   "returned error for RtProc: %llx", i_proc);
                break;
            }

            // For host attentions, clear gpio interrupt type register.
            // If we do not clear gpio register, ipoll status will again
            // get set and we will end up in infinite loop.

            uint64_t hostMask = 0;
            IPOLL::getCheckbits(HOST, hostMask);

            if( i_ipollMask & hostMask)
            {
                // After handling attn, check GP1 for more attns
                // as there could be additional memory units with attns.
                attentions.clear();

                err = memOps.resolve(proc, attentions);

                if(err)
                {
                    ATTN_ERR("RT GP1 Chk:memOps  returned error.HUID:0X%08X ",
                              get_huid( proc ));
                    break;
                }


                // Save the IPR if any attns still active on Centaurs
                if (!attentions.empty())
                {
                    err = getScom(proc, INTR_TYPE_LCL_ERR_STATUS_REG,
                                  l_iprScomData);

                    if(err)
                    {
                        ATTN_ERR("RT SaveIPR returned error.HUID:0X%08X ",
                                  get_huid( proc ));
                        break;
                    }

                } // end if any attentions


                // Clear the IPR (interrupt presentation register)
                err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0);

                if(err)
                {
                    ATTN_ERR("ATTN_RT::handleAttns putscom failed for "
                             "RtProc: %llx address:0x%08X", i_proc,
                              INTR_TYPE_LCL_ERR_STATUS_AND_REG);
                    break;
                }


                // Restore the IPR if any attns still active in Centaurs
                if (!attentions.empty())
                {
                    err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_OR_REG,
                                  l_iprScomData);

                    if(err)
                    {
                        ATTN_ERR("RT RestoreIPR returned error.HUID:0X%08X ",
                                  get_huid( proc ));
                        break;
                    }

                } // end if any attentions

            } // end if i_ipollMask & hostMask)

        } while(0);

        if(err)
        {
            errlCommit( err, ATTN_COMP_ID );
            if(0 == rc)
            {
                rc = -1;
            }
        }


        attentions.clear();
        ATTN_SLOW(EXIT_MRK"ATTN_RT::handleAttns rc: %d", rc);

        return rc;
    }
Beispiel #2
0
errlHndl_t Service::configureInterrupts(
        msg_q_t i_q,
        ConfigureMode i_mode)
{
    errlHndl_t err = NULL;

    // First register for Q
    // This will set up the psi host bridge logic for
    // lcl_err interrupt on all chips

    if(i_mode == UP)
    {
        err = INTR::registerMsgQ(i_q,
                                 ATTENTION,
                                 INTR::ISN_LCL_ERR);
    }

    // setup the ITR macro for GPIO type host attentions,
    // on all procs

    if(!err)
    {
        TargetHandleList procs;
        getTargetService().getAllChips(procs, TYPE_PROC);
        TargetHandleList::iterator it = procs.begin();

        while(it != procs.end())
        {
            uint64_t mask = 0;

            // clear GPIO interrupt type status register

            if(i_mode == UP)
            {
                err = putScom(*it, INTR_TYPE_LCL_ERR_STATUS_AND_REG,
                              0);
            }

            if(err)
            {
                break;
            }

            // unmask GPIO interrupt type

            mask = 0x8000000000000000ull;

            err = putScom(
                    *it,
                    (i_mode == UP
                     ? INTR_TYPE_MASK_AND_REG
                     : INTR_TYPE_MASK_OR_REG),
                    i_mode == UP ? ~mask : mask);

            if(err)
            {
                break;
            }

            // set GPIO interrupt type mode - or

            if(i_mode == UP)
            {
                err = putScom(*it, INTR_TYPE_CONFIG_AND_REG,
                                 ~mask);
            }

            if(err)
            {
                break;
            }

            // enable/disable MCSes

            mask = 0;

            GP1::forEach(~0, &mask, &getPbGp2Mask);

            err = modifyScom(
                             *it,
                             GP2_REG,
                             i_mode == UP ? mask : ~mask,
                             i_mode == UP ? SCOM_OR : SCOM_AND);

            if(err)
            {
                break;
            }

            // enable attentions in ipoll mask

            mask = HostMask::nonHost();
            mask |= HostMask::host();

            // this doesn't have an and/or reg for some reason...

            err = modifyScom(
                    *it,
                    IPOLL::address,
                    i_mode == UP ? ~mask : mask,
                    i_mode == UP ? SCOM_AND : SCOM_OR);

            if(err)
            {
                break;
            }

            ++it;
        }

        if(!err && i_mode == DOWN)
        {
            if(NULL == INTR::unRegisterMsgQ(INTR::ISN_LCL_ERR))
            {
                ATTN_ERR("INTR did not find isn: 0x%07x",
                        INTR::ISN_LCL_ERR);
            }
        }
    }
    return err;
}
Beispiel #3
0
errlHndl_t FakePrd::callPrd(const AttentionList & i_attentions)
{
    errlHndl_t  l_elog = i_attentions.forEach(Clear(*iv_injectSink)).err;

    AttnList    l_attnList;
    i_attentions.getAttnList(l_attnList);


    ATTN_TRACE("fakeCallPrd with Attn Count of %d", l_attnList.size());

    // -----------------------------------------------------
    // This is FAKE code only.
    // If you do the EC/MODEL check, it crashes in CXX testcase.
    // Kind of thinking some library missing that is needed when
    // adding these calls, For now, I will just leave them out
    // and we could probably scrap this test now that it runs
    // successfully  (see attntestproc.H)
    // (Maybe add to 'fake target service' for these ATTRs)
    // -----------------------------------------------------
    // For the initial NIMBUS chip, there is a HW issue
    // which requires us to clear the "Combined Global
    // interrupt register" on recoverable errors.
    // This also affects Checkstop/Special Attns, but
    // the FSP handles those and already clears the reg.
    // The issue does not apply to host/unit cs attns.
//    uint8_t l_ecLevel = 0;
    AttnList::iterator  l_attnIter = l_attnList.begin();

    // Shouldn't be mixing NIMBUS with CUMULUS,etc...
    // so probably don't need to repeat this call per chip.
//    bool l_isNimbus = ( (*l_attnIter).targetHndl->
//                        getAttr<ATTR_MODEL>() == MODEL_NIMBUS );

    // Iterate thru all chips in case PRD handled
    // a chip other than the first one.
    while(l_attnIter != l_attnList.end())
    {
//        l_ecLevel = (*l_attnIter).targetHndl->getAttr<ATTR_EC>();


        if ( (RECOVERABLE == (*l_attnIter).attnType)
//             && (true == l_isNimbus) && (l_ecLevel < 0x11)
           )
        {
            errlHndl_t l_scomErr = NULL;
            uint64_t   l_clrAllBits = 0;

            l_scomErr = putScom( (*l_attnIter).targetHndl,
                                  PIB_INTR_TYPE_REG,
                                  l_clrAllBits
                                );

            if (NULL != l_scomErr)
            {
                 ATTN_ERR("Clear PibIntrReg failed, HUID:0X%08X",
                          get_huid( (*l_attnIter).targetHndl) );
                 errlCommit(l_scomErr, ATTN_COMP_ID);
            } // failed to clear PIB intr reg

        } // if recoverable attn

        ++l_attnIter;

    } // end while looping thru attn list


    return l_elog;
}