[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 13/13] vga: Use linear mapping + dirty logging in ch
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH 13/13] vga: Use linear mapping + dirty logging in chain 4 memory access mode |
Date: |
Tue, 14 Jun 2011 18:53:42 +0200 |
Most VGA memory access modes require MMIO handling as they demand weird
logic to get a byte from or into the video RAM. However, there is one
exception: chain 4 mode with all memory planes enabled for writing. This
mode actually allows lineary mapping, which can then be combined with
dirty logging to accelerate KVM.
This patch accelerates specifically VBE accesses like they are used by
grub in graphical mode. Not only the standard VGA adapter benefits from
this, also vmware and spice in VGA mode.
CC: Gerd Hoffmann <address@hidden>
Signed-off-by: Jan Kiszka <address@hidden>
---
hw/cirrus_vga.c | 1 +
hw/vga.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++---
hw/vga_int.h | 2 +
3 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 54a730d..babb816 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2516,6 +2516,7 @@ static void map_linear_vram(CirrusVGAState *s)
cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
s->vga.vga_io_memory);
s->vga.vga_mem_mapped = false;
+ s->vga.vga_memory_map_mode = 1;
}
}
diff --git a/hw/vga.c b/hw/vga.c
index 4208151..6eef149 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -159,7 +159,13 @@ static void vga_sync_dirty_bitmap(VGACommonState *s)
}
if (s->vga_mem_mapped) {
cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
- cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
+ if (s->vga_memory_map_mode <= 1) {
+ cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
+ if (s->vga_memory_map_mode == 0) {
+ cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xb0000,
+ 0xc0000);
+ }
+ }
}
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_mapped) {
@@ -170,6 +176,61 @@ static void vga_sync_dirty_bitmap(VGACommonState *s)
#endif
}
+static void vga_update_memory_access(VGACommonState *s)
+{
+ target_phys_addr_t offset, io_size;
+ uint8_t memory_map_mode;
+
+ if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
+ memory_map_mode = (s->gr[6] >> 2) & 3;
+ if (s->vga_mem_mapped && memory_map_mode == s->vga_memory_map_mode &&
+ s->bank_offset == s->vga_bank_offs_mapped) {
+ return;
+ }
+ vga_sync_dirty_bitmap(s);
+ s->vga_mem_mapped = true;
+ s->vga_memory_map_mode = memory_map_mode;
+ s->vga_bank_offs_mapped = s->bank_offset;
+
+ if (memory_map_mode <= 1) {
+ if (memory_map_mode == 0) {
+ offset = 0;
+ cpu_register_physical_memory_log(isa_mem_base + 0xb0000,
+ 0x10000,
+ (s->vram_offset + 0x10000) |
+ IO_MEM_RAM, 0, true);
+ io_size = 0;
+ } else {
+ offset = s->bank_offset;
+ io_size = 0x10000;
+ }
+ cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000,
+ (s->vram_offset + offset) |
+ IO_MEM_RAM, 0, true);
+ offset += 0x8000;
+ cpu_register_physical_memory_log(isa_mem_base + 0xa8000, 0x8000,
+ (s->vram_offset + offset) |
+ IO_MEM_RAM, 0, true);
+ } else {
+ offset = (memory_map_mode == 2) ? 0xb0000 : 0xb8000;
+ cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000,
+ (s->vram_offset + offset) |
+ IO_MEM_RAM, 0, true);
+ io_size = 0x18000;
+ }
+ if (io_size > 0) {
+ cpu_register_physical_memory(isa_mem_base + 0xc0000 - io_size,
+ io_size, s->vga_io_memory);
+ }
+ } else if (s->vga_mem_mapped) {
+ vga_sync_dirty_bitmap(s);
+ s->vga_mem_mapped = false;
+ s->plane_updated = 0xf;
+ cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
+ s->vga_io_memory);
+ }
+}
+
static void vga_dumb_update_retrace_info(VGACommonState *s)
{
(void) s;
@@ -463,6 +524,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t
val)
#endif
s->sr[s->sr_index] = val & sr_mask[s->sr_index];
if (s->sr_index == 1) s->update_retrace_info(s);
+ vga_update_memory_access(s);
break;
case 0x3c7:
s->dac_read_index = val;
@@ -490,6 +552,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t
val)
printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
#endif
s->gr[s->gr_index] = val & gr_mask[s->gr_index];
+ vga_update_memory_access(s);
break;
case 0x3b4:
case 0x3d4:
@@ -623,6 +686,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t
addr, uint32_t val)
}
s->vbe_regs[s->vbe_index] = val;
s->bank_offset = (val << 16);
+ vga_update_memory_access(s);
break;
case VBE_DISPI_INDEX_ENABLE:
if ((val & VBE_DISPI_ENABLED) &&
@@ -682,6 +746,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t
addr, uint32_t val)
}
s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
s->vbe_regs[s->vbe_index] = val;
+ vga_update_memory_access(s);
break;
case VBE_DISPI_INDEX_VIRT_WIDTH:
{
@@ -1924,6 +1989,7 @@ void vga_common_reset(VGACommonState *s)
memset(&s->retrace_info, 0, sizeof (s->retrace_info));
break;
}
+ vga_update_memory_access(s);
}
static void vga_reset(void *opaque)
@@ -2255,15 +2321,13 @@ int vga_init_io(VGACommonState *s)
void vga_init(VGACommonState *s)
{
- int vga_io_memory;
-
qemu_register_reset(vga_reset, s);
s->bank_offset = 0;
- vga_io_memory = vga_init_io(s);
+ s->vga_io_memory = vga_init_io(s);
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- vga_io_memory);
+ s->vga_io_memory);
qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
}
diff --git a/hw/vga_int.h b/hw/vga_int.h
index a6ea93c..dd8a283 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -112,6 +112,8 @@ typedef struct VGACommonState {
uint32_t map_addr;
uint32_t map_end;
bool vga_mem_mapped; /* whether 0xa0000..0xbffff is mapped as RAM */
+ int vga_memory_map_mode;
+ int32_t vga_bank_offs_mapped;
uint32_t latch;
uint8_t sr_index;
uint8_t sr[256];
--
1.7.1
- [Qemu-devel] [PATCH 00/13] vga: dirty log cleanup, more linear mapping, Jan Kiszka, 2011/06/14
- [Qemu-devel] [PATCH 04/13] vmware-vga: Disable verbose mode, Jan Kiszka, 2011/06/14
- [Qemu-devel] [PATCH 06/13] vmware-vga: Eliminate vga_dirty_log_restart, Jan Kiszka, 2011/06/14
- [Qemu-devel] [PATCH 13/13] vga: Use linear mapping + dirty logging in chain 4 memory access mode,
Jan Kiszka <=
- [Qemu-devel] [PATCH 05/13] vmware-vga: Remove dead DIRECT_VRAM mode, Jan Kiszka, 2011/06/14
- [Qemu-devel] [PATCH 08/13] vmware-vga: Register reset service, Jan Kiszka, 2011/06/14
- [Qemu-devel] [PATCH 09/13] vmware-vga: Use cpu_register_physical_memory_log for dirty log enabling, Jan Kiszka, 2011/06/14
- [Qemu-devel] [PATCH 07/13] vmware_vga: Do not enable dirty logging when in SVGA mode, Jan Kiszka, 2011/06/14
- [Qemu-devel] [PATCH 01/13] spice: Use cpu_register_physical_memory_log for dirty log enabling, Jan Kiszka, 2011/06/14