This patch refactors the in-kernel PIT to be a logically separate device.

Signed-off-by: Anthony Liguori <[EMAIL PROTECTED]>

diff --git a/qemu/hw/i8254.c b/qemu/hw/i8254.c
index e215f8b..bcd9dba 100644
--- a/qemu/hw/i8254.c
+++ b/qemu/hw/i8254.c
@@ -30,6 +30,9 @@
 
 //#define DEBUG_PIT
 
+#define PIT_SAVEVM_NAME "i8254"
+#define PIT_SAVEVM_VERSION 1
+
 #define RW_STATE_LSB 1
 #define RW_STATE_MSB 2
 #define RW_STATE_WORD0 3
@@ -414,78 +417,12 @@ static void pit_irq_timer(void *opaque)
     pit_irq_timer_update(s, s->next_transition_time);
 }
 
-#ifdef KVM_CAP_PIT
-
-static void kvm_kernel_pit_save_to_user(PITState *s)
-{
-    struct kvm_pit_state pit;
-    struct kvm_pit_channel_state *c;
-    struct PITChannelState *sc;
-    int i;
-
-    kvm_get_pit(kvm_context, &pit);
-
-    for (i = 0; i < 3; i++) {
-       c = &pit.channels[i];
-       sc = &s->channels[i];
-       sc->count = c->count;
-       sc->latched_count = c->latched_count;
-       sc->count_latched = c->count_latched;
-       sc->status_latched = c->status_latched;
-       sc->status = c->status;
-       sc->read_state = c->read_state;
-       sc->write_state = c->write_state;
-       sc->write_latch = c->write_latch;
-       sc->rw_mode = c->rw_mode;
-       sc->mode = c->mode;
-       sc->bcd = c->bcd;
-       sc->gate = c->gate;
-       sc->count_load_time = c->count_load_time;
-    }
-}
-
-static void kvm_kernel_pit_load_from_user(PITState *s)
-{
-    struct kvm_pit_state pit;
-    struct kvm_pit_channel_state *c;
-    struct PITChannelState *sc;
-    int i;
-
-    for (i = 0; i < 3; i++) {
-       c = &pit.channels[i];
-       sc = &s->channels[i];
-       c->count = sc->count;
-       c->latched_count = sc->latched_count;
-       c->count_latched = sc->count_latched;
-       c->status_latched = sc->status_latched;
-       c->status = sc->status;
-       c->read_state = sc->read_state;
-       c->write_state = sc->write_state;
-       c->write_latch = sc->write_latch;
-       c->rw_mode = sc->rw_mode;
-       c->mode = sc->mode;
-       c->bcd = sc->bcd;
-       c->gate = sc->gate;
-       c->count_load_time = sc->count_load_time;
-    }
-
-    kvm_set_pit(kvm_context, &pit);
-}
-
-#endif
-
 static void pit_save(QEMUFile *f, void *opaque)
 {
     PITState *pit = opaque;
     PITChannelState *s;
     int i;
 
-#ifdef KVM_CAP_PIT
-    if (kvm_enabled() && qemu_kvm_pit_in_kernel()) {
-        kvm_kernel_pit_save_to_user(pit);
-    }
-#endif
-
     for(i = 0; i < 3; i++) {
         s = &pit->channels[i];
         qemu_put_be32(f, s->count);
@@ -538,12 +475,6 @@ static int pit_load(QEMUFile *f, void *opaque, int 
version_id)
         }
     }
 
-#ifdef KVM_CAP_PIT
-    if (kvm_enabled() && qemu_kvm_pit_in_kernel()) {
-        kvm_kernel_pit_load_from_user(pit);
-    }
-#endif
-
     return 0;
 }
 
@@ -566,14 +497,13 @@ PITState *pit_init(int base, qemu_irq irq)
     PITState *pit = &pit_state;
     PITChannelState *s;
 
-    if (!kvm_enabled() || !qemu_kvm_pit_in_kernel()) {
-           s = &pit->channels[0];
-           /* the timer 0 is connected to an IRQ */
-           s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
-           s->irq = irq;
-    }
+    s = &pit->channels[0];
+    /* the timer 0 is connected to an IRQ */
+    s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
+    s->irq = irq;
 
