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
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel