WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] stubdom: make use of PVFB resize event

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] stubdom: make use of PVFB resize event
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 22 Apr 2008 07:10:18 -0700
Delivery-date: Tue, 22 Apr 2008 07:11:03 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1208337668 -3600
# Node ID 06242949ff569930bdb13f627fbb54ea13d8af08
# Parent  774e38a40d012d3cc92715237d6932bcf01bbd39
stubdom: make use of PVFB resize event
which with the offset support also permits to expose the VGA vram and
non-shared vram throught PVFB at the same time, switching between both
as appropriate.

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
 extras/mini-os/fbfront.c         |   98 ++++++++++++++----------
 extras/mini-os/include/fbfront.h |    3 
 extras/mini-os/kernel.c          |   15 +++
 tools/ioemu/hw/cirrus_vga.c      |    4 +
 tools/ioemu/hw/vga.c             |    6 -
 tools/ioemu/hw/xenfb.c           |  153 +++++++++++++++++++++++++++------------
 tools/ioemu/vl.h                 |    1 
 7 files changed, 186 insertions(+), 94 deletions(-)

diff -r 774e38a40d01 -r 06242949ff56 extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c  Wed Apr 16 10:07:49 2008 +0100
+++ b/extras/mini-os/fbfront.c  Wed Apr 16 10:21:08 2008 +0100
@@ -243,12 +243,12 @@ struct fbfront_dev {
     char *backend;
     int request_update;
 
-    char *data;
     int width;
     int height;
     int depth;
-    int line_length;
+    int stride;
     int mem_length;
+    int offset;
 };
 
 void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
@@ -256,7 +256,7 @@ void fbfront_handler(evtchn_port_t port,
     wake_up(&fbfront_queue);
 }
 
-struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int 
height, int depth, int line_length, int mem_length)
+struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int 
width, int height, int depth, int stride, int n)
 {
     xenbus_transaction_t xbt;
     char* err;
@@ -289,24 +289,17 @@ struct fbfront_dev *init_fbfront(char *n
     dev->width = s->width = width;
     dev->height = s->height = height;
     dev->depth = s->depth = depth;
-    dev->line_length = s->line_length = line_length;
-    dev->mem_length = s->mem_length = mem_length;
-
-    ASSERT(!((unsigned long)data & ~PAGE_MASK));
-    dev->data = data;
+    dev->stride = s->line_length = stride;
+    dev->mem_length = s->mem_length = n * PAGE_SIZE;
+    dev->offset = 0;
 
     const int max_pd = sizeof(s->pd) / sizeof(s->pd[0]);
     unsigned long mapped = 0;
 
-    for (i = 0; mapped < mem_length && i < max_pd; i++) {
+    for (i = 0; mapped < n && i < max_pd; i++) {
         unsigned long *pd = (unsigned long *) alloc_page();
-        for (j = 0; mapped < mem_length && j < PAGE_SIZE / sizeof(unsigned 
long); j++) {
-            /* Trigger CoW */
-            * ((char *)data + mapped) = 0;
-            barrier();
-            pd[j] = virtual_to_mfn((unsigned long) data + mapped);
-            mapped += PAGE_SIZE;
-        }
+        for (j = 0; mapped < n && j < PAGE_SIZE / sizeof(unsigned long); j++)
+            pd[j] = mfns[mapped++];
         for ( ; j < PAGE_SIZE / sizeof(unsigned long); j++)
             pd[j] = 0;
         s->pd[i] = virt_to_mfn(pd);
@@ -395,31 +388,11 @@ done:
     return dev;
 }
 
-void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int 
height)
+static void fbfront_out_event(struct fbfront_dev *dev, union xenfb_out_event 
*event)
 {
     struct xenfb_page *page = dev->page;
     uint32_t prod;
     DEFINE_WAIT(w);
-
-    if (dev->request_update <= 0)
-        return;
-
-    if (x < 0) {
-        width += x;
-        x = 0;
-    }
-    if (x + width > dev->width)
-        width = dev->width - x;
-
-    if (y < 0) {
-        height += y;
-        y = 0;
-    }
-    if (y + height > dev->height)
-        height = dev->height - y;
-
-    if (width <= 0 || height <= 0)
-        return;
 
     add_waiter(w, fbfront_queue);
     while (page->out_prod - page->out_cons == XENFB_OUT_RING_LEN)
@@ -428,14 +401,55 @@ void fbfront_update(struct fbfront_dev *
 
     prod = page->out_prod;
     mb(); /* ensure ring space available */
-    XENFB_OUT_RING_REF(page, prod).type = XENFB_TYPE_UPDATE;
-    XENFB_OUT_RING_REF(page, prod).update.x = x;
-    XENFB_OUT_RING_REF(page, prod).update.y = y;
-    XENFB_OUT_RING_REF(page, prod).update.width = width;
-    XENFB_OUT_RING_REF(page, prod).update.height = height;
+    XENFB_OUT_RING_REF(page, prod) = *event;
     wmb(); /* ensure ring contents visible */
     page->out_prod = prod + 1;
     notify_remote_via_evtchn(dev->evtchn);
+}
+
+void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int 
height)
+{
+    struct xenfb_update update;
+
+    if (dev->request_update <= 0)
+        return;
+
+    if (x < 0) {
+        width += x;
+        x = 0;
+    }
+    if (x + width > dev->width)
+        width = dev->width - x;
+
+    if (y < 0) {
+        height += y;
+        y = 0;
+    }
+    if (y + height > dev->height)
+        height = dev->height - y;
+
+    if (width <= 0 || height <= 0)
+        return;
+
+    update.type = XENFB_TYPE_UPDATE;
+    update.x = x;
+    update.y = y;
+    update.width = width;
+    update.height = height;
+    fbfront_out_event(dev, (union xenfb_out_event *) &update);
+}
+
+void fbfront_resize(struct fbfront_dev *dev, int width, int height, int 
stride, int depth, int offset)
+{
+    struct xenfb_resize resize;
+
+    resize.type = XENFB_TYPE_RESIZE;
+    dev->width  = resize.width = width;
+    dev->height = resize.height = height;
+    dev->stride = resize.stride = stride;
+    dev->depth  = resize.depth = depth;
+    dev->offset = resize.offset = offset;
+    fbfront_out_event(dev, (union xenfb_out_event *) &resize);
 }
 
 void shutdown_fbfront(struct fbfront_dev *dev)
diff -r 774e38a40d01 -r 06242949ff56 extras/mini-os/include/fbfront.h
--- a/extras/mini-os/include/fbfront.h  Wed Apr 16 10:07:49 2008 +0100
+++ b/extras/mini-os/include/fbfront.h  Wed Apr 16 10:21:08 2008 +0100
@@ -31,11 +31,12 @@ void shutdown_kbdfront(struct kbdfront_d
 void shutdown_kbdfront(struct kbdfront_dev *dev);
 
 
-struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int 
height, int depth, int line_length, int mem_length);
+struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int 
width, int height, int depth, int stride, int n);
 #ifdef HAVE_LIBC
 int fbfront_open(struct fbfront_dev *dev);
 #endif
 
 void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int 
height);
+void fbfront_resize(struct fbfront_dev *dev, int width, int height, int 
stride, int depth, int offset);
 
 void shutdown_fbfront(struct fbfront_dev *dev);
