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-devel

[Xen-devel] [PATCH] minios: add PVFB support

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] minios: add PVFB support
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
Date: Tue, 26 Feb 2008 14:12:15 +0000
Delivery-date: Tue, 26 Feb 2008 06:13:45 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
minios: add PVFB support

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>

diff -r cb3e47897b85 extras/mini-os/fbfront.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/fbfront.c  Tue Feb 26 13:13:00 2008 +0000
@@ -0,0 +1,468 @@
+/*
+ * Frame Buffer + Keyboard driver for Mini-OS. 
+ * Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, 2008
+ * Based on blkfront.c.
+ */
+
+#include <os.h>
+#include <xenbus.h>
+#include <events.h>
+#include <xen/io/kbdif.h>
+#include <xen/io/fbif.h>
+#include <xen/io/protocols.h>
+#include <gnttab.h>
+#include <xmalloc.h>
+#include <fbfront.h>
+#include <lib.h>
+
+DECLARE_WAIT_QUEUE_HEAD(kbdfront_queue);
+
+
+
+
+
+
+struct kbdfront_dev {
+    domid_t dom;
+
+    struct xenkbd_page *page;
+    evtchn_port_t evtchn, local_port;
+
+    char *nodename;
+    char *backend;
+
+    char *data;
+    int width;
+    int height;
+    int depth;
+    int line_length;
+    int mem_length;
+
+#ifdef HAVE_LIBC
+    int fd;
+#endif
+};
+
+void kbdfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
+{
+#ifdef HAVE_LIBC
+    struct kbdfront_dev *dev = data;
+    int fd = dev->fd;
+
+    files[fd].read = 1;
+#endif
+    wake_up(&kbdfront_queue);
+}
+
+struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer)
+{
+    xenbus_transaction_t xbt;
+    char* err;
+    char* message=NULL;
+    struct xenkbd_page *s;
+    int retry=0;
+    char* msg;
+
+    struct kbdfront_dev *dev;
+
+    if (!nodename)
+        nodename = "device/vkbd/0";
+
+    char path[strlen(nodename) + 1 + 10 + 1];
+
+    printk("******************* KBDFRONT for %s **********\n\n\n", nodename);
+
+    dev = malloc(sizeof(*dev));
+    dev->nodename = strdup(nodename);
+
+    evtchn_alloc_unbound_t op;
+    op.dom = DOMID_SELF;
+    snprintf(path, sizeof(path), "%s/backend-id", nodename);
+    dev->dom = op.remote_dom = xenbus_read_integer(path); 
+    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
+    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
+    dev->local_port = bind_evtchn(op.port, kbdfront_handler, dev);
+    dev->evtchn=op.port;
+
+    dev->page = s = (struct xenkbd_page*) alloc_page();
+    memset(s,0,PAGE_SIZE);
+
+    s->in_cons = s->in_prod = 0;
+    s->out_cons = s->out_prod = 0;
+
+    // FIXME: proper frees on failures
+again:
+    err = xenbus_transaction_start(&xbt);
+    if (err) {
+        printk("starting transaction\n");
+    }
+
+    err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s));
+    if (err) {
+        message = "writing page-ref";
+        goto abort_transaction;
+    }
+    err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
+    if (err) {
+        message = "writing event-channel";
+        goto abort_transaction;
+    }
+    if (abs_pointer) {
+        err = xenbus_printf(xbt, nodename, "request-abs-pointer", "1");
+        if (err) {
+            message = "writing event-channel";
+            goto abort_transaction;
+        }
+    }
+
+    err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */
+    if (err)
+        printk("error writing initialized: %s\n", err);
+
+
+    err = xenbus_transaction_end(xbt, 0, &retry);
+    if (retry) {
+            goto again;
+        printk("completing transaction\n");
+    }
+
+    goto done;
+
+abort_transaction:
+    xenbus_transaction_end(xbt, 1, &retry);
+    return NULL;
+
+done:
+
+    snprintf(path, sizeof(path), "%s/backend", nodename);
+    msg = xenbus_read(XBT_NIL, path, &dev->backend);
+    if (msg) {
+        printk("Error %s when reading the backend path %s\n", msg, path);
+        return NULL;
+    }
+
+    printk("backend at %s\n", dev->backend);
+
+    {
+        char path[strlen(dev->backend) + 1 + 6 + 1];
+
+        snprintf(path, sizeof(path), "%s/state", dev->backend);
+
+        xenbus_watch_path(XBT_NIL, path);
+
+        xenbus_wait_for_value(path,"4");
+
+        xenbus_unwatch_path(XBT_NIL, path);
+
+        printk("%s connected\n", dev->backend);
+
+        err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected 
*/
+    }
+
+    printk("************************** KBDFRONT\n");
+
+    return dev;
+}
+
+int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int 
n)
+{
+    struct xenkbd_page *page = dev->page;
+    uint32_t prod, cons;
+    int i;
+
+#ifdef HAVE_LIBC
+    files[dev->fd].read = 0;
+    mb(); /* Make sure to let the handler set read to 1 before we start 
looking at the ring */
+#endif
+
+    prod = page->in_prod;
+
+    if (prod == page->in_cons)
+        return 0;
+
+    rmb();      /* ensure we see ring contents up to prod */
+
+    for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++)
+        memcpy(buf + i, &XENKBD_IN_RING_REF(page, cons), sizeof(*buf));
+
+    mb();       /* ensure we got ring contents */
+    page->in_cons = cons;
+    notify_remote_via_evtchn(dev->evtchn);
+
+#ifdef HAVE_LIBC
+    if (cons != prod)
+        /* still some events to read */
+        files[dev->fd].read = 1;
+#endif
+
+    return i;
+}
+
+
+void shutdown_kbdfront(struct kbdfront_dev *dev)
+{
+    char* err;
+    char *nodename = dev->nodename;
+
+    char path[strlen(dev->backend) + 1 + 5 + 1];
+
+    printk("close kbd: backend at %s\n",dev->backend);
+
+    snprintf(path, sizeof(path), "%s/state", dev->backend);
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
+    xenbus_wait_for_value(path,"5");
+
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
+    xenbus_wait_for_value(path,"6");
+
+    unbind_evtchn(dev->local_port);
+
+    free_pages(dev->page,0);
+    free(nodename);
+    free(dev->backend);
+    free(dev);
+}
+
+#ifdef HAVE_LIBC
+int kbdfront_open(struct kbdfront_dev *dev)
+{
+    dev->fd = alloc_fd(FTYPE_KBD);
+    printk("kbd_open(%s) -> %d\n", dev->nodename, dev->fd);
+    files[dev->fd].kbd.dev = dev;
+    return dev->fd;
+}
+#endif
+
+
+
+
+
+DECLARE_WAIT_QUEUE_HEAD(fbfront_queue);
+
+
+
+
+
+
+struct fbfront_dev {
+    domid_t dom;
+
+    struct xenfb_page *page;
+    evtchn_port_t evtchn, local_port;
+
+    char *nodename;
+    char *backend;
+
+    char *data;
+    int width;
+    int height;
+    int depth;
+    int line_length;
+    int mem_length;
+};
+
+void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
+{
+    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)
+{
+    xenbus_transaction_t xbt;
+    char* err;
+    char* message=NULL;
+    struct xenfb_page *s;
+    int retry=0;
+    char* msg;
+    int i, j;
+    struct fbfront_dev *dev;
+
+    if (!nodename)
+        nodename = "device/vfb/0";
+
+    char path[strlen(nodename) + 1 + 10 + 1];
+
+    printk("******************* FBFRONT for %s **********\n\n\n", nodename);
+
+    dev = malloc(sizeof(*dev));
+    dev->nodename = strdup(nodename);
+
+    evtchn_alloc_unbound_t op;
+    op.dom = DOMID_SELF;
+    snprintf(path, sizeof(path), "%s/backend-id", nodename);
+    dev->dom = op.remote_dom = xenbus_read_integer(path); 
+    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
+    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
+    dev->local_port = bind_evtchn(op.port, fbfront_handler, dev);
+    dev->evtchn=op.port;
+
+    dev->page = s = (struct xenfb_page*) alloc_page();
+    memset(s,0,PAGE_SIZE);
+
+    s->in_cons = s->in_prod = 0;
+    s->out_cons = s->out_prod = 0;
+    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;
+
+    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++) {
+        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);
+            mapped += PAGE_SIZE;
+        }
+        for ( ; j < PAGE_SIZE / sizeof(unsigned long); j++)
+            pd[j] = 0;
+        s->pd[i] = virt_to_mfn(pd);
+    }
+    for ( ; i < max_pd; i++)
+        s->pd[i] = 0;
+
+
+    // FIXME: proper frees on failures
+again:
+    err = xenbus_transaction_start(&xbt);
+    if (err) {
+        printk("starting transaction\n");
+    }
+
+    err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s));
+    if (err) {
+        message = "writing page-ref";
+        goto abort_transaction;
+    }
+    err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
+    if (err) {
+        message = "writing event-channel";
+        goto abort_transaction;
+    }
+    err = xenbus_printf(xbt, nodename, "protocol", "%s",
+                        XEN_IO_PROTO_ABI_NATIVE);
+    if (err) {
+        message = "writing event-channel";
+        goto abort_transaction;
+    }
+    err = xenbus_printf(xbt, nodename, "feature-update", "1");
+    if (err) {
+        message = "writing event-channel";
+        goto abort_transaction;
+    }
+
+    err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */
+
+
+    err = xenbus_transaction_end(xbt, 0, &retry);
+    if (retry) {
+            goto again;
+        printk("completing transaction\n");
+    }
+
+    goto done;
+
+abort_transaction:
+    xenbus_transaction_end(xbt, 1, &retry);
+    return NULL;
+
+done:
+
+    snprintf(path, sizeof(path), "%s/backend", nodename);
+    msg = xenbus_read(XBT_NIL, path, &dev->backend);
+    if (msg) {
+        printk("Error %s when reading the backend path %s\n", msg, path);
+        return NULL;
+    }
+
+    printk("backend at %s\n", dev->backend);
+
+    {
+        char path[strlen(dev->backend) + 1 + 6 + 1];
+
+        snprintf(path, sizeof(path), "%s/state", dev->backend);
+
+        xenbus_watch_path(XBT_NIL, path);
+
+        xenbus_wait_for_value(path,"4");
+
+        printk("%s connected\n", dev->backend);
+
+        xenbus_unwatch_path(XBT_NIL, path);
+
+        err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected 
*/
+    }
+
+    printk("************************** FBFRONT\n");
+
+    return dev;
+}
+
+void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int 
height)
+{
+    struct xenfb_page *page = dev->page;
+    uint32_t prod;
+    DEFINE_WAIT(w);
+
+    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)
+        schedule();
+    remove_waiter(w);
+
+    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;
+    wmb(); /* ensure ring contents visible */
+    page->out_prod = prod + 1;
+    notify_remote_via_evtchn(dev->evtchn);
+}
+
+void shutdown_fbfront(struct fbfront_dev *dev)
+{
+    char* err;
+    char *nodename = dev->nodename;
+
+    char path[strlen(dev->backend) + 1 + 5 + 1];
+
+    printk("close fb: backend at %s\n",dev->backend);
+
+    snprintf(path, sizeof(path), "%s/state", dev->backend);
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
+    xenbus_wait_for_value(path,"5");
+
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
+    xenbus_wait_for_value(path,"6");
+
+    unbind_evtchn(dev->local_port);
+
+    free_pages(dev->page,0);
+    free(nodename);
+    free(dev->backend);
+    free(dev);
+}
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/fbfront.h  Tue Feb 26 13:13:00 2008 +0000
@@ -0,0 +1,38 @@
+#include <xen/io/kbdif.h>
+#include <wait.h>
+
+/* from <linux/input.h> */
+#ifndef BTN_LEFT
+#define BTN_LEFT 0x110
+#endif
+#ifndef BTN_RIGHT
+#define BTN_RIGHT 0x111
+#endif
+#ifndef BTN_MIDDLE
+#define BTN_MIDDLE 0x112
+#endif
+#ifndef KEY_Q
+#define KEY_Q 16
+#endif
+
+
+struct kbdfront_dev;
+struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer);
+#ifdef HAVE_LIBC
+int kbdfront_open(struct kbdfront_dev *dev);
+#endif
+
+int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int 
n);
+extern struct wait_queue_head kbdfront_queue;
+
+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);
+#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 shutdown_fbfront(struct fbfront_dev *dev);
--- a/extras/mini-os/include/lib.h      Mon Feb 25 11:24:06 2008 +0000
+++ b/extras/mini-os/include/lib.h      Tue Feb 26 13:13:00 2008 +0000
@@ -140,6 +140,7 @@
     FTYPE_SOCKET,
     FTYPE_TAP,
     FTYPE_BLK,
