]> xenbits.xen.org Git - xenclient/ioemu-pq.git/commitdiff
intel,switcher: Move intel.c from switcher into intel.
authorJean Guyader <jean.guyader@eu.citrix.com>
Fri, 13 Nov 2009 11:03:38 +0000 (11:03 +0000)
committerJean Guyader <jean.guyader@eu.citrix.com>
Fri, 13 Nov 2009 11:03:38 +0000 (11:03 +0000)
master/intel
master/switcher

index 864b69d27f80219f1af19c1560f0c4517a8b206d..53fa2dc378a8cfb9dc945354452e241fd05635cc 100644 (file)
@@ -200,63 +200,557 @@ index 90bd544..e4e27a9 100644
      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
index 17ff74ac512548de91fde441fa1c4e98fb7a5b43..0a87466958dc1525f4577bf22d0875694112c1f2 100644 (file)
@@ -1,563 +1,3 @@
-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