diff -r 774e38a40d01 -r 06242949ff56 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Wed Apr 16 10:07:49 2008 +0100
+++ b/extras/mini-os/kernel.c   Wed Apr 16 10:21:08 2008 +0100
@@ -297,9 +297,20 @@ static void fbfront_thread(void *p)
 {
     size_t line_length = WIDTH * (DEPTH / 8);
     size_t memsize = HEIGHT * line_length;
-
+    unsigned long *mfns;
+    int i, n = (memsize + PAGE_SIZE-1) / PAGE_SIZE;
+
+    memsize = n * PAGE_SIZE;
     fb = _xmalloc(memsize, PAGE_SIZE);
-    fb_dev = init_fbfront(NULL, fb, WIDTH, HEIGHT, DEPTH, line_length, 
memsize);
+    mfns = xmalloc_array(unsigned long, n);
+    for (i = 0; i < n; i++) {
+        /* trigger CoW */
+        ((char *) fb) [i * PAGE_SIZE] = 0;
+        barrier();
+        mfns[i] = virtual_to_mfn((char *) fb + i * PAGE_SIZE);
+    }
+    fb_dev = init_fbfront(NULL, mfns, WIDTH, HEIGHT, DEPTH, line_length, n);
+    xfree(mfns);
     if (!fb_dev) {
         xfree(fb);
         return;
diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c       Wed Apr 16 10:07:49 2008 +0100
+++ b/tools/ioemu/hw/cirrus_vga.c       Wed Apr 16 10:21:08 2008 +0100
@@ -2595,6 +2595,10 @@ static void *set_vram_mapping(unsigned l
 
     memset(vram_pointer, 0, nr_extents * TARGET_PAGE_SIZE);
 
+#ifdef CONFIG_STUBDOM
+    xenfb_pv_display_start(vram_pointer);
+#endif
+
     free(extent_start);
 
     return vram_pointer;
diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Wed Apr 16 10:07:49 2008 +0100
+++ b/tools/ioemu/hw/vga.c      Wed Apr 16 10:21:08 2008 +0100
@@ -2067,8 +2067,8 @@ void vga_common_init(VGAState *s, Displa
                                  & ~(TARGET_PAGE_SIZE - 1));
 
     /* Video RAM must be 128-bit aligned for SSE optimizations later */
-    s->vram_alloc = qemu_malloc(vga_ram_size + 15);
-    s->vram_ptr = (uint8_t *)((long)(s->vram_alloc + 15) & ~15L);
+    /* and page-aligned for PVFB memory sharing */
+    s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, 
vga_ram_size);
 
     s->vram_offset = vga_ram_offset;
     s->vram_size = vga_ram_size;
@@ -2210,7 +2210,7 @@ void *vga_update_vram(VGAState *s, void 
     }
 
     if (!vga_ram_base) {
-        vga_ram_base = qemu_malloc(vga_ram_size + TARGET_PAGE_SIZE + 1);
+        vga_ram_base = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size + 
TARGET_PAGE_SIZE + 1);
         if (!vga_ram_base) {
             fprintf(stderr, "reallocate error\n");
             return NULL;
diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c    Wed Apr 16 10:07:49 2008 +0100
+++ b/tools/ioemu/hw/xenfb.c    Wed Apr 16 10:21:08 2008 +0100
@@ -1235,14 +1235,10 @@ static struct semaphore kbd_sem = __SEMA
 static struct semaphore kbd_sem = __SEMAPHORE_INITIALIZER(kbd_sem, 0);
 static struct kbdfront_dev *kbd_dev;
 static char *kbd_path, *fb_path;
+static void *vga_vram, *nonshared_vram;
+static DisplayState *xenfb_ds;
 
 static unsigned char linux2scancode[KEY_MAX + 1];
-
-#define WIDTH 1024
-#define HEIGHT 768
-#define DEPTH 32
-#define LINESIZE (1280 * (DEPTH / 8))
-#define MEMSIZE (LINESIZE * HEIGHT)
 
 int xenfb_connect_vkbd(const char *path)
 {
@@ -1256,33 +1252,73 @@ int xenfb_connect_vfb(const char *path)
     return 0;
 }
 
-static void xenfb_pv_update(DisplayState *s, int x, int y, int w, int h)
-{
-    struct fbfront_dev *fb_dev = s->opaque;
+static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
+{
+    struct fbfront_dev *fb_dev = ds->opaque;
+    if (!fb_dev)
+        return;
     fbfront_update(fb_dev, x, y, w, h);
 }
 
-static void xenfb_pv_resize(DisplayState *s, int w, int h, int linesize)
-{
-    struct fbfront_dev *fb_dev = s->opaque;
-    fprintf(stderr,"resize to %dx%d required\n", w, h);
-    s->width = w;
-    s->height = h;
-    /* TODO: send resize event if supported */
-    memset(s->data, 0, MEMSIZE);
-    fbfront_update(fb_dev, 0, 0, WIDTH, HEIGHT);
+static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize)
+{
+    struct fbfront_dev *fb_dev = ds->opaque;
+    fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize);
+    ds->width = w;
+    ds->height = h;
+    if (!linesize)
+        ds->shared_buf = 0;
+    if (!ds->shared_buf)
+        linesize = w * 4;
+    ds->linesize = linesize;
+    if (!fb_dev)
+        return;
+    if (ds->shared_buf) {
+        ds->data = NULL;
+    } else {
+        ds->data = nonshared_vram;
+        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
+    }
 }
 
 static void xenfb_pv_colourdepth(DisplayState *ds, int depth)
 {
-    /* TODO: send redepth event if supported */
+    struct fbfront_dev *fb_dev = ds->opaque;
     static int lastdepth = -1;
+    if (!depth) {
+        ds->shared_buf = 0;
+        ds->depth = 32;
+    } else {
+        ds->shared_buf = 1;
+        ds->depth = depth;
+    }
     if (depth != lastdepth) {
         fprintf(stderr,"redepth to %d required\n", depth);
         lastdepth = depth;
+    } else return;
+    if (!fb_dev)
+        return;
+    if (ds->shared_buf) {
+        ds->data = NULL;
+    } else {
+        ds->data = nonshared_vram;
+        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
VGA_RAM_SIZE);
     }
-    /* We can't redepth for now */
-    ds->depth = DEPTH;
+}
+
+static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
+{
+    struct fbfront_dev *fb_dev = ds->opaque;
+    int offset = pixels - vga_vram;
+    ds->data = pixels;
+    if (!fb_dev)
+        return;
+    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
offset);
+}
+
+static void xenfb_pv_refresh(DisplayState *ds)
+{
+    vga_hw_update();
 }
 
 static void xenfb_kbd_handler(void *opaque)
@@ -1373,13 +1409,6 @@ static void xenfb_kbd_handler(void *opaq
     }
 }
 
