From: Jean Guyader Date: Fri, 13 Nov 2009 11:03:38 +0000 (+0000) Subject: intel,switcher: Move intel.c from switcher into intel. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=fb0f0182139c9713a7a8f8427981cc7f75031203;p=xenclient%2Fioemu-pq.git intel,switcher: Move intel.c from switcher into intel. --- diff --git a/master/intel b/master/intel index 864b69d..53fa2dc 100644 --- a/master/intel +++ b/master/intel @@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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/master/switcher b/master/switcher index 17ff74a..0a87466 100644 --- a/master/switcher +++ b/master/switcher @@ -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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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