-    register_savevm("i8254", base, 1, pit_save, pit_load, pit);
+    register_savevm(PIT_SAVEVM_NAME, base, PIT_SAVEVM_VERSION,
+                   pit_save, pit_load, pit);
 
     qemu_register_reset(pit_reset, pit);
     register_ioport_write(base, 4, 1, pit_ioport_write, pit);
@@ -583,3 +513,83 @@ PITState *pit_init(int base, qemu_irq irq)
 
     return pit;
 }
+
+#ifdef KVM_CAP_PIT
+
+static void kvm_pit_save(QEMUFile *f, void *opaque)
+{
+    PITState *s = opaque;
+    struct kvm_pit_state pit;
+    struct kvm_pit_channel_state *c;
+    struct PITChannelState *sc;
+    int i;
+
+    kvm_get_pit(kvm_context, &pit);
+
+    for (i = 0; i < 3; i++) {
+       c = &pit.channels[i];
+       sc = &s->channels[i];
+       sc->count = c->count;
+       sc->latched_count = c->latched_count;
+       sc->count_latched = c->count_latched;
+       sc->status_latched = c->status_latched;
+       sc->status = c->status;
+       sc->read_state = c->read_state;
+       sc->write_state = c->write_state;
+       sc->write_latch = c->write_latch;
+       sc->rw_mode = c->rw_mode;
+       sc->mode = c->mode;
+       sc->bcd = c->bcd;
+       sc->gate = c->gate;
+       sc->count_load_time = c->count_load_time;
+    }
+
+    pit_save(f, s);
+}
+
+static int kvm_pit_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PITState *s = opaque;
+    struct kvm_pit_state pit;
+    struct kvm_pit_channel_state *c;
+    struct PITChannelState *sc;
+    int i;
+
+    pit_load(f, s, version_id);
+
+    for (i = 0; i < 3; i++) {
+       c = &pit.channels[i];
+       sc = &s->channels[i];
+       c->count = sc->count;
+       c->latched_count = sc->latched_count;
+       c->count_latched = sc->count_latched;
+       c->status_latched = sc->status_latched;
+       c->status = sc->status;
+       c->read_state = sc->read_state;
+       c->write_state = sc->write_state;
+       c->write_latch = sc->write_latch;
+       c->rw_mode = sc->rw_mode;
+       c->mode = sc->mode;
+       c->bcd = sc->bcd;
+       c->gate = sc->gate;
+       c->count_load_time = sc->count_load_time;
+    }
+
+    kvm_set_pit(kvm_context, &pit);
+
+    return 0;
+}
+
+PITState *kvm_pit_init(int base, qemu_irq irq)
+{
+    PITState *pit = &pit_state;
+
+    register_savevm(PIT_SAVEVM_NAME, base, PIT_SAVEVM_VERSION,
+                   kvm_pit_save, kvm_pit_load, pit);
+
+    qemu_register_reset(pit_reset, pit);
+    pit_reset(pit);
+
+    return pit;
+}
+#endif
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 0d2e6c3..97b108a 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -983,7 +983,10 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
     if (pci_enabled) {
         ioapic = ioapic_init();
     }
-    pit = pit_init(0x40, i8259[0]);
+    if (kvm_enabled() && qemu_kvm_pit_in_kernel())
+       pit = kvm_pit_init(0x40, i8259[0]);
+    else
+       pit = pit_init(0x40, i8259[0]);
     pcspk_init(pit);
     if (pci_enabled) {
         pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index 453c641..fb6c07d 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -58,6 +58,10 @@ int pit_get_initial_count(PITState *pit, int channel);
 int pit_get_mode(PITState *pit, int channel);
 int pit_get_out(PITState *pit, int channel, int64_t current_time);
 
+/* i8254-kvm.c */
+
+PITState *kvm_pit_init(int base, qemu_irq irq);
+
 /* vmport.c */
 void vmport_init(CPUState *env);
 void vmport_register(unsigned char command, IOPortReadFunc *func, void 
*opaque);

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to