# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1215775980 -3600
# Node ID 657bdd581db2153b296b7302a9640fac4a7d6170
# Parent b41e07aa555a73b0d48e0fc92ed11b8994aa819f
ioemu: drop shadow vram
We can now actually drop the shadow vram entirely thanks to dirty page
tracking.
Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
tools/ioemu/hw/vga.c | 207 ++++++++++-----------------------------------------
1 files changed, 41 insertions(+), 166 deletions(-)
diff -r b41e07aa555a -r 657bdd581db2 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c Fri Jul 11 12:31:32 2008 +0100
+++ b/tools/ioemu/hw/vga.c Fri Jul 11 12:33:00 2008 +0100
@@ -1383,105 +1383,6 @@ void vga_invalidate_scanlines(VGAState *
}
}
-static inline int cmp_vram(VGAState *s, int offset, int n)
-{
- long *vp, *sp;
-
- if (s->vram_shadow == NULL)
- return 1;
- vp = (long *)(s->vram_ptr + offset);
- sp = (long *)(s->vram_shadow + offset);
- while ((n -= sizeof(*vp)) >= 0) {
- if (*vp++ != *sp++) {
- memcpy(sp - 1, vp - 1, n + sizeof(*vp));
- return 1;
- }
- }
- return 0;
-}
-
-#ifdef USE_SSE2
-
-#include <signal.h>
-#include <setjmp.h>
-#include <emmintrin.h>
-
-int sse2_ok = 1;
-
-static inline unsigned int cpuid_edx(unsigned int op)
-{
- unsigned int eax, edx;
-
-#ifdef __x86_64__
-#define __bx "rbx"
-#else
-#define __bx "ebx"
-#endif
- __asm__("push %%"__bx"; cpuid; pop %%"__bx
- : "=a" (eax), "=d" (edx)
- : "0" (op)
- : "cx");
-#undef __bx
-
- return edx;
-}
-
-jmp_buf sse_jbuf;
-
-void intr(int sig)
-{
- sse2_ok = 0;
- longjmp(sse_jbuf, 1);
-}
-
-void check_sse2(void)
-{
- /* Check 1: What does CPUID say? */
- if ((cpuid_edx(1) & 0x4000000) == 0) {
- sse2_ok = 0;
- return;
- }
-
- /* Check 2: Can we use SSE2 in anger? */
- signal(SIGILL, intr);
- if (setjmp(sse_jbuf) == 0)
- __asm__("xorps %xmm0,%xmm0\n");
-}
-
-int vram_dirty(VGAState *s, int offset, int n)
-{
- __m128i *sp, *vp;
-
- if (s->vram_shadow == NULL)
- return 1;
- if (sse2_ok == 0)
- return cmp_vram(s, offset, n);
- vp = (__m128i *)(s->vram_ptr + offset);
- sp = (__m128i *)(s->vram_shadow + offset);
- while ((n -= sizeof(*vp)) >= 0) {
- if (_mm_movemask_epi8(_mm_cmpeq_epi8(*sp, *vp)) != 0xffff) {
- while (n >= 0) {
- _mm_store_si128(sp++, _mm_load_si128(vp++));
- n -= sizeof(*vp);
- }
- return 1;
- }
- sp++;
- vp++;
- }
- return 0;
-}
-#else /* !USE_SSE2 */
-int vram_dirty(VGAState *s, int offset, int n)
-{
- return cmp_vram(s, offset, n);
-}
-
-void check_sse2(void)
-{
-}
-#endif /* !USE_SSE2 */
-
/*
* graphic modes
*/
@@ -1495,6 +1396,7 @@ static void vga_draw_graphic(VGAState *s
uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line;
ram_addr_t page_min, page_max;
+ unsigned long start, end;
full_update |= update_basic_params(s);
@@ -1609,69 +1511,51 @@ static void vga_draw_graphic(VGAState *s
width, height, v, line_offset, s->cr[9], s->cr[0x17],
s->line_compare, s->sr[0x01]);
#endif
- y = 0;
-
if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3
|| !s->lfb_addr) {
- /* Tricky things happen, disable dirty bit tracking */
- xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
-
- for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
- if (vram_dirty(s, y, TARGET_PAGE_SIZE))
- cpu_physical_memory_set_dirty(s->vram_offset + y);
+ /* Tricky things happen, just track all video memory */
+ start = 0;
+ end = s->vram_size;
} else {
/* Tricky things won't have any effect, i.e. we are in the very simple
* (and very usual) case of a linear buffer. */
- unsigned long end;
-
- for ( ; y < ((s->start_addr * 4) & TARGET_PAGE_MASK); y +=
TARGET_PAGE_SIZE)
- /* We will not read that anyway. */
- cpu_physical_memory_set_dirty(s->vram_offset + y);
-
- if (y < (s->start_addr * 4)) {
- /* start address not aligned on a page, track dirtyness by hand. */
- if (vram_dirty(s, y, TARGET_PAGE_SIZE))
- cpu_physical_memory_set_dirty(s->vram_offset + y);
- y += TARGET_PAGE_SIZE;
- }
-
- /* use page table dirty bit tracking for the inner of the LFB */
- end = s->start_addr * 4 + height * line_offset;
- {
- unsigned long npages = ((end & TARGET_PAGE_MASK) - y) /
TARGET_PAGE_SIZE;
- const int width = sizeof(unsigned long) * 8;
- unsigned long bitmap[(npages + width - 1) / width];
- int err;
-
- if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
- (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages,
bitmap))) {
- int i, j;
- for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
- unsigned long map = bitmap[i];
- for (j = i * width; map && j < npages; map >>= 1, j++)
- if (map & 1)
- cpu_physical_memory_set_dirty(s->vram_offset + y
- + j * TARGET_PAGE_SIZE);
- }
- y += npages * TARGET_PAGE_SIZE;
- } else {
- /* ENODATA just means we have changed mode and will succeed
- * next time */
- if (err != -ENODATA)
- fprintf(stderr, "track_dirty_vram(%lx, %lx) failed
(%d)\n", s->lfb_addr + y, npages, err);
+ /* use page table dirty bit tracking for the LFB plus border */
+ start = (s->start_addr * 4) & TARGET_PAGE_MASK;
+ end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE -
1) & TARGET_PAGE_MASK;
+ }
+
+ for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
+ /* We will not read that anyway. */
+ cpu_physical_memory_set_dirty(s->vram_offset + y);
+
+ {
+ unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
+ const int width = sizeof(unsigned long) * 8;
+ unsigned long bitmap[(npages + width - 1) / width];
+ int err;
+
+ if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
+ (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
+ int i, j;
+ for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
+ unsigned long map = bitmap[i];
+ for (j = i * width; map && j < npages; map >>= 1, j++)
+ if (map & 1)
+ cpu_physical_memory_set_dirty(s->vram_offset + y
+ + j * TARGET_PAGE_SIZE);
}
- }
-
- for ( ; y < s->vram_size && y < end; y += TARGET_PAGE_SIZE)
- /* failed or end address not aligned on a page, track dirtyness by
- * hand. */
- if (vram_dirty(s, y, TARGET_PAGE_SIZE))
- cpu_physical_memory_set_dirty(s->vram_offset + y);
-
- for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
- /* We will not read that anyway. */
- cpu_physical_memory_set_dirty(s->vram_offset + y);
- }
+ y += npages * TARGET_PAGE_SIZE;
+ } else {
+ /* ENODATA just means we have changed mode and will succeed
+ * next time */
+ if (err != -ENODATA)
+ fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n",
s->lfb_addr + y, npages, err);
+ }
+ }
+
+ for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
+ /* We will not read that anyway. */
+ cpu_physical_memory_set_dirty(s->vram_offset + y);
addr1 = (s->start_addr * 4);
bwidth = (width * bits + 7) / 8;
@@ -2140,16 +2024,7 @@ void vga_common_init(VGAState *s, Displa
vga_reset(s);
- check_sse2();
- s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
- if (s->vram_shadow == NULL)
- fprintf(stderr, "Cannot allocate %d bytes for VRAM shadow, "
- "mouse will be slow\n", vga_ram_size);
- s->vram_shadow = (uint8_t *)((long)(s->vram_shadow + TARGET_PAGE_SIZE - 1)
- & ~(TARGET_PAGE_SIZE - 1));
-
- /* Video RAM must be 128-bit aligned for SSE optimizations later */
- /* and page-aligned for PVFB memory sharing */
+ /* Video RAM must be page-aligned for PVFB memory sharing */
s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE,
vga_ram_size);
#ifdef CONFIG_STUBDOM
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|