convert PIT as piix3 proper QOM child. PIT 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: Anthony Liguori <aligu...@us.ibm.com> Signed-off-by: Wanpeng Li <liw...@linux.vnet.ibm.com> --- hw/i8254.c | 2 +- hw/i8254_internal.h | 3 ++- hw/kvm/i8254.c | 8 +------- hw/pc.c | 18 +----------------- hw/piix3.c | 34 ++++++++++++++++++++++++++++++++++ hw/piix3.h | 15 +++++++++++++++ 6 files changed, 54 insertions(+), 26 deletions(-) diff --git a/hw/i8254.c b/hw/i8254.c index bea5f92..8d3616d 100644 --- a/hw/i8254.c +++ b/hw/i8254.c @@ -348,7 +348,7 @@ static void pit_class_initfn(ObjectClass *klass, void *data) } static TypeInfo pit_info = { - .name = "isa-pit", + .name = TYPE_PIT, .parent = TYPE_PIT_COMMON, .instance_size = sizeof(PITCommonState), .class_init = pit_class_initfn, diff --git a/hw/i8254_internal.h b/hw/i8254_internal.h index 686f0c2..1aecad3 100644 --- a/hw/i8254_internal.h +++ b/hw/i8254_internal.h @@ -26,7 +26,6 @@ #define QEMU_I8254_INTERNAL_H #include "hw.h" -#include "pc.h" #include "isa.h" typedef struct PITChannelState { @@ -57,6 +56,8 @@ typedef struct PITCommonState { PITChannelState channels[3]; } PITCommonState; +#define TYPE_KVM_PIT "kvm-pit" +#define TYPE_PIT "isa-pit" #define TYPE_PIT_COMMON "pit-common" #define PIT_COMMON(obj) \ OBJECT_CHECK(PITCommonState, (obj), TYPE_PIT_COMMON) diff --git a/hw/kvm/i8254.c b/hw/kvm/i8254.c index 53d13e3..9f8fb7c 100644 --- a/hw/kvm/i8254.c +++ b/hw/kvm/i8254.c @@ -27,18 +27,12 @@ #include "hw/i8254.h" #include "hw/i8254_internal.h" #include "kvm.h" +#include "hw/piix3.h" #define KVM_PIT_REINJECT_BIT 0 #define CALIBRATION_ROUNDS 3 -typedef struct KVMPITState { - PITCommonState pit; - LostTickPolicy lost_tick_policy; - bool vm_stopped; - int64_t kernel_clock_offset; -} KVMPITState; - static int64_t abs64(int64_t v) { return v < 0 ? -v : v; diff --git a/hw/pc.c b/hw/pc.c index 7105f4e..80b437f 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -946,30 +946,14 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, { int i; DriveInfo *fd[MAX_FD]; - DeviceState *hpet = NULL; - int pit_isa_irq = 0; - qemu_irq pit_alt_irq = NULL; qemu_irq *a20_line; - ISADevice *i8042, *port92, *vmmouse, *pit = NULL; + ISADevice *i8042, *port92, *vmmouse; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); - if (!xen_enabled()) { - if (kvm_irqchip_in_kernel()) { - pit = kvm_pit_init(isa_bus, 0x40); - } else { - pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq); - } - if (hpet) { - /* connect PIT to output control line of the HPET */ - qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(&pit->qdev, 0)); - } - pcspk_init(isa_bus, pit); - } - for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { serial_isa_init(isa_bus, i, serial_hds[i]); diff --git a/hw/piix3.c b/hw/piix3.c index 5fe41cd..41739bd 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -194,6 +194,8 @@ static int piix3_realize(PCIDevice *dev) { PIIX3State *s = PIIX3(dev); qemu_irq rtc_irq; + int pit_isa_irq = 0; + qemu_irq pit_alt_irq = NULL; /* Initialize ISA Bus */ s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); @@ -222,6 +224,8 @@ static int piix3_realize(PCIDevice *dev) sysbus_connect_irq(SYS_BUS_DEVICE(&s->hpet), i, s->pic[i]); } + pit_isa_irq = -1; + pit_alt_irq = qdev_get_gpio_in(DEVICE(&s->hpet), HPET_LEGACY_PIT_INT); rtc_irq = qdev_get_gpio_in(DEVICE(&s->hpet), HPET_LEGACY_RTC_INT); } else { isa_init_irq(ISA_DEVICE(&s->rtc), &rtc_irq, RTC_ISA_IRQ); @@ -230,6 +234,23 @@ static int piix3_realize(PCIDevice *dev) /* Setup the RTC IRQ */ s->rtc.irq = rtc_irq; + /* Realize the PIT */ + if (!xen_enabled()) { + if (kvm_irqchip_in_kernel()) { + qdev_set_parent_bus(DEVICE(&s->pit.kvm_pit), BUS(s->bus)); + qdev_init_nofail(DEVICE(&s->pit.kvm_pit)); + qdev_connect_gpio_out(DEVICE(&s->hpet), 0, + qdev_get_gpio_in(DEVICE(&s->pit.kvm_pit), 0)); + } else { + qdev_set_parent_bus(DEVICE(&s->pit), BUS(s->bus)); + qdev_init_nofail(DEVICE(&s->pit)); + qdev_connect_gpio_out(DEVICE(&s->pit), 0, pit_isa_irq >= 0 ? + isa_get_irq(ISA_DEVICE(&s->pit), pit_isa_irq) : pit_alt_irq); + qdev_connect_gpio_out(DEVICE(&s->hpet), 0, + qdev_get_gpio_in(DEVICE(&s->pit), 0)); + } + } + return 0; } @@ -246,6 +267,19 @@ static void piix3_initfn(Object *obj) object_initialize(&s->hpet, TYPE_HPET); object_property_add_child(obj, "hpet", OBJECT(&s->hpet), NULL); + + if (!xen_enabled()) { + if (kvm_irqchip_in_kernel()) { + object_initialize(&s->pit.kvm_pit, TYPE_KVM_PIT); + object_property_add_child(obj, "kvm-pit", + OBJECT(&s->pit.kvm_pit), NULL); + qdev_prop_set_int32(DEVICE(&s->pit.kvm_pit), "iobase", 0x40); + } else { + object_initialize(&s->pit, TYPE_PIT); + object_property_add_child(obj, "pit", OBJECT(&s->pit), NULL); + qdev_prop_set_int32(DEVICE(&s->pit), "iobase", 0x40); + } + } } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index ef22c03..58486b9 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -32,6 +32,8 @@ #include "pci.h" #include "mc146818rtc.h" #include "hpet_emul.h" +#include "i8254.h" +#include "i8254_internal.h" #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */ @@ -41,6 +43,13 @@ #define TYPE_PIIX3 "PIIX3" #define PIIX3(obj) OBJECT_CHECK(PIIX3State, (obj), TYPE_PIIX3) +typedef struct KVMPITState { + PITCommonState pit; + LostTickPolicy lost_tick_policy; + bool vm_stopped; + int64_t kernel_clock_offset; +} KVMPITState; + typedef struct PIIX3State { PCIDevice dev; @@ -62,6 +71,12 @@ typedef struct PIIX3State { RTCState rtc; HPETState hpet; +#if !defined(CONFIG_XEN_BACKEND) && defined(CONFIG_NO_XEN) + union { + PITCommonState pit; + KVMPITState kvm_pit; + } pit; +#endif qemu_irq *pic; -- 1.7.7.6