+    FTYPE_KBD,
 };
 
 #define MAX_EVTCHN_PORTS 16
@@ -171,6 +172,9 @@
        struct {
            struct blkfront_dev *dev;
        } blk;
+       struct {
+           struct kbdfront_dev *dev;
+       } kbd;
         struct {
             /* To each xenbus FD is associated a queue of watch events for this
              * FD.  */
--- a/extras/mini-os/kernel.c   Mon Feb 25 11:24:06 2008 +0000
+++ b/extras/mini-os/kernel.c   Tue Feb 26 13:13:00 2008 +0000
@@ -39,6 +39,7 @@
 #include <gnttab.h>
 #include <netfront.h>
 #include <blkfront.h>
+#include <fbfront.h>
 #include <fs.h>
 #include <xmalloc.h>
 #include <fcntl.h>
@@ -248,6 +249,152 @@
     }
 }
 
+#define WIDTH 800
+#define HEIGHT 600
+#define DEPTH 32
+
+static uint32_t *fb;
+static struct fbfront_dev *fb_dev;
+static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0);
+
+static void fbfront_drawvert(int x, int y1, int y2, uint32_t color)
+{
+    int y;
+    if (x < 0)
+        return;
+    if (x >= WIDTH)
+        return;
+    if (y1 < 0)
+        y1 = 0;
+    if (y2 >= HEIGHT)
+        y2 = HEIGHT-1;
+    for (y = y1; y <= y2; y++)
+        fb[x + y*WIDTH] ^= color;
+}
+
+static void fbfront_drawhoriz(int x1, int x2, int y, uint32_t color)
+{
+    int x;
+    if (y < 0)
+        return;
+    if (y >= HEIGHT)
+        return;
+    if (x1 < 0)
+        x1 = 0;
+    if (x2 >= WIDTH)
+        x2 = WIDTH-1;
+    for (x = x1; x <= x2; x++)
+        fb[x + y*WIDTH] ^= color;
+}
+
+static void fbfront_thread(void *p)
+{
+    size_t line_length = WIDTH * (DEPTH / 8);
+    size_t memsize = HEIGHT * line_length;
+
+    fb = _xmalloc(memsize, PAGE_SIZE);
+    fb_dev = init_fbfront(NULL, fb, WIDTH, HEIGHT, DEPTH, line_length, 
memsize);
+    if (!fb_dev) {
+        xfree(fb);
+        return;
+    }
+    up(&fbfront_sem);
+}
+
+static void clip_cursor(int *x, int *y)
+{
+    if (*x < 0)
+        *x = 0;
+    if (*x >= WIDTH)
+        *x = WIDTH - 1;
+    if (*y < 0)
+        *y = 0;
+    if (*y >= HEIGHT)
+        *y = HEIGHT - 1;
+}
+
+static void refresh_cursor(int new_x, int new_y)
+{
+    static int old_x = -1, old_y = -1;
+    if (old_x != -1 && old_y != -1) {
+        fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff);
+        fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff);
+        fbfront_update(fb_dev, old_x, old_y, 9, 9);
+    }
+    old_x = new_x;
+    old_y = new_y;
+    fbfront_drawvert(new_x, new_y + 1, new_y + 8, 0xffffffff);
+    fbfront_drawhoriz(new_x + 1, new_x + 8, new_y, 0xffffffff);
+    fbfront_update(fb_dev, new_x, new_y, 9, 9);
+}
+
+static void kbdfront_thread(void *p)
+{
+    struct kbdfront_dev *kbd_dev;
+    DEFINE_WAIT(w);
+    int x = WIDTH / 2, y = HEIGHT / 2, z;
+
+    kbd_dev = init_kbdfront(NULL, 1);
+    if (!kbd_dev)
+        return;
+
+    down(&fbfront_sem);
+    refresh_cursor(x, y);
+    while (1) {
+        union xenkbd_in_event event;
+
+        add_waiter(w, kbdfront_queue);
+
+        if (kbdfront_receive(kbd_dev, &event, 1) == 0)
+            schedule();
+        else switch(event.type) {
+            case XENKBD_TYPE_MOTION:
+                printk("motion x:%d y:%d z:%d\n",
+                        event.motion.rel_x,
+                        event.motion.rel_y,
+                        event.motion.rel_z);
+                x += event.motion.rel_x;
+                y += event.motion.rel_y;
+                z += event.motion.rel_z;
+                clip_cursor(&x, &y);
+                refresh_cursor(x, y);
+                break;
+            case XENKBD_TYPE_POS:
+                printk("pos x:%d y:%d z:%d\n",
+                        event.pos.abs_x,
+                        event.pos.abs_y,
+                        event.pos.abs_z);
+                x = event.pos.abs_x;
+                y = event.pos.abs_y;
+                z = event.pos.abs_z;
+                clip_cursor(&x, &y);
+                refresh_cursor(x, y);
+                break;
+            case XENKBD_TYPE_KEY:
+                printk("key %d %s\n",
+                        event.key.keycode,
+                        event.key.pressed ? "pressed" : "released");
+                if (event.key.keycode == BTN_LEFT) {
+                    printk("mouse %s at (%d,%d,%d)\n",
+                            event.key.pressed ? "clic" : "release", x, y, z);
+                    if (event.key.pressed) {
+                        uint32_t color = rand();
+                        fbfront_drawvert(x - 16, y - 16, y + 15, color);
+                        fbfront_drawhoriz(x - 16, x + 15, y + 16, color);
+                        fbfront_drawvert(x + 16, y - 15, y + 16, color);
+                        fbfront_drawhoriz(x - 15, x + 16, y - 16, color);
+                        fbfront_update(fb_dev, x - 16, y - 16, 33, 33);
+                    }
+                } else if (event.key.keycode == KEY_Q) {
+                    struct sched_shutdown sched_shutdown = { .reason = 
SHUTDOWN_poweroff };
+                    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
+                    do_exit();
+                }
+                break;
+        }
+    }
+}
+
 static void fs_thread(void *p)
 {
     init_fs_frontend();
@@ -261,6 +408,8 @@
     create_thread("periodic_thread", periodic_thread, si);
     create_thread("netfront", netfront_thread, si);
     create_thread("blkfront", blkfront_thread, si);
+    create_thread("fbfront", fbfront_thread, si);
+    create_thread("kbdfront", kbdfront_thread, si);
     create_thread("fs-frontend", fs_thread, si);
     return 0;
 }
