@@ -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,
@@ -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 */
@@ -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;
@@ -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,
@@ -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]);
@@ -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);
@@ -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)
@@ -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;
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 <liwanp@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(-)