From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LJsmo-0005jb-QO for qemu-devel@nongnu.org; Mon, 05 Jan 2009 11:58:42 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LJsmm-0005ik-Uu for qemu-devel@nongnu.org; Mon, 05 Jan 2009 11:58:42 -0500 Received: from [199.232.76.173] (port=37030 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LJsmm-0005ie-P6 for qemu-devel@nongnu.org; Mon, 05 Jan 2009 11:58:40 -0500 Received: from mx2.redhat.com ([66.187.237.31]:56369) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LJsml-000758-TR for qemu-devel@nongnu.org; Mon, 05 Jan 2009 11:58:40 -0500 From: Avi Kivity Date: Mon, 5 Jan 2009 18:58:34 +0200 Message-Id: <1231174714-24897-1-git-send-email-avi@redhat.com> Subject: [Qemu-devel] [PATCH] Add cirrus reset handler Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, blauwirbel@gmail.com 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 --- 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