[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in c
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode |
Date: |
Mon, 22 Aug 2011 19:12:12 +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>
CC: Avi Kivity <address@hidden>
Signed-off-by: Jan Kiszka <address@hidden>
---
hw/vga.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
hw/vga_int.h | 2 ++
2 files changed, 52 insertions(+), 1 deletions(-)
diff --git a/hw/vga.c b/hw/vga.c
index 432d2cb..851fd68 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -152,6 +152,48 @@ static void vga_screen_dump(void *opaque, const char
*filename);
static char *screen_dump_filename;
static DisplayChangeListener *screen_dump_dcl;
+static void vga_update_memory_access(VGACommonState *s)
+{
+ MemoryRegion *region, *old_region = s->chain4_alias;
+ target_phys_addr_t base, offset, size;
+
+ s->chain4_alias = NULL;
+
+ if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
+ offset = 0;
+ switch ((s->gr[6] >> 2) & 3) {
+ case 0:
+ base = 0xa0000;
+ size = 0x20000;
+ break;
+ case 1:
+ base = 0xa0000;
+ size = 0x10000;
+ offset = s->bank_offset;
+ break;
+ case 2:
+ base = 0xb0000;
+ size = 0x8000;
+ break;
+ case 3:
+ base = 0xb8000;
+ size = 0x8000;
+ break;
+ }
+ region = g_malloc(sizeof(*region));
+ memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
+ memory_region_add_subregion_overlap(s->legacy_address_space, base,
+ region, 2);
+ s->chain4_alias = region;
+ }
+ if (old_region) {
+ memory_region_del_subregion(s->legacy_address_space, old_region);
+ memory_region_destroy(old_region);
+ g_free(old_region);
+ s->plane_updated = 0xf;
+ }
+}
+
static void vga_dumb_update_retrace_info(VGACommonState *s)
{
(void) s;
@@ -445,6 +487,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;
@@ -472,6 +515,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:
@@ -605,6 +649,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) &&
@@ -664,6 +709,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:
{
@@ -1238,7 +1284,7 @@ static void vga_draw_text(VGACommonState *s, int
full_update)
s->font_offsets[1] = offset;
full_update = 1;
}
- if (s->plane_updated & (1 << 2)) {
+ if (s->plane_updated & (1 << 2) || s->chain4_alias) {
/* if the plane 2 was modified since the last display, it
indicates the font may have been modified */
s->plane_updated = 0;
@@ -1885,6 +1931,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)
@@ -2242,6 +2289,8 @@ void vga_init(VGACommonState *s, MemoryRegion
*address_space)
s->bank_offset = 0;
+ s->legacy_address_space = address_space;
+
vga_io_memory = vga_init_io(s);
memory_region_add_subregion_overlap(address_space,
isa_mem_base + 0x000a0000,
diff --git a/hw/vga_int.h b/hw/vga_int.h
index d2dd7dd..28b9287 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -105,11 +105,13 @@ typedef uint8_t (* vga_retrace_fn)(struct VGACommonState
*s);
typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
typedef struct VGACommonState {
+ MemoryRegion *legacy_address_space;
uint8_t *vram_ptr;
MemoryRegion vram;
uint32_t vram_size;
uint32_t latch;
uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */
+ MemoryRegion *chain4_alias;
uint8_t sr_index;
uint8_t sr[256];
uint8_t gr_index;
--
1.7.3.4
- [Qemu-devel] [PATCH v3 0/6] vga: dirty log cleanup, more linear mapping, Jan Kiszka, 2011/08/22
- [Qemu-devel] [PATCH v3 3/6] vmware-vga: Remove dead DIRECT_VRAM mode, Jan Kiszka, 2011/08/22
- [Qemu-devel] [PATCH v3 2/6] vmware-vga: Disable verbose mode, Jan Kiszka, 2011/08/22
- [Qemu-devel] [PATCH v3 1/6] vmware-vga: Register reset service, Jan Kiszka, 2011/08/22
- [Qemu-devel] [PATCH v3 6/6] vga: Drop some unused fields, Jan Kiszka, 2011/08/22
- [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode,
Jan Kiszka <=
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Avi Kivity, 2011/08/25
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Jan Kiszka, 2011/08/25
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Avi Kivity, 2011/08/25
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Jan Kiszka, 2011/08/25
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Avi Kivity, 2011/08/25
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Jan Kiszka, 2011/08/25
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Avi Kivity, 2011/08/25
- Re: [Qemu-devel] [PATCH v3 5/6] vga: Use linear mapping + dirty logging in chain 4 memory access mode, Jan Kiszka, 2011/08/25
[Qemu-devel] [PATCH v3 4/6] vmware-vga: Eliminate vga_dirty_log_restart, Jan Kiszka, 2011/08/22
Re: [Qemu-devel] [PATCH v3 0/6] vga: dirty log cleanup, more linear mapping, Anthony Liguori, 2011/08/22