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] minios: add PVFB support

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] minios: add PVFB support
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 26 Feb 2008 11:20:17 -0800
Delivery-date: Tue, 26 Feb 2008 11:21:05 -0800
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 1204037243 0
# Node ID 580bcd4c9642ed6f83b4c35ae0a13bb61efe7035
# Parent  ca2cf5c1adccba39aba6b08d5107cd4c5d1dfd42
minios: add PVFB support
Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
 extras/mini-os/fbfront.c         |  468 +++++++++++++++++++++++++++++++++++++++
 extras/mini-os/include/fbfront.h |   38 +++
 extras/mini-os/include/lib.h     |    4 
 extras/mini-os/kernel.c          |  149 ++++++++++++
 extras/mini-os/lib/sys.c         |   24 ++
 5 files changed, 683 insertions(+)

diff -r ca2cf5c1adcc -r 580bcd4c9642 extras/mini-os/fbfront.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/fbfront.c  Tue Feb 26 14:47:23 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);
+}
diff -r ca2cf5c1adcc -r 580bcd4c9642 extras/mini-os/include/fbfront.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/fbfront.h  Tue Feb 26 14:47:23 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);
diff -r ca2cf5c1adcc -r 580bcd4c9642 extras/mini-os/include/lib.h
--- a/extras/mini-os/include/lib.h      Tue Feb 26 14:46:57 2008 +0000
+++ b/extras/mini-os/include/lib.h      Tue Feb 26 14:47:23 2008 +0000
@@ -140,6 +140,7 @@ enum fd_type {
     FTYPE_SOCKET,
     FTYPE_TAP,
     FTYPE_BLK,
+    FTYPE_KBD,
 };
 
 #define MAX_EVTCHN_PORTS 16
@@ -171,6 +172,9 @@ extern struct file {
        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.  */
diff -r ca2cf5c1adcc -r 580bcd4c9642 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Tue Feb 26 14:46:57 2008 +0000
+++ b/extras/mini-os/kernel.c   Tue Feb 26 14:47:23 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 @@ static void blkfront_thread(void *p)
     }
 }
 
+#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 @@ __attribute__((weak)) int app_main(start
     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;
 }
diff -r ca2cf5c1adcc -r 580bcd4c9642 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c  Tue Feb 26 14:46:57 2008 +0000
+++ b/extras/mini-os/lib/sys.c  Tue Feb 26 14:47:23 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 @@ int read(int fd, void *buf, size_t nbyte
            }
            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 @@ int write(int fd, const void *buf, size_
        case FTYPE_XENBUS:
        case FTYPE_EVTCHN:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
     printk("write(%d): Bad descriptor\n", fd);
@@ -318,6 +330,7 @@ int fsync(int fd) {
        case FTYPE_EVTCHN:
        case FTYPE_TAP:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
     printk("fsync(%d): Bad descriptor\n", fd);
@@ -360,6 +373,10 @@ int close(int fd)
             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 @@ int fstat(int fd, struct stat *buf)
        case FTYPE_EVTCHN:
        case FTYPE_TAP:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
 
@@ -477,6 +495,7 @@ int ftruncate(int fd, off_t length)
        case FTYPE_EVTCHN:
        case FTYPE_TAP:
        case FTYPE_BLK:
+       case FTYPE_KBD:
            break;
     }
 
@@ -587,6 +606,7 @@ static const char file_types[] = {
     [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 @@ static int select_poll(int nfds, fd_set 
        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 @@ int select(int nfds, fd_set *readfds, fd
     DEFINE_WAIT(w2);
     DEFINE_WAIT(w3);
     DEFINE_WAIT(w4);
+    DEFINE_WAIT(w5);
 
     assert(thread == main_thread);
 
@@ -795,6 +817,7 @@ int select(int nfds, fd_set *readfds, fd
     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 @@ out:
     remove_waiter(w2);
     remove_waiter(w3);
     remove_waiter(w4);
+    remove_waiter(w5);
     return ret;
 }
 

_______________________________________________
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] minios: add PVFB support, Xen patchbot-unstable <=