1 /* 2 * QEMU PowerPC sPAPR IRQ interface 3 * 4 * Copyright (c) 2018, IBM Corporation. 5 * 6 * This code is licensed under the GPL version 2 or later. See the 7 * COPYING file in the top-level directory. 8 */ 9 10 #include "qemu/osdep.h" 11 #include "qemu/log.h" 12 #include "qemu/error-report.h" 13 #include "qapi/error.h" 14 #include "hw/ppc/spapr.h" 15 #include "hw/ppc/xics.h" 16 17 void spapr_irq_msi_init(sPAPRMachineState *spapr, uint32_t nr_msis) 18 { 19 spapr->irq_map_nr = nr_msis; 20 spapr->irq_map = bitmap_new(spapr->irq_map_nr); 21 } 22 23 int spapr_irq_msi_alloc(sPAPRMachineState *spapr, uint32_t num, bool align, 24 Error **errp) 25 { 26 int irq; 27 28 /* 29 * The 'align_mask' parameter of bitmap_find_next_zero_area() 30 * should be one less than a power of 2; 0 means no 31 * alignment. Adapt the 'align' value of the former allocator 32 * to fit the requirements of bitmap_find_next_zero_area() 33 */ 34 align -= 1; 35 36 irq = bitmap_find_next_zero_area(spapr->irq_map, spapr->irq_map_nr, 0, num, 37 align); 38 if (irq == spapr->irq_map_nr) { 39 error_setg(errp, "can't find a free %d-IRQ block", num); 40 return -1; 41 } 42 43 bitmap_set(spapr->irq_map, irq, num); 44 45 return irq + SPAPR_IRQ_MSI; 46 } 47 48 void spapr_irq_msi_free(sPAPRMachineState *spapr, int irq, uint32_t num) 49 { 50 bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num); 51 } 52 53 void spapr_irq_msi_reset(sPAPRMachineState *spapr) 54 { 55 bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr); 56 } 57