[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3a/3] Add shadow VRAM



This is a slightly modified version of the original VGA patch that removes
changes to the configure script to check for SSE2 capabilities.  SSE2 is
now only checked at run time.

Signed-off-by: Don Dugger <donald.d.dugger@xxxxxxxxx>

-- 
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
Donald.D.Dugger@xxxxxxxxx
Ph: (303)440-1368


diff -r c445d4a0dd76 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Tue Mar 14 19:33:45 2006 +0100
+++ b/tools/ioemu/hw/vga.c      Thu Mar 16 14:15:07 2006 -0700
@@ -21,6 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include <signal.h>
+#include <setjmp.h>
+#include <emmintrin.h>
+
 #include "vl.h"
 #include "vga_int.h"
 
@@ -149,6 +153,8 @@ static uint8_t expand4to8[16];
 
 VGAState *vga_state;
 int vga_io_memory;
+
+int sse2_ok = 1;
 
 static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
 {
@@ -1340,6 +1346,80 @@ void vga_invalidate_scanlines(VGAState *
     }
 }
 
+extern 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;
+}
+
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+       unsigned int eax, edx;
+
+       __asm__("cpuid"
+               : "=a" (eax), "=d" (edx)
+               : "0" (op)
+               : "bx", "cx");
+       return edx;
+}
+
+jmp_buf sse_jbuf;
+
+void intr(int sig)
+{
+
+       sse2_ok = 0;
+       longjmp(sse_jbuf, 1);
+       return;
+}
+
+void check_sse2(void)
+{
+
+       if ((cpuid_edx(1) & 0x4000000) == 0) {
+               sse2_ok = 0;
+               return;
+       }
+       signal(SIGILL, intr);
+       if (setjmp(sse_jbuf) == 0)
+               __asm__("xorps %xmm0,%xmm0\n");
+       return;
+}
+
+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;
+}
+
 /* 
  * graphic modes
  */
@@ -1434,6 +1514,9 @@ static void vga_draw_graphic(VGAState *s
     printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x 
linecmp=%d sr[0x01]=0x%02x\n",
            width, height, v, line_offset, s->cr[9], s->cr[0x17], 
s->line_compare, s->sr[0x01]);
 #endif
+    for (y = 0; 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);
     addr1 = (s->start_addr * 4);
     bwidth = width * 4;
     y_start = -1;
@@ -1536,8 +1619,17 @@ static void vga_draw_blank(VGAState *s, 
 
 void vga_update_display(void)
 {
+    static int loop;
     VGAState *s = vga_state;
     int full_update, graphic_mode;
+
+    /*
+     *  Only update the display every other time.  The responsiveness is
+     *    acceptable and it cuts down on the overhead of the VRAM compare
+     *    in `vram_dirty'
+     */
+    if (loop++ & 1)
+       return;
 
     if (s->ds->depth == 0) {
         /* nothing to do */
@@ -1569,7 +1661,6 @@ void vga_update_display(void)
             full_update = 1;
         }
 
-        full_update = 1;
         switch(graphic_mode) {
         case GMODE_TEXT:
             vga_draw_text(s, full_update);
@@ -1874,7 +1965,10 @@ void vga_common_init(VGAState *s, Displa
 #else
     s->vram_ptr = qemu_malloc(vga_ram_size);
 #endif
-
+    check_sse2();
+    if ((s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1)) == 
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));
     s->vram_offset = vga_ram_offset;
     s->vram_size = vga_ram_size;
     s->ds = ds;
diff -r c445d4a0dd76 tools/ioemu/hw/vga_int.h
--- a/tools/ioemu/hw/vga_int.h  Tue Mar 14 19:33:45 2006 +0100
+++ b/tools/ioemu/hw/vga_int.h  Thu Mar 16 14:15:07 2006 -0700
@@ -76,6 +76,7 @@
 
 #define VGA_STATE_COMMON                                                \
     uint8_t *vram_ptr;                                                  \
+    uint8_t *vram_shadow;                                              \
     unsigned long vram_offset;                                          \
     unsigned int vram_size;                                             \
     uint32_t latch;                                                     \
diff -r c445d4a0dd76 tools/ioemu/target-i386-dm/Makefile
--- a/tools/ioemu/target-i386-dm/Makefile       Tue Mar 14 19:33:45 2006 +0100
+++ b/tools/ioemu/target-i386-dm/Makefile       Thu Mar 16 14:15:07 2006 -0700
@@ -13,7 +13,7 @@ VPATH+=:$(SRC_PATH)/linux-user
 VPATH+=:$(SRC_PATH)/linux-user
 DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
 endif
-CFLAGS+=-g -fno-strict-aliasing
+CFLAGS+=-g -fno-strict-aliasing -msse2
 LDFLAGS=-g
 LIBS=
 HELPER_CFLAGS=$(CFLAGS)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.