diff --git a/hw/spapr.c b/hw/spapr.c index deb4ae5417..b1189755d3 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -61,6 +61,30 @@ sPAPREnvironment *spapr; +qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num) +{ + uint32_t irq; + qemu_irq qirq; + + if (hint) { + irq = hint; + /* FIXME: we should probably check for collisions somehow */ + } else { + irq = spapr->next_irq++; + } + + qirq = xics_find_qirq(spapr->icp, irq); + if (!qirq) { + return NULL; + } + + if (irq_num) { + *irq_num = irq; + } + + return qirq; +} + static void *spapr_create_fdt_skel(const char *cpu_model, target_phys_addr_t initrd_base, target_phys_addr_t initrd_size, @@ -372,6 +396,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, /* Set up Interrupt Controller */ spapr->icp = xics_system_init(XICS_IRQS); + spapr->next_irq = 16; /* Set up VIO bus */ spapr->vio_bus = spapr_vio_bus_init(); diff --git a/hw/spapr.h b/hw/spapr.h index 3d21b7a1cc..ec910de5b0 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -17,6 +17,7 @@ typedef struct sPAPREnvironment { long rtas_size; void *fdt_skel; target_ulong entry_point; + int next_irq; } sPAPREnvironment; #define H_SUCCESS 0 @@ -281,11 +282,7 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, target_ulong *args); -static inline qemu_irq spapr_find_qirq(sPAPREnvironment *spapr, - int irq_num) -{ - return xics_find_qirq(spapr->icp, irq_num); -} +qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num); static inline uint32_t rtas_ld(target_ulong phys, int n) { diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c index 0546ccb043..35818e18f1 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -600,7 +600,6 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo) { VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo; VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; - VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus); char *id; if (asprintf(&id, "%s@%x", info->dt_name, dev->reg) < 0) { @@ -608,10 +607,11 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo) } dev->qdev.id = id; - if (!dev->vio_irq_num) { - dev->vio_irq_num = bus->irq++; + + dev->qirq = spapr_allocate_irq(dev->vio_irq_num, &dev->vio_irq_num); + if (!dev->qirq) { + return -1; } - dev->qirq = spapr_find_qirq(spapr, dev->vio_irq_num); rtce_init(dev); @@ -666,7 +666,6 @@ VIOsPAPRBus *spapr_vio_bus_init(void) qbus = qbus_create(&spapr_vio_bus_info, dev, "spapr-vio"); bus = DO_UPCAST(VIOsPAPRBus, bus, qbus); - bus->irq = 16; /* hcall-vio */ spapr_register_hypercall(H_VIO_SIGNAL, h_vio_signal); diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h index 7eb5367653..4fe5f742c2 100644 --- a/hw/spapr_vio.h +++ b/hw/spapr_vio.h @@ -67,7 +67,6 @@ typedef struct VIOsPAPRDevice { typedef struct VIOsPAPRBus { BusState bus; - int irq; } VIOsPAPRBus; typedef struct {