Esempio n. 1
0
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi, Error **errp)
{
    ICSState *ics = &icp->ics[src];
    int irq;

    if (irq_hint) {
        assert(src == xics_find_source(icp, irq_hint));
        if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
            error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
            return -1;
        }
        irq = irq_hint;
    } else {
        irq = ics_find_free_block(ics, 1, 1);
        if (irq < 0) {
            error_setg(errp, "can't allocate IRQ: no IRQ left");
            return -1;
        }
        irq += ics->offset;
    }

    ics_set_irq_type(ics, irq - ics->offset, lsi);
    trace_xics_alloc(src, irq);

    return irq;
}
Esempio n. 2
0
int xics_alloc(XICSState *icp, int src, int irq_hint, bool lsi)
{
    ICSState *ics = &icp->ics[src];
    int irq;

    if (irq_hint) {
        assert(src == xics_find_source(icp, irq_hint));
        if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
            trace_xics_alloc_failed_hint(src, irq_hint);
            return -1;
        }
        irq = irq_hint;
    } else {
        irq = ics_find_free_block(ics, 1, 1);
        if (irq < 0) {
            trace_xics_alloc_failed_no_left(src);
            return -1;
        }
        irq += ics->offset;
    }

    ics_set_irq_type(ics, irq - ics->offset, lsi);
    trace_xics_alloc(src, irq);

    return irq;
}
Esempio n. 3
0
/*
 * Allocate block of consequtive IRQs, returns a number of the first.
 * If align==true, aligns the first IRQ number to num.
 */
int xics_alloc_block(XICSState *icp, int src, int num, bool lsi, bool align)
{
    int i, first = -1;
    ICSState *ics = &icp->ics[src];

    assert(src == 0);
    /*
     * MSIMesage::data is used for storing VIRQ so
     * it has to be aligned to num to support multiple
     * MSI vectors. MSI-X is not affected by this.
     * The hint is used for the first IRQ, the rest should
     * be allocated continuously.
     */
    if (align) {
        assert((num == 1) || (num == 2) || (num == 4) ||
               (num == 8) || (num == 16) || (num == 32));
        first = ics_find_free_block(ics, num, num);
    } else {
        first = ics_find_free_block(ics, num, 1);
    }

    if (first >= 0) {
        for (i = first; i < first + num; ++i) {
            ics_set_irq_type(ics, i, lsi);
        }
    }
    first += ics->offset;

    trace_xics_alloc_block(src, first, num, lsi, align);

    return first;
}
Esempio n. 4
0
void xics_set_irq_type(XICSState *icp, int irq, bool lsi)
{
    int src = xics_find_source(icp, irq);
    ICSState *ics;

    assert(src >= 0);

    ics = &icp->ics[src];
    ics_set_irq_type(ics, irq - ics->offset, lsi);
}
Esempio n. 5
0
File: spapr_irq.c Progetto: aik/qemu
static int spapr_irq_claim_xics(sPAPRMachineState *spapr, int irq, bool lsi,
                                Error **errp)
{
    ICSState *ics = spapr->ics;

    assert(ics);

    if (!ics_valid_irq(ics, irq)) {
        error_setg(errp, "IRQ %d is invalid", irq);
        return -1;
    }

    if (!ICS_IRQ_FREE(ics, irq - ics->offset)) {
        error_setg(errp, "IRQ %d is not free", irq);
        return -1;
    }

    ics_set_irq_type(ics, irq - ics->offset, lsi);
    return 0;
}