-static void xenfb_pv_refresh(DisplayState *ds)
-{
-    /* always request negociation */
-    ds->depth = -1;
-    vga_hw_update();
-}
-
 static void kbdfront_thread(void *p)
 {
     int scancode, keycode;
@@ -1399,40 +1428,72 @@ static void kbdfront_thread(void *p)
 
 int xenfb_pv_display_init(DisplayState *ds)
 {
-    void *data;
+    if (!fb_path || !kbd_path)
+        return -1;
+
+    create_thread("kbdfront", kbdfront_thread, (void*) kbd_path);
+
+    xenfb_ds = ds;
+
+    ds->data = nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
+    memset(ds->data, 0, VGA_RAM_SIZE);
+    ds->depth = 32;
+    ds->bgr = 0;
+    ds->width = 640;
+    ds->height = 400;
+    ds->linesize = 640 * 4;
+    ds->dpy_update = xenfb_pv_update;
+    ds->dpy_resize = xenfb_pv_resize;
+    ds->dpy_colourdepth = xenfb_pv_colourdepth;
+    ds->dpy_setdata = xenfb_pv_setdata;
+    ds->dpy_refresh = xenfb_pv_refresh;
+    return 0;
+}
+
+int xenfb_pv_display_start(void *data)
+{
+    DisplayState *ds = xenfb_ds;
     struct fbfront_dev *fb_dev;
     int kbd_fd;
+    int offset = 0;
+    unsigned long *mfns;
+    int n = VGA_RAM_SIZE / PAGE_SIZE;
+    int i;
 
     if (!fb_path || !kbd_path)
-        return -1;
-
-    create_thread("kbdfront", kbdfront_thread, (void*) kbd_path);
-
-    data = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
-    fb_dev = init_fbfront(fb_path, data, WIDTH, HEIGHT, DEPTH, LINESIZE, 
MEMSIZE);
+        return 0;
+
+    vga_vram = data;
+    mfns = malloc(2 * n * sizeof(*mfns));
+    for (i = 0; i < n; i++)
+        mfns[i] = virtual_to_mfn(vga_vram + i * PAGE_SIZE);
+    for (i = 0; i < n; i++)
+        mfns[n + i] = virtual_to_mfn(nonshared_vram + i * PAGE_SIZE);
+
+    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, 
ds->linesize, 2 * n);
+    free(mfns);
     if (!fb_dev) {
         fprintf(stderr,"can't open frame buffer\n");
         exit(1);
     }
     free(fb_path);
 
+    if (ds->shared_buf) {
+        offset = (void*) ds->data - vga_vram;
+    } else {
+        offset = VGA_RAM_SIZE;
+        ds->data = nonshared_vram;
+    }
+    if (offset)
+        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
offset);
+
     down(&kbd_sem);
     free(kbd_path);
 
     kbd_fd = kbdfront_open(kbd_dev);
     qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, ds);
 
-    ds->data = data;
-    ds->linesize = LINESIZE;
-    ds->depth = DEPTH;
-    ds->bgr = 0;
-    ds->width = WIDTH;
-    ds->height = HEIGHT;
-    ds->dpy_update = xenfb_pv_update;
-    ds->dpy_resize = xenfb_pv_resize;
-    ds->dpy_colourdepth = xenfb_pv_colourdepth;
-    ds->dpy_refresh = xenfb_pv_refresh;
-    ds->opaque = fb_dev;
+    xenfb_ds->opaque = fb_dev;
     return 0;
 }
 #endif
diff -r 774e38a40d01 -r 06242949ff56 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Wed Apr 16 10:07:49 2008 +0100
+++ b/tools/ioemu/vl.h  Wed Apr 16 10:21:08 2008 +0100
@@ -1545,6 +1545,7 @@ char *xenstore_vm_read(int domid, char *
 
 /* xenfb.c */
 int xenfb_pv_display_init(DisplayState *ds);
+int xenfb_pv_display_start(void *vram_start);
 int xenfb_connect_vkbd(const char *path);
 int xenfb_connect_vfb(const char *path);
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] stubdom: make use of PVFB resize event, Xen patchbot-unstable <=