qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Add cirrus reset handler


From: Avi Kivity
Subject: [Qemu-devel] [PATCH] Add cirrus reset handler
Date: Mon, 5 Jan 2009 18:58:34 +0200

The vga reset handler overwrites some cirrus registers, causing reboots
to corrupt cirrus state to the point that guests can only bring up 640x480
resolutions.

Fix by adding a dedicated cirrus reset handler (which calls the common vga
handler).

Signed-off-by: Avi Kivity <address@hidden>
---
 hw/cirrus_vga.c |  114 ++++++++++++++++++++++++++++++------------------------
 hw/vga.c        |    4 +-
 hw/vga_int.h    |    1 +
 3 files changed, 66 insertions(+), 53 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 83c5f40..f9ad479 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -287,6 +287,8 @@ typedef struct CirrusVGAState {
     int last_hw_cursor_y_end;
     int real_vram_size; /* XXX: suppress that */
     CPUWriteMemoryFunc **cirrus_linear_write;
+    int device_id;
+    int bustype;
 } CirrusVGAState;
 
 typedef struct PCICirrusVGAState {
@@ -3175,55 +3177,13 @@ static int cirrus_vga_load(QEMUFile *f, void *opaque, 
int version_id)
  *
  ***************************************/
 
-static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
+static void cirrus_reset(void *opaque)
 {
-    int i;
-    static int inited;
-
-    if (!inited) {
-        inited = 1;
-        for(i = 0;i < 256; i++)
-            rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
-        rop_to_index[CIRRUS_ROP_0] = 0;
-        rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
-        rop_to_index[CIRRUS_ROP_NOP] = 2;
-        rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
-        rop_to_index[CIRRUS_ROP_NOTDST] = 4;
-        rop_to_index[CIRRUS_ROP_SRC] = 5;
-        rop_to_index[CIRRUS_ROP_1] = 6;
-        rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
-        rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
-        rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
-        rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
-        rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
-        rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
-        rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
-        rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
-        rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
-    }
-
-    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
-
-    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
-    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
-    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
-    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
-    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
-    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
-    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
-
-    s->vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
-                                           cirrus_vga_mem_write, s);
-    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
-                                 s->vga_io_memory);
-    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+    CirrusVGAState *s = opaque;
 
+    vga_reset(s);
     s->sr[0x06] = 0x0f;
-    if (device_id == CIRRUS_ID_CLGD5446) {
+    if (s->device_id == CIRRUS_ID_CLGD5446) {
         /* 4MB 64 bit memory config, always PCI */
         s->sr[0x1F] = 0x2d;            // MemClock
         s->gr[0x18] = 0x0f;             // fastest memory configuration
@@ -3241,14 +3201,11 @@ static void cirrus_init_common(CirrusVGAState * s, int 
device_id, int is_pci)
     } else {
         s->sr[0x1F] = 0x22;            // MemClock
         s->sr[0x0F] = CIRRUS_MEMSIZE_2M;
-        if (is_pci)
-            s->sr[0x17] = CIRRUS_BUSTYPE_PCI;
-        else
-            s->sr[0x17] = CIRRUS_BUSTYPE_ISA;
+        s->sr[0x17] = s->bustype;
         s->real_vram_size = 2048 * 1024;
         s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
     }
-    s->cr[0x27] = device_id;
+    s->cr[0x27] = s->device_id;
 
     /* Win2K seems to assume that the pattern buffer is at 0xff
        initially ! */
@@ -3281,7 +3238,62 @@ static void cirrus_init_common(CirrusVGAState * s, int 
device_id, int is_pci)
     s->get_resolution = cirrus_get_resolution;
     s->cursor_invalidate = cirrus_cursor_invalidate;
     s->cursor_draw_line = cirrus_cursor_draw_line;
+}
+
+static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
+{
+    int i;
+    static int inited;
+
+    if (!inited) {
+        inited = 1;
+        for(i = 0;i < 256; i++)
+            rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
+        rop_to_index[CIRRUS_ROP_0] = 0;
+        rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
+        rop_to_index[CIRRUS_ROP_NOP] = 2;
+        rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
+        rop_to_index[CIRRUS_ROP_NOTDST] = 4;
+        rop_to_index[CIRRUS_ROP_SRC] = 5;
+        rop_to_index[CIRRUS_ROP_1] = 6;
+        rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
+        rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
+        rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
+        rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
+        rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
+        rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
+        rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
+        rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
+        rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
+        s->device_id = device_id;
+        if (is_pci)
+            s->bustype = CIRRUS_BUSTYPE_PCI;
+        else
+            s->bustype = CIRRUS_BUSTYPE_ISA;
+    }
+
+    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
+
+    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
+    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
+
+    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
+
+    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
+    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
+
+    s->vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read,
+                                           cirrus_vga_mem_write, s);
+    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
+                                 s->vga_io_memory);
+    qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
 
+    qemu_register_reset(cirrus_reset, s);
+    cirrus_reset(s);
     register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s);
 }
 
diff --git a/hw/vga.c b/hw/vga.c
index 8021207..bf84c24 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1839,7 +1839,7 @@ static void vga_invalidate_display(void *opaque)
     s->last_height = -1;
 }
 
-static void vga_reset(void *opaque)
+void vga_reset(void *opaque)
 {
     VGAState *s = (VGAState *) opaque;
 
@@ -2277,7 +2277,6 @@ void vga_common_init(VGAState *s, DisplayState *ds, 
uint8_t *vga_ram_base,
         s->update_retrace_info = vga_precise_update_retrace_info;
         break;
     }
-    qemu_register_reset(vga_reset, s);
     vga_reset(s);
 }
 
@@ -2286,6 +2285,7 @@ void vga_init(VGAState *s)
 {
     int vga_io_memory;
 
+    qemu_register_reset(vga_reset, s);
     register_savevm("vga", 0, 2, vga_save, vga_load, s);
 
     register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 0c6ae7e..39b7367 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -193,6 +193,7 @@ static inline int c6_to_8(int v)
 void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
                      ram_addr_t vga_ram_offset, int vga_ram_size);
 void vga_init(VGAState *s);
+void vga_reset(void *s);
 
 void vga_dirty_log_start(VGAState *s);
 void vga_dirty_log_stop(VGAState *s);
-- 
1.6.0.6





reply via email to

[Prev in Thread] Current Thread [Next in Thread]