Exemplo n.º 1
0
void Service::processAttentions(const TargetHandleList & i_procs)
{
    errlHndl_t err = NULL;
    AttentionList attentions;

    MemOps & memOps = getMemOps();
    ProcOps & procOps = getProcOps();

    do {

        attentions.clear();

        // enumerate the highest priority pending attention
        // on every chip and then give the entire set to PRD

        TargetHandleList::const_iterator pit = i_procs.end();

        while(pit-- != i_procs.begin())
        {
            // enumerate proc local attentions (xstp,spcl,rec).

            err = procOps.resolveIpoll(*pit, attentions);

            if(err)
            {
                errlCommit(err, ATTN_COMP_ID);
            }

            // enumerate host attentions and convert
            // to centaur targets

            err = memOps.resolve(*pit, attentions);

            if(err)
            {
                errlCommit(err, ATTN_COMP_ID);
            }
        }

        err = getPrdWrapper().callPrd(attentions);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }

        // unmask proc local attentions
        // (xstp,rec,special) in ipoll mask

        // any pending attentions will be found
        // on the next pass

        pit = i_procs.end();

        while(pit-- != i_procs.begin())
        {
            mutex_lock(&iv_mutex);

            // the other thread might be trying to mask
            // on the same target.  The mutex ensures
            // neither thread corrupts the register.

            err = modifyScom(
                    *pit,
                    IPOLL::address,
                    ~HostMask::nonHost(),
                    SCOM_AND);

            mutex_unlock(&iv_mutex);

            if(err)
            {
                errlCommit(err, ATTN_COMP_ID);
            }
        }

        // if on a given Centaur with a pending attention
        // on an MBA, an attention comes on in the other MBA
        // we don't get an interrupt for that.  So make another
        // pass and check for that.

    } while(!attentions.empty());
}
Exemplo n.º 2
0
void Service::processIntrQMsgPreAck(const msg_t & i_msg)
{
    // this function should do as little as possible
    // since the hw can't generate additional interrupts
    // until the msg is acknowledged

    TargetHandle_t proc = NULL;

    INTR::XISR_t xisr;

    xisr.u32 = i_msg.data[0];

    TargetHandleList procs;
    getTargetService().getAllChips(procs, TYPE_PROC);

    TargetHandleList::iterator it = procs.begin();

    // resolve the xisr to a proc target

    while(it != procs.end())
    {
        uint64_t node = 0, chip = 0;

        getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, *it, node);
        getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, *it, chip);

        if(node == xisr.node
                && chip == xisr.chip)
        {
            proc = *it;
            break;
        }

        ++it;
    }

    uint64_t hostMask = HostMask::host();
    uint64_t nonHostMask = HostMask::nonHost();
    uint64_t data = 0;

    // do the minimum that is required
    // for sending EOI without getting
    // another interrupt.  for host attentions
    // this is clearing the gpio interrupt
    // type status register
    // and for xstp,rec,spcl this is
    // masking the appropriate bit in
    // ipoll mask

    // read the ipoll status register
    // to determine the interrupt was
    // caused by host attn or something
    // else (xstp,rec,spcl)

    errlHndl_t err = getScom(proc, IPOLL_STATUS_REG, data);

    if(err)
    {
        errlCommit(err, ATTN_COMP_ID);

        // assume everything is on

        data = hostMask | nonHostMask;
    }

    if(data & hostMask)
    {
        // if host attention, clear the ITR macro gpio interrupt
        // type status register.

        err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }

    if(data & nonHostMask)
    {
        // mask local proc xstp,rec and/or special attns if on.

        // the other thread might be trying to unmask
        // on the same target.  The mutex ensures
        // neither thread corrupts the register.

        mutex_lock(&iv_mutex);

        err = modifyScom(proc, IPOLL::address, data & nonHostMask, SCOM_OR);

        mutex_unlock(&iv_mutex);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }
}
Exemplo n.º 3
0
void ServiceCommon::processAttnPreAck(const TargetHandle_t i_proc)
{
    uint64_t hostMask = HostMask::host();
    uint64_t nonHostMask = HostMask::nonHost();
    uint64_t data = 0;

    // do the minimum that is required
    // for sending EOI without getting
    // another interrupt.  for host attentions
    // this is clearing the gpio interrupt
    // type status register
    // and for xstp,rec,spcl this is
    // masking the appropriate bit in
    // ipoll mask

    // read the ipoll status register
    // to determine the interrupt was
    // caused by host attn or something
    // else (xstp,rec,spcl)

    errlHndl_t err = getScom(i_proc, IPOLL_STATUS_REG, data);

    if(err)
    {
        errlCommit(err, ATTN_COMP_ID);

        // assume everything is on

        data = hostMask | nonHostMask;
    }

    if(data & hostMask)
    {
        // if host attention, clear the ITR macro gpio interrupt
        // type status register.

        err = putScom(i_proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }

    if(data & nonHostMask)
    {
        // mask local proc xstp,rec and/or special attns if on.

        // the other thread might be trying to unmask
        // on the same target.  The mutex ensures
        // neither thread corrupts the register.

        mutex_lock(&iv_mutex);

        err = modifyScom(i_proc, IPOLL::address, data & nonHostMask, SCOM_OR);

        mutex_unlock(&iv_mutex);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
errlHndl_t ServiceCommon::configureInterrupts(
        ConfigureMode i_mode)
{
    errlHndl_t err = NULL;

    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;
    }

    return err;
}