--- a/extras/mini-os/lib/sys.c  Mon Feb 25 11:24:06 2008 +0000
+++ b/extras/mini-os/lib/sys.c  Tue Feb 26 13:13:00 2008 +0000
@@ -26,6 +26,7 @@
 #include <wait.h>
 #include <netfront.h>
 #include <blkfront.h>
+#include <fbfront.h>
 #include <xenbus.h>
 #include <xs.h>
 
@@ -221,6 +222,16 @@
            }
            return ret;
        }
+        case FTYPE_KBD: {
+            int ret, n;
+            n = nbytes / sizeof(union xenkbd_in_event);
+            ret = kbdfront_receive(files[fd].kbd.dev, buf, n);
+           if (ret <= 0) {
+               errno = EAGAIN;
+               return -1;
+           }
+           return ret * sizeof(union xenkbd_in_event);
+        }
        case FTYPE_NONE:
        case FTYPE_XENBUS:
        case FTYPE_EVTCHN:
@@ -261,6 +272,7 @@
        case FTYPE_XENBUS:
        case FTYPE_EVTCHN:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
     printk("write(%d): Bad descriptor\n", fd);
@@ -318,6 +330,7 @@
        case FTYPE_EVTCHN:
        case FTYPE_TAP:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
     printk("fsync(%d): Bad descriptor\n", fd);
