All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] stubdom: use PVFB so as to e.g. permit SDL display
@ 2008-02-27 18:42 Samuel Thibault
  2008-02-27 18:45 ` Samuel Thibault
  0 siblings, 1 reply; 2+ messages in thread
From: Samuel Thibault @ 2008-02-27 18:42 UTC (permalink / raw)
  To: xen-devel

This adds support in ioemu for PVFB frontend as stubdomain display.
This permits for instance to use SDL in dom0 to perform the eventual
display.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>

diff -r 2a8eaba24bf0 extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c	Tue Feb 26 15:11:51 2008 +0000
+++ b/extras/mini-os/fbfront.c	Wed Feb 27 18:30:05 2008 +0000
@@ -30,13 +30,6 @@ struct kbdfront_dev {
 
     char *nodename;
     char *backend;
-
-    char *data;
-    int width;
-    int height;
-    int depth;
-    int line_length;
-    int mem_length;
 
 #ifdef HAVE_LIBC
     int fd;
@@ -316,7 +309,10 @@ struct fbfront_dev *init_fbfront(char *n
     for (i = 0; mapped < mem_length && i < max_pd; i++) {
         unsigned long *pd = (unsigned long *) alloc_page();
         for (j = 0; mapped < mem_length && j < PAGE_SIZE / sizeof(unsigned long); j++) {
-            pd[j] = virt_to_mfn((unsigned long) data + mapped);
+            /* Trigger CoW */
+            * ((char *)data + mapped) = 0;
+            barrier();
+            pd[j] = virtual_to_mfn((unsigned long) data + mapped);
             mapped += PAGE_SIZE;
         }
         for ( ; j < PAGE_SIZE / sizeof(unsigned long); j++)
diff -r 2a8eaba24bf0 extras/mini-os/include/fbfront.h
--- a/extras/mini-os/include/fbfront.h	Tue Feb 26 15:11:51 2008 +0000
+++ b/extras/mini-os/include/fbfront.h	Wed Feb 27 18:30:05 2008 +0000
@@ -14,6 +14,9 @@
 #ifndef KEY_Q
 #define KEY_Q 16
 #endif
+#ifndef KEY_MAX
+#define KEY_MAX 0x1ff
+#endif
 
 
 struct kbdfront_dev;
diff -r 2a8eaba24bf0 stubdom/README
--- a/stubdom/README	Tue Feb 26 15:11:51 2008 +0000
+++ b/stubdom/README	Wed Feb 27 18:30:05 2008 +0000
@@ -6,6 +6,73 @@ Then make install to install the result.
 
 Also, run make and make install in $XEN_ROOT/tools/fs-back
 
+General Configuration
+=====================
+
+In your HVM config "hvmconfig",
+
+- use /usr/lib/xen/bin/stubdom-dm as dm script
+
+device_model = '/usr/lib/xen/bin/stubdom-dm'
+
+- comment the disk statement:
+
+#disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
+
+
+Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is the name of your HVM
+guest) with
+
+kernel = "/usr/lib/xen/boot/stubdom.gz"
+vif = [ '', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
+disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
+
+where
+- the first vif ('') is reserved for VNC (see below)
+- 'ip=10.0.1.1,mac= etc...' is the same net configuration as in the hvmconfig
+script,
+- and disk = is the same block configuration as in the hvmconfig script.
+
+Display Configuration
+=====================
+
+There are three posibilities
+
+* Using SDL
+
+In hvmconfig, disable vnc:
+
+vnc = 0
+
+In stubdom-hvmconfig, set a vfb:
+
+vfb = [ 'type=sdl' ]
+
+* Using a VNC server in the stub domain
+
+In hvmconfig, set vnclisten to "172.30.206.1" for instance.  Do not use a host
+name as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since then
+you will not be able to connect to it.
+
+vnc = 1
+vnclisten = "172.30.206.1"
+
+In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance:
+
+vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
+
+* Using a VNC server in dom0
+
+In hvmconfig, disable vnc:
+
+vnc = 0
+
+In stubdom-hvmconfig, set a vfb:
+
+vfb = [ 'type=vnc' ]
+
+and any other parameter as wished.
+
 To run
 ======
 
@@ -13,32 +80,4 @@ ln -s /usr/share/qemu/keymaps /exports/u
 ln -s /usr/share/qemu/keymaps /exports/usr/share/qemu
 /usr/sbin/fs-backend &
 
-
-In your HVM config "hvmconfig",
-
-- use VNC, set vnclisten to "172.30.206.1" for instance.  Do not use a host name
-as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since then you
-will not be able to connect to it.
-
-vnc = 1
-vnclisten = "172.30.206.1"
-
-- use /usr/lib/xen/bin/stubdom-dm as dm script
-
-device_model = '/usr/lib/xen/bin/stubdom-dm'
-
-- comment the disk statement:
-#disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
-
-Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is your HVM guest domain
-name) with
-
-kernel = "/usr/lib/xen/boot/stubdom.gz"
-vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
-disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
-
-where
-- 172.30.206.1 is the IP for vnc,
-- 'ip=10.0.1.1,mac= etc...' is the same net configuration as in the hvmconfig
-script,
-- and disk = is the same block configuration as in the hvmconfig script.
+xm create hvmconfig
diff -r 2a8eaba24bf0 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c	Tue Feb 26 15:11:51 2008 +0000
+++ b/tools/ioemu/hw/xenfb.c	Wed Feb 27 18:30:05 2008 +0000
@@ -18,6 +18,12 @@
 #include <xs.h>
 
 #include "xenfb.h"
+
+#ifdef CONFIG_STUBDOM
+#include <semaphore.h>
+#include <sched.h>
+#include <fbfront.h>
+#endif
 
 #ifndef BTN_LEFT
 #define BTN_LEFT 0x110 /* from <linux/input.h> */
@@ -1124,12 +1130,10 @@ static void xenfb_guest_copy(struct xenf
     dpy_update(xenfb->ds, x, y, w, h);
 }
 
-/* QEMU display state changed, so refresh the framebuffer copy */
-/* XXX - can we optimize this, or the next func at all ? */ 
+/* Periodic update of display, no need for any in our case */
 static void xenfb_update(void *opaque)
 {
     struct xenfb *xenfb = opaque;
-    xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
 }
 
 /* QEMU display state changed, so refresh the framebuffer copy */
@@ -1169,6 +1173,206 @@ static int xenfb_register_console(struct
         return 0;
 }
 
+#ifdef CONFIG_STUBDOM
+static struct semaphore kbd_sem = __SEMAPHORE_INITIALIZER(kbd_sem, 0);
+static struct kbdfront_dev *kbd_dev;
+static char *kbd_path, *fb_path;
+
+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)
+{
+    kbd_path = strdup(path);
+    return 0;
+}
+
+int xenfb_connect_vfb(const char *path)
+{
+    fb_path = strdup(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;
+    fbfront_update(fb_dev, x, y, w, h);
+}
+
+static void xenfb_pv_resize(DisplayState *s, int w, int h)
+{
+    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_colourdepth(DisplayState *s, int depth)
+{
+    /* TODO: send redepth event if supported */
+    fprintf(stderr,"redepth to %d required\n", depth);
+}
+
+static void xenfb_kbd_handler(void *opaque)
+{
+#define KBD_NUM_BATCH 64
+    union xenkbd_in_event buf[KBD_NUM_BATCH];
+    int n, i;
+    DisplayState *s = opaque;
+    static int buttons;
+    static int x, y, z;
+
+    n = kbdfront_receive(kbd_dev, buf, KBD_NUM_BATCH);
+    for (i = 0; i < n; i++) {
+        switch (buf[i].type) {
+
+            case XENKBD_TYPE_MOTION:
+                fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
+                break;
+
+            case XENKBD_TYPE_POS:
+            {
+                int new_x = buf[i].pos.abs_x;
+                int new_y = buf[i].pos.abs_y;
+                int new_z = buf[i].pos.abs_z;
+                if (new_x >= s->width)
+                    new_x = s->width - 1;
+                if (new_y >= s->height)
+                    new_y = s->height - 1;
+                if (kbd_mouse_is_absolute()) {
+                    kbd_mouse_event(
+                            new_x * 0x7FFF / (s->width - 1),
+                            new_y * 0x7FFF / (s->height - 1),
+                            new_z,
+                            buttons);
+                } else {
+                    kbd_mouse_event(
+                            new_x - x,
+                            new_y - y,
+                            new_z - z,
+                            buttons);
+                }
+                x = new_x;
+                y = new_y;
+                z = new_z;
+                break;
+            }
+
+            case XENKBD_TYPE_KEY:
+            {
+                int keycode = buf[i].key.keycode;
+                int button = 0;
+
+                if (keycode == BTN_LEFT)
+                    button = MOUSE_EVENT_LBUTTON;
+                else if (keycode == BTN_RIGHT)
+                    button = MOUSE_EVENT_RBUTTON;
+                else if (keycode == BTN_MIDDLE)
+                    button = MOUSE_EVENT_MBUTTON;
+
+                if (button) {
+                    if (buf[i].key.pressed)
+                        buttons |=  button;
+                    else
+                        buttons &= ~button;
+                    if (kbd_mouse_is_absolute())
+                        kbd_mouse_event(
+                                x * 0x7FFF / s->width,
+                                y * 0x7FFF / s->height,
+                                z,
+                                buttons);
+                    else
+                        kbd_mouse_event(0, 0, 0, buttons);
+                } else {
+                    int scancode = linux2scancode[keycode];
+                    if (!scancode) {
+                        fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
+                        break;
+                    }
+                    if (scancode & 0x80) {
+                        kbd_put_keycode(0xe0);
+                        scancode &= 0x7f;
+                    }
+                    if (!buf[i].key.pressed)
+                        scancode |= 0x80;
+                    kbd_put_keycode(scancode);
+                }
+                break;
+            }
+        }
+    }
+}
+
+static void xenfb_pv_refresh(DisplayState *ds)
+{
+    vga_hw_update();
+}
+
+static void kbdfront_thread(void *p)
+{
+    int scancode, keycode;
+    kbd_dev = init_kbdfront(p, 1);
+    if (!kbd_dev) {
+        fprintf(stderr,"can't open keyboard\n");
+        exit(1);
+    }
+    up(&kbd_sem);
+    for (scancode = 0; scancode < 128; scancode++) {
+        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
+        linux2scancode[keycode] = scancode;
+        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
+        linux2scancode[keycode] = scancode | 0x80;
+    }
+}
+
+int xenfb_pv_display_init(DisplayState *ds)
+{
+    void *data;
+    struct fbfront_dev *fb_dev;
+    int kbd_fd;
+
+    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);
+    if (!fb_dev) {
+        fprintf(stderr,"can't open frame buffer\n");
+        exit(1);
+    }
+    free(fb_path);
+
+    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 = NULL; //xenfb_pv_colourdepth;
+    ds->dpy_refresh = xenfb_pv_refresh;
+    ds->opaque = fb_dev;
+    return 0;
+}
+#endif
+
 /*
  * Local variables:
  *  c-indent-level: 8
diff -r 2a8eaba24bf0 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c	Tue Feb 26 15:11:51 2008 +0000
+++ b/tools/ioemu/vl.c	Wed Feb 27 18:30:05 2008 +0000
@@ -7831,6 +7831,10 @@ int main(int argc, char **argv)
     init_ioports();
 
     /* terminal init */
+#ifdef CONFIG_STUBDOM
+    if (xenfb_pv_display_init(ds) == 0) {
+    } else
+#endif
     if (nographic) {
         dumb_display_init(ds);
     } else if (vnc_display != NULL || vncunused != 0) {
diff -r 2a8eaba24bf0 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h	Tue Feb 26 15:11:51 2008 +0000
+++ b/tools/ioemu/vl.h	Wed Feb 27 18:30:05 2008 +0000
@@ -1525,6 +1525,11 @@ int xenstore_vm_write(int domid, char *k
 int xenstore_vm_write(int domid, char *key, char *val);
 char *xenstore_vm_read(int domid, char *key, unsigned int *len);
 
+/* xenfb.c */
+int xenfb_pv_display_init(DisplayState *ds);
+int xenfb_connect_vkbd(const char *path);
+int xenfb_connect_vfb(const char *path);
+
 /* helper2.c */
 extern long time_offset;
 void timeoffset_get(void);
diff -r 2a8eaba24bf0 tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c	Tue Feb 26 15:11:51 2008 +0000
+++ b/tools/ioemu/xenstore.c	Wed Feb 27 18:30:05 2008 +0000
@@ -238,6 +238,37 @@ void xenstore_parse_domain_config(int do
         }
     }
 
+#ifdef CONFIG_STUBDOM
+    if (pasprintf(&buf, "%s/device/vkbd", path) == -1)
+        goto out;
+
+    free(e);
+    e = xs_directory(xsh, XBT_NULL, buf, &num);
+
+    if (e) {
+        for (i = 0; i < num; i++) {
+            if (pasprintf(&buf, "%s/device/vkbd/%s", path, e[i]) == -1)
+                continue;
+            xenfb_connect_vkbd(buf);
+        }
+    }
+
+    if (pasprintf(&buf, "%s/device/vfb", path) == -1)
+        goto out;
+
+    free(e);
+    e = xs_directory(xsh, XBT_NULL, buf, &num);
+
+    if (e) {
+        for (i = 0; i < num; i++) {
+            if (pasprintf(&buf, "%s/device/vfb/%s", path, e[i]) == -1)
+                continue;
+            xenfb_connect_vfb(buf);
+        }
+    }
+#endif
+
+
     /* Set a watch for log-dirty requests from the migration tools */
     if (pasprintf(&buf, "/local/domain/0/device-model/%u/logdirty/next-active",
                   domid) != -1) {

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] stubdom: use PVFB so as to e.g. permit SDL display
  2008-02-27 18:42 [PATCH] stubdom: use PVFB so as to e.g. permit SDL display Samuel Thibault
@ 2008-02-27 18:45 ` Samuel Thibault
  0 siblings, 0 replies; 2+ messages in thread
From: Samuel Thibault @ 2008-02-27 18:45 UTC (permalink / raw)
  To: xen-devel

Samuel Thibault, le Wed 27 Feb 2008 18:42:19 +0000, a écrit :
> +#define WIDTH 1024
> +#define HEIGHT 768
> +#define DEPTH 32
> +#define LINESIZE (1280 * (DEPTH / 8))
> +#define MEMSIZE (LINESIZE * HEIGHT)

Note: because the PVFB resize patch has not been integrated yet, for now
the window is always set to 1024x768, and output is clipped to that.

Samuel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-02-27 18:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-27 18:42 [PATCH] stubdom: use PVFB so as to e.g. permit SDL display Samuel Thibault
2008-02-27 18:45 ` Samuel Thibault

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.