s->graphic_mode = -1;
vga_update_display(s);
diff --git a/intel.c b/intel.c
-index 62701cc..1f87945 100644
---- a/intel.c
+new file mode 100644
+index 0000000..3fd2379
+--- /dev/null
+++ b/intel.c
-@@ -11,6 +11,7 @@
-
- #include "qemu-common.h"
- #include "qemu-timer.h"
-+#include "qemu-xen.h"
- #include "console.h"
- #include "sysemu.h"
-
-@@ -405,28 +406,20 @@ static void intel_focus(int focus)
- focus, IntelX, IntelY, IntelPitch);
- }
-
--int intel_enter(void)
--{
-- intel_focus(1);
-- return 1;
--}
--
--int intel_leave(void)
--{
-- intel_focus(0);
-- return 1;
--}
--
--void intel_enter_leave(const char *path, void *opaque)
-+static void intel_enter_leave(const char *path, void *opaque)
- {
+@@ -0,0 +1,507 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <sys/mman.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <assert.h>
++#include <signal.h>
++#include <pci/pci.h>
++
++#include "qemu-common.h"
++#include "qemu-timer.h"
++#include "console.h"
++#include "sysemu.h"
++
++#include "intel_reg.h"
++#include "intel.h"
++
++#define INTEL_DEBUG(format, args...) \
++ fprintf (stderr, "intel.c:%d:%s " format , __LINE__, __func__, ## args);
++
++extern int vga_passthrough;
++uint32_t guest_framebuffer;
++int intel_output = INTEL_OUTPUT_BLITTED;
++static int display = 0;
++
++static int mmio_fd = -1;
++static int mem_fd = -1;
++static uint8_t *intel_mem = NULL;
++static uint8_t *intel_mmio = NULL;
++static int intel_force_full_update = 0;
++static int intel_have_focus;
++static int IntelPitch = 16;
++static int IntelX = 1280;
++static int IntelY = 1024;
++static DisplayState *lds = NULL;
++static uint32_t intel_fb_base, intel_mmio_base;
++static uint32_t map_s, map_d, map_size;
++static int refresh;
++static QEMUTimer *check_linear_timer = NULL;
++
++static void set_data_pointer(DisplaySurface *surf);
++static void intel_resize(DisplayState *ds);
++
++static inline unsigned int intel_get_reg(unsigned int reg)
++{
++ return *(unsigned int*)(intel_mmio + reg);
++}
++
++static char surfaenabled(void)
++{
++ return !!(intel_get_reg(REG_DR_DSPACNTR) & (1 << 31));
++}
++
++static inline unsigned int intel_get_surface(void)
++{
++ if (surfaenabled())
++ return intel_get_reg(REG_DR_DSPASURF);
++ else
++ return intel_get_reg(REG_DR_DSPBSURF);
++}
++
++static inline void intel_get_res(unsigned int *x,
++ unsigned int *y,
++ unsigned int *pitch)
++{
++ if (surfaenabled())
++ {
++ INTEL_DEBUG("Get resolution from PIPEA\n")
++ *pitch = intel_get_reg(REG_DR_DSPASTRIDE);
++ *x = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1;
++ *y = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1;
++ }
++ else
++ {
++ INTEL_DEBUG("Get resolution from PIPEB\n")
++ *pitch = intel_get_reg(REG_DR_DSPBSTRIDE);
++ *x = ((intel_get_reg(REG_DE_PIPEBSRC) >> 16) & 0xfff) + 1;
++ *y = (intel_get_reg(REG_DE_PIPEBSRC) & 0xfff) + 1;
++ }
++}
++
++
++
++static void intel_force_linear(int linesize)
++{
++ unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
++ unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF);
++ unsigned int *dspasurf = (unsigned int *)(intel_mmio + REG_DR_DSPASURF);
++ unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
++
++ unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
++ unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF);
++ unsigned int *dspbsurf = (unsigned int *)(intel_mmio + REG_DR_DSPBSURF);
++ unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
++ volatile unsigned int *fbc_ctl = (unsigned int *)(intel_mmio + REG_FBC_CONTROL);
++
++ unsigned int surfa = 0, surfb = 0, pipea = 0, pipeb = 0;
++ char pipeaenabled = !!(*pipeaconf & (1 << 30));
++ char pipebenabled = !!(*pipebconf & (1 << 30));
++
++ INTEL_DEBUG("DSPASURF CTRL: 0x%x\n", intel_get_reg(REG_DR_DSPACNTR));
++
++ if (pipeaenabled)
++ {
++ INTEL_DEBUG("PIPEACONF enabled.\n");
++ /* Disable surface */
++ pipea = *pipeaconf & (0x3 << 18);
++ *pipeaconf &= ~(0x3 << 18);
++ *dspacntr |= (1 << 31);
++ /* Address of the surface to map to */
++ surfa = *dspasurf;
++ *dspasurf = 0x00000000;
++ *dspacntr &= ~(1 << 31);
++ *dspasurf = 0x00000000;
++ *pipeaconf |= pipea;
++ }
++
++ if (pipebenabled) {
++ INTEL_DEBUG("PIPEBCONF enabled.\n");
++
++ /* Disable surface */
++ pipeb = *pipebconf & (0x3 << 18);
++ *pipebconf &= ~(0x3 << 18);
++ *dspbcntr |= (1 << 31);
++ /* Address of the surface to map to */
++ surfb = *dspbsurf;
++ *dspbsurf = 0x00000000;
++ *dspbcntr &= ~(1 << 31);
++ *dspbsurf = 0x00000000;
++ *pipebconf |= pipeb;
++ }
++
++ usleep(50 * 1000); /* 50 ms */
++
++ if (pipeaenabled)
++ {
++ *pipeaconf &= ~(0x3 << 18);
++ /* Enable surface linear mode */
++ *dspacntr &= ~(1 << 10);
++ if (linesize) *dspastride = linesize;
++ *dspasurf = surfa;
++ *dspacntr |= (1 << 31);
++ *pipeaconf |= pipea;
++ }
++
++ if (pipebenabled) {
++ *pipebconf &= ~(0x3 << 18);
++ /* Enable surface linear mode */
++ *dspbcntr &= ~(1 << 10);
++ if (linesize) *dspbstride = linesize;
++ *dspbsurf = surfb;
++ *dspbcntr |= (1 << 31);
++ *pipebconf |= pipeb;
++ }
++ if (linesize) IntelPitch = linesize;
++
++ usleep(50 * 1000); /* 50 ms */
++
++ /* Clear the compression bit */
++ *fbc_ctl &= ~(1 << 31);
++ /* Wait for the status register */
++ while (intel_get_reg(REG_FBC_STATUS) & (1 << 31))
++ ;
++}
++
++static void set_fb_mapping(void)
++{
++ DisplaySurface *surf = lds->surface;
++ int rc;
++ unsigned long nr_pfn;
++
++ intel_output = INTEL_OUTPUT_MAPPED;
++
++ unset_vga_acc();
++ INTEL_DEBUG("set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_surface()), guest_framebuffer);
++ nr_pfn = (ds_get_linesize(lds) * ds_get_height(lds)) >> TARGET_PAGE_BITS;
++
++ rc = xc_domain_memory_mapping(xc_handle,
++ domid,
++ (guest_framebuffer >> TARGET_PAGE_BITS),
++ ((intel_fb_base + intel_get_surface()) >> TARGET_PAGE_BITS),
++ nr_pfn,
++ DPCI_ADD_MAPPING);
++ if (rc) {
++ fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
++ return;
++ }
++ memcpy((uint8_t *)(intel_mem + intel_get_surface()),
++ ds_get_data(lds), ds_get_linesize(lds) * ds_get_height(lds));
++ map_s = ((intel_fb_base + intel_get_surface()) >> TARGET_PAGE_BITS);
++ map_d = (guest_framebuffer >> TARGET_PAGE_BITS);
++ map_size = nr_pfn;
++}
++
++static void unset_fb_mapping(void)
++{
++ int rc;
++
++ INTEL_DEBUG("unset_fb_mapping: %x %x\n", map_d, map_s);
++
++ rc = xc_domain_memory_mapping(xc_handle,
++ domid,
++ map_d,
++ map_s,
++ map_size,
++ DPCI_REMOVE_MAPPING);
++ if (rc) {
++ fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
++ return;
++ }
++
++ set_vga_acc();
++ intel_output = INTEL_OUTPUT_BLITTED;
++ memcpy(ds_get_data(lds),
++ (uint8_t *) (intel_mem + intel_get_surface()),
++ ds_get_linesize(lds) * ds_get_height(lds));
++ map_s = 0;
++ map_d = 0;
++ map_size = 0;
++}
++
++
++static void intel_update(DisplayState *ds, int x, int y, int w, int h)
++{
++ /* do nothing */
++ int i, bpp = ds_get_bytes_per_pixel(ds);
++ unsigned char *s, *d;
++
++ if (!intel_have_focus || !is_buffer_shared(ds->surface))
++ return;
++
++ if ((x > IntelX || y > IntelY))
++ return;
++ if ((x + w) > IntelX)
++ w = IntelX - x;
++ if ((y + h) > IntelY)
++ h = IntelY - y;
++
++ s = ds_get_data(ds);
++ d = (unsigned char *)(intel_mem + intel_get_surface());
++ /* Center the screen */
++ if (ds_get_width(ds) < IntelX && ds_get_height(ds) < IntelY)
++ d += IntelPitch * ((IntelY - ds_get_height(ds)) / 2) +
++ 4 * ((IntelX - ds_get_width(ds)) / 2);
++
++ s += (ds_get_linesize(ds) * y) + bpp * x;
++ d += (IntelPitch * y) + bpp * x;
++ for (i = 0; i < h; i++) {
++ memcpy(d, s, w * bpp);
++ s += ds_get_linesize(ds);
++ d += IntelPitch;
++ }
++}
++
++static void intel_resize(DisplayState *ds)
++{
++ INTEL_DEBUG("intel_resize: shared=%d, width=%d, height=%d, depth=%d\n",
++ is_buffer_shared(ds->surface),
++ ds_get_width(ds),
++ ds_get_height(ds),
++ ds_get_bytes_per_pixel(ds));
++ if (intel_have_focus)
++ {
++ if (ds_get_width(ds) == IntelX && ds_get_height(ds) == IntelY &&
++ is_buffer_shared(ds->surface))
++ {
++ if (!map_size)
++ {
++ intel_force_linear(ds_get_linesize(ds));
++ set_fb_mapping();
++ }
++ }
++ else
++ {
++ if (map_size)
++ unset_fb_mapping();
++ else
++ intel_force_linear(0);
++ }
++ } else {
++ if (map_size)
++ unset_fb_mapping();
++ }
++}
++
++static void intel_setdata(DisplayState *ds)
++{
++ if (!map_size)
++ return;
++ unset_fb_mapping();
++ set_fb_mapping();
++}
++
++static void intel_refresh(DisplayState *ds)
++{
++ vga_hw_update();
++}
++
++static void intel_init_mapping(void)
++{
++ struct pci_access *pci_bus;
++ struct pci_dev *pci_dev;
++
++ mmio_fd = open("/dev/mem", O_RDWR);
++ if (mmio_fd == -1)
++ {
++ perror("open");
++ exit(1);
++ }
++ mem_fd = open("/dev/mem", O_RDWR);
++ if (mem_fd == -1)
++ {
++ perror("open");
++ exit(1);
++ }
++
++ pci_bus = pci_alloc();
++ pci_init(pci_bus);
++ pci_dev = pci_get_dev(pci_bus, 0, 0, 2, 0);
++ pci_fill_info(pci_dev, PCI_FILL_BASES);
++ intel_fb_base = pci_dev->base_addr[2] & 0xfffff000;
++ intel_mmio_base = pci_dev->base_addr[0] & 0xfffff000;
++ pci_free_dev(pci_dev);
++ pci_cleanup(pci_bus);
++
++ INTEL_DEBUG("Map intel main mem 0x%x\n", intel_fb_base);
++ intel_mem = mmap(NULL, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED,
++ mem_fd, intel_fb_base);
++ if (intel_mem == MAP_FAILED)
++ {
++ perror("mmap");
++ exit(1);
++ }
++
++ INTEL_DEBUG("Map intel mmio 0x%x\n", intel_mmio_base);
++ intel_mmio = mmap(NULL, 4 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED,
++ mmio_fd, intel_mmio_base);
++ if (intel_mmio == MAP_FAILED)
++ {
++ perror("mmap");
++ exit(1);
++ }
++}
++
++static void set_data_pointer(DisplaySurface *surf)
++{
++ surf->data = (unsigned char *)(intel_mem + intel_get_surface());
++ memset(surf->data, 0x00, surf->linesize * IntelY);
++ surf->data = surf->data +
++ surf->linesize * ((IntelY - surf->height) / 2) +
++ 4 * ((IntelX - surf->width) / 2);
++}
++
++static int intel_getfocus(void)
++{
++ return intel_have_focus;
++}
++
++static inline int is_linear(void)
++{
++ if (surfaenabled())
++ return (intel_get_reg(REG_DR_DSPACNTR) & (1 << 10)) == 0;
++ else
++ return (intel_get_reg(REG_DR_DSPBCNTR) & (1 << 10)) == 0;
++}
++
++static void intel_check_linear(void)
++{
++ if (!check_linear_timer)
++ check_linear_timer = qemu_new_timer(rt_clock, intel_check_linear, NULL);
++
++ if (intel_have_focus && !is_linear())
++ {
++ intel_force_linear(0);
++ vga_hw_invalidate();
++ vga_hw_update();
++ }
++
++ if (intel_have_focus)
++ qemu_mod_timer(check_linear_timer,
++ qemu_get_clock(rt_clock) + 4000);
++}
++
++static void intel_focus(int focus)
++{
++ if (intel_have_focus == focus)
++ return;
++
++ intel_have_focus = focus;
++ if (intel_have_focus) {
++ intel_get_res(&IntelX, &IntelY, &IntelPitch);
++
++ if (!guest_framebuffer)
++ intel_force_linear(0);
++ memset((uint8_t *)(intel_mem + intel_get_surface()), 0,
++ IntelX * IntelY * 4);
++ }
++ vga_hw_invalidate();
++ vga_hw_update();
++ intel_check_linear();
++
++ INTEL_DEBUG("intel_focus %d, x=%d, y=%d, stride=%d\n",
++ focus, IntelX, IntelY, IntelPitch);
++}
++
++void intel_enter_leave(const char *path, void *opaque)
++{
++ int state;
+ char *tmp;
- int state;
- int enter = (int)opaque;
-
-- state = xenstore_dom_read(domid, path, NULL);
++ int enter = (int)opaque;
++
+ if (!(tmp = xenstore_read(path)))
+ return;
+ state = strtol(tmp, NULL, 10);
+ free(tmp);
- if (state == 1)
- {
- intel_focus(enter);
-- xenstore_dom_write(domid, path, "2");
++ if (state == 1)
++ {
++ intel_focus(enter);
+ xenstore_write(path, "2");
- }
- }
-
-@@ -509,7 +502,7 @@ void intel_display_init(DisplayState *ds)
- dpy_resize(ds);
- }
-
-- xenstore_dom_watch(domid, "switcher/enter", intel_enter_leave, (void*)0);
-- xenstore_dom_watch(domid, "switcher/leave", intel_enter_leave, (void*)1);
++ }
++}
++
++static DisplaySurface* intel_create_displaysurface(int width, int height)
++{
++ DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
++ if (surface == NULL) {
++ fprintf(stderr, "sdl_create_displaysurface: malloc failed\n");
++ exit(1);
++ }
++
++ surface->width = width;
++ surface->height = height;
++
++ INTEL_DEBUG("intel_create_displaysurface: focus=%d %d %d\n", intel_have_focus, width, height);
++ if (intel_have_focus) {
++ surface->pf = qemu_default_pixelformat(32);
++ surface->flags = QEMU_ALLOCATED_FLAG | INTEL_MAPPED_FLAG;
++ surface->linesize = IntelPitch;
++ set_data_pointer(surface);
++ } else {
++ surface->data = qemu_mallocz(width * height * 4);
++ surface->linesize = width * 4;
++ surface->pf = qemu_default_pixelformat(32);
++ surface->flags = QEMU_ALLOCATED_FLAG;
++ }
++
++ return surface;
++}
++
++static void intel_free_displaysurface(DisplaySurface *surface)
++{
++ if (surface == NULL)
++ return;
++ if ((!(surface->flags & INTEL_MAPPED_FLAG)) && (surface->flags & QEMU_ALLOCATED_FLAG))
++ qemu_free(surface->data);
++ qemu_free(surface);
++}
++
++static DisplaySurface* intel_resize_displaysurface(DisplaySurface *surface, int width, int height)
++{
++ intel_free_displaysurface(surface);
++ if (map_size)
++ unset_fb_mapping();
++ return intel_create_displaysurface(width, height);
++}
++
++void intel_display_init(DisplayState *ds)
++{
++ DisplayChangeListener *dcl;
++ DisplayAllocator *da;
++
++ intel_init_mapping();
++
++ INTEL_DEBUG("Frambuffer is at 0x%x\n", intel_get_surface());
++
++ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
++ if (!dcl)
++ exit(1);
++ dcl->dpy_update = intel_update;
++ dcl->dpy_resize = intel_resize;
++ dcl->dpy_setdata = intel_setdata;
++ dcl->dpy_refresh = intel_refresh;
++ register_displaychangelistener(ds, dcl);
++
++ da = qemu_mallocz(sizeof(DisplayAllocator));
++ if (!da)
++ exit(1);
++ da->create_displaysurface = intel_create_displaysurface;
++ da->resize_displaysurface = intel_resize_displaysurface;
++ da->free_displaysurface = intel_free_displaysurface;
++ if (register_displayallocator(ds, da) != da) {
++ fprintf(stderr, "intel_display_init: could not register DisplayAllocator\n");
++ exit(1);
++ } else {
++ DisplaySurface *surf;
++ surf = intel_create_displaysurface(ds_get_width(ds), ds_get_height(ds));
++ defaultallocator_free_displaysurface(ds->surface);
++ ds->surface = surf;
++ dpy_resize(ds);
++ }
++
+ xenstore_dom_watch(domid, "switcher/enter", intel_enter_leave, (void*)1);
+ xenstore_dom_watch(domid, "switcher/leave", intel_enter_leave, (void*)0);
- lds = ds;
- }
++ lds = ds;
++}
+diff --git a/intel.h b/intel.h
+new file mode 100644
+index 0000000..25086be
+--- /dev/null
++++ b/intel.h
+@@ -0,0 +1,5 @@
++extern int intel_output;
++#define INTEL_OUTPUT_UNDEF 0
++#define INTEL_OUTPUT_MAPPED 1
++#define INTEL_OUTPUT_BLITTED 2
++
+diff --git a/intel_reg.h b/intel_reg.h
+new file mode 100644
+index 0000000..cd7855e
+--- /dev/null
++++ b/intel_reg.h
+@@ -0,0 +1,22 @@
++
++#define TileW 128
++#define TileH 8
++
++#define REG_DR_DSPASURF 0x7019C
++#define REG_DR_DSPACNTR 0x70180
++#define REG_DR_DSPASTRIDE 0x70188
++#define REG_DR_PIPEACONF 0x70008
++
++#define REG_DR_DSPBSURF 0x7119C
++#define REG_DR_DSPBCNTR 0x71180
++#define REG_DR_DSPBSTRIDE 0x71188
++#define REG_DR_PIPEBCONF 0x71008
++
++#define REG_DE_PIPEASRC 0x6001c
++#define REG_DE_PIPEBSRC 0x6101c
++
++#define REG_FBC_CONTROL 0x03208
++#define REG_FBC_STATUS 0x03210
++
++
++
diff --git a/vl.c b/vl.c
index 6350384..cf7ad19 100644
--- a/vl.c
-diff --git a/intel.c b/intel.c
-new file mode 100644
-index 0000000..62701cc
---- /dev/null
-+++ b/intel.c
-@@ -0,0 +1,515 @@
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdint.h>
-+#include <sys/mman.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <assert.h>
-+#include <signal.h>
-+#include <pci/pci.h>
-+
-+#include "qemu-common.h"
-+#include "qemu-timer.h"
-+#include "console.h"
-+#include "sysemu.h"
-+
-+#include "intel_reg.h"
-+#include "intel.h"
-+
-+#define INTEL_DEBUG(format, args...) \
-+ fprintf (stderr, "intel.c:%d:%s " format , __LINE__, __func__, ## args);
-+
-+extern int vga_passthrough;
-+uint32_t guest_framebuffer;
-+int intel_output = INTEL_OUTPUT_BLITTED;
-+static int display = 0;
-+
-+static int mmio_fd = -1;
-+static int mem_fd = -1;
-+static uint8_t *intel_mem = NULL;
-+static uint8_t *intel_mmio = NULL;
-+static int intel_force_full_update = 0;
-+static int intel_have_focus;
-+static int IntelPitch = 16;
-+static int IntelX = 1280;
-+static int IntelY = 1024;
-+static DisplayState *lds = NULL;
-+static uint32_t intel_fb_base, intel_mmio_base;
-+static uint32_t map_s, map_d, map_size;
-+static int refresh;
-+static QEMUTimer *check_linear_timer = NULL;
-+
-+static void set_data_pointer(DisplaySurface *surf);
-+static void intel_resize(DisplayState *ds);
-+
-+static inline unsigned int intel_get_reg(unsigned int reg)
-+{
-+ return *(unsigned int*)(intel_mmio + reg);
-+}
-+
-+static char surfaenabled(void)
-+{
-+ return !!(intel_get_reg(REG_DR_DSPACNTR) & (1 << 31));
-+}
-+
-+static inline unsigned int intel_get_surface(void)
-+{
-+ if (surfaenabled())
-+ return intel_get_reg(REG_DR_DSPASURF);
-+ else
-+ return intel_get_reg(REG_DR_DSPBSURF);
-+}
-+
-+static inline void intel_get_res(unsigned int *x,
-+ unsigned int *y,
-+ unsigned int *pitch)
-+{
-+ if (surfaenabled())
-+ {
-+ INTEL_DEBUG("Get resolution from PIPEA\n")
-+ *pitch = intel_get_reg(REG_DR_DSPASTRIDE);
-+ *x = ((intel_get_reg(REG_DE_PIPEASRC) >> 16) & 0xfff) + 1;
-+ *y = (intel_get_reg(REG_DE_PIPEASRC) & 0xfff) + 1;
-+ }
-+ else
-+ {
-+ INTEL_DEBUG("Get resolution from PIPEB\n")
-+ *pitch = intel_get_reg(REG_DR_DSPBSTRIDE);
-+ *x = ((intel_get_reg(REG_DE_PIPEBSRC) >> 16) & 0xfff) + 1;
-+ *y = (intel_get_reg(REG_DE_PIPEBSRC) & 0xfff) + 1;
-+ }
-+}
-+
-+
-+
-+static void intel_force_linear(int linesize)
-+{
-+ unsigned int *dspacntr = (unsigned int *)(intel_mmio + REG_DR_DSPACNTR);
-+ unsigned int *pipeaconf = (unsigned int *)(intel_mmio + REG_DR_PIPEACONF);
-+ unsigned int *dspasurf = (unsigned int *)(intel_mmio + REG_DR_DSPASURF);
-+ unsigned int *dspastride = (unsigned int *)(intel_mmio + REG_DR_DSPASTRIDE);
-+
-+ unsigned int *dspbcntr = (unsigned int *)(intel_mmio + REG_DR_DSPBCNTR);
-+ unsigned int *pipebconf = (unsigned int *)(intel_mmio + REG_DR_PIPEBCONF);
-+ unsigned int *dspbsurf = (unsigned int *)(intel_mmio + REG_DR_DSPBSURF);
-+ unsigned int *dspbstride = (unsigned int *)(intel_mmio + REG_DR_DSPBSTRIDE);
-+ volatile unsigned int *fbc_ctl = (unsigned int *)(intel_mmio + REG_FBC_CONTROL);
-+
-+ unsigned int surfa = 0, surfb = 0, pipea = 0, pipeb = 0;
-+ char pipeaenabled = !!(*pipeaconf & (1 << 30));
-+ char pipebenabled = !!(*pipebconf & (1 << 30));
-+
-+ INTEL_DEBUG("DSPASURF CTRL: 0x%x\n", intel_get_reg(REG_DR_DSPACNTR));
-+
-+ if (pipeaenabled)
-+ {
-+ INTEL_DEBUG("PIPEACONF enabled.\n");
-+ /* Disable surface */
-+ pipea = *pipeaconf & (0x3 << 18);
-+ *pipeaconf &= ~(0x3 << 18);
-+ *dspacntr |= (1 << 31);
-+ /* Address of the surface to map to */
-+ surfa = *dspasurf;
-+ *dspasurf = 0x00000000;
-+ *dspacntr &= ~(1 << 31);
-+ *dspasurf = 0x00000000;
-+ *pipeaconf |= pipea;
-+ }
-+
-+ if (pipebenabled) {
-+ INTEL_DEBUG("PIPEBCONF enabled.\n");
-+
-+ /* Disable surface */
-+ pipeb = *pipebconf & (0x3 << 18);
-+ *pipebconf &= ~(0x3 << 18);
-+ *dspbcntr |= (1 << 31);
-+ /* Address of the surface to map to */
-+ surfb = *dspbsurf;
-+ *dspbsurf = 0x00000000;
-+ *dspbcntr &= ~(1 << 31);
-+ *dspbsurf = 0x00000000;
-+ *pipebconf |= pipeb;
-+ }
-+
-+ usleep(50 * 1000); /* 50 ms */
-+
-+ if (pipeaenabled)
-+ {
-+ *pipeaconf &= ~(0x3 << 18);
-+ /* Enable surface linear mode */
-+ *dspacntr &= ~(1 << 10);
-+ if (linesize) *dspastride = linesize;
-+ *dspasurf = surfa;
-+ *dspacntr |= (1 << 31);
-+ *pipeaconf |= pipea;
-+ }
-+
-+ if (pipebenabled) {
-+ *pipebconf &= ~(0x3 << 18);
-+ /* Enable surface linear mode */
-+ *dspbcntr &= ~(1 << 10);
-+ if (linesize) *dspbstride = linesize;
-+ *dspbsurf = surfb;
-+ *dspbcntr |= (1 << 31);
-+ *pipebconf |= pipeb;
-+ }
-+ if (linesize) IntelPitch = linesize;
-+
-+ usleep(50 * 1000); /* 50 ms */
-+
-+ /* Clear the compression bit */
-+ *fbc_ctl &= ~(1 << 31);
-+ /* Wait for the status register */
-+ while (intel_get_reg(REG_FBC_STATUS) & (1 << 31))
-+ ;
-+}
-+
-+static void set_fb_mapping(void)
-+{
-+ DisplaySurface *surf = lds->surface;
-+ int rc;
-+ unsigned long nr_pfn;
-+
-+ intel_output = INTEL_OUTPUT_MAPPED;
-+
-+ unset_vga_acc();
-+ INTEL_DEBUG("set_fb_mapping: %x %x\n", (intel_fb_base + intel_get_surface()), guest_framebuffer);
-+ nr_pfn = (ds_get_linesize(lds) * ds_get_height(lds)) >> TARGET_PAGE_BITS;
-+
-+ rc = xc_domain_memory_mapping(xc_handle,
-+ domid,
-+ (guest_framebuffer >> TARGET_PAGE_BITS),
-+ ((intel_fb_base + intel_get_surface()) >> TARGET_PAGE_BITS),
-+ nr_pfn,
-+ DPCI_ADD_MAPPING);
-+ if (rc) {
-+ fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
-+ return;
-+ }
-+ memcpy((uint8_t *)(intel_mem + intel_get_surface()),
-+ ds_get_data(lds), ds_get_linesize(lds) * ds_get_height(lds));
-+ map_s = ((intel_fb_base + intel_get_surface()) >> TARGET_PAGE_BITS);
-+ map_d = (guest_framebuffer >> TARGET_PAGE_BITS);
-+ map_size = nr_pfn;
-+}
-+
-+static void unset_fb_mapping(void)
-+{
-+ int rc;
-+
-+ INTEL_DEBUG("unset_fb_mapping: %x %x\n", map_d, map_s);
-+
-+ rc = xc_domain_memory_mapping(xc_handle,
-+ domid,
-+ map_d,
-+ map_s,
-+ map_size,
-+ DPCI_REMOVE_MAPPING);
-+ if (rc) {
-+ fprintf(stderr, "xc_domain_memory_mapping failed %d\n", rc);
-+ return;
-+ }
-+
-+ set_vga_acc();
-+ intel_output = INTEL_OUTPUT_BLITTED;
-+ memcpy(ds_get_data(lds),
-+ (uint8_t *) (intel_mem + intel_get_surface()),
-+ ds_get_linesize(lds) * ds_get_height(lds));
-+ map_s = 0;
-+ map_d = 0;
-+ map_size = 0;
-+}
-+
-+
-+static void intel_update(DisplayState *ds, int x, int y, int w, int h)
-+{
-+ /* do nothing */
-+ int i, bpp = ds_get_bytes_per_pixel(ds);
-+ unsigned char *s, *d;
-+
-+ if (!intel_have_focus || !is_buffer_shared(ds->surface))
-+ return;
-+
-+ if ((x > IntelX || y > IntelY))
-+ return;
-+ if ((x + w) > IntelX)
-+ w = IntelX - x;
-+ if ((y + h) > IntelY)
-+ h = IntelY - y;
-+
-+ s = ds_get_data(ds);
-+ d = (unsigned char *)(intel_mem + intel_get_surface());
-+ /* Center the screen */
-+ if (ds_get_width(ds) < IntelX && ds_get_height(ds) < IntelY)
-+ d += IntelPitch * ((IntelY - ds_get_height(ds)) / 2) +
-+ 4 * ((IntelX - ds_get_width(ds)) / 2);
-+
-+ s += (ds_get_linesize(ds) * y) + bpp * x;
-+ d += (IntelPitch * y) + bpp * x;
-+ for (i = 0; i < h; i++) {
-+ memcpy(d, s, w * bpp);
-+ s += ds_get_linesize(ds);
-+ d += IntelPitch;
-+ }
-+}
-+
-+static void intel_resize(DisplayState *ds)
-+{
-+ INTEL_DEBUG("intel_resize: shared=%d, width=%d, height=%d, depth=%d\n",
-+ is_buffer_shared(ds->surface),
-+ ds_get_width(ds),
-+ ds_get_height(ds),
-+ ds_get_bytes_per_pixel(ds));
-+ if (intel_have_focus)
-+ {
-+ if (ds_get_width(ds) == IntelX && ds_get_height(ds) == IntelY &&
-+ is_buffer_shared(ds->surface))
-+ {
-+ if (!map_size)
-+ {
-+ intel_force_linear(ds_get_linesize(ds));
-+ set_fb_mapping();
-+ }
-+ }
-+ else
-+ {
-+ if (map_size)
-+ unset_fb_mapping();
-+ else
-+ intel_force_linear(0);
-+ }
-+ } else {
-+ if (map_size)
-+ unset_fb_mapping();
-+ }
-+}
-+
-+static void intel_setdata(DisplayState *ds)
-+{
-+ if (!map_size)
-+ return;
-+ unset_fb_mapping();
-+ set_fb_mapping();
-+}
-+
-+static void intel_refresh(DisplayState *ds)
-+{
-+ vga_hw_update();
-+}
-+
-+static void intel_init_mapping(void)
-+{
-+ struct pci_access *pci_bus;
-+ struct pci_dev *pci_dev;
-+
-+ mmio_fd = open("/dev/mem", O_RDWR);
-+ if (mmio_fd == -1)
-+ {
-+ perror("open");
-+ exit(1);
-+ }
-+ mem_fd = open("/dev/mem", O_RDWR);
-+ if (mem_fd == -1)
-+ {
-+ perror("open");
-+ exit(1);
-+ }
-+
-+ pci_bus = pci_alloc();
-+ pci_init(pci_bus);
-+ pci_dev = pci_get_dev(pci_bus, 0, 0, 2, 0);
-+ pci_fill_info(pci_dev, PCI_FILL_BASES);
-+ intel_fb_base = pci_dev->base_addr[2] & 0xfffff000;
-+ intel_mmio_base = pci_dev->base_addr[0] & 0xfffff000;
-+ pci_free_dev(pci_dev);
-+ pci_cleanup(pci_bus);
-+
-+ INTEL_DEBUG("Map intel main mem 0x%x\n", intel_fb_base);
-+ intel_mem = mmap(NULL, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED,
-+ mem_fd, intel_fb_base);
-+ if (intel_mem == MAP_FAILED)
-+ {
-+ perror("mmap");
-+ exit(1);
-+ }
-+
-+ INTEL_DEBUG("Map intel mmio 0x%x\n", intel_mmio_base);
-+ intel_mmio = mmap(NULL, 4 * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED,
-+ mmio_fd, intel_mmio_base);
-+ if (intel_mmio == MAP_FAILED)
-+ {
-+ perror("mmap");
-+ exit(1);
-+ }
-+}
-+
-+static void set_data_pointer(DisplaySurface *surf)
-+{
-+ surf->data = (unsigned char *)(intel_mem + intel_get_surface());
-+ memset(surf->data, 0x00, surf->linesize * IntelY);
-+ surf->data = surf->data +
-+ surf->linesize * ((IntelY - surf->height) / 2) +
-+ 4 * ((IntelX - surf->width) / 2);
-+}
-+
-+static int intel_getfocus(void)
-+{
-+ return intel_have_focus;
-+}
-+
-+static inline int is_linear(void)
-+{
-+ if (surfaenabled())
-+ return (intel_get_reg(REG_DR_DSPACNTR) & (1 << 10)) == 0;
-+ else
-+ return (intel_get_reg(REG_DR_DSPBCNTR) & (1 << 10)) == 0;
-+}
-+
-+static void intel_check_linear(void)
-+{
-+ if (!check_linear_timer)
-+ check_linear_timer = qemu_new_timer(rt_clock, intel_check_linear, NULL);
-+
-+ if (intel_have_focus && !is_linear())
-+ {
-+ intel_force_linear(0);
-+ vga_hw_invalidate();
-+ vga_hw_update();
-+ }
-+
-+ if (intel_have_focus)
-+ qemu_mod_timer(check_linear_timer,
-+ qemu_get_clock(rt_clock) + 4000);
-+}
-+
-+static void intel_focus(int focus)
-+{
-+ if (intel_have_focus == focus)
-+ return;
-+
-+ intel_have_focus = focus;
-+ if (intel_have_focus) {
-+ intel_get_res(&IntelX, &IntelY, &IntelPitch);
-+
-+ if (!guest_framebuffer)
-+ intel_force_linear(0);
-+ memset((uint8_t *)(intel_mem + intel_get_surface()), 0,
-+ IntelX * IntelY * 4);
-+ }
-+ vga_hw_invalidate();
-+ vga_hw_update();
-+ intel_check_linear();
-+
-+ INTEL_DEBUG("intel_focus %d, x=%d, y=%d, stride=%d\n",
-+ focus, IntelX, IntelY, IntelPitch);
-+}
-+
-+int intel_enter(void)
-+{
-+ intel_focus(1);
-+ return 1;
-+}
-+
-+int intel_leave(void)
-+{
-+ intel_focus(0);
-+ return 1;
-+}
-+
-+void intel_enter_leave(const char *path, void *opaque)
-+{
-+ int state;
-+ int enter = (int)opaque;
-+
-+ state = xenstore_dom_read(domid, path, NULL);
-+ if (state == 1)
-+ {
-+ intel_focus(enter);
-+ xenstore_dom_write(domid, path, "2");
-+ }
-+}
-+
-+static DisplaySurface* intel_create_displaysurface(int width, int height)
-+{
-+ DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
-+ if (surface == NULL) {
-+ fprintf(stderr, "sdl_create_displaysurface: malloc failed\n");
-+ exit(1);
-+ }
-+
-+ surface->width = width;
-+ surface->height = height;
-+
-+ INTEL_DEBUG("intel_create_displaysurface: focus=%d %d %d\n", intel_have_focus, width, height);
-+ if (intel_have_focus) {
-+ surface->pf = qemu_default_pixelformat(32);
-+ surface->flags = QEMU_ALLOCATED_FLAG | INTEL_MAPPED_FLAG;
-+ surface->linesize = IntelPitch;
-+ set_data_pointer(surface);
-+ } else {
-+ surface->data = qemu_mallocz(width * height * 4);
-+ surface->linesize = width * 4;
-+ surface->pf = qemu_default_pixelformat(32);
-+ surface->flags = QEMU_ALLOCATED_FLAG;
-+ }
-+
-+ return surface;
-+}
-+
-+static void intel_free_displaysurface(DisplaySurface *surface)
-+{
-+ if (surface == NULL)
-+ return;
-+ if ((!(surface->flags & INTEL_MAPPED_FLAG)) && (surface->flags & QEMU_ALLOCATED_FLAG))
-+ qemu_free(surface->data);
-+ qemu_free(surface);
-+}
-+
-+static DisplaySurface* intel_resize_displaysurface(DisplaySurface *surface, int width, int height)
-+{
-+ intel_free_displaysurface(surface);
-+ if (map_size)
-+ unset_fb_mapping();
-+ return intel_create_displaysurface(width, height);
-+}
-+
-+void intel_display_init(DisplayState *ds)
-+{
-+ DisplayChangeListener *dcl;
-+ DisplayAllocator *da;
-+
-+ intel_init_mapping();
-+
-+ INTEL_DEBUG("Frambuffer is at 0x%x\n", intel_get_surface());
-+
-+ dcl = qemu_mallocz(sizeof(DisplayChangeListener));
-+ if (!dcl)
-+ exit(1);
-+ dcl->dpy_update = intel_update;
-+ dcl->dpy_resize = intel_resize;
-+ dcl->dpy_setdata = intel_setdata;
-+ dcl->dpy_refresh = intel_refresh;
-+ register_displaychangelistener(ds, dcl);
-+
-+ da = qemu_mallocz(sizeof(DisplayAllocator));
-+ if (!da)
-+ exit(1);
-+ da->create_displaysurface = intel_create_displaysurface;
-+ da->resize_displaysurface = intel_resize_displaysurface;
-+ da->free_displaysurface = intel_free_displaysurface;
-+ if (register_displayallocator(ds, da) != da) {
-+ fprintf(stderr, "intel_display_init: could not register DisplayAllocator\n");
-+ exit(1);
-+ } else {
-+ DisplaySurface *surf;
-+ surf = intel_create_displaysurface(ds_get_width(ds), ds_get_height(ds));
-+ defaultallocator_free_displaysurface(ds->surface);
-+ ds->surface = surf;
-+ dpy_resize(ds);
-+ }
-+
-+ xenstore_dom_watch(domid, "switcher/enter", intel_enter_leave, (void*)0);
-+ xenstore_dom_watch(domid, "switcher/leave", intel_enter_leave, (void*)1);
-+ lds = ds;
-+}
-diff --git a/intel.h b/intel.h
-new file mode 100644
-index 0000000..25086be
---- /dev/null
-+++ b/intel.h
-@@ -0,0 +1,5 @@
-+extern int intel_output;
-+#define INTEL_OUTPUT_UNDEF 0
-+#define INTEL_OUTPUT_MAPPED 1
-+#define INTEL_OUTPUT_BLITTED 2
-+
-diff --git a/intel_reg.h b/intel_reg.h
-new file mode 100644
-index 0000000..cd7855e
---- /dev/null
-+++ b/intel_reg.h
-@@ -0,0 +1,22 @@
-+
-+#define TileW 128
-+#define TileH 8
-+
-+#define REG_DR_DSPASURF 0x7019C
-+#define REG_DR_DSPACNTR 0x70180
-+#define REG_DR_DSPASTRIDE 0x70188
-+#define REG_DR_PIPEACONF 0x70008
-+
-+#define REG_DR_DSPBSURF 0x7119C
-+#define REG_DR_DSPBCNTR 0x71180
-+#define REG_DR_DSPBSTRIDE 0x71188
-+#define REG_DR_PIPEBCONF 0x71008
-+
-+#define REG_DE_PIPEASRC 0x6001c
-+#define REG_DE_PIPEBSRC 0x6101c
-+
-+#define REG_FBC_CONTROL 0x03208
-+#define REG_FBC_STATUS 0x03210
-+
-+
-+
diff --git a/qemu-xen.h b/qemu-xen.h
index 7883718..0b6214c 100644
--- a/qemu-xen.h