[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] ioemu: drop shadow vram
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |