convert IOAPIC as piix3 proper QOM child. IOAPIC creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function.
Signed-off-by: Wanpeng Li <liw...@linux.vnet.ibm.com> --- hw/ioapic.c | 2 +- hw/ioapic.h | 2 -- hw/ioapic_internal.h | 2 ++ hw/kvm/ioapic.c | 9 +-------- hw/pc.c | 30 ++---------------------------- hw/pc.h | 2 ++ hw/piix3.c | 38 ++++++++++++++++++++++++++++++++++++++ hw/piix3.h | 13 +++++++++++++ 8 files changed, 59 insertions(+), 39 deletions(-) diff --git a/hw/ioapic.c b/hw/ioapic.c index 7273095..927a099 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -245,7 +245,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data) } static TypeInfo ioapic_info = { - .name = "ioapic", + .name = TYPE_IOAPIC, .parent = TYPE_IOAPIC_COMMON, .instance_size = sizeof(IOAPICCommonState), .class_init = ioapic_class_init, diff --git a/hw/ioapic.h b/hw/ioapic.h index 86e63da..649dd0c 100644 --- a/hw/ioapic.h +++ b/hw/ioapic.h @@ -20,8 +20,6 @@ #ifndef HW_IOAPIC_H #define HW_IOAPIC_H -#define IOAPIC_NUM_PINS 24 - void ioapic_eoi_broadcast(int vector); #endif /* !HW_IOAPIC_H */ diff --git a/hw/ioapic_internal.h b/hw/ioapic_internal.h index e04c9f3..d3cb4c9 100644 --- a/hw/ioapic_internal.h +++ b/hw/ioapic_internal.h @@ -88,6 +88,8 @@ typedef struct IOAPICCommonClass { void (*post_load)(IOAPICCommonState *s); } IOAPICCommonClass; +#define IOAPIC_NUM_PINS 24 + struct IOAPICCommonState { SysBusDevice busdev; MemoryRegion io_memory; diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c index 6c3b8fe..e88843e 100644 --- a/hw/kvm/ioapic.c +++ b/hw/kvm/ioapic.c @@ -15,13 +15,6 @@ #include "hw/apic_internal.h" #include "kvm.h" -typedef struct KVMIOAPICState KVMIOAPICState; - -struct KVMIOAPICState { - IOAPICCommonState ioapic; - uint32_t kvm_gsi_base; -}; - static void kvm_ioapic_get(IOAPICCommonState *s) { struct kvm_irqchip chip; @@ -111,7 +104,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data) } static TypeInfo kvm_ioapic_info = { - .name = "kvm-ioapic", + .name = TYPE_KVM_IOAPIC, .parent = TYPE_IOAPIC_COMMON, .instance_size = sizeof(KVMIOAPICState), .class_init = kvm_ioapic_class_init, diff --git a/hw/pc.c b/hw/pc.c index 74cec55..31031fa 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -79,6 +79,8 @@ BusState *idebus[MAX_IDE_BUS]; +GSIState *gsi_state; + struct e820_entry { uint64_t address; uint64_t length; @@ -1011,30 +1013,6 @@ static void kvm_piix3_gsi_handler(void *opaque, int n, int level) } } -static void ioapic_init(GSIState *gsi_state) -{ - DeviceState *dev; - SysBusDevice *d; - unsigned int i; - - if (kvm_irqchip_in_kernel()) { - dev = qdev_create(NULL, "kvm-ioapic"); - } else { - dev = qdev_create(NULL, "ioapic"); - } - - /* FIXME: this should be under the piix3. */ - object_property_add_child(object_resolve_path("i440fx", NULL), - "ioapic", OBJECT(dev), NULL); - qdev_init_nofail(dev); - d = sysbus_from_qdev(dev); - sysbus_mmio_map(d, 0, 0xfec00000); - - for (i = 0; i < IOAPIC_NUM_PINS; i++) { - gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); - } -} - static PCIBus *i440fx_init(I440FXPMCState **pi440fx_state, int *piix3_devfn, ISABus **isa_bus, qemu_irq *pic, MemoryRegion *address_space_mem, @@ -1091,7 +1069,6 @@ static void pc_init1(MemoryRegion *system_memory, qemu_irq *gsi; qemu_irq *i8259; qemu_irq *smi_irq; - GSIState *gsi_state; ISADevice *rtc_state; ISADevice *floppy; @@ -1153,9 +1130,6 @@ static void pc_init1(MemoryRegion *system_memory, for (i = 0; i < ISA_NUM_IRQS; i++) { gsi_state->i8259_irq[i] = i8259[i]; } - if (pci_enabled) { - ioapic_init(gsi_state); - } pc_register_ferr_irq(gsi[13]); diff --git a/hw/pc.h b/hw/pc.h index 620349f..7f6ff93 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -54,6 +54,8 @@ typedef struct GSIState { qemu_irq ioapic_irq[IOAPIC_NUM_PINS]; } GSIState; +extern GSIState *gsi_state; + void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque); void vmmouse_get_data(uint32_t *data); void vmmouse_set_data(const uint32_t *data); diff --git a/hw/piix3.c b/hw/piix3.c index 7ca0f83..99b1ecc 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -203,6 +203,7 @@ static int piix3_realize(PCIDevice *dev) qemu_irq *a20_line; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; int i; + SysBusDevice *d; /* Initialize ISA Bus */ s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); @@ -313,6 +314,31 @@ static int piix3_realize(PCIDevice *dev) } } + /* Realize the IOAPIC */ + if (pci_is_enabled) { + if (kvm_irqchip_in_kernel()) { + qdev_set_parent_bus(DEVICE(&s->ioapic.kvm_ioapic), + sysbus_get_default()); + qdev_init_nofail(DEVICE(&s->ioapic.kvm_ioapic)); + d = sysbus_from_qdev(DEVICE(&s->ioapic.kvm_ioapic)); + sysbus_mmio_map(d, 0, 0xfec00000); + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + gsi_state->ioapic_irq[i] = qdev_get_gpio_in( + DEVICE(&s->ioapic.kvm_ioapic), i); + } + } else { + qdev_set_parent_bus(DEVICE(&s->ioapic.ioapic), + sysbus_get_default()); + qdev_init_nofail(DEVICE(&s->ioapic.ioapic)); + d = sysbus_from_qdev(DEVICE(&s->ioapic.ioapic)); + sysbus_mmio_map(d, 0, 0xfec00000); + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + gsi_state->ioapic_irq[i] = qdev_get_gpio_in( + DEVICE(&s->ioapic.ioapic), i); + } + } + } + return 0; } @@ -375,6 +401,18 @@ static void piix3_initfn(Object *obj) object_property_add_child(obj, "isa-ide", OBJECT(&s->ide.isa), NULL); } + + if (pci_is_enabled) { + if (kvm_irqchip_in_kernel()) { + object_initialize(&s->ioapic.kvm_ioapic, TYPE_KVM_IOAPIC); + object_property_add_child(obj, "kvm-ioapic", + OBJECT(&s->ioapic.kvm_ioapic), NULL); + } else { + object_initialize(&s->ioapic.ioapic, TYPE_IOAPIC); + object_property_add_child(obj, + "ioapic", OBJECT(&s->ioapic.ioapic), NULL); + } + } } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index 8916e4a..c6be9e6 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -38,6 +38,7 @@ #include "ps2.h" #include "console.h" #include "ide/pci.h" +#include "ioapic_internal.h" #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */ @@ -64,6 +65,9 @@ typedef struct KVMPITState { #define MAX_IDE_BUS 2 +#define TYPE_IOAPIC "ioapic" +#define TYPE_KVM_IOAPIC "kvm-ioapic" + typedef struct _VMMouseState { ISADevice dev; uint32_t queue[VMMOUSE_QUEUE_SIZE]; @@ -112,6 +116,11 @@ typedef struct ISAKBDState { MemoryRegion io[2]; } ISAKBDState; +typedef struct KVMIOAPICState { + IOAPICCommonState ioapic; + uint32_t kvm_gsi_base; +} KVMIOAPICState; + typedef struct PIIX3State { PCIDevice dev; @@ -148,6 +157,10 @@ typedef struct PIIX3State { ISAIDEState isa; PCIIDEState pci; } ide; + union { + IOAPICCommonState ioapic; + KVMIOAPICState kvm_ioapic; + } ioapic; qemu_irq *pic; -- 1.7.7.6