convert RTC as piix3 proper QOM child. RTC 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/mc146818rtc.c | 29 +---------------------------- hw/mc146818rtc.h | 30 ++++++++++++++++++++++++++++++ hw/pc.c | 13 +++++++------ hw/piix3.c | 14 ++++++++++++++ hw/piix3.h | 5 +++++ 5 files changed, 57 insertions(+), 34 deletions(-) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 98839f2..f385f4c 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -56,33 +56,6 @@ #define RTC_CLOCK_RATE 32768 #define UIP_HOLD_LENGTH (8 * NSEC_PER_SEC / 32768) -typedef struct RTCState { - ISADevice dev; - MemoryRegion io; - uint8_t cmos_data[128]; - uint8_t cmos_index; - int32_t base_year; - uint64_t base_rtc; - uint64_t last_update; - int64_t offset; - qemu_irq irq; - qemu_irq sqw_irq; - int it_shift; - /* periodic timer */ - QEMUTimer *periodic_timer; - int64_t next_periodic_time; - /* update-ended timer */ - QEMUTimer *update_timer; - uint64_t next_alarm_time; - uint16_t irq_reinject_on_ack_count; - uint32_t irq_coalesced; - uint32_t period; - QEMUTimer *coalesced_timer; - Notifier clock_reset_notifier; - LostTickPolicy lost_tick_policy; - Notifier suspend_notifier; -} RTCState; - static void rtc_set_time(RTCState *s); static void rtc_update_time(RTCState *s); static void rtc_set_cmos(RTCState *s, const struct tm *tm); @@ -894,7 +867,7 @@ static void rtc_class_initfn(ObjectClass *klass, void *data) } static TypeInfo mc146818rtc_info = { - .name = "mc146818rtc", + .name = TYPE_RTC, .parent = TYPE_ISA_DEVICE, .instance_size = sizeof(RTCState), .class_init = rtc_class_initfn, diff --git a/hw/mc146818rtc.h b/hw/mc146818rtc.h index f286b6a..a8f1428 100644 --- a/hw/mc146818rtc.h +++ b/hw/mc146818rtc.h @@ -3,6 +3,36 @@ #include "isa.h" #include "mc146818rtc_regs.h" +#include "notify.h" + +#define TYPE_RTC "mc146818rtc" + +typedef struct RTCState { + ISADevice dev; + MemoryRegion io; + uint8_t cmos_data[128]; + uint8_t cmos_index; + int32_t base_year; + uint64_t base_rtc; + uint64_t last_update; + int64_t offset; + qemu_irq irq; + qemu_irq sqw_irq; + int it_shift; + /* periodic timer */ + QEMUTimer *periodic_timer; + int64_t next_periodic_time; + /* update-ended timer */ + QEMUTimer *update_timer; + uint64_t next_alarm_time; + uint16_t irq_reinject_on_ack_count; + uint32_t irq_coalesced; + uint32_t period; + QEMUTimer *coalesced_timer; + Notifier clock_reset_notifier; + LostTickPolicy lost_tick_policy; + Notifier suspend_notifier; +} RTCState; ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq); void rtc_set_memory(ISADevice *dev, int addr, int val); diff --git a/hw/pc.c b/hw/pc.c index c40e112..7fed363 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -90,6 +90,8 @@ struct e820_table { struct e820_entry entry[E820_NR_ENTRIES]; } QEMU_PACKED __attribute((__aligned__(4))); +qemu_irq rtc_irq; + static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; @@ -941,7 +943,6 @@ static void cpu_request_exit(void *opaque, int irq, int level) } static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, - ISADevice **rtc_state, ISADevice **floppy, bool no_vmport) { @@ -950,7 +951,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, DeviceState *hpet = NULL; int pit_isa_irq = 0; qemu_irq pit_alt_irq = NULL; - qemu_irq rtc_irq = NULL; qemu_irq *a20_line; ISADevice *i8042, *port92, *vmmouse, *pit = NULL; qemu_irq *cpu_exit_irq; @@ -977,9 +977,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT); } } - *rtc_state = rtc_init(isa_bus, 2000, rtc_irq); - - qemu_register_boot_set(pc_boot_set, *rtc_state); if (!xen_enabled()) { if (kvm_irqchip_in_kernel()) { @@ -1237,7 +1234,7 @@ static void pc_init1(MemoryRegion *system_memory, } /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled()); + pc_basic_device_init(isa_bus, gsi, &floppy, xen_enabled()); for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; @@ -1269,6 +1266,10 @@ static void pc_init1(MemoryRegion *system_memory, } } + /* FIXME */ + rtc_state = ISA_DEVICE(object_resolve_path("rtc", NULL)); + qemu_register_boot_set(pc_boot_set, rtc_state); + audio_init(isa_bus, pci_enabled ? pci_bus : NULL); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, diff --git a/hw/piix3.c b/hw/piix3.c index 7d4145f..a40c8cd 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -198,6 +198,17 @@ static int piix3_realize(PCIDevice *dev) s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); isa_bus_irqs(s->bus, s->pic); + /* Realize the RTC */ + qdev_set_parent_bus(DEVICE(&s->rtc), BUS(s->bus)); + qdev_init_nofail(DEVICE(&s->rtc)); + + /* Setup the RTC IRQ */ + if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { + s->rtc.irq = rtc_irq; + } else { + isa_init_irq(ISA_DEVICE(&s->rtc), &rtc_irq, RTC_ISA_IRQ); + } + return 0; } @@ -208,6 +219,9 @@ static void piix3_initfn(Object *obj) qdev_prop_set_int32(DEVICE(s), "addr", PCI_DEVFN(1, 0)); qdev_prop_set_bit(DEVICE(s), "multifunction", true); + object_initialize(&s->rtc, TYPE_RTC); + object_property_add_child(obj, "rtc", OBJECT(&s->rtc), NULL); + qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000); } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index 0fb04f2..23ee74a 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -30,6 +30,7 @@ #define QEMU_PIIX3_H #include "pci.h" +#include "mc146818rtc.h" #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */ @@ -58,6 +59,8 @@ typedef struct PIIX3State { ISABus *bus; + RTCState rtc; + qemu_irq *pic; /* This member isn't used. Just for save/load compatibility */ @@ -70,4 +73,6 @@ void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level); void piix3_set_irq(void *opaque, int pirq, int level); +extern qemu_irq rtc_irq; + #endif -- 1.7.7.6