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; }
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; }
static void ics_free(ICSState *ics, int srcno, int num) { int i; for (i = srcno; i < srcno + num; ++i) { if (ICS_IRQ_FREE(ics, i)) { trace_xics_ics_free_warn(ics - ics->icp->ics, i + ics->offset); } memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); } }
static void spapr_irq_free_xics(sPAPRMachineState *spapr, int irq, int num) { ICSState *ics = spapr->ics; uint32_t srcno = irq - ics->offset; int i; if (ics_valid_irq(ics, irq)) { trace_spapr_irq_free(0, irq, num); for (i = srcno; i < srcno + num; ++i) { if (ICS_IRQ_FREE(ics, i)) { trace_spapr_irq_free_warn(0, i); } memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); } } }
static int ics_find_free_block(ICSState *ics, int num, int alignnum) { int first, i; for (first = 0; first < ics->nr_irqs; first += alignnum) { if (num > (ics->nr_irqs - first)) { return -1; } for (i = first; i < first + num; ++i) { if (!ICS_IRQ_FREE(ics, i)) { break; } } if (i == (first + num)) { return first; } } return -1; }
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; }