@@ -360,6 +373,10 @@
             shutdown_blkfront(files[fd].blk.dev);
            files[fd].type = FTYPE_NONE;
            return 0;
+       case FTYPE_KBD:
+            shutdown_kbdfront(files[fd].kbd.dev);
+            files[fd].type = FTYPE_NONE;
+            return 0;
        case FTYPE_NONE:
            break;
     }
@@ -450,6 +467,7 @@
        case FTYPE_EVTCHN:
        case FTYPE_TAP:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
 
@@ -477,6 +495,7 @@
        case FTYPE_EVTCHN:
        case FTYPE_TAP:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
 
@@ -587,6 +606,7 @@
     [FTYPE_SOCKET]     = 'S',
     [FTYPE_TAP]                = 'T',
     [FTYPE_BLK]                = 'B',
+    [FTYPE_KBD]                = 'K',
 };
 #ifdef LIBC_DEBUG
 static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set 
*exceptfds, struct timeval *timeout)
@@ -694,6 +714,7 @@
        case FTYPE_EVTCHN:
        case FTYPE_TAP:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            if (FD_ISSET(i, readfds)) {
                if (files[i].read)
                    n++;
@@ -775,6 +796,7 @@
     DEFINE_WAIT(w2);
     DEFINE_WAIT(w3);
     DEFINE_WAIT(w4);
+    DEFINE_WAIT(w5);
 
     assert(thread == main_thread);
 
@@ -795,6 +817,7 @@
     add_waiter(w2, event_queue);
     add_waiter(w3, blkfront_queue);
     add_waiter(w4, xenbus_watch_queue);
+    add_waiter(w5, kbdfront_queue);
 
     myread = *readfds;
     mywrite = *writefds;
@@ -860,6 +883,7 @@
     remove_waiter(w2);
     remove_waiter(w3);
     remove_waiter(w4);
+    remove_waiter(w5);
     return ret;
 }
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] minios: add PVFB support, Samuel Thibault <=