debuggers.hg

changeset 18066:657bdd581db2

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@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jul 11 12:33:00 2008 +0100 (2008-07-11)
parents b41e07aa555a
children 1699ae3e57dc
files tools/ioemu/hw/vga.c
line diff
     1.1 --- a/tools/ioemu/hw/vga.c	Fri Jul 11 12:31:32 2008 +0100
     1.2 +++ b/tools/ioemu/hw/vga.c	Fri Jul 11 12:33:00 2008 +0100
     1.3 @@ -1383,105 +1383,6 @@ void vga_invalidate_scanlines(VGAState *
     1.4      }
     1.5  }
     1.6  
     1.7 -static inline int cmp_vram(VGAState *s, int offset, int n)
     1.8 -{
     1.9 -    long *vp, *sp;
    1.10 -
    1.11 -    if (s->vram_shadow == NULL)
    1.12 -        return 1;
    1.13 -    vp = (long *)(s->vram_ptr + offset);
    1.14 -    sp = (long *)(s->vram_shadow + offset);
    1.15 -    while ((n -= sizeof(*vp)) >= 0) {
    1.16 -        if (*vp++ != *sp++) {
    1.17 -            memcpy(sp - 1, vp - 1, n + sizeof(*vp));
    1.18 -            return 1;
    1.19 -        }
    1.20 -    }
    1.21 -    return 0;
    1.22 -}
    1.23 -
    1.24 -#ifdef USE_SSE2
    1.25 -
    1.26 -#include <signal.h>
    1.27 -#include <setjmp.h>
    1.28 -#include <emmintrin.h>
    1.29 -
    1.30 -int sse2_ok = 1;
    1.31 -
    1.32 -static inline unsigned int cpuid_edx(unsigned int op)
    1.33 -{
    1.34 -    unsigned int eax, edx;
    1.35 -
    1.36 -#ifdef __x86_64__
    1.37 -#define __bx "rbx"
    1.38 -#else
    1.39 -#define __bx "ebx"
    1.40 -#endif
    1.41 -    __asm__("push %%"__bx"; cpuid; pop %%"__bx
    1.42 -            : "=a" (eax), "=d" (edx)
    1.43 -            : "0" (op)
    1.44 -            : "cx");
    1.45 -#undef __bx
    1.46 -
    1.47 -    return edx;
    1.48 -}
    1.49 -
    1.50 -jmp_buf sse_jbuf;
    1.51 -
    1.52 -void intr(int sig)
    1.53 -{
    1.54 -    sse2_ok = 0;
    1.55 -    longjmp(sse_jbuf, 1);
    1.56 -}
    1.57 -
    1.58 -void check_sse2(void)
    1.59 -{
    1.60 -    /* Check 1: What does CPUID say? */
    1.61 -    if ((cpuid_edx(1) & 0x4000000) == 0) {
    1.62 -        sse2_ok = 0;
    1.63 -        return;
    1.64 -    }
    1.65 -
    1.66 -    /* Check 2: Can we use SSE2 in anger? */
    1.67 -    signal(SIGILL, intr);
    1.68 -    if (setjmp(sse_jbuf) == 0)
    1.69 -        __asm__("xorps %xmm0,%xmm0\n");
    1.70 -}
    1.71 -
    1.72 -int vram_dirty(VGAState *s, int offset, int n)
    1.73 -{
    1.74 -    __m128i *sp, *vp;
    1.75 -
    1.76 -    if (s->vram_shadow == NULL)
    1.77 -        return 1;
    1.78 -    if (sse2_ok == 0)
    1.79 -        return cmp_vram(s, offset, n);
    1.80 -    vp = (__m128i *)(s->vram_ptr + offset);
    1.81 -    sp = (__m128i *)(s->vram_shadow + offset);
    1.82 -    while ((n -= sizeof(*vp)) >= 0) {
    1.83 -        if (_mm_movemask_epi8(_mm_cmpeq_epi8(*sp, *vp)) != 0xffff) {
    1.84 -            while (n >= 0) {
    1.85 -                _mm_store_si128(sp++, _mm_load_si128(vp++));
    1.86 -                n -= sizeof(*vp);
    1.87 -            }
    1.88 -            return 1;
    1.89 -        }
    1.90 -        sp++;
    1.91 -        vp++;
    1.92 -    }
    1.93 -    return 0;
    1.94 -}
    1.95 -#else /* !USE_SSE2 */
    1.96 -int vram_dirty(VGAState *s, int offset, int n)
    1.97 -{
    1.98 -    return cmp_vram(s, offset, n);
    1.99 -}
   1.100 -
   1.101 -void check_sse2(void)
   1.102 -{
   1.103 -}
   1.104 -#endif /* !USE_SSE2 */
   1.105 -
   1.106  /* 
   1.107   * graphic modes
   1.108   */
   1.109 @@ -1495,6 +1396,7 @@ static void vga_draw_graphic(VGAState *s
   1.110      uint32_t v, addr1, addr;
   1.111      vga_draw_line_func *vga_draw_line;
   1.112      ram_addr_t page_min, page_max;
   1.113 +    unsigned long start, end;
   1.114  
   1.115      full_update |= update_basic_params(s);
   1.116  
   1.117 @@ -1609,69 +1511,51 @@ static void vga_draw_graphic(VGAState *s
   1.118             width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
   1.119  #endif
   1.120  
   1.121 -    y = 0;
   1.122 -
   1.123      if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3
   1.124              || !s->lfb_addr) {
   1.125 -        /* Tricky things happen, disable dirty bit tracking */
   1.126 -        xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
   1.127 -
   1.128 -        for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
   1.129 -            if (vram_dirty(s, y, TARGET_PAGE_SIZE))
   1.130 -                cpu_physical_memory_set_dirty(s->vram_offset + y);
   1.131 +        /* Tricky things happen, just track all video memory */
   1.132 +        start = 0;
   1.133 +        end = s->vram_size;
   1.134      } else {
   1.135          /* Tricky things won't have any effect, i.e. we are in the very simple
   1.136           * (and very usual) case of a linear buffer. */
   1.137 -        unsigned long end;
   1.138 -
   1.139 -        for ( ; y < ((s->start_addr * 4) & TARGET_PAGE_MASK); y += TARGET_PAGE_SIZE)
   1.140 -            /* We will not read that anyway. */
   1.141 -            cpu_physical_memory_set_dirty(s->vram_offset + y);
   1.142 +        /* use page table dirty bit tracking for the LFB plus border */
   1.143 +        start = (s->start_addr * 4) & TARGET_PAGE_MASK;
   1.144 +        end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
   1.145 +    }
   1.146  
   1.147 -        if (y < (s->start_addr * 4)) {
   1.148 -            /* start address not aligned on a page, track dirtyness by hand. */
   1.149 -            if (vram_dirty(s, y, TARGET_PAGE_SIZE))
   1.150 -                cpu_physical_memory_set_dirty(s->vram_offset + y);
   1.151 -            y += TARGET_PAGE_SIZE;
   1.152 -        }
   1.153 +    for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
   1.154 +        /* We will not read that anyway. */
   1.155 +        cpu_physical_memory_set_dirty(s->vram_offset + y);
   1.156  
   1.157 -        /* use page table dirty bit tracking for the inner of the LFB */
   1.158 -        end = s->start_addr * 4 + height * line_offset;
   1.159 -        {
   1.160 -            unsigned long npages = ((end & TARGET_PAGE_MASK) - y) / TARGET_PAGE_SIZE;
   1.161 -            const int width = sizeof(unsigned long) * 8;
   1.162 -            unsigned long bitmap[(npages + width - 1) / width];
   1.163 -            int err;
   1.164 +    {
   1.165 +        unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
   1.166 +        const int width = sizeof(unsigned long) * 8;
   1.167 +        unsigned long bitmap[(npages + width - 1) / width];
   1.168 +        int err;
   1.169  
   1.170 -            if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
   1.171 -                        (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
   1.172 -                int i, j;
   1.173 -                for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
   1.174 -                    unsigned long map = bitmap[i];
   1.175 -                    for (j = i * width; map && j < npages; map >>= 1, j++)
   1.176 -                        if (map & 1)
   1.177 -                            cpu_physical_memory_set_dirty(s->vram_offset + y
   1.178 -                                + j * TARGET_PAGE_SIZE);
   1.179 -                }
   1.180 -                y += npages * TARGET_PAGE_SIZE;
   1.181 -            } else {
   1.182 -                /* ENODATA just means we have changed mode and will succeed
   1.183 -                 * next time */
   1.184 -                if (err != -ENODATA)
   1.185 -                    fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n", s->lfb_addr + y, npages, err);
   1.186 +        if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
   1.187 +                    (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
   1.188 +            int i, j;
   1.189 +            for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
   1.190 +                unsigned long map = bitmap[i];
   1.191 +                for (j = i * width; map && j < npages; map >>= 1, j++)
   1.192 +                    if (map & 1)
   1.193 +                        cpu_physical_memory_set_dirty(s->vram_offset + y
   1.194 +                            + j * TARGET_PAGE_SIZE);
   1.195              }
   1.196 +            y += npages * TARGET_PAGE_SIZE;
   1.197 +        } else {
   1.198 +            /* ENODATA just means we have changed mode and will succeed
   1.199 +             * next time */
   1.200 +            if (err != -ENODATA)
   1.201 +                fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n", s->lfb_addr + y, npages, err);
   1.202          }
   1.203 +    }
   1.204  
   1.205 -        for ( ; y < s->vram_size && y < end; y += TARGET_PAGE_SIZE)
   1.206 -            /* failed or end address not aligned on a page, track dirtyness by
   1.207 -             * hand. */
   1.208 -            if (vram_dirty(s, y, TARGET_PAGE_SIZE))
   1.209 -                cpu_physical_memory_set_dirty(s->vram_offset + y);
   1.210 -
   1.211 -        for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
   1.212 -            /* We will not read that anyway. */
   1.213 -            cpu_physical_memory_set_dirty(s->vram_offset + y);
   1.214 -    }
   1.215 +    for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
   1.216 +        /* We will not read that anyway. */
   1.217 +        cpu_physical_memory_set_dirty(s->vram_offset + y);
   1.218  
   1.219      addr1 = (s->start_addr * 4);
   1.220      bwidth = (width * bits + 7) / 8;
   1.221 @@ -2140,16 +2024,7 @@ void vga_common_init(VGAState *s, Displa
   1.222  
   1.223      vga_reset(s);
   1.224  
   1.225 -    check_sse2();
   1.226 -    s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
   1.227 -    if (s->vram_shadow == NULL)
   1.228 -        fprintf(stderr, "Cannot allocate %d bytes for VRAM shadow, "
   1.229 -                "mouse will be slow\n", vga_ram_size);
   1.230 -    s->vram_shadow = (uint8_t *)((long)(s->vram_shadow + TARGET_PAGE_SIZE - 1)
   1.231 -                                 & ~(TARGET_PAGE_SIZE - 1));
   1.232 -
   1.233 -    /* Video RAM must be 128-bit aligned for SSE optimizations later */
   1.234 -    /* and page-aligned for PVFB memory sharing */
   1.235 +    /* Video RAM must be page-aligned for PVFB memory sharing */
   1.236      s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size);
   1.237  
   1.238  #ifdef CONFIG_STUBDOM