[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1204045924 25200
# Node ID f97a0b6152c3ce0c5a0428d729be27d02e4eabe1
# Parent  7e8334e651c479fc1277db84d49a97b73b86d27e
# Parent  2a8eaba24bf0482db8d44aa1c638ffa7e3894f43
merge with xen-unstable.hg
---
 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/math.c               |   23 
 extras/mini-os/lib/sys.c                |   24 
 stubdom/README                          |   17 
 stubdom/stubdom-dm                      |    3 
 tools/blktap/drivers/block-aio.c        |  144 ----
 tools/blktap/drivers/block-qcow.c       |  249 +------
 tools/blktap/drivers/block-qcow2.c      |  275 --------
 tools/blktap/drivers/tapaio.c           |  190 +++++
 tools/blktap/drivers/tapaio.h           |   64 +
 tools/examples/vtpm-common.sh           |   25 
 tools/examples/vtpm-delete              |   13 
 tools/firmware/hvmloader/acpi/build.c   |   78 --
 tools/firmware/hvmloader/acpi/dsdt.asl  |   20 
 tools/firmware/hvmloader/acpi/dsdt.c    | 1059 ++++++++++++++++----------------
 tools/ioemu/Makefile.target             |    4 
 tools/ioemu/hw/e1000.c                  |  995 ++++++++++++++++++++++++++++++
 tools/ioemu/hw/e1000_hw.h               |  865 ++++++++++++++++++++++++++
 tools/ioemu/hw/pci.c                    |    2 
 tools/ioemu/hw/xen_console.c            |    2 
 tools/ioemu/hw/xenfb.c                  |    2 
 tools/ioemu/osdep.c                     |    2 
 tools/ioemu/vl.h                        |    5 
 tools/ioemu/vnc.c                       |  196 +++++
 tools/python/xen/lowlevel/xc/xc.c       |   13 
 tools/python/xen/xend/XendDomainInfo.py |    2 
 tools/python/xen/xend/XendNode.py       |   18 
 tools/python/xen/xend/image.py          |    2 
 tools/xentrace/xentrace.c               |   97 ++
 xen/arch/x86/hvm/emulate.c              |   88 +-
 xen/arch/x86/hvm/hvm.c                  |   20 
 xen/arch/x86/hvm/io.c                   |    4 
 xen/arch/x86/hvm/svm/svm.c              |   35 -
 xen/arch/x86/hvm/vmx/intr.c             |    4 
 xen/arch/x86/hvm/vmx/realmode.c         |  143 +---
 xen/arch/x86/hvm/vmx/vmx.c              |   37 -
 xen/arch/x86/hvm/vmx/x86_32/exits.S     |    9 
 xen/arch/x86/hvm/vmx/x86_64/exits.S     |    9 
 xen/arch/x86/mm/shadow/multi.c          |    2 
 xen/arch/x86/oprofile/xenoprof.c        |   25 
 xen/arch/x86/x86_emulate.c              |  165 ++--
 xen/common/compat/xenoprof.c            |    1 
 xen/common/grant_table.c                |   24 
 xen/include/asm-ia64/grant_table.h      |    6 
 xen/include/asm-powerpc/grant_table.h   |   11 
 xen/include/asm-x86/grant_table.h       |   14 
 xen/include/asm-x86/hvm/emulate.h       |   14 
 xen/include/asm-x86/hvm/hvm.h           |   17 
 xen/include/asm-x86/x86_emulate.h       |   23 
 xen/include/asm-x86/xenoprof.h          |    1 
 xen/include/public/io/protocols.h       |   22 
 xen/include/public/kexec.h              |   18 
 xen/include/public/libelf.h             |   22 
 56 files changed, 4207 insertions(+), 1555 deletions(-)

diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/fbfront.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/fbfront.c  Tue Feb 26 10:12:04 2008 -0700
@@ -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 7e8334e651c4 -r f97a0b6152c3 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 10:12:04 2008 -0700
@@ -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 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/include/lib.h
--- a/extras/mini-os/include/lib.h      Mon Feb 25 06:29:01 2008 -0700
+++ b/extras/mini-os/include/lib.h      Tue Feb 26 10:12:04 2008 -0700
@@ -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 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Mon Feb 25 06:29:01 2008 -0700
+++ b/extras/mini-os/kernel.c   Tue Feb 26 10:12:04 2008 -0700
@@ -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 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/lib/math.c
--- a/extras/mini-os/lib/math.c Mon Feb 25 06:29:01 2008 -0700
+++ b/extras/mini-os/lib/math.c Tue Feb 26 10:12:04 2008 -0700
@@ -388,6 +388,29 @@ __umoddi3(u_quad_t a, u_quad_t b)
         return (r);
 }
 
+/*
+ * Return remainder after dividing two signed quads.
+ *
+ * XXX
+ * If -1/2 should produce -1 on this machine, this code is wrong.
+ */
+quad_t
+__moddi3(quad_t a, quad_t b)
+{
+       u_quad_t ua, ub, ur;
+       int neg;
+
+       if (a < 0)
+               ua = -(u_quad_t)a, neg = 1;
+       else
+               ua = a, neg = 0;
+       if (b < 0)
+               ub = -(u_quad_t)b;
+       else
+               ub = b;
+       (void)__qdivrem(ua, ub, &ur);
+       return (neg ? -ur : ur);
+}
 #endif /* !defined(__ia64__) */
 
 #ifndef HAVE_LIBC
diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c  Mon Feb 25 06:29:01 2008 -0700
+++ b/extras/mini-os/lib/sys.c  Tue Feb 26 10:12:04 2008 -0700
@@ -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;
 }
 
diff -r 7e8334e651c4 -r f97a0b6152c3 stubdom/README
--- a/stubdom/README    Mon Feb 25 06:29:01 2008 -0700
+++ b/stubdom/README    Tue Feb 26 10:12:04 2008 -0700
@@ -16,10 +16,12 @@ ln -s /usr/share/qemu/keymaps /exports/u
 
 In your HVM config "hvmconfig",
 
-- use VNC, set vnclisten to "172.30.206.1" for instance:
+- 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" 
+vnc = 1
+vnclisten = "172.30.206.1"
 
 - use /usr/lib/xen/bin/stubdom-dm as dm script
 
@@ -28,14 +30,15 @@ device_model = '/usr/lib/xen/bin/stubdom
 - 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 ("hvmconfig" must match your main config 
file)
-with
+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']
+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=' is the same net configuration as in the hvmconfig script,
+- '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.
diff -r 7e8334e651c4 -r f97a0b6152c3 stubdom/stubdom-dm
--- a/stubdom/stubdom-dm        Mon Feb 25 06:29:01 2008 -0700
+++ b/stubdom/stubdom-dm        Tue Feb 26 10:12:04 2008 -0700
@@ -62,11 +62,12 @@ done
 
 creation="xm create -c stubdom-$domname target=$domid memory=32"
 
-(while true ; do sleep 60 ; done) | $creation &
+(while true ; do sleep 60 ; done) | $creation > 
/var/log/xen/qemu-dm-$domid.log &
 #xterm -geometry +0+0 -e /bin/sh -c "$creation ; echo ; echo press ENTER to 
shut down ; read" &
 consolepid=$!
 
 
+# Wait for vnc server to appear
 while ! vnc_port=`xenstore-read /local/domain/$domid/console/vnc-port`
 do
         # Check that the stubdom job is still alive
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/block-aio.c
--- a/tools/blktap/drivers/block-aio.c  Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/blktap/drivers/block-aio.c  Tue Feb 26 10:12:04 2008 -0700
@@ -52,28 +52,11 @@
 #define O_LARGEFILE    0
 #endif
 
-struct pending_aio {
-       td_callback_t cb;
-       int id;
-       void *private;
-       uint64_t lsec;
-};
-
 struct tdaio_state {
        int fd;
-       
-       /* libaio state */
-       tap_aio_context_t  aio_ctx;
-       struct iocb        iocb_list  [MAX_AIO_REQS];
-       struct iocb       *iocb_free  [MAX_AIO_REQS];
-       struct pending_aio pending_aio[MAX_AIO_REQS];
-       int                iocb_free_count;
-       struct iocb       *iocb_queue[MAX_AIO_REQS];
-       int                iocb_queued;
-       struct io_event    aio_events[MAX_AIO_REQS];
+       tap_aio_context_t aio;
 };
 
-#define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list)
 
 /*Get Image size, secsize*/
 static int get_image_info(struct td_state *s, int fd)
@@ -131,7 +114,7 @@ static inline void init_fds(struct disk_
        for(i = 0; i < MAX_IOFD; i++) 
                dd->io_fd[i] = 0;
 
-       dd->io_fd[0] = prv->aio_ctx.pollfd;
+       dd->io_fd[0] = prv->aio.aio_ctx.pollfd;
 }
 
 /* Open the disk file and initialize aio state. */
@@ -142,27 +125,11 @@ int tdaio_open (struct disk_driver *dd, 
        struct tdaio_state *prv = (struct tdaio_state *)dd->private;
 
        DPRINTF("block-aio open('%s')", name);
+
        /* Initialize AIO */
-       prv->iocb_free_count = MAX_AIO_REQS;
-       prv->iocb_queued     = 0;
-
-       ret = tap_aio_setup(&prv->aio_ctx, prv->aio_events, MAX_AIO_REQS);
-       if (ret < 0) {
-                if (ret == -EAGAIN) {
-                        DPRINTF("Couldn't setup AIO context.  If you are "
-                                "trying to concurrently use a large number "
-                                "of blktap-based disks, you may need to "
-                                "increase the system-wide aio request limit. "
-                                "(e.g. 'echo echo 1048576 > /proc/sys/fs/"
-                                "aio-max-nr')\n");
-                } else {
-                        DPRINTF("Couldn't setup AIO context.\n");
-                }
-               goto done;
-       }
-
-       for (i=0;i<MAX_AIO_REQS;i++)
-               prv->iocb_free[i] = &prv->iocb_list[i];
+       ret = tap_aio_init(&prv->aio, 0, MAX_AIO_REQS);
+       if (ret != 0)
+               return ret;
 
        /* Open the file */
        o_flags = O_DIRECT | O_LARGEFILE | 
@@ -198,87 +165,40 @@ int tdaio_queue_read(struct disk_driver 
                     int nb_sectors, char *buf, td_callback_t cb,
                     int id, void *private)
 {
-       struct   iocb *io;
-       struct   pending_aio *pio;
        struct   td_state    *s   = dd->td_state;
        struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
-       long     ioidx;
-       
-       if (prv->iocb_free_count == 0)
-               return -ENOMEM;
-       io = prv->iocb_free[--prv->iocb_free_count];
-       
-       ioidx = IOCB_IDX(prv, io);
-       pio = &prv->pending_aio[ioidx];
-       pio->cb = cb;
-       pio->id = id;
-       pio->private = private;
-       pio->lsec = sector;
-       
-       io_prep_pread(io, prv->fd, buf, size, offset);
-       io->data = (void *)ioidx;
-       
-       prv->iocb_queue[prv->iocb_queued++] = io;
-
-       return 0;
+
+       return tap_aio_read(&prv->aio, prv->fd, size, offset, buf, 
+               cb, id, sector, private);
 }
                        
 int tdaio_queue_write(struct disk_driver *dd, uint64_t sector,
                      int nb_sectors, char *buf, td_callback_t cb,
                      int id, void *private)
 {
-       struct   iocb *io;
-       struct   pending_aio *pio;
        struct   td_state    *s   = dd->td_state;
        struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
        int      size    = nb_sectors * s->sector_size;
        uint64_t offset  = sector * (uint64_t)s->sector_size;
-       long     ioidx;
+
+       return tap_aio_write(&prv->aio, prv->fd, size, offset, buf,
+               cb, id, sector, private);
+}
+
+int tdaio_submit(struct disk_driver *dd)
+{
+       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
+
+       return tap_aio_submit(&prv->aio);
+}
+                       
+int tdaio_close(struct disk_driver *dd)
+{
+       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
        
-       if (prv->iocb_free_count == 0)
-               return -ENOMEM;
-       io = prv->iocb_free[--prv->iocb_free_count];
-       
-       ioidx = IOCB_IDX(prv, io);
-       pio = &prv->pending_aio[ioidx];
-       pio->cb = cb;
-       pio->id = id;
-       pio->private = private;
-       pio->lsec = sector;
-       
-       io_prep_pwrite(io, prv->fd, buf, size, offset);
-       io->data = (void *)ioidx;
-       
-       prv->iocb_queue[prv->iocb_queued++] = io;
-
-       return 0;
-}
-                       
-int tdaio_submit(struct disk_driver *dd)
-{
-       int ret;
-       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
-
-       if (!prv->iocb_queued)
-               return 0;
-
-       ret = io_submit(prv->aio_ctx.aio_ctx, prv->iocb_queued, 
prv->iocb_queue);
-       
-       /* XXX: TODO: Handle error conditions here. */
-       
-       /* Success case: */
-       prv->iocb_queued = 0;
-       
-       return 0;
-}
-
-int tdaio_close(struct disk_driver *dd)
-{
-       struct tdaio_state *prv = (struct tdaio_state *)dd->private;
-       
-       io_destroy(prv->aio_ctx.aio_ctx);
+       io_destroy(prv->aio.aio_ctx.aio_ctx);
        close(prv->fd);
 
        return 0;
@@ -290,26 +210,26 @@ int tdaio_do_callbacks(struct disk_drive
        struct io_event *ep;
        struct tdaio_state *prv = (struct tdaio_state *)dd->private;
 
-       nr_events = tap_aio_get_events(&prv->aio_ctx);
+       nr_events = tap_aio_get_events(&prv->aio.aio_ctx);
 repeat:
-       for (ep = prv->aio_events, i = nr_events; i-- > 0; ep++) {
+       for (ep = prv->aio.aio_events, i = nr_events; i-- > 0; ep++) {
                struct iocb        *io  = ep->obj;
                struct pending_aio *pio;
                
-               pio = &prv->pending_aio[(long)io->data];
+               pio = &prv->aio.pending_aio[(long)io->data];
                rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1,
-                              pio->lsec, io->u.c.nbytes >> 9, 
+                              pio->sector, io->u.c.nbytes >> 9, 
                               pio->id, pio->private);
 
-               prv->iocb_free[prv->iocb_free_count++] = io;
+               prv->aio.iocb_free[prv->aio.iocb_free_count++] = io;
        }
 
        if (nr_events) {
-               nr_events = tap_aio_more_events(&prv->aio_ctx);
+               nr_events = tap_aio_more_events(&prv->aio.aio_ctx);
                goto repeat;
        }
 
-       tap_aio_continue(&prv->aio_ctx);
+       tap_aio_continue(&prv->aio.aio_ctx);
 
        return rsp;
 }
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/blktap/drivers/block-qcow.c Tue Feb 26 10:12:04 2008 -0700
@@ -59,15 +59,7 @@
         (l + (s - 1)) - ((l + (s - 1)) % s)); \
 })
 
-struct pending_aio {
-        td_callback_t cb;
-        int id;
-        void *private;
-       int nb_sectors;
-       char *buf;
-       uint64_t sector;
-};
-
+#undef IOCB_IDX
 #define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list)
 
 #define ZERO_TEST(_b) (_b | 0x00)
@@ -140,109 +132,18 @@ struct tdqcow_state {
        uint32_t l2_cache_counts[L2_CACHE_SIZE];      /*Cache access record*/
        uint8_t *cluster_cache;          
        uint8_t *cluster_data;
-       uint8_t *sector_lock;          /*Locking bitmap for AIO reads/writes*/
        uint64_t cluster_cache_offset; /**/
        uint32_t crypt_method;         /*current crypt method, 0 if no 
                                        *key yet */
        uint32_t crypt_method_header;  /**/
        AES_KEY aes_encrypt_key;       /*AES key*/
        AES_KEY aes_decrypt_key;       /*AES key*/
-        /* libaio state */
-        tap_aio_context_t   aio_ctx;
-        int                 max_aio_reqs;
-        struct iocb        *iocb_list;
-        struct iocb       **iocb_free;
-        struct pending_aio *pending_aio;
-        int                 iocb_free_count;
-        struct iocb       **iocb_queue;
-        int                 iocb_queued;
-        struct io_event    *aio_events;
+        
+       /* libaio state */
+       tap_aio_context_t       aio;
 };
 
 static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
-
-static void free_aio_state(struct disk_driver *dd)
-{
-        struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
-
-        if (s->sector_lock)
-                free(s->sector_lock);
-        if (s->iocb_list)
-                free(s->iocb_list);
-        if (s->pending_aio)
-                free(s->pending_aio);
-        if (s->aio_events)
-                free(s->aio_events);
-        if (s->iocb_free)
-                free(s->iocb_free);
-        if (s->iocb_queue)
-                free(s->iocb_queue);
-}
-
-static int init_aio_state(struct disk_driver *dd)
-{
-       int i, ret;
-       struct td_state     *bs = dd->td_state;
-       struct tdqcow_state  *s = (struct tdqcow_state *)dd->private;
-        long     ioidx;
-
-        s->iocb_list = NULL;
-        s->pending_aio = NULL;
-        s->aio_events = NULL;
-        s->iocb_free = NULL;
-        s->iocb_queue = NULL;
-
-        /*Initialize Locking bitmap*/
-       s->sector_lock = calloc(1, bs->size);
-       
-       if (!s->sector_lock) {
-               DPRINTF("Failed to allocate sector lock\n");
-               goto fail;
-       }
-
-        /* A segment (i.e. a page) can span multiple clusters */
-        s->max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
-            MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
-
-        /* Initialize AIO */
-        s->iocb_free_count = s->max_aio_reqs;
-        s->iocb_queued     = 0;
-
-        if (!(s->iocb_list = malloc(sizeof(struct iocb) * s->max_aio_reqs)) ||
-            !(s->pending_aio = malloc(sizeof(struct pending_aio) * 
s->max_aio_reqs)) ||
-            !(s->aio_events = malloc(sizeof(struct io_event) * 
s->max_aio_reqs)) ||
-            !(s->iocb_free = malloc(sizeof(struct iocb *) * s->max_aio_reqs)) 
||
-            !(s->iocb_queue = malloc(sizeof(struct iocb *) * 
s->max_aio_reqs))) {
-                DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
-                        s->max_aio_reqs);
-                goto fail;
-        }
-
-       ret = tap_aio_setup(&s->aio_ctx, s->aio_events, s->max_aio_reqs);
-       if (ret < 0) {
-                if (ret == -EAGAIN) {
-                        DPRINTF("Couldn't setup AIO context.  If you are "
-                                "trying to concurrently use a large number "
-                                "of blktap-based disks, you may need to "
-                                "increase the system-wide aio request limit. "
-                                "(e.g. 'echo echo 1048576 > /proc/sys/fs/"
-                                "aio-max-nr')\n");
-                } else {
-                        DPRINTF("Couldn't setup AIO context.\n");
-                }
-               goto fail;
-       }
-
-        for (i=0;i<s->max_aio_reqs;i++)
-                s->iocb_free[i] = &s->iocb_list[i];
-
-        DPRINTF("AIO state initialised\n");
-
-        return 0;
-
- fail:
-       return -1;
-}
 
 static uint32_t gen_cksum(char *ptr, int len)
 {
@@ -337,79 +238,6 @@ static int qcow_set_key(struct tdqcow_st
        }
 #endif
        return 0;
-}
-
-static int async_read(struct tdqcow_state *s, int size, 
-                     uint64_t offset, char *buf, td_callback_t cb,
-                     int id, uint64_t sector, void *private)
-{
-        struct   iocb *io;
-        struct   pending_aio *pio;
-       long     ioidx;
-
-        io = s->iocb_free[--s->iocb_free_count];
-
-        ioidx = IOCB_IDX(s, io);
-        pio = &s->pending_aio[ioidx];
-        pio->cb = cb;
-        pio->id = id;
-        pio->private = private;
-       pio->nb_sectors = size/512;
-       pio->buf = buf;
-       pio->sector = sector;
-
-        io_prep_pread(io, s->fd, buf, size, offset);
-        io->data = (void *)ioidx;
-
-        s->iocb_queue[s->iocb_queued++] = io;
-
-        return 1;
-}
-
-static int async_write(struct tdqcow_state *s, int size,
-                      uint64_t offset, char *buf, td_callback_t cb,
-                      int id, uint64_t sector, void *private)
-{
-        struct   iocb *io;
-        struct   pending_aio *pio;
-       long     ioidx;
-
-        io = s->iocb_free[--s->iocb_free_count];
-
-        ioidx = IOCB_IDX(s, io);
-        pio = &s->pending_aio[ioidx];
-        pio->cb = cb;
-        pio->id = id;
-        pio->private = private;
-       pio->nb_sectors = size/512;
-       pio->buf = buf;
-       pio->sector = sector;
-
-        io_prep_pwrite(io, s->fd, buf, size, offset);
-        io->data = (void *)ioidx;
-
-        s->iocb_queue[s->iocb_queued++] = io;
-
-        return 1;
-}
-
-/*TODO: Fix sector span!*/
-static int aio_can_lock(struct tdqcow_state *s, uint64_t sector)
-{
-       return (s->sector_lock[sector] ? 0 : 1);
-}
-
-static int aio_lock(struct tdqcow_state *s, uint64_t sector)
-{
-       return ++s->sector_lock[sector];
-}
-
-static void aio_unlock(struct tdqcow_state *s, uint64_t sector)
-{
-       if (!s->sector_lock[sector]) return;
-
-       --s->sector_lock[sector];
-       return;
 }
 
 /* 
@@ -841,13 +669,14 @@ static inline void init_fds(struct disk_
        for(i = 0; i < MAX_IOFD; i++) 
                dd->io_fd[i] = 0;
 
-       dd->io_fd[0] = s->aio_ctx.pollfd;
+       dd->io_fd[0] = s->aio.aio_ctx.pollfd;
 }
 
 /* Open the disk file and initialize qcow state. */
 int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags)
 {
        int fd, len, i, shift, ret, size, l1_table_size, o_flags;
+       int max_aio_reqs;
        struct td_state     *bs = dd->td_state;
        struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
        char *buf;
@@ -996,9 +825,14 @@ int tdqcow_open (struct disk_driver *dd,
        }
 
  end_xenhdr:
-       if (init_aio_state(dd)!=0) {
+       
+       /* A segment (i.e. a page) can span multiple clusters */
+       max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
+               MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
+
+       if (tap_aio_init(&s->aio, bs->size, max_aio_reqs)!=0) {
                DPRINTF("Unable to initialise AIO state\n");
-                free_aio_state(dd);
+                tap_aio_free(&s->aio);
                goto fail;
        }
        init_fds(dd);
@@ -1015,7 +849,7 @@ int tdqcow_open (struct disk_driver *dd,
        
 fail:
        DPRINTF("QCOW Open failed\n");
-       free_aio_state(dd);
+       tap_aio_free(&s->aio);
        free(s->l1_table);
        free(s->l2_cache);
        free(s->cluster_cache);
@@ -1037,7 +871,7 @@ int tdqcow_queue_read(struct disk_driver
 
        /*Check we can get a lock*/
        for (i = 0; i < nb_sectors; i++) 
-               if (!aio_can_lock(s, sector + i)) 
+               if (!tap_aio_can_lock(&s->aio, sector + i)) 
                        return cb(dd, -EBUSY, sector, nb_sectors, id, private);
 
        /*We store a local record of the request*/
@@ -1049,11 +883,11 @@ int tdqcow_queue_read(struct disk_driver
                if (n > nb_sectors)
                        n = nb_sectors;
 
-               if (s->iocb_free_count == 0 || !aio_lock(s, sector)) 
+               if (s->aio.iocb_free_count == 0 || !tap_aio_lock(&s->aio, 
sector)) 
                        return cb(dd, -EBUSY, sector, nb_sectors, id, private);
                
                if(!cluster_offset) {
-                       aio_unlock(s, sector);
+                       tap_aio_unlock(&s->aio, sector);
                        ret = cb(dd, BLK_NOT_ALLOCATED, 
                                 sector, n, id, private);
                        if (ret == -EBUSY) {
@@ -1064,7 +898,7 @@ int tdqcow_queue_read(struct disk_driver
                        } else
                                rsp += ret;
                } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
-                       aio_unlock(s, sector);
+                       tap_aio_unlock(&s->aio, sector);
                        if (decompress_cluster(s, cluster_offset) < 0) {
                                rsp += cb(dd, -EIO, sector, 
                                          nb_sectors, id, private);
@@ -1074,7 +908,7 @@ int tdqcow_queue_read(struct disk_driver
                               512 * n);
                        rsp += cb(dd, 0, sector, n, id, private);
                } else {
-                       async_read(s, n * 512, 
+                       tap_aio_read(&s->aio, s->fd, n * 512, 
                                   (cluster_offset + index_in_cluster * 512),
                                   buf, cb, id, sector, private);
                }
@@ -1099,7 +933,7 @@ int tdqcow_queue_write(struct disk_drive
 
        /*Check we can get a lock*/
        for (i = 0; i < nb_sectors; i++)
-               if (!aio_can_lock(s, sector + i))  
+               if (!tap_aio_can_lock(&s->aio, sector + i))  
                        return cb(dd, -EBUSY, sector, nb_sectors, id, private);
                   
        /*We store a local record of the request*/
@@ -1109,7 +943,7 @@ int tdqcow_queue_write(struct disk_drive
                if (n > nb_sectors)
                        n = nb_sectors;
 
-               if (s->iocb_free_count == 0 || !aio_lock(s, sector))
+               if (s->aio.iocb_free_count == 0 || !tap_aio_lock(&s->aio, 
sector))
                        return cb(dd, -EBUSY, sector, nb_sectors, id, private);
 
                cluster_offset = get_cluster_offset(s, sector << 9, 1, 0,
@@ -1117,7 +951,7 @@ int tdqcow_queue_write(struct disk_drive
                                                    index_in_cluster+n);
                if (!cluster_offset) {
                        DPRINTF("Ooops, no write cluster offset!\n");
-                       aio_unlock(s, sector);
+                       tap_aio_unlock(&s->aio, sector);
                        return cb(dd, -EIO, sector, nb_sectors, id, private);
                }
 
@@ -1125,12 +959,12 @@ int tdqcow_queue_write(struct disk_drive
                        encrypt_sectors(s, sector, s->cluster_data, 
                                        (unsigned char *)buf, n, 1,
                                        &s->aes_encrypt_key);
-                       async_write(s, n * 512, 
+                       tap_aio_write(&s->aio, s->fd, n * 512, 
                                    (cluster_offset + index_in_cluster*512),
                                    (char *)s->cluster_data, cb, id, sector, 
                                    private);
                } else {
-                       async_write(s, n * 512, 
+                       tap_aio_write(&s->aio, s->fd, n * 512, 
                                    (cluster_offset + index_in_cluster*512),
                                    buf, cb, id, sector, private);
                }
@@ -1146,20 +980,9 @@ int tdqcow_queue_write(struct disk_drive
                
 int tdqcow_submit(struct disk_driver *dd)
 {
-        int ret;
-        struct   tdqcow_state *prv = (struct tdqcow_state *)dd->private;
-
-       if (!prv->iocb_queued)
-               return 0;
-
-       ret = io_submit(prv->aio_ctx.aio_ctx, prv->iocb_queued, 
prv->iocb_queue);
-
-        /* XXX: TODO: Handle error conditions here. */
-
-        /* Success case: */
-        prv->iocb_queued = 0;
-
-        return 0;
+        struct tdqcow_state *prv = (struct tdqcow_state *)dd->private;
+
+       return tap_aio_submit(&prv->aio);
 }
 
 int tdqcow_close(struct disk_driver *dd)
@@ -1180,7 +1003,7 @@ int tdqcow_close(struct disk_driver *dd)
                close(fd);
        }
 
-       io_destroy(s->aio_ctx.aio_ctx);
+       io_destroy(s->aio.aio_ctx.aio_ctx);
        free(s->name);
        free(s->l1_table);
        free(s->l2_cache);
@@ -1198,15 +1021,15 @@ int tdqcow_do_callbacks(struct disk_driv
 
         if (sid > MAX_IOFD) return 1;
 
-        nr_events = tap_aio_get_events(&prv->aio_ctx);
+        nr_events = tap_aio_get_events(&prv->aio.aio_ctx);
 repeat:
-        for (ep = prv->aio_events, i = nr_events; i-- > 0; ep++) {
+        for (ep = prv->aio.aio_events, i = nr_events; i-- > 0; ep++) {
                 struct iocb        *io  = ep->obj;
                 struct pending_aio *pio;
 
-                pio = &prv->pending_aio[(long)io->data];
-
-               aio_unlock(prv, pio->sector);
+                pio = &prv->aio.pending_aio[(long)io->data];
+
+               tap_aio_unlock(&prv->aio, pio->sector);
 
                if (prv->crypt_method)
                        encrypt_sectors(prv, pio->sector, 
@@ -1219,15 +1042,15 @@ repeat:
                               pio->sector, pio->nb_sectors,
                               pio->id, pio->private);
 
-                prv->iocb_free[prv->iocb_free_count++] = io;
+                prv->aio.iocb_free[prv->aio.iocb_free_count++] = io;
         }
 
         if (nr_events) {
-                nr_events = tap_aio_more_events(&prv->aio_ctx);
+                nr_events = tap_aio_more_events(&prv->aio.aio_ctx);
                 goto repeat;
         }
 
-        tap_aio_continue(&prv->aio_ctx);
+        tap_aio_continue(&prv->aio.aio_ctx);
 
         return rsp;
 }
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/block-qcow2.c
--- a/tools/blktap/drivers/block-qcow2.c        Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/blktap/drivers/block-qcow2.c        Tue Feb 26 10:12:04 2008 -0700
@@ -145,20 +145,7 @@ typedef struct BDRVQcowState {
 
        int64_t total_sectors;
 
-
-       struct {
-               tap_aio_context_t    aio_ctx;
-               int                  max_aio_reqs;
-               struct iocb         *iocb_list;
-               struct iocb        **iocb_free;
-               struct pending_aio  *pending_aio;
-               int                  iocb_free_count;
-               struct iocb        **iocb_queue;
-               int                  iocb_queued;
-               struct io_event     *aio_events;
-               
-               uint8_t *sector_lock;              /*Locking bitmap for AIO 
reads/writes*/
-       } async;
+       tap_aio_context_t async;
 
        /* Original qemu variables */
        int cluster_bits;
@@ -222,9 +209,6 @@ static void check_refcounts(struct disk_
 static void check_refcounts(struct disk_driver *bs);
 #endif
 
-static int init_aio_state(struct disk_driver *bs);
-static void free_aio_state(struct disk_driver *bs);
-
 static int qcow_sync_read(struct disk_driver *dd, uint64_t sector,
                int nb_sectors, char *buf, td_callback_t cb,
                int id, void *prv);
@@ -309,7 +293,7 @@ static int qcow_open(struct disk_driver 
 static int qcow_open(struct disk_driver *bs, const char *filename, td_flag_t 
flags)
 {
        BDRVQcowState *s = bs->private;
-       int len, i, shift, ret;
+       int len, i, shift, ret, max_aio_reqs;
        QCowHeader header;
 
        int fd, o_flags;
@@ -475,9 +459,14 @@ static int qcow_open(struct disk_driver 
 
 #ifdef USE_AIO
        /* Initialize AIO */
-       if (init_aio_state(bs)!=0) {
+
+       /* A segment (i.e. a page) can span multiple clusters */
+       max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
+               MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
+
+       if (tap_aio_init(&s->async, bs->td_state->size, max_aio_reqs)) {
                DPRINTF("Unable to initialise AIO state\n");
-               free_aio_state(bs);
+               tap_aio_free(&s->async);
                goto fail;
        }
 
@@ -496,7 +485,7 @@ static int qcow_open(struct disk_driver 
        DPRINTF("qcow_open failed\n");
 
 #ifdef USE_AIO 
-       free_aio_state(bs);
+       tap_aio_free(&s->async);
 #endif
 
        qcow_free_snapshots(bs);
@@ -1070,200 +1059,6 @@ static int qcow_write(struct disk_driver
 #ifdef USE_AIO
 
 /*
- * General AIO helper functions
- */
-
-#define IOCB_IDX(_s, _io) ((_io) - (_s)->async.iocb_list)
-
-struct pending_aio {
-       td_callback_t cb;
-       int id;
-       void *private;
-       int nb_sectors;
-       char *buf;
-       uint64_t sector;
-};
-
-
-static int init_aio_state(struct disk_driver *dd)
-{
-       int i, ret;
-       struct td_state *bs = dd->td_state;
-       struct BDRVQcowState *s = (struct BDRVQcowState*) dd->private;
-       long ioidx;
-
-       s->async.iocb_list = NULL;
-       s->async.pending_aio = NULL;
-       s->async.aio_events = NULL;
-       s->async.iocb_free = NULL;
-       s->async.iocb_queue = NULL;
-
-       /*Initialize Locking bitmap*/
-       s->async.sector_lock = calloc(1, bs->size);
-               
-       if (!s->async.sector_lock) {
-               DPRINTF("Failed to allocate sector lock\n");
-               goto fail;
-       }
-
-       /* A segment (i.e. a page) can span multiple clusters */
-       s->async.max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
-               MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
-
-       /* Initialize AIO */
-       s->async.iocb_free_count = s->async.max_aio_reqs;
-       s->async.iocb_queued     = 0;
-
-       if (!(s->async.iocb_list = malloc(sizeof(struct iocb) * 
s->async.max_aio_reqs)) ||
-               !(s->async.pending_aio = malloc(sizeof(struct pending_aio) * 
s->async.max_aio_reqs)) ||
-               !(s->async.aio_events = malloc(sizeof(struct io_event) * 
s->async.max_aio_reqs)) ||
-               !(s->async.iocb_free = malloc(sizeof(struct iocb *) * 
s->async.max_aio_reqs)) ||
-               !(s->async.iocb_queue = malloc(sizeof(struct iocb *) * 
s->async.max_aio_reqs))) 
-       {
-               DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
-                               s->async.max_aio_reqs);
-               goto fail;
-       }
-
-       ret = tap_aio_setup(&s->async.aio_ctx, s->async.aio_events, 
s->async.max_aio_reqs);
-       if (ret < 0) {
-               if (ret == -EAGAIN) {
-                       DPRINTF("Couldn't setup AIO context.  If you are "
-                               "trying to concurrently use a large number "
-                               "of blktap-based disks, you may need to "
-                               "increase the system-wide aio request limit. "
-                               "(e.g. 'echo echo 1048576 > /proc/sys/fs/"
-                               "aio-max-nr')\n");
-               } else {
-                       DPRINTF("Couldn't setup AIO context.\n");
-               }
-               goto fail;
-       }
-
-       for (i=0;i<s->async.max_aio_reqs;i++)
-                       s->async.iocb_free[i] = &s->async.iocb_list[i];
-
-       DPRINTF("AIO state initialised\n");
-
-       return 0;
-
-fail:
-       return -1;
-}
-
-static void free_aio_state(struct disk_driver *dd)
-{
-       struct BDRVQcowState *s = (struct BDRVQcowState*) dd->private;
-
-       if (s->async.sector_lock)
-               free(s->async.sector_lock);
-       if (s->async.iocb_list)
-               free(s->async.iocb_list);
-       if (s->async.pending_aio)
-               free(s->async.pending_aio);
-       if (s->async.aio_events)
-               free(s->async.aio_events);
-       if (s->async.iocb_free)
-               free(s->async.iocb_free);
-       if (s->async.iocb_queue)
-               free(s->async.iocb_queue);
-}
-
-static int async_read(struct BDRVQcowState *s, int size, 
-               uint64_t offset, char *buf, td_callback_t cb,
-               int id, uint64_t sector, void *private)
-{
-       struct   iocb *io;
-       struct   pending_aio *pio;
-       long     ioidx;
-
-       io = s->async.iocb_free[--s->async.iocb_free_count];
-
-       ioidx = IOCB_IDX(s, io);
-       pio = &s->async.pending_aio[ioidx];
-       pio->cb = cb;
-       pio->id = id;
-       pio->private = private;
-       pio->nb_sectors = size/512;
-       pio->buf = buf;
-       pio->sector = sector;
-
-       io_prep_pread(io, s->fd, buf, size, offset);
-       io->data = (void *)ioidx;
-
-       s->async.iocb_queue[s->async.iocb_queued++] = io;
-
-       return 1;
-}
-
-static int async_write(struct BDRVQcowState *s, int size,
-               uint64_t offset, char *buf, td_callback_t cb,
-               int id, uint64_t sector, void *private)
-{
-       struct   iocb *io;
-       struct   pending_aio *pio;
-       long     ioidx;
-
-       io = s->async.iocb_free[--s->async.iocb_free_count];
-
-       ioidx = IOCB_IDX(s, io);
-       pio = &s->async.pending_aio[ioidx];
-       pio->cb = cb;
-       pio->id = id;
-       pio->private = private;
-       pio->nb_sectors = size/512;
-       pio->buf = buf;
-       pio->sector = sector;
-
-       io_prep_pwrite(io, s->fd, buf, size, offset);
-       io->data = (void *)ioidx;
-
-       s->async.iocb_queue[s->async.iocb_queued++] = io;
-
-       return 1;
-}
-
-static int async_submit(struct disk_driver *dd)
-{
-       int ret;
-       struct BDRVQcowState *prv = (struct BDRVQcowState*) dd->private;
-
-       if (!prv->async.iocb_queued)
-               return 0;
-
-       ret = io_submit(prv->async.aio_ctx.aio_ctx, prv->async.iocb_queued, 
prv->async.iocb_queue);
-
-       /* XXX: TODO: Handle error conditions here. */
-
-       /* Success case: */
-       prv->async.iocb_queued = 0;
-
-       return 0;
-}
-
-/*TODO: Fix sector span!*/
-static int aio_can_lock(struct BDRVQcowState *s, uint64_t sector)
-{
-       return (s->async.sector_lock[sector] ? 0 : 1);
-}
-
-static int aio_lock(struct BDRVQcowState *s, uint64_t sector)
-{
-       return ++s->async.sector_lock[sector];
-}
-
-static void aio_unlock(struct BDRVQcowState *s, uint64_t sector)
-{
-       if (!s->async.sector_lock[sector]) return;
-
-       --s->async.sector_lock[sector];
-       return;
-}
-
-
-
-
-/*
  * QCOW2 specific AIO functions
  */
 
@@ -1278,7 +1073,7 @@ static int qcow_queue_read(struct disk_d
 
        /*Check we can get a lock*/
        for (i = 0; i < nb_sectors; i++) 
-               if (!aio_can_lock(s, sector + i)) 
+               if (!tap_aio_can_lock(&s->async, sector + i)) 
                        return cb(bs, -EBUSY, sector, nb_sectors, id, private);
 
        while (nb_sectors > 0) {
@@ -1290,13 +1085,13 @@ static int qcow_queue_read(struct disk_d
                if (n > nb_sectors)
                        n = nb_sectors;
 
-               if (s->async.iocb_free_count == 0 || !aio_lock(s, sector)) 
+               if (s->async.iocb_free_count == 0 || !tap_aio_lock(&s->async, 
sector)) 
                        return cb(bs, -EBUSY, sector, nb_sectors, id, private);
 
                if (!cluster_offset) {
 
                        /* The requested sector is not allocated */
-                       aio_unlock(s, sector);
+                       tap_aio_unlock(&s->async, sector);
                        ret = cb(bs, BLK_NOT_ALLOCATED, 
                                        sector, n, id, private);
                        if (ret == -EBUSY) {
@@ -1311,7 +1106,7 @@ static int qcow_queue_read(struct disk_d
                } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
 
                        /* sync read for compressed clusters */
-                       aio_unlock(s, sector);
+                       tap_aio_unlock(&s->async, sector);
                        if (decompress_cluster(s, cluster_offset) < 0) {
                                rsp += cb(bs, -EIO, sector, nb_sectors, id, 
private);
                                goto done;
@@ -1323,7 +1118,7 @@ static int qcow_queue_read(struct disk_d
                } else {
 
                        /* async read */
-                       async_read(s, n * 512, 
+                       tap_aio_read(&s->async, s->fd, n * 512, 
                                        (cluster_offset + index_in_cluster * 
512),
                                        buf, cb, id, sector, private);
                }
@@ -1351,7 +1146,7 @@ static int qcow_queue_write(struct disk_
        
        /*Check we can get a lock*/
        for (i = 0; i < nb_sectors; i++) 
-               if (!aio_can_lock(s, sector + i)) 
+               if (!tap_aio_can_lock(&s->async, sector + i)) 
                        return cb(bs, -EBUSY, sector, nb_sectors, id, private);
 
 
@@ -1362,7 +1157,7 @@ static int qcow_queue_write(struct disk_
                if (n > nb_sectors)
                        n = nb_sectors;
 
-               if (s->async.iocb_free_count == 0 || !aio_lock(s, sector))
+               if (s->async.iocb_free_count == 0 || !tap_aio_lock(&s->async, 
sector))
                        return cb(bs, -EBUSY, sector, nb_sectors, id, private);
 
 
@@ -1372,14 +1167,14 @@ static int qcow_queue_write(struct disk_
 
                if (!cluster_offset) {
                        DPRINTF("Ooops, no write cluster offset!\n");
-                       aio_unlock(s, sector);
+                       tap_aio_unlock(&s->async, sector);
                        return cb(bs, -EIO, sector, nb_sectors, id, private);
                }
 
 
                // TODO Encryption
 
-               async_write(s, n * 512, 
+               tap_aio_write(&s->async, s->fd, n * 512, 
                                (cluster_offset + index_in_cluster*512),
                                buf, cb, id, sector, private);
 
@@ -1402,9 +1197,14 @@ static int qcow_close(struct disk_driver
 static int qcow_close(struct disk_driver *bs)
 {
        BDRVQcowState *s = bs->private;
-               
+       
+#ifdef USE_AIO 
+       io_destroy(s->async.aio_ctx.aio_ctx);
+       tap_aio_free(&s->async);
+#else          
        close(s->poll_pipe[0]);
-               close(s->poll_pipe[1]);
+       close(s->poll_pipe[1]);
+#endif         
 
        qemu_free(s->l1_table);
        qemu_free(s->l2_cache);
@@ -1606,23 +1406,10 @@ static int qcow_write_compressed(struct 
 
 static int qcow_submit(struct disk_driver *bs)
 {
-       int ret;
-       struct   BDRVQcowState *prv = (struct BDRVQcowState*)bs->private;
-
-
-       fsync(prv->fd);
-
-       if (!prv->async.iocb_queued)
-               return 0;
-
-       ret = io_submit(prv->async.aio_ctx.aio_ctx, prv->async.iocb_queued, 
prv->async.iocb_queue);
-
-       /* XXX: TODO: Handle error conditions here. */
-
-       /* Success case: */
-       prv->async.iocb_queued = 0;
-
-       return 0;
+       struct BDRVQcowState *s = (struct BDRVQcowState*) bs->private;
+
+       fsync(s->fd);
+       return tap_aio_submit(&s->async);
 }
 
 
@@ -2246,7 +2033,7 @@ repeat:
 
                pio = &prv->async.pending_aio[(long)io->data];
 
-               aio_unlock(prv, pio->sector);
+               tap_aio_unlock(&prv->async, pio->sector);
 
                if (prv->crypt_method)
                        encrypt_sectors(prv, pio->sector, 
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/tapaio.c
--- a/tools/blktap/drivers/tapaio.c     Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/blktap/drivers/tapaio.c     Tue Feb 26 10:12:04 2008 -0700
@@ -32,6 +32,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
+#include <stdlib.h>
 
 /**
  * We used a kernel patch to return an fd associated with the AIO context
@@ -62,7 +63,7 @@ static void *
 static void *
 tap_aio_completion_thread(void *arg)
 {
-       tap_aio_context_t *ctx = (tap_aio_context_t *) arg;
+       tap_aio_internal_context_t *ctx = (tap_aio_internal_context_t *) arg;
        int command;
        int nr_events;
        int rc;
@@ -84,7 +85,7 @@ tap_aio_completion_thread(void *arg)
 }
 
 void
-tap_aio_continue(tap_aio_context_t *ctx)
+tap_aio_continue(tap_aio_internal_context_t *ctx)
 {
         int cmd = 0;
 
@@ -95,8 +96,8 @@ tap_aio_continue(tap_aio_context_t *ctx)
                 DPRINTF("Cannot write to command pipe\n");
 }
 
-int
-tap_aio_setup(tap_aio_context_t *ctx,
+static int
+tap_aio_setup(tap_aio_internal_context_t *ctx,
               struct io_event *aio_events,
               int max_aio_events)
 {
@@ -144,7 +145,7 @@ tap_aio_setup(tap_aio_context_t *ctx,
 }
 
 int
-tap_aio_get_events(tap_aio_context_t *ctx)
+tap_aio_get_events(tap_aio_internal_context_t *ctx)
 {
         int nr_events = 0;
 
@@ -171,10 +172,185 @@ tap_aio_get_events(tap_aio_context_t *ct
         return nr_events;
 }
 
-int tap_aio_more_events(tap_aio_context_t *ctx)
+int tap_aio_more_events(tap_aio_internal_context_t *ctx)
 {
         return io_getevents(ctx->aio_ctx, 0,
                             ctx->max_aio_events, ctx->aio_events, NULL);
 }
 
-
+int tap_aio_init(tap_aio_context_t *ctx, uint64_t sectors,
+               int max_aio_reqs)
+{
+       int i, ret;
+       long ioidx;
+
+       ctx->iocb_list = NULL;
+       ctx->pending_aio = NULL;
+       ctx->aio_events = NULL;
+       ctx->iocb_free = NULL;
+       ctx->iocb_queue = NULL;
+
+       /*Initialize Locking bitmap*/
+       ctx->sector_lock = calloc(1, sectors);
+               
+       if (!ctx->sector_lock) {
+               DPRINTF("Failed to allocate sector lock\n");
+               goto fail;
+       }
+
+
+       /* Initialize AIO */
+       ctx->max_aio_reqs = max_aio_reqs;
+       ctx->iocb_free_count = ctx->max_aio_reqs;
+       ctx->iocb_queued         = 0;
+
+       if (!(ctx->iocb_list = malloc(sizeof(struct iocb) * ctx->max_aio_reqs)) 
||
+               !(ctx->pending_aio = malloc(sizeof(struct pending_aio) * 
ctx->max_aio_reqs)) ||
+               !(ctx->aio_events = malloc(sizeof(struct io_event) * 
ctx->max_aio_reqs)) ||
+               !(ctx->iocb_free = malloc(sizeof(struct iocb *) * 
ctx->max_aio_reqs)) ||
+               !(ctx->iocb_queue = malloc(sizeof(struct iocb *) * 
ctx->max_aio_reqs))) 
+       {
+               DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
+                               ctx->max_aio_reqs);
+               goto fail;
+       }
+
+       ret = tap_aio_setup(&ctx->aio_ctx, ctx->aio_events, ctx->max_aio_reqs);
+       if (ret < 0) {
+               if (ret == -EAGAIN) {
+                       DPRINTF("Couldn't setup AIO context.  If you are "
+                               "trying to concurrently use a large number "
+                               "of blktap-based disks, you may need to "
+                               "increase the system-wide aio request limit. "
+                               "(e.g. 'echo echo 1048576 > /proc/sys/fs/"
+                               "aio-max-nr')\n");
+               } else {
+                       DPRINTF("Couldn't setup AIO context.\n");
+               }
+               goto fail;
+       }
+
+       for (i=0;i<ctx->max_aio_reqs;i++)
+               ctx->iocb_free[i] = &ctx->iocb_list[i];
+
+       DPRINTF("AIO state initialised\n");
+
+       return 0;
+
+fail:
+       return -1;
+}
+
+void tap_aio_free(tap_aio_context_t *ctx)
+{
+       if (ctx->sector_lock)
+               free(ctx->sector_lock);
+       if (ctx->iocb_list)
+               free(ctx->iocb_list);
+       if (ctx->pending_aio)
+               free(ctx->pending_aio);
+       if (ctx->aio_events)
+               free(ctx->aio_events);
+       if (ctx->iocb_free)
+               free(ctx->iocb_free);
+       if (ctx->iocb_queue)
+               free(ctx->iocb_queue);
+}
+
+/*TODO: Fix sector span!*/
+int tap_aio_can_lock(tap_aio_context_t *ctx, uint64_t sector)
+{
+       return (ctx->sector_lock[sector] ? 0 : 1);
+}
+
+int tap_aio_lock(tap_aio_context_t *ctx, uint64_t sector)
+{
+       return ++ctx->sector_lock[sector];
+}
+
+void tap_aio_unlock(tap_aio_context_t *ctx, uint64_t sector)
+{
+       if (!ctx->sector_lock[sector]) return;
+
+       --ctx->sector_lock[sector];
+       return;
+}
+
+
+int tap_aio_read(tap_aio_context_t *ctx, int fd, int size, 
+               uint64_t offset, char *buf, td_callback_t cb,
+               int id, uint64_t sector, void *private)
+{
+       struct   iocb *io;
+       struct   pending_aio *pio;
+       long     ioidx;
+
+       if (ctx->iocb_free_count == 0)
+               return -ENOMEM;
+
+       io = ctx->iocb_free[--ctx->iocb_free_count];
+
+       ioidx = IOCB_IDX(ctx, io);
+       pio = &ctx->pending_aio[ioidx];
+       pio->cb = cb;
+       pio->id = id;
+       pio->private = private;
+       pio->nb_sectors = size/512;
+       pio->buf = buf;
+       pio->sector = sector;
+
+       io_prep_pread(io, fd, buf, size, offset);
+       io->data = (void *)ioidx;
+
+       ctx->iocb_queue[ctx->iocb_queued++] = io;
+
+       return 0;
+}
+
+int tap_aio_write(tap_aio_context_t *ctx, int fd, int size,
+               uint64_t offset, char *buf, td_callback_t cb,
+               int id, uint64_t sector, void *private)
+{
+       struct   iocb *io;
+       struct   pending_aio *pio;
+       long     ioidx;
+
+       if (ctx->iocb_free_count == 0)
+               return -ENOMEM;
+
+       io = ctx->iocb_free[--ctx->iocb_free_count];
+
+       ioidx = IOCB_IDX(ctx, io);
+       pio = &ctx->pending_aio[ioidx];
+       pio->cb = cb;
+       pio->id = id;
+       pio->private = private;
+       pio->nb_sectors = size/512;
+       pio->buf = buf;
+       pio->sector = sector;
+
+       io_prep_pwrite(io, fd, buf, size, offset);
+       io->data = (void *)ioidx;
+
+       ctx->iocb_queue[ctx->iocb_queued++] = io;
+
+       return 0;
+}
+
+int tap_aio_submit(tap_aio_context_t *ctx)
+{
+       int ret;
+
+       if (!ctx->iocb_queued)
+               return 0;
+
+       ret = io_submit(ctx->aio_ctx.aio_ctx, ctx->iocb_queued, 
ctx->iocb_queue);
+
+       /* XXX: TODO: Handle error conditions here. */
+
+       /* Success case: */
+       ctx->iocb_queued = 0;
+
+       return 0;
+}
+
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/tapaio.h
--- a/tools/blktap/drivers/tapaio.h     Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/blktap/drivers/tapaio.h     Tue Feb 26 10:12:04 2008 -0700
@@ -32,8 +32,13 @@
 
 #include <pthread.h>
 #include <libaio.h>
+#include <stdint.h>
 
-struct tap_aio_context {
+#include "tapdisk.h"
+
+#define IOCB_IDX(_ctx, _io) ((_io) - (_ctx)->iocb_list)
+
+struct tap_aio_internal_context {
         io_context_t     aio_ctx;
 
         struct io_event *aio_events;
@@ -45,14 +50,59 @@ struct tap_aio_context {
         int              pollfd;
         unsigned int     poll_in_thread : 1;
 };
+       
+
+typedef struct tap_aio_internal_context tap_aio_internal_context_t;
+
+
+struct pending_aio {
+       td_callback_t cb;
+       int id;
+       void *private;
+       int nb_sectors;
+       char *buf;
+       uint64_t sector;
+};
+
+       
+struct tap_aio_context {
+       tap_aio_internal_context_t    aio_ctx;
+
+       int                  max_aio_reqs;
+       struct iocb         *iocb_list;
+       struct iocb        **iocb_free;
+       struct pending_aio  *pending_aio;
+       int                  iocb_free_count;
+       struct iocb        **iocb_queue;
+       int                  iocb_queued;
+       struct io_event     *aio_events;
+
+       /* Locking bitmap for AIO reads/writes */
+       uint8_t *sector_lock;              
+};
 
 typedef struct tap_aio_context tap_aio_context_t;
 
-int  tap_aio_setup      (tap_aio_context_t *ctx,
-                         struct io_event *aio_events,
-                         int max_aio_events);
-void tap_aio_continue   (tap_aio_context_t *ctx);
-int  tap_aio_get_events (tap_aio_context_t *ctx);
-int  tap_aio_more_events(tap_aio_context_t *ctx);
+void tap_aio_continue   (tap_aio_internal_context_t *ctx);
+int  tap_aio_get_events (tap_aio_internal_context_t *ctx);
+int  tap_aio_more_events(tap_aio_internal_context_t *ctx);
+
+
+int tap_aio_init(tap_aio_context_t *ctx, uint64_t sectors,
+               int max_aio_reqs);
+void tap_aio_free(tap_aio_context_t *ctx);
+
+int tap_aio_can_lock(tap_aio_context_t *ctx, uint64_t sector);
+int tap_aio_lock(tap_aio_context_t *ctx, uint64_t sector);
+void tap_aio_unlock(tap_aio_context_t *ctx, uint64_t sector);
+
+
+int tap_aio_read(tap_aio_context_t *ctx, int fd, int size, 
+               uint64_t offset, char *buf, td_callback_t cb,
+               int id, uint64_t sector, void *private);
+int tap_aio_write(tap_aio_context_t *ctx, int fd, int size,
+               uint64_t offset, char *buf, td_callback_t cb,
+               int id, uint64_t sector, void *private);
+int tap_aio_submit(tap_aio_context_t *ctx);
 
 #endif /* __TAPAIO_H__ */
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh     Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/examples/vtpm-common.sh     Tue Feb 26 10:12:04 2008 -0700
@@ -407,7 +407,7 @@ function vtpm_domid_from_name () {
        local id name ids
        ids=$(xenstore-list /local/domain)
        for id in $ids; do
-               name=$(xenstore_read /local/domain/$id/name)
+               name=$(xenstore-read /local/domain/$id/name)
                if [ "$name" == "$1" ]; then
                        echo "$id"
                        return
@@ -416,16 +416,33 @@ function vtpm_domid_from_name () {
        echo "-1"
 }
 
+#Determine the virtual TPM's instance number using the domain ID.
+#1st parm: domain ID
+function vtpm_uuid_by_domid() {
+       echo $(xenstore-read /local/domain/0/backend/vtpm/$1/0/uuid)
+}
+
+
+# Determine the vTPM's UUID by the name of the VM
+function vtpm_uuid_from_vmname() {
+       local domid=$(vtpm_domid_from_name $1)
+       if [ "$domid" != "-1" ]; then
+               echo $(vtpm_uuid_by_domid $domid)
+               return
+       fi
+       echo ""
+}
 
 #Add a virtual TPM instance number and its associated domain name
 #to the VTPMDB file and activate usage of this virtual TPM instance
 #by writing the instance number into the xenstore
 #1st parm: name of virtual machine
-#2nd parm: instance of assoicate virtual TPM
+#2nd parm: instance of associated virtual TPM
 function vtpm_add_and_activate() {
        local domid=$(vtpm_domid_from_name $1)
-       if [ "$domid" != "-1" ]; then
-               vtpmdb_add_instance $1 $2
+       local vtpm_uuid=$(vtpm_uuid_from_vmname $1)
+       if [ "$vtpm_uuid" != "" -a "$domid" != "-1" ]; then
+               vtpmdb_add_instance $vtpm_uuid $2
                xenstore-write backend/vtpm/$domid/0/instance $2
        fi
 }
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/examples/vtpm-delete
--- a/tools/examples/vtpm-delete        Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/examples/vtpm-delete        Tue Feb 26 10:12:04 2008 -0700
@@ -1,9 +1,18 @@
 #!/bin/bash
 
 # This scripts must be called the following way:
-# vtpm-delete <domain name>
+# vtpm-delete <vtpm uuid>
+# or
+# vtpm-delete --vmname <vm name>
 
 dir=$(dirname "$0")
 . "$dir/vtpm-common.sh"
 
-vtpm_delete_instance $1
+if [ "$1" == "--vmname" ]; then
+       vtpm_uuid=$(vtpm_uuid_from_vmname $2)
+       if [ "$vtpm_uuid" != "" ];then
+               vtpm_delete_instance $vtpm_uuid
+       fi
+else
+       vtpm_delete_instance $1
+fi
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/firmware/hvmloader/acpi/build.c     Tue Feb 26 10:12:04 2008 -0700
@@ -189,80 +189,6 @@ static int construct_hpet(struct acpi_20
     return offset;
 }
 
-static int construct_processor_objects(uint8_t *buf)
-{
-    static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 };
-    static const char hex[] = "0123456789ABCDEF";
-    static const char pr_scope[] = "\\_PR_";
-    unsigned int i, length, nr_cpus = get_vcpu_nr();
-    struct acpi_header *hdr;
-    uint8_t *p = buf;
-
-    /*
-     * 1. Table Header.
-     */
-
-    hdr = (struct acpi_header *)p;
-    hdr->signature = ASCII32('S','S','D','T');
-    hdr->revision  = 2;
-    fixed_strcpy(hdr->oem_id, ACPI_OEM_ID);
-    fixed_strcpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID);
-    hdr->oem_revision = ACPI_OEM_REVISION;
-    hdr->creator_id = ACPI_CREATOR_ID;
-    hdr->creator_revision = ACPI_CREATOR_REVISION;
-    p += sizeof(*hdr);
-
-    /*
-     * 2. Scope Definition.
-     */
-
-    /* ScopeOp */
-    *p++ = 0x10;
-
-    /* PkgLength (includes length bytes!). */
-    length = 1 + strlen(pr_scope) + (nr_cpus * sizeof(pdat));
-    if ( length <= 0x3f )
-    {
-        *p++ = length;
-    }
-    else if ( ++length <= 0xfff )
-    {
-        *p++ = 0x40 | (length & 0xf);
-        *p++ = length >> 4;
-    }
-    else
-    {
-        length++;
-        *p++ = 0x80 | (length & 0xf);
-        *p++ = (length >>  4) & 0xff;
-        *p++ = (length >> 12) & 0xff;
-    }
-
-    /* NameString */
-    strncpy((char *)p, pr_scope, strlen(pr_scope));
-    p += strlen(pr_scope);
-
-    /*
-     * 3. Processor Objects.
-     */
-
-    for ( i = 0; i < nr_cpus; i++ )
-    {
-        memcpy(p, pdat, sizeof(pdat));
-        /* ProcessorName */
-        p[5] = hex[(i>>4)&15];
-        p[6] = hex[(i>>0)&15];
-        /* ProcessorID */
-        p[7] = i;
-        p += sizeof(pdat);
-    }
-
-    hdr->length = p - buf;
-    set_checksum(hdr, offsetof(struct acpi_header, checksum), hdr->length);
-
-    return hdr->length;
-}
-
 static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
 {
     int offset = 0, nr_tables = 0;
@@ -287,10 +213,6 @@ static int construct_secondary_tables(ui
         offset += construct_hpet(hpet);
         table_ptrs[nr_tables++] = (unsigned long)hpet;
     }
-
-    /* Processor Object SSDT. */
-    table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
-    offset += construct_processor_objects(&buf[offset]);
 
     /* TPM TCPA and SSDT. */
     tis_hdr = (uint16_t *)0xFED40F00;
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/firmware/hvmloader/acpi/dsdt.asl
--- a/tools/firmware/hvmloader/acpi/dsdt.asl    Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl    Tue Feb 26 10:12:04 2008 -0700
@@ -26,6 +26,26 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
     Name (\APCB, 0xFEC00000)
     Name (\APCL, 0x00010000)
     Name (\PUID, 0x00)
+
+    Scope (\_PR)
+    {
+        Processor (PR00, 0x00, 0x0000, 0x00) {}
+        Processor (PR01, 0x01, 0x0000, 0x00) {}
+        Processor (PR02, 0x02, 0x0000, 0x00) {}
+        Processor (PR03, 0x03, 0x0000, 0x00) {}
+        Processor (PR04, 0x00, 0x0000, 0x00) {}
+        Processor (PR05, 0x01, 0x0000, 0x00) {}
+        Processor (PR06, 0x02, 0x0000, 0x00) {}
+        Processor (PR07, 0x03, 0x0000, 0x00) {}
+        Processor (PR08, 0x00, 0x0000, 0x00) {}
+        Processor (PR09, 0x01, 0x0000, 0x00) {}
+        Processor (PR0A, 0x02, 0x0000, 0x00) {}
+        Processor (PR0B, 0x03, 0x0000, 0x00) {}
+        Processor (PR0C, 0x00, 0x0000, 0x00) {}
+        Processor (PR0D, 0x01, 0x0000, 0x00) {}
+        Processor (PR0E, 0x02, 0x0000, 0x00) {}
+        Processor (PR0F, 0x03, 0x0000, 0x00) {}
+    }
 
     /* S4 (STD) and S5 (power-off) type codes: must match piix4 emulation. */
     Name (\_S4, Package (0x04)
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/firmware/hvmloader/acpi/dsdt.c
--- a/tools/firmware/hvmloader/acpi/dsdt.c      Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/firmware/hvmloader/acpi/dsdt.c      Tue Feb 26 10:12:04 2008 -0700
@@ -5,15 +5,15 @@
  * Copyright (C) 2000 - 2006 Intel Corporation
  * Supports ACPI Specification Revision 3.0a
  * 
- * Compilation of "dsdt.asl" - Fri Feb 15 14:07:57 2008
+ * Compilation of "dsdt.asl" - Mon Feb 25 10:54:06 2008
  * 
  * C source code output
  *
  */
 unsigned char AmlCode[] =
 {
-    0x44,0x53,0x44,0x54,0x5A,0x10,0x00,0x00,  /* 00000000    "DSDTZ..." */
-    0x02,0xCC,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
+    0x44,0x53,0x44,0x54,0x31,0x11,0x00,0x00,  /* 00000000    "DSDT1..." */
+    0x02,0xC7,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
     0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00,  /* 00000010    "HVM....." */
     0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
     0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    "... .PMB" */
@@ -23,518 +23,545 @@ unsigned char AmlCode[] =
     0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0,  /* 00000040    "APCB...." */
     0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00,  /* 00000048    "..APCL.." */
     0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44,  /* 00000050    "....PUID" */
-    0x00,0x08,0x5F,0x53,0x34,0x5F,0x12,0x08,  /* 00000058    ".._S4_.." */
-    0x04,0x0A,0x06,0x0A,0x06,0x00,0x00,0x08,  /* 00000060    "........" */
-    0x5F,0x53,0x35,0x5F,0x12,0x08,0x04,0x0A,  /* 00000068    "_S5_...." */
-    0x07,0x0A,0x07,0x00,0x00,0x08,0x50,0x49,  /* 00000070    "......PI" */
-    0x43,0x44,0x00,0x14,0x0C,0x5F,0x50,0x49,  /* 00000078    "CD..._PI" */
-    0x43,0x01,0x70,0x68,0x50,0x49,0x43,0x44,  /* 00000080    "C.phPICD" */
-    0x10,0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B,  /* 00000088    ".B._SB_[" */
-    0x80,0x42,0x49,0x4F,0x53,0x00,0x0C,0x00,  /* 00000090    ".BIOS..." */
-    0xA0,0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21,  /* 00000098    ".....[.!" */
-    0x42,0x49,0x4F,0x53,0x01,0x55,0x41,0x52,  /* 000000A0    "BIOS.UAR" */
-    0x31,0x01,0x55,0x41,0x52,0x32,0x01,0x48,  /* 000000A8    "1.UAR2.H" */
-    0x50,0x45,0x54,0x01,0x00,0x1D,0x50,0x4D,  /* 000000B0    "PET...PM" */
-    0x49,0x4E,0x20,0x50,0x4C,0x45,0x4E,0x20,  /* 000000B8    "IN PLEN " */
-    0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D,0x30,  /* 000000C0    "[.I.MEM0" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000000C8    "._HID.A." */
-    0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 000000D0    "..._CRS." */
-    0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00,0x0D,  /* 000000D8    "3.0.+..." */
-    0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E0    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E8    "........" */
-    0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,0x00,  /* 000000F0    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000F8    "........" */
-    0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,  /* 00000100    "........" */
-    0x00,0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50,  /* 00000108    ".y.[.N.P" */
-    0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 00000110    "CI0._HID" */
-    0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55,  /* 00000118    ".A...._U" */
-    0x49,0x44,0x00,0x08,0x5F,0x41,0x44,0x52,  /* 00000120    "ID.._ADR" */
-    0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x14,  /* 00000128    ".._BBN.." */
-    0x4E,0x0C,0x5F,0x43,0x52,0x53,0x00,0x08,  /* 00000130    "N._CRS.." */
-    0x50,0x52,0x54,0x30,0x11,0x42,0x07,0x0A,  /* 00000138    "PRT0.B.." */
-    0x6E,0x88,0x0D,0x00,0x02,0x0E,0x00,0x00,  /* 00000140    "n......." */
-    0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,  /* 00000148    "........" */
-    0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,  /* 00000150    ".G......" */
-    0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,  /* 00000158    "........" */
-    0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,  /* 00000160    "........" */
-    0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,  /* 00000168    "........" */
-    0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,  /* 00000170    "........" */
-    0xF3,0x87,0x17,0x00,0x00,0x0C,0x03,0x00,  /* 00000178    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,  /* 00000180    "........" */
-    0xFF,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000188    "........" */
-    0x00,0x02,0x00,0x87,0x17,0x00,0x00,0x0C,  /* 00000190    "........" */
-    0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000198    "........" */
-    0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00,  /* 000001A0    "........" */
-    0x00,0x00,0x00,0x00,0x05,0x79,0x00,0x8A,  /* 000001A8    ".....y.." */
-    0x50,0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D,  /* 000001B0    "PRT0.\MM" */
-    0x49,0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A,  /* 000001B8    "IN.PRT0." */
-    0x60,0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52,  /* 000001C0    "`MMAX.PR" */
-    0x54,0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E,  /* 000001C8    "T0.hMLEN" */
-    0x70,0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49,  /* 000001D0    "pPMINMMI" */
-    0x4E,0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C,  /* 000001D8    "NpPLENML" */
-    0x45,0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D,  /* 000001E0    "ENrMMINM" */
-    0x4C,0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74,  /* 000001E8    "LENMMAXt" */
-    0x4D,0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41,  /* 000001F0    "MMAX.MMA" */
-    0x58,0xA4,0x50,0x52,0x54,0x30,0x08,0x42,  /* 000001F8    "X.PRT0.B" */
-    0x55,0x46,0x41,0x11,0x09,0x0A,0x06,0x23,  /* 00000200    "UFA....#" */
-    0x20,0x0C,0x18,0x79,0x00,0x08,0x42,0x55,  /* 00000208    " ..y..BU" */
-    0x46,0x42,0x11,0x09,0x0A,0x06,0x23,0x00,  /* 00000210    "FB....#." */
-    0x00,0x18,0x79,0x00,0x8B,0x42,0x55,0x46,  /* 00000218    "..y..BUF" */
-    0x42,0x01,0x49,0x52,0x51,0x56,0x5B,0x82,  /* 00000220    "B.IRQV[." */
-    0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,  /* 00000228    "H.LNKA._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 00000230    "HID.A..." */
-    0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,  /* 00000238    "._UID..." */
-    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 00000240    "_STA.{PI" */
-    0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000248    "RA..`..." */
-    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000250    "`......." */
-    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000258    "....._PR" */
-    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000260    "S..BUFA." */
-    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000268    "._DIS.}P" */
-    0x49,0x52,0x41,0x0A,0x80,0x50,0x49,0x52,  /* 00000270    "IRA..PIR" */
-    0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000278    "A.._CRS." */
-    0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,  /* 00000280    "{PIRA..`" */
-    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 00000288    "y.`IRQV." */
-    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 00000290    "BUFB.._S" */
-    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 00000298    "RS..h.IR" */
-    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 000002A0    "Q1.IRQ1`" */
-    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x41,  /* 000002A8    "v`p`PIRA" */
-    0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,  /* 000002B0    "[.I.LNKB" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000002B8    "._HID.A." */
-    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 000002C0    "..._UID." */
-    0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,  /* 000002C8    "..._STA." */
-    0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,0x60,  /* 000002D0    "{PIRB..`" */
-    0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,  /* 000002D8    "...`...." */
-    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,  /* 000002E0    "........" */
-    0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55,  /* 000002E8    "_PRS..BU" */
-    0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 000002F0    "FA.._DIS" */
-    0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 000002F8    ".}PIRB.." */
-    0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,  /* 00000300    "PIRB.._C" */
-    0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x42,  /* 00000308    "RS.{PIRB" */
-    0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52,  /* 00000310    "..`y.`IR" */
-    0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14,  /* 00000318    "QV.BUFB." */
-    0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00000320    "._SRS..h" */
-    0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52,  /* 00000328    ".IRQ1.IR" */
-    0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50,  /* 00000330    "Q1`v`p`P" */
-    0x49,0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,  /* 00000338    "IRB[.I.L" */
-    0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,  /* 00000340    "NKC._HID" */
-    0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,  /* 00000348    ".A...._U" */
-    0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,  /* 00000350    "ID...._S" */
-    0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x43,  /* 00000358    "TA.{PIRC" */
-    0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,  /* 00000360    "..`...`." */
-    0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,  /* 00000368    "........" */
-    0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,  /* 00000370    "..._PRS." */
-    0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F,  /* 00000378    ".BUFA.._" */
-    0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52,  /* 00000380    "DIS.}PIR" */
-    0x43,0x0A,0x80,0x50,0x49,0x52,0x43,0x14,  /* 00000388    "C..PIRC." */
-    0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,  /* 00000390    "._CRS.{P" */
-    0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,  /* 00000398    "IRC..`y." */
-    0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55,  /* 000003A0    "`IRQV.BU" */
-    0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,  /* 000003A8    "FB.._SRS" */
-    0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31,  /* 000003B0    "..h.IRQ1" */
-    0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60,  /* 000003B8    ".IRQ1`v`" */
-    0x70,0x60,0x50,0x49,0x52,0x43,0x5B,0x82,  /* 000003C0    "p`PIRC[." */
-    0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,  /* 000003C8    "I.LNKD._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 000003D0    "HID.A..." */
-    0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,  /* 000003D8    "._UID..." */
-    0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,  /* 000003E0    "._STA.{P" */
-    0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,  /* 000003E8    "IRD..`.." */
-    0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,  /* 000003F0    ".`......" */
-    0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,  /* 000003F8    "......_P" */
-    0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41,  /* 00000400    "RS..BUFA" */
-    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 00000408    ".._DIS.}" */
-    0x50,0x49,0x52,0x44,0x0A,0x80,0x50,0x49,  /* 00000410    "PIRD..PI" */
-    0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000418    "RD.._CRS" */
-    0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,  /* 00000420    ".{PIRD.." */
-    0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56,  /* 00000428    "`y.`IRQV" */
-    0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,  /* 00000430    ".BUFB.._" */
-    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00000438    "SRS..h.I" */
-    0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31,  /* 00000440    "RQ1.IRQ1" */
-    0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52,  /* 00000448    "`v`p`PIR" */
-    0x44,0x5B,0x82,0x44,0x05,0x48,0x50,0x45,  /* 00000450    "D[.D.HPE" */
-    0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000458    "T._HID.A" */
-    0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44,  /* 00000460    "...._UID" */
-    0x00,0x14,0x18,0x5F,0x53,0x54,0x41,0x00,  /* 00000468    "..._STA." */
-    0xA0,0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50,  /* 00000470    "...^^^HP" */
-    0x45,0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4,  /* 00000478    "ET......" */
-    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000480    "..._CRS." */
-    0x1F,0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,  /* 00000488    "........" */
-    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,  /* 00000490    "........" */
-    0xFE,0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,  /* 00000498    "........" */
-    0x00,0x00,0x04,0x00,0x00,0x79,0x00,0x14,  /* 000004A0    ".....y.." */
-    0x16,0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,  /* 000004A8    "._PRT..." */
-    0x50,0x49,0x43,0x44,0xA4,0x50,0x52,0x54,  /* 000004B0    "PICD.PRT" */
-    0x41,0xA4,0x50,0x52,0x54,0x50,0x08,0x50,  /* 000004B8    "A.PRTP.P" */
-    0x52,0x54,0x50,0x12,0x49,0x36,0x3C,0x12,  /* 000004C0    "RTP.I6<." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,  /* 000004C8    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000004D0    "LNKB...." */
-    0x0C,0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,  /* 000004D8    "......LN" */
-    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000004E0    "KC......" */
-    0xFF,0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000004E8    ".....LNK" */
-    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000004F0    "D......." */
-    0x01,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000004F8    "....LNKA" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,  /* 00000500    "........" */
-    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000508    "..LNKC.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,  /* 00000510    "........" */
-    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000518    "LNKD...." */
-    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,  /* 00000520    ".......L" */
-    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000528    "NKA....." */
-    0xFF,0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000530    "......LN" */
-    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000538    "KB......" */
-    0xFF,0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000540    "....LNKD" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000548    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000550    "..LNKA.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 00000558    "........" */
-    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000560    ".LNKB..." */
-    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,  /* 00000568    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000570    "LNKC...." */
-    0x0C,0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,  /* 00000578    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000580    "KA......" */
-    0xFF,0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000588    "....LNKB" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,  /* 00000590    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000598    "...LNKC." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000005A0    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000005A8    "..LNKD.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,  /* 000005B0    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000005B8    "LNKB...." */
-    0x0C,0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,  /* 000005C0    "......LN" */
-    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000005C8    "KC......" */
-    0xFF,0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000005D0    ".....LNK" */
-    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000005D8    "D......." */
-    0x05,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000005E0    "....LNKA" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,  /* 000005E8    "........" */
-    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000005F0    "..LNKC.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,  /* 000005F8    "........" */
-    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000600    "LNKD...." */
-    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,  /* 00000608    ".......L" */
-    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000610    "NKA....." */
-    0xFF,0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000618    "......LN" */
-    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000620    "KB......" */
-    0xFF,0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000628    "....LNKD" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000630    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000638    "..LNKA.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 00000640    "........" */
-    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000648    ".LNKB..." */
-    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,  /* 00000650    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000658    "LNKC...." */
-    0x0C,0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,  /* 00000660    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000668    "KA......" */
-    0xFF,0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000670    "....LNKB" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,  /* 00000678    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000680    "...LNKC." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000688    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000690    "..LNKD.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,  /* 00000698    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000006A0    "LNKB...." */
-    0x0C,0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,  /* 000006A8    "......LN" */
-    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000006B0    "KC......" */
-    0xFF,0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000006B8    ".....LNK" */
-    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000006C0    "D......." */
-    0x09,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000006C8    "....LNKA" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,  /* 000006D0    "........" */
-    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000006D8    "..LNKC.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,  /* 000006E0    "........" */
-    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 000006E8    "LNKD...." */
-    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,  /* 000006F0    ".......L" */
-    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000006F8    "NKA....." */
-    0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000700    "......LN" */
-    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000708    "KB......" */
-    0xFF,0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000710    "....LNKD" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000718    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000720    "..LNKA.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 00000728    "........" */
-    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000730    ".LNKB..." */
-    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,  /* 00000738    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000740    "LNKC...." */
-    0x0C,0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,  /* 00000748    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000750    "KA......" */
-    0xFF,0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000758    "....LNKB" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,  /* 00000760    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000768    "...LNKC." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000770    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000778    "..LNKD.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,  /* 00000780    "........" */
-    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 00000788    "LNKB...." */
-    0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,  /* 00000790    "......LN" */
-    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000798    "KC......" */
-    0xFF,0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000007A0    ".....LNK" */
-    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000007A8    "D......." */
-    0x0D,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000007B0    "....LNKA" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,  /* 000007B8    "........" */
-    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000007C0    "..LNKC.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,  /* 000007C8    "........" */
-    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 000007D0    "LNKD...." */
-    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,  /* 000007D8    ".......L" */
-    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000007E0    "NKA....." */
-    0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,  /* 000007E8    "......LN" */
-    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000007F0    "KB......" */
-    0xFF,0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 000007F8    "....LNKD" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000800    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000808    "..LNKA.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000810    "........" */
-    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000818    ".LNKB..." */
-    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,  /* 00000820    "........" */
-    0x4C,0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,  /* 00000828    "LNKC..PR" */
-    0x54,0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,  /* 00000830    "TA.A/<.." */
-    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,  /* 00000838    "........" */
-    0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000840    "........" */
-    0x01,0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,  /* 00000848    "........" */
-    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,  /* 00000850    "........" */
-    0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000858    "........" */
-    0xFF,0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,  /* 00000860    "........" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000868    "........" */
-    0x00,0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,  /* 00000870    "........" */
-    0xFF,0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,  /* 00000878    "........" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000880    "........" */
-    0x0A,0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,  /* 00000888    "........" */
-    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,  /* 00000890    "........" */
-    0x0A,0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000898    "........" */
-    0x03,0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,  /* 000008A0    "........" */
-    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,  /* 000008A8    "........" */
-    0x0A,0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000008B0    "........" */
-    0x03,0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,  /* 000008B8    "........" */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 000008C0    "........" */
-    0x03,0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,  /* 000008C8    "........" */
-    0xFF,0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,  /* 000008D0    "....... " */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000008D8    "........" */
-    0x01,0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,  /* 000008E0    "...!...." */
-    0xFF,0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,  /* 000008E8    "........" */
-    0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,  /* 000008F0    ""......." */
-    0x00,0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,  /* 000008F8    ".....#.." */
-    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,  /* 00000900    "........" */
-    0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000908    ".$......" */
-    0x05,0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,  /* 00000910    ".....%.." */
-    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,  /* 00000918    "........" */
-    0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000920    "..&....." */
-    0xFF,0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,  /* 00000928    ".......'" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000930    "........" */
-    0x00,0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,  /* 00000938    "...(...." */
-    0xFF,0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,  /* 00000940    ".......)" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000948    "........" */
-    0x0A,0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,  /* 00000950    "....*..." */
-    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,  /* 00000958    "........" */
-    0x0A,0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000960    ".+......" */
-    0x07,0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,  /* 00000968    ".....,.." */
-    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,  /* 00000970    "........" */
-    0x0A,0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000978    ".-......" */
-    0x07,0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,  /* 00000980    "........" */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 00000988    "........" */
-    0x03,0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,  /* 00000990    ".../...." */
-    0xFF,0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,  /* 00000998    "........" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 000009A0    "........" */
-    0x01,0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,  /* 000009A8    "........" */
-    0xFF,0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,  /* 000009B0    "........" */
-    0x13,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,  /* 000009B8    "........" */
-    0x00,0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,  /* 000009C0    "........" */
-    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,  /* 000009C8    "........" */
-    0x0A,0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 000009D0    "........" */
-    0x09,0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,  /* 000009D8    "........" */
-    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,  /* 000009E0    "........" */
-    0x00,0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,  /* 000009E8    "........" */
-    0xFF,0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,  /* 000009F0    "........" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 000009F8    "........" */
-    0x00,0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,  /* 00000A00    "........" */
-    0xFF,0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,  /* 00000A08    "........" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 00000A10    "........" */
-    0x0A,0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,  /* 00000A18    "........" */
-    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,  /* 00000A20    "........" */
-    0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000A28    "........" */
-    0x0B,0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,  /* 00000A30    "........" */
-    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,  /* 00000A38    "........" */
-    0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A40    "........" */
-    0x0B,0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,  /* 00000A48    "........" */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 00000A50    "........" */
-    0x03,0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,  /* 00000A58    "... ...." */
-    0xFF,0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,  /* 00000A60    ".......!" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000A68    "........" */
-    0x01,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,  /* 00000A70    "..."...." */
-    0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,  /* 00000A78    "........" */
-    0x23,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,  /* 00000A80    "#......." */
-    0x00,0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,  /* 00000A88    ".....$.." */
-    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,  /* 00000A90    "........" */
-    0x0A,0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000A98    ".%......" */
-    0x0D,0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,  /* 00000AA0    ".....&.." */
-    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,  /* 00000AA8    "........" */
-    0x00,0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000AB0    "..'....." */
-    0xFF,0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,  /* 00000AB8    ".......(" */
-    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000AC0    "........" */
-    0x00,0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,  /* 00000AC8    "...)...." */
-    0xFF,0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,  /* 00000AD0    ".......*" */
-    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000AD8    "........" */
-    0x0A,0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,  /* 00000AE0    "....+..." */
-    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,  /* 00000AE8    "........" */
-    0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000AF0    ".,......" */
-    0x0F,0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,  /* 00000AF8    ".....-.." */
-    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,  /* 00000B00    "........" */
-    0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000B08    "........" */
-    0x0F,0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,  /* 00000B10    "....../." */
-    0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000B18    "........" */
-    0x03,0x00,0x0A,0x10,0x5B,0x82,0x46,0x37,  /* 00000B20    "....[.F7" */
-    0x49,0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,  /* 00000B28    "ISA_._AD" */
-    0x52,0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,  /* 00000B30    "R.....[." */
-    0x50,0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,  /* 00000B38    "PIRQ..`." */
-    0x04,0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,  /* 00000B40    "...\.[.)" */
-    0x5C,0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,  /* 00000B48    "\/._SB_P" */
-    0x43,0x49,0x30,0x49,0x53,0x41,0x5F,0x50,  /* 00000B50    "CI0ISA_P" */
-    0x49,0x52,0x51,0x01,0x50,0x49,0x52,0x41,  /* 00000B58    "IRQ.PIRA" */
-    0x08,0x50,0x49,0x52,0x42,0x08,0x50,0x49,  /* 00000B60    ".PIRB.PI" */
-    0x52,0x43,0x08,0x50,0x49,0x52,0x44,0x08,  /* 00000B68    "RC.PIRD." */
-    0x5B,0x82,0x46,0x0B,0x53,0x59,0x53,0x52,  /* 00000B70    "[.F.SYSR" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000B78    "._HID.A." */
-    0x0C,0x02,0x08,0x5F,0x55,0x49,0x44,0x01,  /* 00000B80    "..._UID." */
-    0x08,0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,  /* 00000B88    ".CRS_.N." */
-    0x0A,0x8A,0x47,0x01,0x10,0x00,0x10,0x00,  /* 00000B90    "..G....." */
-    0x00,0x10,0x47,0x01,0x22,0x00,0x22,0x00,  /* 00000B98    "..G."."." */
-    0x00,0x0C,0x47,0x01,0x30,0x00,0x30,0x00,  /* 00000BA0    "..G.0.0." */
-    0x00,0x10,0x47,0x01,0x44,0x00,0x44,0x00,  /* 00000BA8    "..G.D.D." */
-    0x00,0x1C,0x47,0x01,0x62,0x00,0x62,0x00,  /* 00000BB0    "..G.b.b." */
-    0x00,0x02,0x47,0x01,0x65,0x00,0x65,0x00,  /* 00000BB8    "..G.e.e." */
-    0x00,0x0B,0x47,0x01,0x72,0x00,0x72,0x00,  /* 00000BC0    "..G.r.r." */
-    0x00,0x0E,0x47,0x01,0x80,0x00,0x80,0x00,  /* 00000BC8    "..G....." */
-    0x00,0x01,0x47,0x01,0x84,0x00,0x84,0x00,  /* 00000BD0    "..G....." */
-    0x00,0x03,0x47,0x01,0x88,0x00,0x88,0x00,  /* 00000BD8    "..G....." */
-    0x00,0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,  /* 00000BE0    "..G....." */
-    0x00,0x03,0x47,0x01,0x90,0x00,0x90,0x00,  /* 00000BE8    "..G....." */
-    0x00,0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,  /* 00000BF0    "..G....." */
-    0x00,0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,  /* 00000BF8    "..G....." */
-    0x00,0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,  /* 00000C00    "..G....." */
-    0x00,0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,  /* 00000C08    "..G....." */
-    0x00,0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,  /* 00000C10    "..G....." */
-    0x00,0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,  /* 00000C18    "..y..._C" */
-    0x52,0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,  /* 00000C20    "RS..CRS_" */
-    0x5B,0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,  /* 00000C28    "[.+PIC_." */
-    0x5F,0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,  /* 00000C30    "_HID.A.." */
-    0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,0x15,  /* 00000C38    "_CRS...." */
-    0x47,0x01,0x20,0x00,0x20,0x00,0x01,0x02,  /* 00000C40    "G. . ..." */
-    0x47,0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,  /* 00000C48    "G......." */
-    0x22,0x04,0x00,0x79,0x00,0x5B,0x82,0x47,  /* 00000C50    ""..y.[.G" */
-    0x05,0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,  /* 00000C58    ".DMA0._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,  /* 00000C60    "ID.A...." */
-    0x5F,0x43,0x52,0x53,0x11,0x41,0x04,0x0A,  /* 00000C68    "_CRS.A.." */
-    0x3D,0x2A,0x10,0x04,0x47,0x01,0x00,0x00,  /* 00000C70    "=*..G..." */
-    0x00,0x00,0x00,0x10,0x47,0x01,0x81,0x00,  /* 00000C78    "....G..." */
-    0x81,0x00,0x00,0x03,0x47,0x01,0x87,0x00,  /* 00000C80    "....G..." */
-    0x87,0x00,0x00,0x01,0x47,0x01,0x89,0x00,  /* 00000C88    "....G..." */
-    0x89,0x00,0x00,0x03,0x47,0x01,0x8F,0x00,  /* 00000C90    "....G..." */
-    0x8F,0x00,0x00,0x01,0x47,0x01,0xC0,0x00,  /* 00000C98    "....G..." */
-    0xC0,0x00,0x00,0x20,0x47,0x01,0x80,0x04,  /* 00000CA0    "... G..." */
-    0x80,0x04,0x00,0x10,0x79,0x00,0x5B,0x82,  /* 00000CA8    "....y.[." */
-    0x25,0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,  /* 00000CB0    "%TMR_._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,  /* 00000CB8    "ID.A...." */
-    0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,  /* 00000CC0    "_CRS...." */
-    0x47,0x01,0x40,0x00,0x40,0x00,0x00,0x04,  /* 00000CC8    "G.@.@..." */
-    0x22,0x01,0x00,0x79,0x00,0x5B,0x82,0x25,  /* 00000CD0    ""..y.[.%" */
-    0x52,0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,  /* 00000CD8    "RTC_._HI" */
-    0x44,0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,  /* 00000CE0    "D.A...._" */
-    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000CE8    "CRS....G" */
-    0x01,0x70,0x00,0x70,0x00,0x00,0x02,0x22,  /* 00000CF0    ".p.p..."" */
-    0x00,0x01,0x79,0x00,0x5B,0x82,0x22,0x53,  /* 00000CF8    "..y.[."S" */
-    0x50,0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,  /* 00000D00    "PKR._HID" */
-    0x0C,0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,  /* 00000D08    ".A...._C" */
-    0x52,0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,  /* 00000D10    "RS....G." */
-    0x61,0x00,0x61,0x00,0x00,0x01,0x79,0x00,  /* 00000D18    "a.a...y." */
-    0x5B,0x82,0x31,0x50,0x53,0x32,0x4D,0x08,  /* 00000D20    "[.1PS2M." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,  /* 00000D28    "_HID.A.." */
-    0x13,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,  /* 00000D30    ".._CID.A" */
-    0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,  /* 00000D38    "....._ST" */
-    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000D40    "A....._C" */
-    0x52,0x53,0x11,0x08,0x0A,0x05,0x22,0x00,  /* 00000D48    "RS...."." */
-    0x10,0x79,0x00,0x5B,0x82,0x42,0x04,0x50,  /* 00000D50    ".y.[.B.P" */
-    0x53,0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,  /* 00000D58    "S2K._HID" */
-    0x0C,0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,  /* 00000D60    ".A...._C" */
-    0x49,0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,  /* 00000D68    "ID.A...." */
-    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D70    "._STA..." */
-    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x18,  /* 00000D78    ".._CRS.." */
-    0x0A,0x15,0x47,0x01,0x60,0x00,0x60,0x00,  /* 00000D80    "..G.`.`." */
-    0x00,0x01,0x47,0x01,0x64,0x00,0x64,0x00,  /* 00000D88    "..G.d.d." */
-    0x00,0x01,0x22,0x02,0x00,0x79,0x00,0x5B,  /* 00000D90    ".."..y.[" */
-    0x82,0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,  /* 00000D98    ".:FDC0._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,  /* 00000DA0    "HID.A..." */
-    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 00000DA8    ".._STA.." */
-    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000DB0    "..._CRS." */
-    0x1B,0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,  /* 00000DB8    "...G...." */
-    0x03,0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,  /* 00000DC0    "...G...." */
-    0x03,0x01,0x01,0x22,0x40,0x00,0x2A,0x04,  /* 00000DC8    "..."@.*." */
-    0x00,0x79,0x00,0x5B,0x82,0x46,0x04,0x55,  /* 00000DD0    ".y.[.F.U" */
-    0x41,0x52,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00000DD8    "AR1._HID" */
-    0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,  /* 00000DE0    ".A...._U" */
-    0x49,0x44,0x01,0x14,0x19,0x5F,0x53,0x54,  /* 00000DE8    "ID..._ST" */
-    0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,  /* 00000DF0    "A....^^^" */
-    0x5E,0x55,0x41,0x52,0x31,0x00,0xA4,0x00,  /* 00000DF8    "^UAR1..." */
-    0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000E00    "......_C" */
-    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000E08    "RS....G." */
-    0xF8,0x03,0xF8,0x03,0x08,0x08,0x22,0x10,  /* 00000E10    "......"." */
-    0x00,0x79,0x00,0x5B,0x82,0x47,0x04,0x55,  /* 00000E18    ".y.[.G.U" */
-    0x41,0x52,0x32,0x08,0x5F,0x48,0x49,0x44,  /* 00000E20    "AR2._HID" */
-    0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,  /* 00000E28    ".A...._U" */
-    0x49,0x44,0x0A,0x02,0x14,0x19,0x5F,0x53,  /* 00000E30    "ID...._S" */
-    0x54,0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,  /* 00000E38    "TA....^^" */
-    0x5E,0x5E,0x55,0x41,0x52,0x32,0x00,0xA4,  /* 00000E40    "^^UAR2.." */
-    0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000E48    "......._" */
-    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000E50    "CRS....G" */
-    0x01,0xF8,0x02,0xF8,0x02,0x08,0x08,0x22,  /* 00000E58    "......."" */
-    0x08,0x00,0x79,0x00,0x5B,0x82,0x36,0x4C,  /* 00000E60    "..y.[.6L" */
-    0x54,0x50,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00000E68    "TP1._HID" */
-    0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F,0x55,  /* 00000E70    ".A...._U" */
-    0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53,  /* 00000E78    "ID...._S" */
-    0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000E80    "TA....._" */
-    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000E88    "CRS....G" */
-    0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22,  /* 00000E90    ".x.x..."" */
-    0x80,0x00,0x79,0x00,0x5B,0x82,0x4D,0x07,  /* 00000E98    "..y.[.M." */
-    0x53,0x31,0x46,0x30,0x08,0x5F,0x41,0x44,  /* 00000EA0    "S1F0._AD" */
-    0x52,0x0C,0x00,0x00,0x06,0x00,0x08,0x5F,  /* 00000EA8    "R......_" */
-    0x53,0x55,0x4E,0x01,0x14,0x13,0x5F,0x50,  /* 00000EB0    "SUN..._P" */
-    0x53,0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E,  /* 00000EB8    "S0.p..\." */
-    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000EC0    "_GPEDPT2" */
-    0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70,  /* 00000EC8    ".._PS3.p" */
-    0x0A,0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000ED0    "..\._GPE" */
-    0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,  /* 00000ED8    "DPT2.._E" */
-    0x4A,0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E,  /* 00000EE0    "J0.p..\." */
-    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000EE8    "_GPEDPT2" */
-    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000EF0    "p.\._GPE" */
-    0x50,0x48,0x50,0x31,0x14,0x1E,0x5F,0x53,  /* 00000EF8    "PHP1.._S" */
-    0x54,0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E,  /* 00000F00    "TA.p..\." */
-    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F08    "_GPEDPT2" */
-    0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000F10    ".\._GPEP" */
-    0x48,0x50,0x31,0x5B,0x82,0x4E,0x07,0x53,  /* 00000F18    "HP1[.N.S" */
-    0x32,0x46,0x30,0x08,0x5F,0x41,0x44,0x52,  /* 00000F20    "2F0._ADR" */
-    0x0C,0x00,0x00,0x07,0x00,0x08,0x5F,0x53,  /* 00000F28    "......_S" */
-    0x55,0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50,  /* 00000F30    "UN...._P" */
-    0x53,0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E,  /* 00000F38    "S0.p..\." */
-    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F40    "_GPEDPT2" */
-    0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70,  /* 00000F48    ".._PS3.p" */
-    0x0A,0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000F50    "..\._GPE" */
-    0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,  /* 00000F58    "DPT2.._E" */
-    0x4A,0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E,  /* 00000F60    "J0.p..\." */
-    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F68    "_GPEDPT2" */
-    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000F70    "p.\._GPE" */
-    0x50,0x48,0x50,0x32,0x14,0x1E,0x5F,0x53,  /* 00000F78    "PHP2.._S" */
-    0x54,0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E,  /* 00000F80    "TA.p..\." */
-    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F88    "_GPEDPT2" */
-    0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000F90    ".\._GPEP" */
-    0x48,0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47,  /* 00000F98    "HP2.N._G" */
-    0x50,0x45,0x5B,0x80,0x50,0x48,0x50,0x5F,  /* 00000FA0    "PE[.PHP_" */
-    0x01,0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81,  /* 00000FA8    "......[." */
-    0x15,0x50,0x48,0x50,0x5F,0x01,0x50,0x53,  /* 00000FB0    ".PHP_.PS" */
-    0x54,0x41,0x08,0x50,0x48,0x50,0x31,0x08,  /* 00000FB8    "TA.PHP1." */
-    0x50,0x48,0x50,0x32,0x08,0x5B,0x80,0x44,  /* 00000FC0    "PHP2.[.D" */
-    0x47,0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A,  /* 00000FC8    "G1_..D.." */
-    0x04,0x5B,0x81,0x10,0x44,0x47,0x31,0x5F,  /* 00000FD0    ".[..DG1_" */
-    0x01,0x44,0x50,0x54,0x31,0x08,0x44,0x50,  /* 00000FD8    ".DPT1.DP" */
-    0x54,0x32,0x08,0x14,0x46,0x07,0x5F,0x4C,  /* 00000FE0    "T2..F._L" */
-    0x30,0x33,0x00,0x08,0x53,0x4C,0x54,0x5F,  /* 00000FE8    "03..SLT_" */
-    0x00,0x08,0x45,0x56,0x54,0x5F,0x00,0x70,  /* 00000FF0    "..EVT_.p" */
-    0x50,0x53,0x54,0x41,0x61,0x7A,0x61,0x0A,  /* 00000FF8    "PSTAaza." */
-    0x04,0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A,  /* 00001000    ".SLT_{a." */
-    0x0F,0x45,0x56,0x54,0x5F,0x70,0x53,0x4C,  /* 00001008    ".EVT_pSL" */
-    0x54,0x5F,0x44,0x50,0x54,0x31,0x70,0x45,  /* 00001010    "T_DPT1pE" */
-    0x56,0x54,0x5F,0x44,0x50,0x54,0x32,0xA0,  /* 00001018    "VT_DPT2." */
-    0x1B,0x93,0x53,0x4C,0x54,0x5F,0x01,0x86,  /* 00001020    "..SLT_.." */
-    0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,  /* 00001028    "\/._SB_P" */
-    0x43,0x49,0x30,0x53,0x31,0x46,0x30,0x45,  /* 00001030    "CI0S1F0E" */
-    0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93,  /* 00001038    "VT_....." */
-    0x53,0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C,  /* 00001040    "SLT_...\" */
-    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00001048    "/._SB_PC" */
-    0x49,0x30,0x53,0x32,0x46,0x30,0x45,0x56,  /* 00001050    "I0S2F0EV" */
-    0x54,0x5F,
+    0x00,0x10,0x46,0x0D,0x5F,0x50,0x52,0x5F,  /* 00000058    "..F._PR_" */
+    0x5B,0x83,0x0B,0x50,0x52,0x30,0x30,0x00,  /* 00000060    "[..PR00." */
+    0x00,0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,  /* 00000068    ".....[.." */
+    0x50,0x52,0x30,0x31,0x01,0x00,0x00,0x00,  /* 00000070    "PR01...." */
+    0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,  /* 00000078    "..[..PR0" */
+    0x32,0x02,0x00,0x00,0x00,0x00,0x00,0x5B,  /* 00000080    "2......[" */
+    0x83,0x0B,0x50,0x52,0x30,0x33,0x03,0x00,  /* 00000088    "..PR03.." */
+    0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,  /* 00000090    "....[..P" */
+    0x52,0x30,0x34,0x00,0x00,0x00,0x00,0x00,  /* 00000098    "R04....." */
+    0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,0x35,  /* 000000A0    ".[..PR05" */
+    0x01,0x00,0x00,0x00,0x00,0x00,0x5B,0x83,  /* 000000A8    "......[." */
+    0x0B,0x50,0x52,0x30,0x36,0x02,0x00,0x00,  /* 000000B0    ".PR06..." */
+    0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,  /* 000000B8    "...[..PR" */
+    0x30,0x37,0x03,0x00,0x00,0x00,0x00,0x00,  /* 000000C0    "07......" */
+    0x5B,0x83,0x0B,0x50,0x52,0x30,0x38,0x00,  /* 000000C8    "[..PR08." */
+    0x00,0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,  /* 000000D0    ".....[.." */
+    0x50,0x52,0x30,0x39,0x01,0x00,0x00,0x00,  /* 000000D8    "PR09...." */
+    0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,  /* 000000E0    "..[..PR0" */
+    0x41,0x02,0x00,0x00,0x00,0x00,0x00,0x5B,  /* 000000E8    "A......[" */
+    0x83,0x0B,0x50,0x52,0x30,0x42,0x03,0x00,  /* 000000F0    "..PR0B.." */
+    0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,  /* 000000F8    "....[..P" */
+    0x52,0x30,0x43,0x00,0x00,0x00,0x00,0x00,  /* 00000100    "R0C....." */
+    0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,0x44,  /* 00000108    ".[..PR0D" */
+    0x01,0x00,0x00,0x00,0x00,0x00,0x5B,0x83,  /* 00000110    "......[." */
+    0x0B,0x50,0x52,0x30,0x45,0x02,0x00,0x00,  /* 00000118    ".PR0E..." */
+    0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,  /* 00000120    "...[..PR" */
+    0x30,0x46,0x03,0x00,0x00,0x00,0x00,0x00,  /* 00000128    "0F......" */
+    0x08,0x5F,0x53,0x34,0x5F,0x12,0x08,0x04,  /* 00000130    "._S4_..." */
+    0x0A,0x06,0x0A,0x06,0x00,0x00,0x08,0x5F,  /* 00000138    "......._" */
+    0x53,0x35,0x5F,0x12,0x08,0x04,0x0A,0x07,  /* 00000140    "S5_....." */
+    0x0A,0x07,0x00,0x00,0x08,0x50,0x49,0x43,  /* 00000148    ".....PIC" */
+    0x44,0x00,0x14,0x0C,0x5F,0x50,0x49,0x43,  /* 00000150    "D..._PIC" */
+    0x01,0x70,0x68,0x50,0x49,0x43,0x44,0x10,  /* 00000158    ".phPICD." */
+    0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B,0x80,  /* 00000160    "B._SB_[." */
+    0x42,0x49,0x4F,0x53,0x00,0x0C,0x00,0xA0,  /* 00000168    "BIOS...." */
+    0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21,0x42,  /* 00000170    "....[.!B" */
+    0x49,0x4F,0x53,0x01,0x55,0x41,0x52,0x31,  /* 00000178    "IOS.UAR1" */
+    0x01,0x55,0x41,0x52,0x32,0x01,0x48,0x50,  /* 00000180    ".UAR2.HP" */
+    0x45,0x54,0x01,0x00,0x1D,0x50,0x4D,0x49,  /* 00000188    "ET...PMI" */
+    0x4E,0x20,0x50,0x4C,0x45,0x4E,0x20,0x5B,  /* 00000190    "N PLEN [" */
+    0x82,0x49,0x04,0x4D,0x45,0x4D,0x30,0x08,  /* 00000198    ".I.MEM0." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 000001A0    "_HID.A.." */
+    0x02,0x08,0x5F,0x43,0x52,0x53,0x11,0x33,  /* 000001A8    ".._CRS.3" */
+    0x0A,0x30,0x8A,0x2B,0x00,0x00,0x0D,0x03,  /* 000001B0    ".0.+...." */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001B8    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001C0    "........" */
+    0xFF,0xFF,0x09,0x00,0x00,0x00,0x00,0x00,  /* 000001C8    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001D0    "........" */
+    0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,  /* 000001D8    "........" */
+    0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50,0x43,  /* 000001E0    "y.[.N.PC" */
+    0x49,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 000001E8    "I0._HID." */
+    0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55,0x49,  /* 000001F0    "A...._UI" */
+    0x44,0x00,0x08,0x5F,0x41,0x44,0x52,0x00,  /* 000001F8    "D.._ADR." */
+    0x08,0x5F,0x42,0x42,0x4E,0x00,0x14,0x4E,  /* 00000200    "._BBN..N" */
+    0x0C,0x5F,0x43,0x52,0x53,0x00,0x08,0x50,  /* 00000208    "._CRS..P" */
+    0x52,0x54,0x30,0x11,0x42,0x07,0x0A,0x6E,  /* 00000210    "RT0.B..n" */
+    0x88,0x0D,0x00,0x02,0x0E,0x00,0x00,0x00,  /* 00000218    "........" */
+    0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,  /* 00000220    "........" */
+    0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,0x08,  /* 00000228    "G......." */
+    0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,  /* 00000230    "........" */
+    0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,0x0C,  /* 00000238    "........" */
+    0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,  /* 00000240    "........" */
+    0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,0xF3,  /* 00000248    "........" */
+    0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00,  /* 00000250    "........" */
+    0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,0xFF,  /* 00000258    "........" */
+    0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000260    "........" */
+    0x02,0x00,0x87,0x17,0x00,0x00,0x0C,0x03,  /* 00000268    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,  /* 00000270    "........" */
+    0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00,0x00,  /* 00000278    "........" */
+    0x00,0x00,0x00,0x05,0x79,0x00,0x8A,0x50,  /* 00000280    "....y..P" */
+    0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D,0x49,  /* 00000288    "RT0.\MMI" */
+    0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A,0x60,  /* 00000290    "N.PRT0.`" */
+    0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52,0x54,  /* 00000298    "MMAX.PRT" */
+    0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E,0x70,  /* 000002A0    "0.hMLENp" */
+    0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49,0x4E,  /* 000002A8    "PMINMMIN" */
+    0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C,0x45,  /* 000002B0    "pPLENMLE" */
+    0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D,0x4C,  /* 000002B8    "NrMMINML" */
+    0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74,0x4D,  /* 000002C0    "ENMMAXtM" */
+    0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41,0x58,  /* 000002C8    "MAX.MMAX" */
+    0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55,  /* 000002D0    ".PRT0.BU" */
+    0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x20,  /* 000002D8    "FA....# " */
+    0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46,  /* 000002E0    "..y..BUF" */
+    0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00,  /* 000002E8    "B....#.." */
+    0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42,  /* 000002F0    ".y..BUFB" */
+    0x01,0x49,0x52,0x51,0x56,0x5B,0x82,0x48,  /* 000002F8    ".IRQV[.H" */
+    0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48,  /* 00000300    ".LNKA._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000308    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F,  /* 00000310    "_UID..._" */
+    0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52,  /* 00000318    "STA.{PIR" */
+    0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,  /* 00000320    "A..`...`" */
+    0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 00000328    "........" */
+    0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,  /* 00000330    "...._PRS" */
+    0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11,  /* 00000338    "..BUFA.." */
+    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 00000340    "_DIS.}PI" */
+    0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41,  /* 00000348    "RA..PIRA" */
+    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,  /* 00000350    ".._CRS.{" */
+    0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,0x79,  /* 00000358    "PIRA..`y" */
+    0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42,  /* 00000360    ".`IRQV.B" */
+    0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,  /* 00000368    "UFB.._SR" */
+    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 00000370    "S..h.IRQ" */
+    0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76,  /* 00000378    "1.IRQ1`v" */
+    0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B,  /* 00000380    "`p`PIRA[" */
+    0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08,  /* 00000388    ".I.LNKB." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000390    "_HID.A.." */
+    0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,  /* 00000398    ".._UID.." */
+    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 000003A0    ".._STA.{" */
+    0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0,  /* 000003A8    "PIRB..`." */
+    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 000003B0    "..`....." */
+    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 000003B8    "......._" */
+    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 000003C0    "PRS..BUF" */
+    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 000003C8    "A.._DIS." */
+    0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50,  /* 000003D0    "}PIRB..P" */
+    0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52,  /* 000003D8    "IRB.._CR" */
+    0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,  /* 000003E0    "S.{PIRB." */
+    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 000003E8    ".`y.`IRQ" */
+    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 000003F0    "V.BUFB.." */
+    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 000003F8    "_SRS..h." */
+    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 00000400    "IRQ1.IRQ" */
+    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 00000408    "1`v`p`PI" */
+    0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E,  /* 00000410    "RB[.I.LN" */
+    0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000418    "KC._HID." */
+    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 00000420    "A...._UI" */
+    0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54,  /* 00000428    "D...._ST" */
+    0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A,  /* 00000430    "A.{PIRC." */
+    0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,  /* 00000438    ".`...`.." */
+    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 00000440    "........" */
+    0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,  /* 00000448    ".._PRS.." */
+    0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44,  /* 00000450    "BUFA.._D" */
+    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43,  /* 00000458    "IS.}PIRC" */
+    0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A,  /* 00000460    "..PIRC.." */
+    0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49,  /* 00000468    "_CRS.{PI" */
+    0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60,  /* 00000470    "RC..`y.`" */
+    0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46,  /* 00000478    "IRQV.BUF" */
+    0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,  /* 00000480    "B.._SRS." */
+    0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82,  /* 00000488    ".h.IRQ1." */
+    0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70,  /* 00000490    "IRQ1`v`p" */
+    0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49,  /* 00000498    "`PIRC[.I" */
+    0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,  /* 000004A0    ".LNKD._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 000004A8    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C,  /* 000004B0    "_UID...." */
+    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 000004B8    "_STA.{PI" */
+    0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 000004C0    "RD..`..." */
+    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 000004C8    "`......." */
+    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 000004D0    "....._PR" */
+    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 000004D8    "S..BUFA." */
+    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 000004E0    "._DIS.}P" */
+    0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52,  /* 000004E8    "IRD..PIR" */
+    0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 000004F0    "D.._CRS." */
+    0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60,  /* 000004F8    "{PIRD..`" */
+    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 00000500    "y.`IRQV." */
+    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 00000508    "BUFB.._S" */
+    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 00000510    "RS..h.IR" */
+    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 00000518    "Q1.IRQ1`" */
+    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44,  /* 00000520    "v`p`PIRD" */
+    0x5B,0x82,0x44,0x05,0x48,0x50,0x45,0x54,  /* 00000528    "[.D.HPET" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000530    "._HID.A." */
+    0x01,0x03,0x08,0x5F,0x55,0x49,0x44,0x00,  /* 00000538    "..._UID." */
+    0x14,0x18,0x5F,0x53,0x54,0x41,0x00,0xA0,  /* 00000540    ".._STA.." */
+    0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50,0x45,  /* 00000548    "..^^^HPE" */
+    0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A,  /* 00000550    "T......." */
+    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1F,  /* 00000558    ".._CRS.." */
+    0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,0x01,  /* 00000560    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFE,  /* 00000568    "........" */
+    0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,0x00,  /* 00000570    "........" */
+    0x00,0x04,0x00,0x00,0x79,0x00,0x14,0x16,  /* 00000578    "....y..." */
+    0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,0x50,  /* 00000580    "_PRT...P" */
+    0x49,0x43,0x44,0xA4,0x50,0x52,0x54,0x41,  /* 00000588    "ICD.PRTA" */
+    0xA4,0x50,0x52,0x54,0x50,0x08,0x50,0x52,  /* 00000590    ".PRTP.PR" */
+    0x54,0x50,0x12,0x49,0x36,0x3C,0x12,0x0D,  /* 00000598    "TP.I6<.." */
+    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C,  /* 000005A0    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 000005A8    "NKB....." */
+    0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B,  /* 000005B0    ".....LNK" */
+    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000005B8    "C......." */
+    0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 000005C0    "....LNKD" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,  /* 000005C8    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 000005D0    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 000005D8    "........" */
+    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000005E0    ".LNKC..." */
+    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x4C,  /* 000005E8    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000005F0    "NKD....." */
+    0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,0x4E,  /* 000005F8    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000600    "KA......" */
+    0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000608    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000610    "B......." */
+    0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000618    "...LNKD." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000620    "........" */
+    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000628    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,  /* 00000630    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 00000638    "LNKB...." */
+    0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,0x4C,  /* 00000640    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000648    "NKC....." */
+    0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000650    ".....LNK" */
+    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000658    "A......." */
+    0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000660    "...LNKB." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 00000668    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000670    "..LNKC.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,  /* 00000678    "........" */
+    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000680    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x4C,  /* 00000688    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000690    "NKB....." */
+    0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000698    ".....LNK" */
+    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000006A0    "C......." */
+    0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 000006A8    "....LNKD" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,  /* 000006B0    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 000006B8    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 000006C0    "........" */
+    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000006C8    ".LNKC..." */
+    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x4C,  /* 000006D0    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000006D8    "NKD....." */
+    0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,0x4E,  /* 000006E0    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000006E8    "KA......" */
+    0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000006F0    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006F8    "B......." */
+    0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000700    "...LNKD." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 00000708    "........" */
+    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000710    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02,  /* 00000718    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 00000720    "LNKB...." */
+    0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,0x4C,  /* 00000728    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000730    "NKC....." */
+    0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000738    ".....LNK" */
+    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000740    "A......." */
+    0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000748    "...LNKB." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000750    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000758    "..LNKC.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,  /* 00000760    "........" */
+    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000768    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x4C,  /* 00000770    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000778    "NKB....." */
+    0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000780    ".....LNK" */
+    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000788    "C......." */
+    0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000790    "....LNKD" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000798    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 000007A0    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 000007A8    "........" */
+    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000007B0    ".LNKC..." */
+    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C,  /* 000007B8    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000007C0    "NKD....." */
+    0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E,  /* 000007C8    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000007D0    "KA......" */
+    0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000007D8    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000007E0    "B......." */
+    0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000007E8    "...LNKD." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 000007F0    "........" */
+    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000007F8    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02,  /* 00000800    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 00000808    "LNKB...." */
+    0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x4C,  /* 00000810    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000818    "NKC....." */
+    0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000820    ".....LNK" */
+    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000828    "A......." */
+    0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000830    "...LNKB." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000838    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000840    "..LNKC.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,  /* 00000848    "........" */
+    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000850    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x4C,  /* 00000858    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000860    "NKB....." */
+    0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000868    ".....LNK" */
+    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000870    "C......." */
+    0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000878    "....LNKD" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000880    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000888    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000890    "........" */
+    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000898    ".LNKC..." */
+    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x4C,  /* 000008A0    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000008A8    "NKD....." */
+    0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,0x4E,  /* 000008B0    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000008B8    "KA......" */
+    0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000008C0    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000008C8    "B......." */
+    0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000008D0    "...LNKD." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 000008D8    "........" */
+    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000008E0    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02,  /* 000008E8    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000008F0    "LNKB...." */
+    0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x4C,  /* 000008F8    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,0x54,  /* 00000900    "NKC..PRT" */
+    0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,0x04,  /* 00000908    "A.A/<..." */
+    0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,0x0A,  /* 00000910    "........" */
+    0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,  /* 00000918    "........" */
+    0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,0x04,  /* 00000920    "........" */
+    0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x00,  /* 00000928    "........" */
+    0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000930    "........" */
+    0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,0x12,  /* 00000938    "........" */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,  /* 00000940    "........" */
+    0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000948    "........" */
+    0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,0x12,  /* 00000950    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,  /* 00000958    "........" */
+    0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C,  /* 00000960    "........" */
+    0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,0x0A,  /* 00000968    "........" */
+    0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000970    "........" */
+    0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,0x04,  /* 00000978    "........" */
+    0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,0x0A,  /* 00000980    "........" */
+    0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000988    "........" */
+    0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,0x0C,  /* 00000990    "........" */
+    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,  /* 00000998    "........" */
+    0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,0xFF,  /* 000009A0    "........" */
+    0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,0x12,  /* 000009A8    "...... ." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,  /* 000009B0    "........" */
+    0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,0xFF,  /* 000009B8    "..!....." */
+    0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,0x22,  /* 000009C0    "......."" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000009C8    "........" */
+    0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,0x04,  /* 000009D0    "....#..." */
+    0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,0x0A,  /* 000009D8    "........" */
+    0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05,  /* 000009E0    "$......." */
+    0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,0x04,  /* 000009E8    "....%..." */
+    0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x00,  /* 000009F0    "........" */
+    0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000009F8    ".&......" */
+    0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,0x12,  /* 00000A00    "......'." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,  /* 00000A08    "........" */
+    0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A10    "..(....." */
+    0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,0x12,  /* 00000A18    "......)." */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,  /* 00000A20    "........" */
+    0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C,  /* 00000A28    "...*...." */
+    0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,0x0A,  /* 00000A30    "........" */
+    0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000A38    "+......." */
+    0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,0x04,  /* 00000A40    "....,..." */
+    0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,0x0A,  /* 00000A48    "........" */
+    0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000A50    "-......." */
+    0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,0x0C,  /* 00000A58    "........" */
+    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,  /* 00000A60    "........" */
+    0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A68    "../....." */
+    0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,0x12,  /* 00000A70    "........" */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01,  /* 00000A78    "........" */
+    0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000A80    "........" */
+    0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,0x13,  /* 00000A88    "........" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000A90    "........" */
+    0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,0x04,  /* 00000A98    "........" */
+    0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,0x0A,  /* 00000AA0    "........" */
+    0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000AA8    "........" */
+    0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,0x04,  /* 00000AB0    "........" */
+    0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x00,  /* 00000AB8    "........" */
+    0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000AC0    "........" */
+    0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,0x12,  /* 00000AC8    "........" */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,  /* 00000AD0    "........" */
+    0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000AD8    "........" */
+    0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,0x12,  /* 00000AE0    "........" */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,  /* 00000AE8    "........" */
+    0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,0x0C,  /* 00000AF0    "........" */
+    0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,0x0A,  /* 00000AF8    "........" */
+    0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000B00    "........" */
+    0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,0x04,  /* 00000B08    "........" */
+    0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,0x0A,  /* 00000B10    "........" */
+    0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000B18    "........" */
+    0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,0x0C,  /* 00000B20    "........" */
+    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,  /* 00000B28    "........" */
+    0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000B30    ".. ....." */
+    0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,0x12,  /* 00000B38    "......!." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01,  /* 00000B40    "........" */
+    0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000B48    ".."....." */
+    0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,0x23,  /* 00000B50    ".......#" */
+    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000B58    "........" */
+    0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,0x04,  /* 00000B60    "....$..." */
+    0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,0x0A,  /* 00000B68    "........" */
+    0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000B70    "%......." */
+    0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,0x04,  /* 00000B78    "....&..." */
+    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x00,  /* 00000B80    "........" */
+    0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000B88    ".'......" */
+    0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,0x12,  /* 00000B90    "......(." */
+    0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,  /* 00000B98    "........" */
+    0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000BA0    "..)....." */
+    0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,0x12,  /* 00000BA8    "......*." */
+    0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,  /* 00000BB0    "........" */
+    0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,0x0C,  /* 00000BB8    "...+...." */
+    0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,0x0A,  /* 00000BC0    "........" */
+    0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000BC8    ",......." */
+    0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,0x04,  /* 00000BD0    "....-..." */
+    0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,0x0A,  /* 00000BD8    "........" */
+    0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000BE0    "........" */
+    0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,0x0C,  /* 00000BE8    "...../.." */
+    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,  /* 00000BF0    "........" */
+    0x00,0x0A,0x10,0x5B,0x82,0x46,0x37,0x49,  /* 00000BF8    "...[.F7I" */
+    0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,0x52,  /* 00000C00    "SA_._ADR" */
+    0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,0x50,  /* 00000C08    ".....[.P" */
+    0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,0x04,  /* 00000C10    "IRQ..`.." */
+    0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,0x5C,  /* 00000C18    "..\.[.)\" */
+    0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00000C20    "/._SB_PC" */
+    0x49,0x30,0x49,0x53,0x41,0x5F,0x50,0x49,  /* 00000C28    "I0ISA_PI" */
+    0x52,0x51,0x01,0x50,0x49,0x52,0x41,0x08,  /* 00000C30    "RQ.PIRA." */
+    0x50,0x49,0x52,0x42,0x08,0x50,0x49,0x52,  /* 00000C38    "PIRB.PIR" */
+    0x43,0x08,0x50,0x49,0x52,0x44,0x08,0x5B,  /* 00000C40    "C.PIRD.[" */
+    0x82,0x46,0x0B,0x53,0x59,0x53,0x52,0x08,  /* 00000C48    ".F.SYSR." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000C50    "_HID.A.." */
+    0x02,0x08,0x5F,0x55,0x49,0x44,0x01,0x08,  /* 00000C58    ".._UID.." */
+    0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,0x0A,  /* 00000C60    "CRS_.N.." */
+    0x8A,0x47,0x01,0x10,0x00,0x10,0x00,0x00,  /* 00000C68    ".G......" */
+    0x10,0x47,0x01,0x22,0x00,0x22,0x00,0x00,  /* 00000C70    ".G.".".." */
+    0x0C,0x47,0x01,0x30,0x00,0x30,0x00,0x00,  /* 00000C78    ".G.0.0.." */
+    0x10,0x47,0x01,0x44,0x00,0x44,0x00,0x00,  /* 00000C80    ".G.D.D.." */
+    0x1C,0x47,0x01,0x62,0x00,0x62,0x00,0x00,  /* 00000C88    ".G.b.b.." */
+    0x02,0x47,0x01,0x65,0x00,0x65,0x00,0x00,  /* 00000C90    ".G.e.e.." */
+    0x0B,0x47,0x01,0x72,0x00,0x72,0x00,0x00,  /* 00000C98    ".G.r.r.." */
+    0x0E,0x47,0x01,0x80,0x00,0x80,0x00,0x00,  /* 00000CA0    ".G......" */
+    0x01,0x47,0x01,0x84,0x00,0x84,0x00,0x00,  /* 00000CA8    ".G......" */
+    0x03,0x47,0x01,0x88,0x00,0x88,0x00,0x00,  /* 00000CB0    ".G......" */
+    0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,0x00,  /* 00000CB8    ".G......" */
+    0x03,0x47,0x01,0x90,0x00,0x90,0x00,0x00,  /* 00000CC0    ".G......" */
+    0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,0x00,  /* 00000CC8    ".G......" */
+    0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,0x00,  /* 00000CD0    ".G......" */
+    0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,0x00,  /* 00000CD8    ".G......" */
+    0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,0x00,  /* 00000CE0    ".G......" */
+    0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,0x00,  /* 00000CE8    ".G......" */
+    0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,0x52,  /* 00000CF0    ".y..._CR" */
+    0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,0x5B,  /* 00000CF8    "S..CRS_[" */
+    0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,0x5F,  /* 00000D00    ".+PIC_._" */
+    0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,0x5F,  /* 00000D08    "HID.A.._" */
+    0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47,  /* 00000D10    "CRS....G" */
+    0x01,0x20,0x00,0x20,0x00,0x01,0x02,0x47,  /* 00000D18    ". . ...G" */
+    0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,0x22,  /* 00000D20    "......."" */
+    0x04,0x00,0x79,0x00,0x5B,0x82,0x47,0x05,  /* 00000D28    "..y.[.G." */
+    0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,0x49,  /* 00000D30    "DMA0._HI" */
+    0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,0x5F,  /* 00000D38    "D.A...._" */
+    0x43,0x52,0x53,0x11,0x41,0x04,0x0A,0x3D,  /* 00000D40    "CRS.A..=" */
+    0x2A,0x10,0x04,0x47,0x01,0x00,0x00,0x00,  /* 00000D48    "*..G...." */
+    0x00,0x00,0x10,0x47,0x01,0x81,0x00,0x81,  /* 00000D50    "...G...." */
+    0x00,0x00,0x03,0x47,0x01,0x87,0x00,0x87,  /* 00000D58    "...G...." */
+    0x00,0x00,0x01,0x47,0x01,0x89,0x00,0x89,  /* 00000D60    "...G...." */
+    0x00,0x00,0x03,0x47,0x01,0x8F,0x00,0x8F,  /* 00000D68    "...G...." */
+    0x00,0x00,0x01,0x47,0x01,0xC0,0x00,0xC0,  /* 00000D70    "...G...." */
+    0x00,0x00,0x20,0x47,0x01,0x80,0x04,0x80,  /* 00000D78    ".. G...." */
+    0x04,0x00,0x10,0x79,0x00,0x5B,0x82,0x25,  /* 00000D80    "...y.[.%" */
+    0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,0x49,  /* 00000D88    "TMR_._HI" */
+    0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,0x5F,  /* 00000D90    "D.A...._" */
+    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000D98    "CRS....G" */
+    0x01,0x40,0x00,0x40,0x00,0x00,0x04,0x22,  /* 00000DA0    ".@.@..."" */
+    0x01,0x00,0x79,0x00,0x5B,0x82,0x25,0x52,  /* 00000DA8    "..y.[.%R" */
+    0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,  /* 00000DB0    "TC_._HID" */
+    0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,0x43,  /* 00000DB8    ".A...._C" */
+    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000DC0    "RS....G." */
+    0x70,0x00,0x70,0x00,0x00,0x02,0x22,0x00,  /* 00000DC8    "p.p..."." */
+    0x01,0x79,0x00,0x5B,0x82,0x22,0x53,0x50,  /* 00000DD0    ".y.[."SP" */
+    0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000DD8    "KR._HID." */
+    0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,0x52,  /* 00000DE0    "A...._CR" */
+    0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,0x61,  /* 00000DE8    "S....G.a" */
+    0x00,0x61,0x00,0x00,0x01,0x79,0x00,0x5B,  /* 00000DF0    ".a...y.[" */
+    0x82,0x31,0x50,0x53,0x32,0x4D,0x08,0x5F,  /* 00000DF8    ".1PS2M._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,  /* 00000E00    "HID.A..." */
+    0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,  /* 00000E08    "._CID.A." */
+    0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,0x41,  /* 00000E10    "...._STA" */
+    0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000E18    "....._CR" */
+    0x53,0x11,0x08,0x0A,0x05,0x22,0x00,0x10,  /* 00000E20    "S....".." */
+    0x79,0x00,0x5B,0x82,0x42,0x04,0x50,0x53,  /* 00000E28    "y.[.B.PS" */
+    0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000E30    "2K._HID." */
+    0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,0x49,  /* 00000E38    "A...._CI" */
+    0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,0x09,  /* 00000E40    "D.A....." */
+    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 00000E48    "_STA...." */
+    0x08,0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,  /* 00000E50    "._CRS..." */
+    0x15,0x47,0x01,0x60,0x00,0x60,0x00,0x00,  /* 00000E58    ".G.`.`.." */
+    0x01,0x47,0x01,0x64,0x00,0x64,0x00,0x00,  /* 00000E60    ".G.d.d.." */
+    0x01,0x22,0x02,0x00,0x79,0x00,0x5B,0x82,  /* 00000E68    "."..y.[." */
+    0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,0x48,  /* 00000E70    ":FDC0._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,0x14,  /* 00000E78    "ID.A...." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000E80    "._STA..." */
+    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1B,  /* 00000E88    ".._CRS.." */
+    0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,0x03,  /* 00000E90    "..G....." */
+    0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,0x03,  /* 00000E98    "..G....." */
+    0x01,0x01,0x22,0x40,0x00,0x2A,0x04,0x00,  /* 00000EA0    ".."@.*.." */
+    0x79,0x00,0x5B,0x82,0x46,0x04,0x55,0x41,  /* 00000EA8    "y.[.F.UA" */
+    0x52,0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000EB0    "R1._HID." */
+    0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,  /* 00000EB8    "A...._UI" */
+    0x44,0x01,0x14,0x19,0x5F,0x53,0x54,0x41,  /* 00000EC0    "D..._STA" */
+    0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,0x5E,  /* 00000EC8    "....^^^^" */
+    0x55,0x41,0x52,0x31,0x00,0xA4,0x00,0xA1,  /* 00000ED0    "UAR1...." */
+    0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000ED8    "....._CR" */
+    0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8,  /* 00000EE0    "S....G.." */
+    0x03,0xF8,0x03,0x08,0x08,0x22,0x10,0x00,  /* 00000EE8    ".....".." */
+    0x79,0x00,0x5B,0x82,0x47,0x04,0x55,0x41,  /* 00000EF0    "y.[.G.UA" */
+    0x52,0x32,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000EF8    "R2._HID." */
+    0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,  /* 00000F00    "A...._UI" */
+    0x44,0x0A,0x02,0x14,0x19,0x5F,0x53,0x54,  /* 00000F08    "D...._ST" */
+    0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,  /* 00000F10    "A....^^^" */
+    0x5E,0x55,0x41,0x52,0x32,0x00,0xA4,0x00,  /* 00000F18    "^UAR2..." */
+    0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000F20    "......_C" */
+    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000F28    "RS....G." */
+    0xF8,0x02,0xF8,0x02,0x08,0x08,0x22,0x08,  /* 00000F30    "......"." */
+    0x00,0x79,0x00,0x5B,0x82,0x36,0x4C,0x54,  /* 00000F38    ".y.[.6LT" */
+    0x50,0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000F40    "P1._HID." */
+    0x41,0xD0,0x04,0x00,0x08,0x5F,0x55,0x49,  /* 00000F48    "A...._UI" */
+    0x44,0x0A,0x02,0x14,0x09,0x5F,0x53,0x54,  /* 00000F50    "D...._ST" */
+    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000F58    "A....._C" */
+    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000F60    "RS....G." */
+    0x78,0x03,0x78,0x03,0x08,0x08,0x22,0x80,  /* 00000F68    "x.x..."." */
+    0x00,0x79,0x00,0x5B,0x82,0x4D,0x07,0x53,  /* 00000F70    ".y.[.M.S" */
+    0x31,0x46,0x30,0x08,0x5F,0x41,0x44,0x52,  /* 00000F78    "1F0._ADR" */
+    0x0C,0x00,0x00,0x06,0x00,0x08,0x5F,0x53,  /* 00000F80    "......_S" */
+    0x55,0x4E,0x01,0x14,0x13,0x5F,0x50,0x53,  /* 00000F88    "UN..._PS" */
+    0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E,0x5F,  /* 00000F90    "0.p..\._" */
+    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00000F98    "GPEDPT2." */
+    0x13,0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,  /* 00000FA0    "._PS3.p." */
+    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00000FA8    ".\._GPED" */
+    0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,  /* 00000FB0    "PT2.._EJ" */
+    0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E,0x5F,  /* 00000FB8    "0.p..\._" */
+    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x70,  /* 00000FC0    "GPEDPT2p" */
+    0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000FC8    ".\._GPEP" */
+    0x48,0x50,0x31,0x14,0x1E,0x5F,0x53,0x54,  /* 00000FD0    "HP1.._ST" */
+    0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E,0x5F,  /* 00000FD8    "A.p..\._" */
+    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0xA4,  /* 00000FE0    "GPEDPT2." */
+    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,  /* 00000FE8    "\._GPEPH" */
+    0x50,0x31,0x5B,0x82,0x4E,0x07,0x53,0x32,  /* 00000FF0    "P1[.N.S2" */
+    0x46,0x30,0x08,0x5F,0x41,0x44,0x52,0x0C,  /* 00000FF8    "F0._ADR." */
+    0x00,0x00,0x07,0x00,0x08,0x5F,0x53,0x55,  /* 00001000    "....._SU" */
+    0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50,0x53,  /* 00001008    "N...._PS" */
+    0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E,0x5F,  /* 00001010    "0.p..\._" */
+    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001018    "GPEDPT2." */
+    0x13,0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,  /* 00001020    "._PS3.p." */
+    0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001028    ".\._GPED" */
+    0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,  /* 00001030    "PT2.._EJ" */
+    0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E,0x5F,  /* 00001038    "0.p..\._" */
+    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x70,  /* 00001040    "GPEDPT2p" */
+    0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00001048    ".\._GPEP" */
+    0x48,0x50,0x32,0x14,0x1E,0x5F,0x53,0x54,  /* 00001050    "HP2.._ST" */
+    0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E,0x5F,  /* 00001058    "A.p..\._" */
+    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0xA4,  /* 00001060    "GPEDPT2." */
+    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,  /* 00001068    "\._GPEPH" */
+    0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47,0x50,  /* 00001070    "P2.N._GP" */
+    0x45,0x5B,0x80,0x50,0x48,0x50,0x5F,0x01,  /* 00001078    "E[.PHP_." */
+    0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81,0x15,  /* 00001080    ".....[.." */
+    0x50,0x48,0x50,0x5F,0x01,0x50,0x53,0x54,  /* 00001088    "PHP_.PST" */
+    0x41,0x08,0x50,0x48,0x50,0x31,0x08,0x50,  /* 00001090    "A.PHP1.P" */
+    0x48,0x50,0x32,0x08,0x5B,0x80,0x44,0x47,  /* 00001098    "HP2.[.DG" */
+    0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A,0x04,  /* 000010A0    "1_..D..." */
+    0x5B,0x81,0x10,0x44,0x47,0x31,0x5F,0x01,  /* 000010A8    "[..DG1_." */
+    0x44,0x50,0x54,0x31,0x08,0x44,0x50,0x54,  /* 000010B0    "DPT1.DPT" */
+    0x32,0x08,0x14,0x46,0x07,0x5F,0x4C,0x30,  /* 000010B8    "2..F._L0" */
+    0x33,0x00,0x08,0x53,0x4C,0x54,0x5F,0x00,  /* 000010C0    "3..SLT_." */
+    0x08,0x45,0x56,0x54,0x5F,0x00,0x70,0x50,  /* 000010C8    ".EVT_.pP" */
+    0x53,0x54,0x41,0x61,0x7A,0x61,0x0A,0x04,  /* 000010D0    "STAaza.." */
+    0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A,0x0F,  /* 000010D8    "SLT_{a.." */
+    0x45,0x56,0x54,0x5F,0x70,0x53,0x4C,0x54,  /* 000010E0    "EVT_pSLT" */
+    0x5F,0x44,0x50,0x54,0x31,0x70,0x45,0x56,  /* 000010E8    "_DPT1pEV" */
+    0x54,0x5F,0x44,0x50,0x54,0x32,0xA0,0x1B,  /* 000010F0    "T_DPT2.." */
+    0x93,0x53,0x4C,0x54,0x5F,0x01,0x86,0x5C,  /* 000010F8    ".SLT_..\" */
+    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00001100    "/._SB_PC" */
+    0x49,0x30,0x53,0x31,0x46,0x30,0x45,0x56,  /* 00001108    "I0S1F0EV" */
+    0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93,0x53,  /* 00001110    "T_.....S" */
+    0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C,0x2F,  /* 00001118    "LT_...\/" */
+    0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,  /* 00001120    "._SB_PCI" */
+    0x30,0x53,0x32,0x46,0x30,0x45,0x56,0x54,  /* 00001128    "0S2F0EVT" */
+    0x5F,
 };
 int DsdtLen=sizeof(AmlCode);
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target       Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/ioemu/Makefile.target       Tue Feb 26 10:12:04 2008 -0700
@@ -357,7 +357,7 @@ endif
 endif
 
 ifdef CONFIG_STUBDOM
-CONFIG_PASSTHROUGH=1
+#CONFIG_PASSTHROUGH=1
 else
   ifeq (,$(wildcard /usr/include/pci))
 $(warning *** pciutils-devl package not found - missing /usr/include/pci)
@@ -415,7 +415,7 @@ VL_OBJS+= usb.o usb-hub.o usb-linux.o us
 VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
 
 # PCI network cards
-VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o
+VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o e1000.o
 
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/e1000.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/e1000.c    Tue Feb 26 10:12:04 2008 -0700
@@ -0,0 +1,995 @@
+/*
+ * QEMU e1000 emulation
+ *
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
+ * Copyright (c) 2008 Qumranet
+ * Based on work done by:
+ * Copyright (c) 2007 Dan Aloni
+ * Copyright (c) 2004 Antony T Curtis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "vl.h"
+
+#include "e1000_hw.h"
+
+#define DEBUG
+
+#ifdef DEBUG
+enum {
+    DEBUG_GENERAL,     DEBUG_IO,       DEBUG_MMIO,     DEBUG_INTERRUPT,
+    DEBUG_RX,          DEBUG_TX,       DEBUG_MDIC,     DEBUG_EEPROM,
+    DEBUG_UNKNOWN,     DEBUG_TXSUM,    DEBUG_TXERR,    DEBUG_RXERR,
+    DEBUG_RXFILTER,    DEBUG_NOTYET,
+};
+#define DBGBIT(x)      (1<<DEBUG_##x)
+static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
+
+#define        DBGOUT(what, fmt, params...) do { \
+    if (debugflags & DBGBIT(what)) \
+        fprintf(stderr, "e1000: " fmt, ##params); \
+    } while (0)
+#else
+#define        DBGOUT(what, fmt, params...) do {} while (0)
+#endif
+
+#define IOPORT_SIZE       0x40
+#define PNPMMIO_SIZE      0x60000
+
+/*
+ * HW models:
+ *  E1000_DEV_ID_82540EM works with Windows and Linux
+ *  E1000_DEV_ID_82573L OK with windoze and Linux 2.6.22,
+ *     appears to perform better than 82540EM, but breaks with Linux 2.6.18
+ *  E1000_DEV_ID_82544GC_COPPER appears to work; not well tested
+ *  Others never tested
+ */
+enum { E1000_DEVID = E1000_DEV_ID_82540EM };
+
+/*
+ * May need to specify additional MAC-to-PHY entries --
+ * Intel's Windows driver refuses to initialize unless they match
+ */
+enum {
+    PHY_ID2_INIT = E1000_DEVID == E1000_DEV_ID_82573L ?                0xcc2 :
+                   E1000_DEVID == E1000_DEV_ID_82544GC_COPPER ?        0xc30 :
+                   /* default to E1000_DEV_ID_82540EM */       0xc20
+};
+
+typedef struct E1000State_st {
+    PCIDevice dev;
+    VLANClientState *vc;
+    NICInfo *nd;
+    uint32_t instance;
+    uint32_t mmio_base;
+    int mmio_index;
+
+    uint32_t mac_reg[0x8000];
+    uint16_t phy_reg[0x20];
+    uint16_t eeprom_data[64];
+
+    uint32_t rxbuf_size;
+    uint32_t rxbuf_min_shift;
+    int check_rxov;
+    struct e1000_tx {
+        unsigned char header[256];
+        unsigned char data[0x10000];
+        uint16_t size;
+        unsigned char sum_needed;
+        uint8_t ipcss;
+        uint8_t ipcso;
+        uint16_t ipcse;
+        uint8_t tucss;
+        uint8_t tucso;
+        uint16_t tucse;
+        uint8_t hdr_len;
+        uint16_t mss;
+        uint32_t paylen;
+        uint16_t tso_frames;
+        char tse;
+        char ip;
+        char tcp;
+    } tx;
+
+    struct {
+        uint32_t val_in;       // shifted in from guest driver
+        uint16_t bitnum_in;
+        uint16_t bitnum_out;
+        uint16_t reading;
+        uint32_t old_eecd;
+    } eecd_state;
+} E1000State;
+
+#define        defreg(x)       x = (E1000_##x>>2)
+enum {
+    defreg(CTRL),      defreg(EECD),   defreg(EERD),   defreg(GPRC),
+    defreg(GPTC),      defreg(ICR),    defreg(ICS),    defreg(IMC),
+    defreg(IMS),       defreg(LEDCTL), defreg(MANC),   defreg(MDIC),
+    defreg(MPC),       defreg(PBA),    defreg(RCTL),   defreg(RDBAH),
+    defreg(RDBAL),     defreg(RDH),    defreg(RDLEN),  defreg(RDT),
+    defreg(STATUS),    defreg(SWSM),   defreg(TCTL),   defreg(TDBAH),
+    defreg(TDBAL),     defreg(TDH),    defreg(TDLEN),  defreg(TDT),
+    defreg(TORH),      defreg(TORL),   defreg(TOTH),   defreg(TOTL),
+    defreg(TPR),       defreg(TPT),    defreg(TXDCTL), defreg(WUFC),
+    defreg(RA),                defreg(MTA),    defreg(CRCERRS),
+};
+
+enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W };
+static char phy_regcap[0x20] = {
+    [PHY_STATUS] = PHY_R,      [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
+    [PHY_ID1] = PHY_R,         [M88E1000_PHY_SPEC_CTRL] = PHY_RW,
+    [PHY_CTRL] = PHY_RW,       [PHY_1000T_CTRL] = PHY_RW,
+    [PHY_LP_ABILITY] = PHY_R,  [PHY_1000T_STATUS] = PHY_R,
+    [PHY_AUTONEG_ADV] = PHY_RW,        [M88E1000_RX_ERR_CNTR] = PHY_R,
+    [PHY_ID2] = PHY_R,
+};
+
+static void
+ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr,
+           uint32_t size, int type)
+{
+    DBGOUT(IO, "e1000_ioport_map addr=0x%04x size=0x%08x\n", addr, size);
+}
+
+static void
+set_interrupt_cause(E1000State *s, int index, uint32_t val)
+{
+    if (val)
+        val |= E1000_ICR_INT_ASSERTED;
+    s->mac_reg[ICR] = val;
+    pci_set_irq(&s->dev, 0, (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0);
+}
+
+static void
+set_ics(E1000State *s, int index, uint32_t val)
+{
+    DBGOUT(INTERRUPT, "set_ics %x, ICR %x, IMR %x\n", val, s->mac_reg[ICR],
+        s->mac_reg[IMS]);
+    set_interrupt_cause(s, 0, val | s->mac_reg[ICR]);
+}
+
+static int
+rxbufsize(uint32_t v)
+{
+    v &= E1000_RCTL_BSEX | E1000_RCTL_SZ_16384 | E1000_RCTL_SZ_8192 |
+         E1000_RCTL_SZ_4096 | E1000_RCTL_SZ_2048 | E1000_RCTL_SZ_1024 |
+         E1000_RCTL_SZ_512 | E1000_RCTL_SZ_256;
+    switch (v) {
+    case E1000_RCTL_BSEX | E1000_RCTL_SZ_16384:
+        return 16384;
+    case E1000_RCTL_BSEX | E1000_RCTL_SZ_8192:
+        return 8192;
+    case E1000_RCTL_BSEX | E1000_RCTL_SZ_4096:
+        return 4096;
+    case E1000_RCTL_SZ_1024:
+        return 1024;
+    case E1000_RCTL_SZ_512:
+        return 512;
+    case E1000_RCTL_SZ_256:
+        return 256;
+    }
+    return 2048;
+}
+
+static void
+set_rx_control(E1000State *s, int index, uint32_t val)
+{
+    s->mac_reg[RCTL] = val;
+    s->rxbuf_size = rxbufsize(val);
+    s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
+    DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
+           s->mac_reg[RCTL]);
+}
+
+static void
+set_mdic(E1000State *s, int index, uint32_t val)
+{
+    uint32_t data = val & E1000_MDIC_DATA_MASK;
+    uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
+
+    if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) // phy #
+        val = s->mac_reg[MDIC] | E1000_MDIC_ERROR;
+    else if (val & E1000_MDIC_OP_READ) {
+        DBGOUT(MDIC, "MDIC read reg 0x%x\n", addr);
+        if (!(phy_regcap[addr] & PHY_R)) {
+            DBGOUT(MDIC, "MDIC read reg %x unhandled\n", addr);
+            val |= E1000_MDIC_ERROR;
+        } else
+            val = (val ^ data) | s->phy_reg[addr];
+    } else if (val & E1000_MDIC_OP_WRITE) {
+        DBGOUT(MDIC, "MDIC write reg 0x%x, value 0x%x\n", addr, data);
+        if (!(phy_regcap[addr] & PHY_W)) {
+            DBGOUT(MDIC, "MDIC write reg %x unhandled\n", addr);
+            val |= E1000_MDIC_ERROR;
+        } else
+            s->phy_reg[addr] = data;
+    }
+    s->mac_reg[MDIC] = val | E1000_MDIC_READY;
+    set_ics(s, 0, E1000_ICR_MDAC);
+}
+
+static uint32_t
+get_eecd(E1000State *s, int index)
+{
+    uint32_t ret = E1000_EECD_PRES|E1000_EECD_GNT | s->eecd_state.old_eecd;
+
+    DBGOUT(EEPROM, "reading eeprom bit %d (reading %d)\n",
+           s->eecd_state.bitnum_out, s->eecd_state.reading);
+    if (!s->eecd_state.reading ||
+        ((s->eeprom_data[(s->eecd_state.bitnum_out >> 4) & 0x3f] >>
+          ((s->eecd_state.bitnum_out & 0xf) ^ 0xf))) & 1)
+        ret |= E1000_EECD_DO;
+    return ret;
+}
+
+static void
+set_eecd(E1000State *s, int index, uint32_t val)
+{
+    uint32_t oldval = s->eecd_state.old_eecd;
+
+    s->eecd_state.old_eecd = val & (E1000_EECD_SK | E1000_EECD_CS |
+            E1000_EECD_DI|E1000_EECD_FWE_MASK|E1000_EECD_REQ);
+    if (!(E1000_EECD_SK & (val ^ oldval)))     // no clock edge
+        return;
+    if (!(E1000_EECD_SK & val)) {              // falling edge
+        s->eecd_state.bitnum_out++;
+        return;
+    }
+    if (!(val & E1000_EECD_CS)) {              // rising, no CS (EEPROM reset)
+        memset(&s->eecd_state, 0, sizeof s->eecd_state);
+        return;
+    }
+    s->eecd_state.val_in <<= 1;
+    if (val & E1000_EECD_DI)
+        s->eecd_state.val_in |= 1;
+    if (++s->eecd_state.bitnum_in == 9 && !s->eecd_state.reading) {
+        s->eecd_state.bitnum_out = ((s->eecd_state.val_in & 0x3f)<<4)-1;
+        s->eecd_state.reading = (((s->eecd_state.val_in >> 6) & 7) ==
+            EEPROM_READ_OPCODE_MICROWIRE);
+    }
+    DBGOUT(EEPROM, "eeprom bitnum in %d out %d, reading %d\n",
+           s->eecd_state.bitnum_in, s->eecd_state.bitnum_out,
+           s->eecd_state.reading);
+}
+
+static uint32_t
+flash_eerd_read(E1000State *s, int x)
+{
+    unsigned int index, r = s->mac_reg[EERD] & ~E1000_EEPROM_RW_REG_START;
+
+    if ((index = r >> E1000_EEPROM_RW_ADDR_SHIFT) > EEPROM_CHECKSUM_REG)
+        return 0;
+    return (s->eeprom_data[index] << E1000_EEPROM_RW_REG_DATA) |
+           E1000_EEPROM_RW_REG_DONE | r;
+}
+
+static unsigned int
+do_cksum(uint8_t *dp, uint8_t *de)
+{
+    unsigned int bsum[2] = {0, 0}, i, sum;
+
+    for (i = 1; dp < de; bsum[i^=1] += *dp++)
+        ;
+    sum = (bsum[0] << 8) + bsum[1];
+    sum = (sum >> 16) + (sum & 0xffff);
+    return ~(sum + (sum >> 16));
+}
+
+static void
+putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
+{
+    if (cse && cse < n)
+        n = cse + 1;
+    if (sloc < n-1)
+        cpu_to_be16wu((uint16_t *)(data + sloc),
+                      do_cksum(data + css, data + n));
+}
+
+static void
+xmit_seg(E1000State *s)
+{
+    uint16_t len, *sp;
+    unsigned int frames = s->tx.tso_frames, css, sofar, n;
+    struct e1000_tx *tp = &s->tx;
+
+    if (tp->tse) {
+        css = tp->ipcss;
+        DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",
+               frames, tp->size, css);
+        if (tp->ip) {          // IPv4
+            cpu_to_be16wu((uint16_t *)(tp->data+css+2),
+                          tp->size - css);
+            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
+                          be16_to_cpup((uint16_t *)(tp->data+css+4))+frames);
+        } else                 // IPv6
+            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
+                          tp->size - css);
+        css = tp->tucss;
+        len = tp->size - css;
+        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);
+        if (tp->tcp) {
+            sofar = frames * tp->mss;
+            cpu_to_be32wu((uint32_t *)(tp->data+css+4),        // seq
+                be32_to_cpup((uint32_t *)(tp->data+css+4))+sofar);
+            if (tp->paylen - sofar > tp->mss)
+                tp->data[css + 13] &= ~9;              // PSH, FIN
+        } else // UDP
+            cpu_to_be16wu((uint16_t *)(tp->data+css+4), len);
+        if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {
+            // add pseudo-header length before checksum calculation
+            sp = (uint16_t *)(tp->data + tp->tucso);
+            cpu_to_be16wu(sp, be16_to_cpup(sp) + len);
+        }
+        tp->tso_frames++;
+    }
+
+    if (tp->sum_needed & E1000_TXD_POPTS_TXSM)
+        putsum(tp->data, tp->size, tp->tucso, tp->tucss, tp->tucse);
+    if (tp->sum_needed & E1000_TXD_POPTS_IXSM)
+        putsum(tp->data, tp->size, tp->ipcso, tp->ipcss, tp->ipcse);
+    qemu_send_packet(s->vc, tp->data, tp->size);
+    s->mac_reg[TPT]++;
+    s->mac_reg[GPTC]++;
+    n = s->mac_reg[TOTL];
+    if ((s->mac_reg[TOTL] += s->tx.size) < n)
+        s->mac_reg[TOTH]++;
+}
+
+static void
+process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
+{
+    uint32_t txd_lower = le32_to_cpu(dp->lower.data);
+    uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D);
+    unsigned int split_size = txd_lower & 0xffff, bytes, sz, op;
+    unsigned int msh = 0xfffff, hdr = 0;
+    uint64_t addr;
+    struct e1000_context_desc *xp = (struct e1000_context_desc *)dp;
+    struct e1000_tx *tp = &s->tx;
+
+    if (dtype == E1000_TXD_CMD_DEXT) { // context descriptor
+        op = le32_to_cpu(xp->cmd_and_length);
+        tp->ipcss = xp->lower_setup.ip_fields.ipcss;
+        tp->ipcso = xp->lower_setup.ip_fields.ipcso;
+        tp->ipcse = le16_to_cpu(xp->lower_setup.ip_fields.ipcse);
+        tp->tucss = xp->upper_setup.tcp_fields.tucss;
+        tp->tucso = xp->upper_setup.tcp_fields.tucso;
+        tp->tucse = le16_to_cpu(xp->upper_setup.tcp_fields.tucse);
+        tp->paylen = op & 0xfffff;
+        tp->hdr_len = xp->tcp_seg_setup.fields.hdr_len;
+        tp->mss = le16_to_cpu(xp->tcp_seg_setup.fields.mss);
+        tp->ip = (op & E1000_TXD_CMD_IP) ? 1 : 0;
+        tp->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
+        tp->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
+        tp->tso_frames = 0;
+        if (tp->tucso == 0) {  // this is probably wrong
+            DBGOUT(TXSUM, "TCP/UDP: cso 0!\n");
+            tp->tucso = tp->tucss + (tp->tcp ? 16 : 6);
+        }
+        return;
+    } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D))
+        tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8;
+
+    addr = le64_to_cpu(dp->buffer_addr);
+    if (tp->tse) {
+        hdr = tp->hdr_len;
+        msh = hdr + tp->mss;
+    }
+    do {
+        bytes = split_size;
+        if (tp->size + bytes > msh)
+            bytes = msh - tp->size;
+        cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
+        if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
+            memmove(tp->header, tp->data, hdr);
+        tp->size = sz;
+        addr += bytes;
+        if (sz == msh) {
+            xmit_seg(s);
+            memmove(tp->data, tp->header, hdr);
+            tp->size = hdr;
+        }
+    } while (split_size -= bytes);
+
+    if (!(txd_lower & E1000_TXD_CMD_EOP))
+        return;
+    if (tp->size > hdr)
+        xmit_seg(s);
+    tp->tso_frames = 0;
+    tp->sum_needed = 0;
+    tp->size = 0;
+}
+
+static uint32_t
+txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
+{
+    uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data);
+
+    if (!(txd_lower & (E1000_TXD_CMD_RS|E1000_TXD_CMD_RPS)))
+        return 0;
+    txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) &
+                ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU);
+    dp->upper.data = cpu_to_le32(txd_upper);
+    cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp),
+                              (void *)&dp->upper, sizeof(dp->upper));
+    return E1000_ICR_TXDW;
+}
+
+static void
+start_xmit(E1000State *s)
+{
+    target_phys_addr_t base;
+    struct e1000_tx_desc desc;
+    uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE;
+
+    if (!(s->mac_reg[TCTL] & E1000_TCTL_EN)) {
+        DBGOUT(TX, "tx disabled\n");
+        return;
+    }
+
+    while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
+        base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] +
+               sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
+        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
+
+        DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH],
+               (void *)desc.buffer_addr, desc.lower.data,
+               desc.upper.data);
+
+        process_tx_desc(s, &desc);
+        cause |= txdesc_writeback(base, &desc);
+
+        if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN])
+            s->mac_reg[TDH] = 0;
+        /*
+         * the following could happen only if guest sw assigns
+         * bogus values to TDT/TDLEN.
+         * there's nothing too intelligent we could do about this.
+         */
+        if (s->mac_reg[TDH] == tdh_start) {
+            DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
+                   tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
+            break;
+        }
+    }
+    set_ics(s, 0, cause);
+}
+
+static int
+receive_filter(E1000State *s, const uint8_t *buf, int size)
+{
+    static uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    static int mta_shift[] = {4, 3, 2, 0};
+    uint32_t f, rctl = s->mac_reg[RCTL], ra[2], *rp;
+
+    if (rctl & E1000_RCTL_UPE)                 // promiscuous
+        return 1;
+
+    if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE))       // promiscuous mcast
+        return 1;
+
+    if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast))
+        return 1;
+
+    for (rp = s->mac_reg + RA; rp < s->mac_reg + RA + 32; rp += 2) {
+        if (!(rp[1] & E1000_RAH_AV))
+            continue;
+        ra[0] = cpu_to_le32(rp[0]);
+        ra[1] = cpu_to_le32(rp[1]);
+        if (!memcmp(buf, (uint8_t *)ra, 6)) {
+            DBGOUT(RXFILTER,
+                   "unicast match[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                   (int)(rp - s->mac_reg - RA)/2,
+                   buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+            return 1;
+        }
+    }
+    DBGOUT(RXFILTER, "unicast mismatch: %02x:%02x:%02x:%02x:%02x:%02x\n",
+           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+
+    f = mta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
+    f = (((buf[5] << 8) | buf[4]) >> f) & 0xfff;
+    if (s->mac_reg[MTA + (f >> 5)] & (1 << (f & 0x1f)))
+        return 1;
+    DBGOUT(RXFILTER,
+           "dropping, inexact filter mismatch: %02x:%02x:%02x:%02x:%02x:%02x 
MO %d MTA[%d] %x\n",
+           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
+           (rctl >> E1000_RCTL_MO_SHIFT) & 3, f >> 5,
+           s->mac_reg[MTA + (f >> 5)]);
+
+    return 0;
+}
+
+static int
+e1000_can_receive(void *opaque)
+{
+    E1000State *s = opaque;
+
+    return (!(s->mac_reg[RCTL] & E1000_RCTL_EN) ||
+            s->mac_reg[RDH] != s->mac_reg[RDT]);
+}
+
+static void
+e1000_receive(void *opaque, const uint8_t *buf, int size)
+{
+    E1000State *s = opaque;
+    struct e1000_rx_desc desc;
+    target_phys_addr_t base;
+    unsigned int n, rdt;
+    uint32_t rdh_start;
+
+    if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
+        return;
+
+    if (size > s->rxbuf_size) {
+        DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size,
+               s->rxbuf_size);
+        return;
+    }
+
+    if (!receive_filter(s, buf, size))
+        return;
+
+    rdh_start = s->mac_reg[RDH];
+    size += 4; // for the header
+    do {
+        if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
+            set_ics(s, 0, E1000_ICS_RXO);
+            return;
+        }
+        base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
+               sizeof(desc) * s->mac_reg[RDH];
+        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
+        desc.status |= E1000_RXD_STAT_DD;
+        if (desc.buffer_addr) {
+            cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
+                                      (void *)buf, size);
+            desc.length = cpu_to_le16(size);
+            desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
+        } else // as per intel docs; skip descriptors with null buf addr
+            DBGOUT(RX, "Null RX descriptor!!\n");
+        cpu_physical_memory_write(base, (void *)&desc, sizeof(desc));
+
+        if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
+            s->mac_reg[RDH] = 0;
+        s->check_rxov = 1;
+        /* see comment in start_xmit; same here */
+        if (s->mac_reg[RDH] == rdh_start) {
+            DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
+                   rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
+            set_ics(s, 0, E1000_ICS_RXO);
+            return;
+        }
+    } while (desc.buffer_addr == 0);
+
+    s->mac_reg[GPRC]++;
+    s->mac_reg[TPR]++;
+    n = s->mac_reg[TORL];
+    if ((s->mac_reg[TORL] += size) < n)
+        s->mac_reg[TORH]++;
+
+    n = E1000_ICS_RXT0;
+    if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])
+        rdt += s->mac_reg[RDLEN] / sizeof(desc);
+    if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >=
+        s->mac_reg[RDLEN])
+        n |= E1000_ICS_RXDMT0;
+
+    set_ics(s, 0, n);
+}
+
+static uint32_t
+mac_readreg(E1000State *s, int index)
+{
+    return s->mac_reg[index];
+}
+
+static uint32_t
+mac_icr_read(E1000State *s, int index)
+{
+    uint32_t ret = s->mac_reg[ICR];
+
+    DBGOUT(INTERRUPT, "ICR read: %x\n", ret);
+    set_interrupt_cause(s, 0, 0);
+    return ret;
+}
+
+static uint32_t
+mac_read_clr4(E1000State *s, int index)
+{
+    uint32_t ret = s->mac_reg[index];
+
+    s->mac_reg[index] = 0;
+    return ret;
+}
+
+static uint32_t
+mac_read_clr8(E1000State *s, int index)
+{
+    uint32_t ret = s->mac_reg[index];
+
+    s->mac_reg[index] = 0;
+    s->mac_reg[index-1] = 0;
+    return ret;
+}
+
+static void
+mac_writereg(E1000State *s, int index, uint32_t val)
+{
+    s->mac_reg[index] = val;
+}
+
+static void
+set_rdt(E1000State *s, int index, uint32_t val)
+{
+    s->check_rxov = 0;
+    s->mac_reg[index] = val & 0xffff;
+}
+
+static void
+set_16bit(E1000State *s, int index, uint32_t val)
+{
+    s->mac_reg[index] = val & 0xffff;
+}
+
+static void
+set_dlen(E1000State *s, int index, uint32_t val)
+{
+    s->mac_reg[index] = val & 0xfff80;
+}
+
+static void
+set_tctl(E1000State *s, int index, uint32_t val)
+{
+    s->mac_reg[index] = val;
+    s->mac_reg[TDT] &= 0xffff;
+    start_xmit(s);
+}
+
+static void
+set_icr(E1000State *s, int index, uint32_t val)
+{
+    DBGOUT(INTERRUPT, "set_icr %x\n", val);
+    set_interrupt_cause(s, 0, s->mac_reg[ICR] & ~val);
+}
+
+static void
+set_imc(E1000State *s, int index, uint32_t val)
+{
+    s->mac_reg[IMS] &= ~val;
+    set_ics(s, 0, 0);
+}
+
+static void
+set_ims(E1000State *s, int index, uint32_t val)
+{
+    s->mac_reg[IMS] |= val;
+    set_ics(s, 0, 0);
+}
+
+#define getreg(x)      [x] = mac_readreg
+static uint32_t (*macreg_readops[])(E1000State *, int) = {
+    getreg(PBA),       getreg(RCTL),   getreg(TDH),    getreg(TXDCTL),
+    getreg(WUFC),      getreg(TDT),    getreg(CTRL),   getreg(LEDCTL),
+    getreg(MANC),      getreg(MDIC),   getreg(SWSM),   getreg(STATUS),
+    getreg(TORL),      getreg(TOTL),   getreg(IMS),    getreg(TCTL),
+    getreg(RDH),       getreg(RDT),
+
+    [TOTH] = mac_read_clr8,    [TORH] = mac_read_clr8, [GPRC] = mac_read_clr4,
+    [GPTC] = mac_read_clr4,    [TPR] = mac_read_clr4,  [TPT] = mac_read_clr4,
+    [ICR] = mac_icr_read,      [EECD] = get_eecd,      [EERD] = 
flash_eerd_read,
+    [CRCERRS ... MPC] = &mac_readreg,
+    [RA ... RA+31] = &mac_readreg,
+    [MTA ... MTA+127] = &mac_readreg,
+};
+enum { NREADOPS = sizeof(macreg_readops) / sizeof(*macreg_readops) };
+
+#define putreg(x)      [x] = mac_writereg
+static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
+    putreg(PBA),       putreg(EERD),   putreg(SWSM),   putreg(WUFC),
+    putreg(TDBAL),     putreg(TDBAH),  putreg(TXDCTL), putreg(RDBAH),
+    putreg(RDBAL),     putreg(LEDCTL),
+    [TDLEN] = set_dlen,        [RDLEN] = set_dlen,     [TCTL] = set_tctl,
+    [TDT] = set_tctl,  [MDIC] = set_mdic,      [ICS] = set_ics,
+    [TDH] = set_16bit, [RDH] = set_16bit,      [RDT] = set_rdt,
+    [IMC] = set_imc,   [IMS] = set_ims,        [ICR] = set_icr,
+    [EECD] = set_eecd, [RCTL] = set_rx_control,
+    [RA ... RA+31] = &mac_writereg,
+    [MTA ... MTA+127] = &mac_writereg,
+};
+enum { NWRITEOPS = sizeof(macreg_writeops) / sizeof(*macreg_writeops) };
+
+static void
+e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    E1000State *s = opaque;
+    unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
+
+    if (index < NWRITEOPS && macreg_writeops[index])
+        macreg_writeops[index](s, index, le32_to_cpu(val));
+    else if (index < NREADOPS && macreg_readops[index])
+        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
+    else
+        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
+               index<<2, val);
+}
+
+static void
+e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    // emulate hw without byte enables: no RMW
+    e1000_mmio_writel(opaque, addr & ~3,
+                      cpu_to_le32(le16_to_cpu(val & 0xffff) << (8*(addr & 
3))));
+}
+
+static void
+e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    // emulate hw without byte enables: no RMW
+    e1000_mmio_writel(opaque, addr & ~3,
+                      cpu_to_le32((val & 0xff)  << (8*(addr & 3))));
+}
+
+static uint32_t
+e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
+{
+    E1000State *s = opaque;
+    unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
+
+    if (index < NREADOPS && macreg_readops[index])
+        return cpu_to_le32(macreg_readops[index](s, index));
+    DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2);
+    return 0;
+}
+
+static uint32_t
+e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
+{
+    return (le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
+            (8 * (addr & 3))) & 0xff;
+}
+
+static uint32_t
+e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
+{
+    return cpu_to_le16((le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
+                        (8 * (addr & 3))) & 0xffff);
+}
+
+int mac_regtosave[] = {
+    CTRL,      EECD,   EERD,   GPRC,   GPTC,   ICR,    ICS,    IMC,    IMS,
+    LEDCTL,    MANC,   MDIC,   MPC,    PBA,    RCTL,   RDBAH,  RDBAL,  RDH,
+    RDLEN,     RDT,    STATUS, SWSM,   TCTL,   TDBAH,  TDBAL,  TDH,    TDLEN,
+    TDT,       TORH,   TORL,   TOTH,   TOTL,   TPR,    TPT,    TXDCTL, WUFC,
+};
+enum { MAC_NSAVE = sizeof mac_regtosave/sizeof *mac_regtosave };
+
+struct {
+    int size;
+    int array0;
+} mac_regarraystosave[] = { {32, RA}, {128, MTA} };
+enum { MAC_NARRAYS = sizeof mac_regarraystosave/sizeof *mac_regarraystosave };
+
+static void
+nic_save(QEMUFile *f, void *opaque)
+{
+    E1000State *s = (E1000State *)opaque;
+    int i, j;
+
+    pci_device_save(&s->dev, f);
+    qemu_put_be32s(f, &s->instance);
+    qemu_put_be32s(f, &s->mmio_base);
+    qemu_put_be32s(f, &s->rxbuf_size);
+    qemu_put_be32s(f, &s->rxbuf_min_shift);
+    qemu_put_be32s(f, &s->eecd_state.val_in);
+    qemu_put_be16s(f, &s->eecd_state.bitnum_in);
+    qemu_put_be16s(f, &s->eecd_state.bitnum_out);
+    qemu_put_be16s(f, &s->eecd_state.reading);
+    qemu_put_be32s(f, &s->eecd_state.old_eecd);
+    qemu_put_8s(f, &s->tx.ipcss);
+    qemu_put_8s(f, &s->tx.ipcso);
+    qemu_put_be16s(f, &s->tx.ipcse);
+    qemu_put_8s(f, &s->tx.tucss);
+    qemu_put_8s(f, &s->tx.tucso);
+    qemu_put_be16s(f, &s->tx.tucse);
+    qemu_put_be32s(f, &s->tx.paylen);
+    qemu_put_8s(f, &s->tx.hdr_len);
+    qemu_put_be16s(f, &s->tx.mss);
+    qemu_put_be16s(f, &s->tx.size);
+    qemu_put_be16s(f, &s->tx.tso_frames);
+    qemu_put_8s(f, &s->tx.sum_needed);
+    qemu_put_8s(f, &s->tx.ip);
+    qemu_put_8s(f, &s->tx.tcp);
+    qemu_put_buffer(f, s->tx.header, sizeof s->tx.header);
+    qemu_put_buffer(f, s->tx.data, sizeof s->tx.data);
+    for (i = 0; i < 64; i++)
+        qemu_put_be16s(f, s->eeprom_data + i);
+    for (i = 0; i < 0x20; i++)
+        qemu_put_be16s(f, s->phy_reg + i);
+    for (i = 0; i < MAC_NSAVE; i++)
+        qemu_put_be32s(f, s->mac_reg + mac_regtosave[i]);
+    for (i = 0; i < MAC_NARRAYS; i++)
+        for (j = 0; j < mac_regarraystosave[i].size; j++)
+            qemu_put_be32s(f,
+                           s->mac_reg + mac_regarraystosave[i].array0 + j);
+}
+
+static int
+nic_load(QEMUFile *f, void *opaque, int version_id)
+{
+    E1000State *s = (E1000State *)opaque;
+    int i, j, ret;
+
+    if ((ret = pci_device_load(&s->dev, f)) < 0)
+        return ret;
+    qemu_get_be32s(f, &s->instance);
+    qemu_get_be32s(f, &s->mmio_base);
+    qemu_get_be32s(f, &s->rxbuf_size);
+    qemu_get_be32s(f, &s->rxbuf_min_shift);
+    qemu_get_be32s(f, &s->eecd_state.val_in);
+    qemu_get_be16s(f, &s->eecd_state.bitnum_in);
+    qemu_get_be16s(f, &s->eecd_state.bitnum_out);
+    qemu_get_be16s(f, &s->eecd_state.reading);
+    qemu_get_be32s(f, &s->eecd_state.old_eecd);
+    qemu_get_8s(f, &s->tx.ipcss);
+    qemu_get_8s(f, &s->tx.ipcso);
+    qemu_get_be16s(f, &s->tx.ipcse);
+    qemu_get_8s(f, &s->tx.tucss);
+    qemu_get_8s(f, &s->tx.tucso);
+    qemu_get_be16s(f, &s->tx.tucse);
+    qemu_get_be32s(f, &s->tx.paylen);
+    qemu_get_8s(f, &s->tx.hdr_len);
+    qemu_get_be16s(f, &s->tx.mss);
+    qemu_get_be16s(f, &s->tx.size);
+    qemu_get_be16s(f, &s->tx.tso_frames);
+    qemu_get_8s(f, &s->tx.sum_needed);
+    qemu_get_8s(f, &s->tx.ip);
+    qemu_get_8s(f, &s->tx.tcp);
+    qemu_get_buffer(f, s->tx.header, sizeof s->tx.header);
+    qemu_get_buffer(f, s->tx.data, sizeof s->tx.data);
+    for (i = 0; i < 64; i++)
+        qemu_get_be16s(f, s->eeprom_data + i);
+    for (i = 0; i < 0x20; i++)
+        qemu_get_be16s(f, s->phy_reg + i);
+    for (i = 0; i < MAC_NSAVE; i++)
+        qemu_get_be32s(f, s->mac_reg + mac_regtosave[i]);
+    for (i = 0; i < MAC_NARRAYS; i++)
+        for (j = 0; j < mac_regarraystosave[i].size; j++)
+            qemu_get_be32s(f,
+                           s->mac_reg + mac_regarraystosave[i].array0 + j);
+    return 0;
+}
+
+static uint16_t e1000_eeprom_template[64] = {
+    0x0000, 0x0000, 0x0000, 0x0000,      0xffff, 0x0000,      0x0000, 0x0000,
+    0x3000, 0x1000, 0x6403, E1000_DEVID, 0x8086, E1000_DEVID, 0x8086, 0x3040,
+    0x0008, 0x2000, 0x7e14, 0x0048,      0x1000, 0x00d8,      0x0000, 0x2700,
+    0x6cc9, 0x3150, 0x0722, 0x040b,      0x0984, 0x0000,      0xc000, 0x0706,
+    0x1008, 0x0000, 0x0f04, 0x7fff,      0x4d01, 0xffff,      0xffff, 0xffff,
+    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,
+    0x0100, 0x4000, 0x121c, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,
+    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0x0000,
+};
+
+static uint16_t phy_reg_init[] = {
+    [PHY_CTRL] = 0x1140,                       [PHY_STATUS] = 0x796d, // link 
initially up
+    [PHY_ID1] = 0x141,                         [PHY_ID2] = PHY_ID2_INIT,
+    [PHY_1000T_CTRL] = 0x0e00,                 [M88E1000_PHY_SPEC_CTRL] = 
0x360,
+    [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60,     [PHY_AUTONEG_ADV] = 0xde1,
+    [PHY_LP_ABILITY] = 0x1e0,                  [PHY_1000T_STATUS] = 0x3c00,
+};
+
+static uint32_t mac_reg_init[] = {
+    [PBA] =     0x00100030,
+    [LEDCTL] =  0x602,
+    [CTRL] =    E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN0 |
+                E1000_CTRL_SPD_1000 | E1000_CTRL_SLU,
+    [STATUS] =  0x80000000 | E1000_STATUS_GIO_MASTER_ENABLE |
+                E1000_STATUS_ASDV | E1000_STATUS_MTXCKOK |
+                E1000_STATUS_SPEED_1000 | E1000_STATUS_FD |
+                E1000_STATUS_LU,
+    [MANC] =    E1000_MANC_EN_MNG2HOST | E1000_MANC_RCV_TCO_EN |
+                E1000_MANC_ARP_EN | E1000_MANC_0298_EN |
+                E1000_MANC_RMCP_EN,
+};
+
+/* PCI interface */
+
+static CPUWriteMemoryFunc *e1000_mmio_write[] = {
+    e1000_mmio_writeb, e1000_mmio_writew,      e1000_mmio_writel
+};
+
+static CPUReadMemoryFunc *e1000_mmio_read[] = {
+    e1000_mmio_readb,  e1000_mmio_readw,       e1000_mmio_readl
+};
+
+static void
+e1000_mmio_map(PCIDevice *pci_dev, int region_num,
+                uint32_t addr, uint32_t size, int type)
+{
+    E1000State *d = (E1000State *)pci_dev;
+
+    DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size);
+
+    d->mmio_base = addr;
+    cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
+}
+
+void
+pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
+{
+    E1000State *d;
+    uint8_t *pci_conf;
+    static int instance;
+    uint16_t checksum = 0;
+    char *info_str = "e1000";
+    int i;
+
+    d = (E1000State *)pci_register_device(bus, "e1000",
+                sizeof(E1000State), devfn, NULL, NULL);
+
+    pci_conf = d->dev.config;
+    memset(pci_conf, 0, 256);
+
+    *(uint16_t *)(pci_conf+0x00) = cpu_to_le16(0x8086);
+    *(uint16_t *)(pci_conf+0x02) = cpu_to_le16(E1000_DEVID);
+    *(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407);
+    *(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);
+    pci_conf[0x08] = 0x03;
+    pci_conf[0x0a] = 0x00; // ethernet network controller
+    pci_conf[0x0b] = 0x02;
+    pci_conf[0x0c] = 0x10;
+
+    pci_conf[0x3d] = 1; // interrupt pin 0
+
+    d->mmio_index = cpu_register_io_memory(0, e1000_mmio_read,
+            e1000_mmio_write, d);
+
+    pci_register_io_region((PCIDevice *)d, 0, PNPMMIO_SIZE,
+                           PCI_ADDRESS_SPACE_MEM, e1000_mmio_map);
+
+    pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE,
+                           PCI_ADDRESS_SPACE_IO, ioport_map);
+
+    d->instance = instance++;
+
+    d->nd = nd;
+    memmove(d->eeprom_data, e1000_eeprom_template,
+        sizeof e1000_eeprom_template);
+    for (i = 0; i < 3; i++)
+        d->eeprom_data[i] = (nd->macaddr[2*i+1]<<8) | nd->macaddr[2*i];
+    for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+        checksum += d->eeprom_data[i];
+    checksum = (uint16_t) EEPROM_SUM - checksum;
+    d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
+
+    memset(d->phy_reg, 0, sizeof d->phy_reg);
+    memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
+    memset(d->mac_reg, 0, sizeof d->mac_reg);
+    memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
+    d->rxbuf_min_shift = 1;
+    memset(&d->tx, 0, sizeof d->tx);
+
+    d->vc = qemu_new_vlan_client(nd->vlan, e1000_receive,
+                                 e1000_can_receive, d);
+
+    snprintf(d->vc->info_str, sizeof(d->vc->info_str),
+             "%s macaddr=%02x:%02x:%02x:%02x:%02x:%02x", info_str,
+             d->nd->macaddr[0], d->nd->macaddr[1], d->nd->macaddr[2],
+             d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);
+
+    register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);
+}
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/e1000_hw.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/e1000_hw.h Tue Feb 26 10:12:04 2008 -0700
@@ -0,0 +1,865 @@
+/*******************************************************************************
+
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2006 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  Linux NICS <linux.nics@xxxxxxxxx>
+  e1000-devel Mailing List <e1000-devel@xxxxxxxxxxxxxxxxxxxxx>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* e1000_hw.h
+ * Structures, enums, and macros for the MAC
+ */
+
+#ifndef _E1000_HW_H_
+#define _E1000_HW_H_
+
+
+/* PCI Device IDs */
+#define E1000_DEV_ID_82542               0x1000
+#define E1000_DEV_ID_82543GC_FIBER       0x1001
+#define E1000_DEV_ID_82543GC_COPPER      0x1004
+#define E1000_DEV_ID_82544EI_COPPER      0x1008
+#define E1000_DEV_ID_82544EI_FIBER       0x1009
+#define E1000_DEV_ID_82544GC_COPPER      0x100C
+#define E1000_DEV_ID_82544GC_LOM         0x100D
+#define E1000_DEV_ID_82540EM             0x100E
+#define E1000_DEV_ID_82540EM_LOM         0x1015
+#define E1000_DEV_ID_82540EP_LOM         0x1016
+#define E1000_DEV_ID_82540EP             0x1017
+#define E1000_DEV_ID_82540EP_LP          0x101E
+#define E1000_DEV_ID_82545EM_COPPER      0x100F
+#define E1000_DEV_ID_82545EM_FIBER       0x1011
+#define E1000_DEV_ID_82545GM_COPPER      0x1026
+#define E1000_DEV_ID_82545GM_FIBER       0x1027
+#define E1000_DEV_ID_82545GM_SERDES      0x1028
+#define E1000_DEV_ID_82546EB_COPPER      0x1010
+#define E1000_DEV_ID_82546EB_FIBER       0x1012
+#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
+#define E1000_DEV_ID_82541EI             0x1013
+#define E1000_DEV_ID_82541EI_MOBILE      0x1018
+#define E1000_DEV_ID_82541ER_LOM         0x1014
+#define E1000_DEV_ID_82541ER             0x1078
+#define E1000_DEV_ID_82547GI             0x1075
+#define E1000_DEV_ID_82541GI             0x1076
+#define E1000_DEV_ID_82541GI_MOBILE      0x1077
+#define E1000_DEV_ID_82541GI_LF          0x107C
+#define E1000_DEV_ID_82546GB_COPPER      0x1079
+#define E1000_DEV_ID_82546GB_FIBER       0x107A
+#define E1000_DEV_ID_82546GB_SERDES      0x107B
+#define E1000_DEV_ID_82546GB_PCIE        0x108A
+#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
+#define E1000_DEV_ID_82547EI             0x1019
+#define E1000_DEV_ID_82547EI_MOBILE      0x101A
+#define E1000_DEV_ID_82571EB_COPPER      0x105E
+#define E1000_DEV_ID_82571EB_FIBER       0x105F
+#define E1000_DEV_ID_82571EB_SERDES      0x1060
+#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
+#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
+#define E1000_DEV_ID_82571EB_QUAD_FIBER  0x10A5
+#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE  0x10BC
+#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
+#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
+#define E1000_DEV_ID_82572EI_COPPER      0x107D
+#define E1000_DEV_ID_82572EI_FIBER       0x107E
+#define E1000_DEV_ID_82572EI_SERDES      0x107F
+#define E1000_DEV_ID_82572EI             0x10B9
+#define E1000_DEV_ID_82573E              0x108B
+#define E1000_DEV_ID_82573E_IAMT         0x108C
+#define E1000_DEV_ID_82573L              0x109A
+#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
+#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT     0x1096
+#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT     0x1098
+#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT     0x10BA
+#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT     0x10BB
+
+#define E1000_DEV_ID_ICH8_IGP_M_AMT      0x1049
+#define E1000_DEV_ID_ICH8_IGP_AMT        0x104A
+#define E1000_DEV_ID_ICH8_IGP_C          0x104B
+#define E1000_DEV_ID_ICH8_IFE            0x104C
+#define E1000_DEV_ID_ICH8_IFE_GT         0x10C4
+#define E1000_DEV_ID_ICH8_IFE_G          0x10C5
+#define E1000_DEV_ID_ICH8_IGP_M          0x104D
+
+/* Register Set. (82543, 82544)
+ *
+ * Registers are defined to be 32 bits and  should be accessed as 32 bit 
values.
+ * These registers are physically located on the NIC, but are mapped into the
+ * host memory address space.
+ *
+ * RW - register is both readable and writable
+ * RO - register is read only
+ * WO - register is write only
+ * R/clr - register is read only and is cleared when read
+ * A - register array
+ */
+#define E1000_CTRL     0x00000  /* Device Control - RW */
+#define E1000_CTRL_DUP 0x00004  /* Device Control Duplicate (Shadow) - RW */
+#define E1000_STATUS   0x00008  /* Device Status - RO */
+#define E1000_EECD     0x00010  /* EEPROM/Flash Control - RW */
+#define E1000_EERD     0x00014  /* EEPROM Read - RW */
+#define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
+#define E1000_FLA      0x0001C  /* Flash Access - RW */
+#define E1000_MDIC     0x00020  /* MDI Control - RW */
+#define E1000_SCTL     0x00024  /* SerDes Control - RW */
+#define E1000_FEXTNVM  0x00028  /* Future Extended NVM register */
+#define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
+#define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
+#define E1000_FCT      0x00030  /* Flow Control Type - RW */
+#define E1000_VET      0x00038  /* VLAN Ether Type - RW */
+#define E1000_ICR      0x000C0  /* Interrupt Cause Read - R/clr */
+#define E1000_ITR      0x000C4  /* Interrupt Throttling Rate - RW */
+#define E1000_ICS      0x000C8  /* Interrupt Cause Set - WO */
+#define E1000_IMS      0x000D0  /* Interrupt Mask Set - RW */
+#define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
+#define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
+#define E1000_RCTL     0x00100  /* RX Control - RW */
+#define E1000_RDTR1    0x02820  /* RX Delay Timer (1) - RW */
+#define E1000_RDBAL1   0x02900  /* RX Descriptor Base Address Low (1) - RW */
+#define E1000_RDBAH1   0x02904  /* RX Descriptor Base Address High (1) - RW */
+#define E1000_RDLEN1   0x02908  /* RX Descriptor Length (1) - RW */
+#define E1000_RDH1     0x02910  /* RX Descriptor Head (1) - RW */
+#define E1000_RDT1     0x02918  /* RX Descriptor Tail (1) - RW */
+#define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
+#define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
+#define E1000_RXCW     0x00180  /* RX Configuration Word - RO */
+#define E1000_TCTL     0x00400  /* TX Control - RW */
+#define E1000_TCTL_EXT 0x00404  /* Extended TX Control - RW */
+#define E1000_TIPG     0x00410  /* TX Inter-packet gap -RW */
+#define E1000_TBT      0x00448  /* TX Burst Timer - RW */
+#define E1000_AIT      0x00458  /* Adaptive Interframe Spacing Throttle - RW */
+#define E1000_LEDCTL   0x00E00  /* LED Control - RW */
+#define E1000_EXTCNF_CTRL  0x00F00  /* Extended Configuration Control */
+#define E1000_EXTCNF_SIZE  0x00F08  /* Extended Configuration Size */
+#define E1000_PHY_CTRL     0x00F10  /* PHY Control Register in CSR */
+#define FEXTNVM_SW_CONFIG  0x0001
+#define E1000_PBA      0x01000  /* Packet Buffer Allocation - RW */
+#define E1000_PBS      0x01008  /* Packet Buffer Size */
+#define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
+#define E1000_FLASH_UPDATES 1000
+#define E1000_EEARBC   0x01024  /* EEPROM Auto Read Bus Control */
+#define E1000_FLASHT   0x01028  /* FLASH Timer Register */
+#define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */
+#define E1000_FLSWCTL  0x01030  /* FLASH control register */
+#define E1000_FLSWDATA 0x01034  /* FLASH data register */
+#define E1000_FLSWCNT  0x01038  /* FLASH Access Counter */
+#define E1000_FLOP     0x0103C  /* FLASH Opcode Register */
+#define E1000_ERT      0x02008  /* Early Rx Threshold - RW */
+#define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
+#define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
+#define E1000_PSRCTL   0x02170  /* Packet Split Receive Control - RW */
+#define E1000_RDBAL    0x02800  /* RX Descriptor Base Address Low - RW */
+#define E1000_RDBAH    0x02804  /* RX Descriptor Base Address High - RW */
+#define E1000_RDLEN    0x02808  /* RX Descriptor Length - RW */
+#define E1000_RDH      0x02810  /* RX Descriptor Head - RW */
+#define E1000_RDT      0x02818  /* RX Descriptor Tail - RW */
+#define E1000_RDTR     0x02820  /* RX Delay Timer - RW */
+#define E1000_RDBAL0   E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
+#define E1000_RDBAH0   E1000_RDBAH /* RX Desc Base Address High (0) - RW */
+#define E1000_RDLEN0   E1000_RDLEN /* RX Desc Length (0) - RW */
+#define E1000_RDH0     E1000_RDH   /* RX Desc Head (0) - RW */
+#define E1000_RDT0     E1000_RDT   /* RX Desc Tail (0) - RW */
+#define E1000_RDTR0    E1000_RDTR  /* RX Delay Timer (0) - RW */
+#define E1000_RXDCTL   0x02828  /* RX Descriptor Control queue 0 - RW */
+#define E1000_RXDCTL1  0x02928  /* RX Descriptor Control queue 1 - RW */
+#define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
+#define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
+#define E1000_RAID     0x02C08  /* Receive Ack Interrupt Delay - RW */
+#define E1000_TXDMAC   0x03000  /* TX DMA Control - RW */
+#define E1000_KABGTXD  0x03004  /* AFE Band Gap Transmit Ref Data */
+#define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
+#define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
+#define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
+#define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */
+#define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
+#define E1000_TDBAL    0x03800  /* TX Descriptor Base Address Low - RW */
+#define E1000_TDBAH    0x03804  /* TX Descriptor Base Address High - RW */
+#define E1000_TDLEN    0x03808  /* TX Descriptor Length - RW */
+#define E1000_TDH      0x03810  /* TX Descriptor Head - RW */
+#define E1000_TDT      0x03818  /* TX Descripotr Tail - RW */
+#define E1000_TIDV     0x03820  /* TX Interrupt Delay Value - RW */
+#define E1000_TXDCTL   0x03828  /* TX Descriptor Control - RW */
+#define E1000_TADV     0x0382C  /* TX Interrupt Absolute Delay Val - RW */
+#define E1000_TSPMT    0x03830  /* TCP Segmentation PAD & Min Threshold - RW */
+#define E1000_TARC0    0x03840  /* TX Arbitration Count (0) */
+#define E1000_TDBAL1   0x03900  /* TX Desc Base Address Low (1) - RW */
+#define E1000_TDBAH1   0x03904  /* TX Desc Base Address High (1) - RW */
+#define E1000_TDLEN1   0x03908  /* TX Desc Length (1) - RW */
+#define E1000_TDH1     0x03910  /* TX Desc Head (1) - RW */
+#define E1000_TDT1     0x03918  /* TX Desc Tail (1) - RW */
+#define E1000_TXDCTL1  0x03928  /* TX Descriptor Control (1) - RW */
+#define E1000_TARC1    0x03940  /* TX Arbitration Count (1) */
+#define E1000_CRCERRS  0x04000  /* CRC Error Count - R/clr */
+#define E1000_ALGNERRC 0x04004  /* Alignment Error Count - R/clr */
+#define E1000_SYMERRS  0x04008  /* Symbol Error Count - R/clr */
+#define E1000_RXERRC   0x0400C  /* Receive Error Count - R/clr */
+#define E1000_MPC      0x04010  /* Missed Packet Count - R/clr */
+#define E1000_SCC      0x04014  /* Single Collision Count - R/clr */
+#define E1000_ECOL     0x04018  /* Excessive Collision Count - R/clr */
+#define E1000_MCC      0x0401C  /* Multiple Collision Count - R/clr */
+#define E1000_LATECOL  0x04020  /* Late Collision Count - R/clr */
+#define E1000_COLC     0x04028  /* Collision Count - R/clr */
+#define E1000_DC       0x04030  /* Defer Count - R/clr */
+#define E1000_TNCRS    0x04034  /* TX-No CRS - R/clr */
+#define E1000_SEC      0x04038  /* Sequence Error Count - R/clr */
+#define E1000_CEXTERR  0x0403C  /* Carrier Extension Error Count - R/clr */
+#define E1000_RLEC     0x04040  /* Receive Length Error Count - R/clr */
+#define E1000_XONRXC   0x04048  /* XON RX Count - R/clr */
+#define E1000_XONTXC   0x0404C  /* XON TX Count - R/clr */
+#define E1000_XOFFRXC  0x04050  /* XOFF RX Count - R/clr */
+#define E1000_XOFFTXC  0x04054  /* XOFF TX Count - R/clr */
+#define E1000_FCRUC    0x04058  /* Flow Control RX Unsupported Count- R/clr */
+#define E1000_PRC64    0x0405C  /* Packets RX (64 bytes) - R/clr */
+#define E1000_PRC127   0x04060  /* Packets RX (65-127 bytes) - R/clr */
+#define E1000_PRC255   0x04064  /* Packets RX (128-255 bytes) - R/clr */
+#define E1000_PRC511   0x04068  /* Packets RX (255-511 bytes) - R/clr */
+#define E1000_PRC1023  0x0406C  /* Packets RX (512-1023 bytes) - R/clr */
+#define E1000_PRC1522  0x04070  /* Packets RX (1024-1522 bytes) - R/clr */
+#define E1000_GPRC     0x04074  /* Good Packets RX Count - R/clr */
+#define E1000_BPRC     0x04078  /* Broadcast Packets RX Count - R/clr */
+#define E1000_MPRC     0x0407C  /* Multicast Packets RX Count - R/clr */
+#define E1000_GPTC     0x04080  /* Good Packets TX Count - R/clr */
+#define E1000_GORCL    0x04088  /* Good Octets RX Count Low - R/clr */
+#define E1000_GORCH    0x0408C  /* Good Octets RX Count High - R/clr */
+#define E1000_GOTCL    0x04090  /* Good Octets TX Count Low - R/clr */
+#define E1000_GOTCH    0x04094  /* Good Octets TX Count High - R/clr */
+#define E1000_RNBC     0x040A0  /* RX No Buffers Count - R/clr */
+#define E1000_RUC      0x040A4  /* RX Undersize Count - R/clr */
+#define E1000_RFC      0x040A8  /* RX Fragment Count - R/clr */
+#define E1000_ROC      0x040AC  /* RX Oversize Count - R/clr */
+#define E1000_RJC      0x040B0  /* RX Jabber Count - R/clr */
+#define E1000_MGTPRC   0x040B4  /* Management Packets RX Count - R/clr */
+#define E1000_MGTPDC   0x040B8  /* Management Packets Dropped Count - R/clr */
+#define E1000_MGTPTC   0x040BC  /* Management Packets TX Count - R/clr */
+#define E1000_TORL     0x040C0  /* Total Octets RX Low - R/clr */
+#define E1000_TORH     0x040C4  /* Total Octets RX High - R/clr */
+#define E1000_TOTL     0x040C8  /* Total Octets TX Low - R/clr */
+#define E1000_TOTH     0x040CC  /* Total Octets TX High - R/clr */
+#define E1000_TPR      0x040D0  /* Total Packets RX - R/clr */
+#define E1000_TPT      0x040D4  /* Total Packets TX - R/clr */
+#define E1000_PTC64    0x040D8  /* Packets TX (64 bytes) - R/clr */
+#define E1000_PTC127   0x040DC  /* Packets TX (65-127 bytes) - R/clr */
+#define E1000_PTC255   0x040E0  /* Packets TX (128-255 bytes) - R/clr */
+#define E1000_PTC511   0x040E4  /* Packets TX (256-511 bytes) - R/clr */
+#define E1000_PTC1023  0x040E8  /* Packets TX (512-1023 bytes) - R/clr */
+#define E1000_PTC1522  0x040EC  /* Packets TX (1024-1522 Bytes) - R/clr */
+#define E1000_MPTC     0x040F0  /* Multicast Packets TX Count - R/clr */
+#define E1000_BPTC     0x040F4  /* Broadcast Packets TX Count - R/clr */
+#define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
+#define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
+#define E1000_IAC      0x04100  /* Interrupt Assertion Count */
+#define E1000_ICRXPTC  0x04104  /* Interrupt Cause Rx Packet Timer Expire 
Count */
+#define E1000_ICRXATC  0x04108  /* Interrupt Cause Rx Absolute Timer Expire 
Count */
+#define E1000_ICTXPTC  0x0410C  /* Interrupt Cause Tx Packet Timer Expire 
Count */
+#define E1000_ICTXATC  0x04110  /* Interrupt Cause Tx Absolute Timer Expire 
Count */
+#define E1000_ICTXQEC  0x04118  /* Interrupt Cause Tx Queue Empty Count */
+#define E1000_ICTXQMTC 0x0411C  /* Interrupt Cause Tx Queue Minimum Threshold 
Count */
+#define E1000_ICRXDMTC 0x04120  /* Interrupt Cause Rx Descriptor Minimum 
Threshold Count */
+#define E1000_ICRXOC   0x04124  /* Interrupt Cause Receiver Overrun Count */
+#define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
+#define E1000_RFCTL    0x05008  /* Receive Filter Control*/
+#define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
+#define E1000_RA       0x05400  /* Receive Address - RW Array */
+#define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
+#define E1000_WUC      0x05800  /* Wakeup Control - RW */
+#define E1000_WUFC     0x05808  /* Wakeup Filter Control - RW */
+#define E1000_WUS      0x05810  /* Wakeup Status - RO */
+#define E1000_MANC     0x05820  /* Management Control - RW */
+#define E1000_IPAV     0x05838  /* IP Address Valid - RW */
+#define E1000_IP4AT    0x05840  /* IPv4 Address Table - RW Array */
+#define E1000_IP6AT    0x05880  /* IPv6 Address Table - RW Array */
+#define E1000_WUPL     0x05900  /* Wakeup Packet Length - RW */
+#define E1000_WUPM     0x05A00  /* Wakeup Packet Memory - RO A */
+#define E1000_FFLT     0x05F00  /* Flexible Filter Length Table - RW Array */
+#define E1000_HOST_IF  0x08800  /* Host Interface */
+#define E1000_FFMT     0x09000  /* Flexible Filter Mask Table - RW Array */
+#define E1000_FFVT     0x09800  /* Flexible Filter Value Table - RW Array */
+
+#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
+#define E1000_MDPHYA     0x0003C  /* PHY address - RW */
+#define E1000_MANC2H     0x05860  /* Managment Control To Host - RW */
+#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
+
+#define E1000_GCR       0x05B00 /* PCI-Ex Control */
+#define E1000_GSCL_1    0x05B10 /* PCI-Ex Statistic Control #1 */
+#define E1000_GSCL_2    0x05B14 /* PCI-Ex Statistic Control #2 */
+#define E1000_GSCL_3    0x05B18 /* PCI-Ex Statistic Control #3 */
+#define E1000_GSCL_4    0x05B1C /* PCI-Ex Statistic Control #4 */
+#define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
+#define E1000_SWSM      0x05B50 /* SW Semaphore */
+#define E1000_FWSM      0x05B54 /* FW Semaphore */
+#define E1000_FFLT_DBG  0x05F04 /* Debug Register */
+#define E1000_HICR      0x08F00 /* Host Inteface Control */
+
+/* RSS registers */
+#define E1000_CPUVEC    0x02C10 /* CPU Vector Register - RW */
+#define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
+#define E1000_RETA      0x05C00 /* Redirection Table - RW Array */
+#define E1000_RSSRK     0x05C80 /* RSS Random Key - RW Array */
+#define E1000_RSSIM     0x05864 /* RSS Interrupt Mask */
+#define E1000_RSSIR     0x05868 /* RSS Interrupt Request */
+
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CTRL         0x00 /* Control Register */
+#define PHY_STATUS       0x01 /* Status Regiser */
+#define PHY_ID1          0x02 /* Phy Id Reg (word 1) */
+#define PHY_ID2          0x03 /* Phy Id Reg (word 2) */
+#define PHY_AUTONEG_ADV  0x04 /* Autoneg Advertisement */
+#define PHY_LP_ABILITY   0x05 /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP  0x06 /* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
+#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
+#define PHY_1000T_CTRL   0x09 /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS   0x0F /* Extended Status Reg */
+
+#define MAX_PHY_REG_ADDRESS        0x1F  /* 5 bit address bus (0-0x1F) */
+#define MAX_PHY_MULTI_PAGE_REG     0xF   /* Registers equal on all pages */
+
+/* M88E1000 Specific Registers */
+#define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
+#define M88E1000_PHY_SPEC_STATUS   0x11  /* PHY Specific Status Register */
+#define M88E1000_INT_ENABLE        0x12  /* Interrupt Enable Register */
+#define M88E1000_INT_STATUS        0x13  /* Interrupt Status Register */
+#define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */
+#define M88E1000_RX_ERR_CNTR       0x15  /* Receive Error Counter */
+
+#define M88E1000_PHY_EXT_CTRL      0x1A  /* PHY extend control register */
+#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
+#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */
+#define M88E1000_PHY_VCO_REG_BIT8  0x100 /* Bits 8 & 11 are adjusted for */
+#define M88E1000_PHY_VCO_REG_BIT11 0x800    /* improved BER performance */
+
+/* Interrupt Cause Read */
+#define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
+#define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
+#define E1000_ICR_LSC           0x00000004 /* Link Status Change */
+#define E1000_ICR_RXSEQ         0x00000008 /* rx sequence error */
+#define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
+#define E1000_ICR_RXO           0x00000040 /* rx overrun */
+#define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
+#define E1000_ICR_MDAC          0x00000200 /* MDIO access complete */
+#define E1000_ICR_RXCFG         0x00000400 /* RX /c/ ordered set */
+#define E1000_ICR_GPI_EN0       0x00000800 /* GP Int 0 */
+#define E1000_ICR_GPI_EN1       0x00001000 /* GP Int 1 */
+#define E1000_ICR_GPI_EN2       0x00002000 /* GP Int 2 */
+#define E1000_ICR_GPI_EN3       0x00004000 /* GP Int 3 */
+#define E1000_ICR_TXD_LOW       0x00008000
+#define E1000_ICR_SRPD          0x00010000
+#define E1000_ICR_ACK           0x00020000 /* Receive Ack frame */
+#define E1000_ICR_MNG           0x00040000 /* Manageability event */
+#define E1000_ICR_DOCK          0x00080000 /* Dock/Undock */
+#define E1000_ICR_INT_ASSERTED  0x80000000 /* If this bit asserted, the driver 
should claim the interrupt */
+#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO 
parity error */
+#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO 
parity error */
+#define E1000_ICR_HOST_ARB_PAR  0x00400000 /* host arb read buffer parity 
error */
+#define E1000_ICR_PB_PAR        0x00800000 /* packet buffer parity error */
+#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO 
parity error */
+#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO 
parity error */
+#define E1000_ICR_ALL_PARITY    0x03F00000 /* all parity error bits */
+#define E1000_ICR_DSW           0x00000020 /* FW changed the status of DISSW 
bit in the FWSM */
+#define E1000_ICR_PHYINT        0x00001000 /* LAN connected device generates 
an interrupt */
+#define E1000_ICR_EPRST         0x00100000 /* ME handware reset occurs */
+
+/* Interrupt Cause Set */
+#define E1000_ICS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back 
*/
+#define E1000_ICS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
+#define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
+#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_ICS_RXO       E1000_ICR_RXO       /* rx overrun */
+#define E1000_ICS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_ICS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
+#define E1000_ICS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
+#define E1000_ICS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
+#define E1000_ICS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
+#define E1000_ICS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
+#define E1000_ICS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
+#define E1000_ICS_TXD_LOW   E1000_ICR_TXD_LOW
+#define E1000_ICS_SRPD      E1000_ICR_SRPD
+#define E1000_ICS_ACK       E1000_ICR_ACK       /* Receive Ack frame */
+#define E1000_ICS_MNG       E1000_ICR_MNG       /* Manageability event */
+#define E1000_ICS_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
+#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx 
descriptor FIFO parity error */
+#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx 
descriptor FIFO parity error */
+#define E1000_ICS_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR  /* host arb read 
buffer parity error */
+#define E1000_ICS_PB_PAR        E1000_ICR_PB_PAR        /* packet buffer 
parity error */
+#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx 
descriptor FIFO parity error */
+#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx 
descriptor FIFO parity error */
+#define E1000_ICS_DSW       E1000_ICR_DSW
+#define E1000_ICS_PHYINT    E1000_ICR_PHYINT
+#define E1000_ICS_EPRST     E1000_ICR_EPRST
+
+/* Interrupt Mask Set */
+#define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back 
*/
+#define E1000_IMS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
+#define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
+#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_IMS_RXO       E1000_ICR_RXO       /* rx overrun */
+#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_IMS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
+#define E1000_IMS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
+#define E1000_IMS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
+#define E1000_IMS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
+#define E1000_IMS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
+#define E1000_IMS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
+#define E1000_IMS_TXD_LOW   E1000_ICR_TXD_LOW
+#define E1000_IMS_SRPD      E1000_ICR_SRPD
+#define E1000_IMS_ACK       E1000_ICR_ACK       /* Receive Ack frame */
+#define E1000_IMS_MNG       E1000_ICR_MNG       /* Manageability event */
+#define E1000_IMS_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
+#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx 
descriptor FIFO parity error */
+#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx 
descriptor FIFO parity error */
+#define E1000_IMS_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR  /* host arb read 
buffer parity error */
+#define E1000_IMS_PB_PAR        E1000_ICR_PB_PAR        /* packet buffer 
parity error */
+#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx 
descriptor FIFO parity error */
+#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx 
descriptor FIFO parity error */
+#define E1000_IMS_DSW       E1000_ICR_DSW
+#define E1000_IMS_PHYINT    E1000_ICR_PHYINT
+#define E1000_IMS_EPRST     E1000_ICR_EPRST
+
+/* Interrupt Mask Clear */
+#define E1000_IMC_TXDW      E1000_ICR_TXDW      /* Transmit desc written back 
*/
+#define E1000_IMC_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
+#define E1000_IMC_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_IMC_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
+#define E1000_IMC_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_IMC_RXO       E1000_ICR_RXO       /* rx overrun */
+#define E1000_IMC_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_IMC_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
+#define E1000_IMC_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
+#define E1000_IMC_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
+#define E1000_IMC_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
+#define E1000_IMC_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
+#define E1000_IMC_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
+#define E1000_IMC_TXD_LOW   E1000_ICR_TXD_LOW
+#define E1000_IMC_SRPD      E1000_ICR_SRPD
+#define E1000_IMC_ACK       E1000_ICR_ACK       /* Receive Ack frame */
+#define E1000_IMC_MNG       E1000_ICR_MNG       /* Manageability event */
+#define E1000_IMC_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
+#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx 
descriptor FIFO parity error */
+#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx 
descriptor FIFO parity error */
+#define E1000_IMC_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR  /* host arb read 
buffer parity error */
+#define E1000_IMC_PB_PAR        E1000_ICR_PB_PAR        /* packet buffer 
parity error */
+#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx 
descriptor FIFO parity error */
+#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx 
descriptor FIFO parity error */
+#define E1000_IMC_DSW       E1000_ICR_DSW
+#define E1000_IMC_PHYINT    E1000_ICR_PHYINT
+#define E1000_IMC_EPRST     E1000_ICR_EPRST
+
+/* Receive Control */
+#define E1000_RCTL_RST            0x00000001    /* Software reset */
+#define E1000_RCTL_EN             0x00000002    /* enable */
+#define E1000_RCTL_SBP            0x00000004    /* store bad packet */
+#define E1000_RCTL_UPE            0x00000008    /* unicast promiscuous enable 
*/
+#define E1000_RCTL_MPE            0x00000010    /* multicast promiscuous enab 
*/
+#define E1000_RCTL_LPE            0x00000020    /* long packet enable */
+#define E1000_RCTL_LBM_NO         0x00000000    /* no loopback mode */
+#define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
+#define E1000_RCTL_LBM_SLP        0x00000080    /* serial link loopback mode */
+#define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
+#define E1000_RCTL_DTYP_MASK      0x00000C00    /* Descriptor type mask */
+#define E1000_RCTL_DTYP_PS        0x00000400    /* Packet Split descriptor */
+#define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size 
*/
+#define E1000_RCTL_RDMTS_QUAT     0x00000100    /* rx desc min threshold size 
*/
+#define E1000_RCTL_RDMTS_EIGTH    0x00000200    /* rx desc min threshold size 
*/
+#define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
+#define E1000_RCTL_MO_0           0x00000000    /* multicast offset 11:0 */
+#define E1000_RCTL_MO_1           0x00001000    /* multicast offset 12:1 */
+#define E1000_RCTL_MO_2           0x00002000    /* multicast offset 13:2 */
+#define E1000_RCTL_MO_3           0x00003000    /* multicast offset 15:4 */
+#define E1000_RCTL_MDR            0x00004000    /* multicast desc ring 0 */
+#define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+#define E1000_RCTL_SZ_2048        0x00000000    /* rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024        0x00010000    /* rx buffer size 1024 */
+#define E1000_RCTL_SZ_512         0x00020000    /* rx buffer size 512 */
+#define E1000_RCTL_SZ_256         0x00030000    /* rx buffer size 256 */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+#define E1000_RCTL_SZ_16384       0x00010000    /* rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192        0x00020000    /* rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096        0x00030000    /* rx buffer size 4096 */
+#define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
+#define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
+#define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
+#define E1000_RCTL_DPF            0x00400000    /* discard pause frames */
+#define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
+#define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
+#define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */
+#define E1000_RCTL_FLXBUF_MASK    0x78000000    /* Flexible buffer size */
+#define E1000_RCTL_FLXBUF_SHIFT   27            /* Flexible buffer shift */
+
+
+#define E1000_EEPROM_SWDPIN0   0x0001   /* SWDPIN 0 EEPROM Value */
+#define E1000_EEPROM_LED_LOGIC 0x0020   /* Led Logic Word */
+#define E1000_EEPROM_RW_REG_DATA   16   /* Offset to data in EEPROM read/write 
registers */
+#define E1000_EEPROM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */
+#define E1000_EEPROM_RW_REG_START  1    /* First bit for telling part to start 
operation */
+#define E1000_EEPROM_RW_ADDR_SHIFT 2    /* Shift to the address bits */
+#define E1000_EEPROM_POLL_WRITE    1    /* Flag for polling for write complete 
*/
+#define E1000_EEPROM_POLL_READ     0    /* Flag for polling for read complete 
*/
+/* Register Bit Masks */
+/* Device Control */
+#define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
+#define E1000_CTRL_BEM      0x00000002  /* Endian Mode.0=little,1=big */
+#define E1000_CTRL_PRIOR    0x00000004  /* Priority on PCI. 0=rx,1=fair */
+#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests 
*/
+#define E1000_CTRL_LRST     0x00000008  /* Link reset. 0=normal,1=reset */
+#define E1000_CTRL_TME      0x00000010  /* Test mode. 0=normal,1=test */
+#define E1000_CTRL_SLE      0x00000020  /* Serial Link on 0=dis,1=en */
+#define E1000_CTRL_ASDE     0x00000020  /* Auto-speed detect enable */
+#define E1000_CTRL_SLU      0x00000040  /* Set link up (Force Link) */
+#define E1000_CTRL_ILOS     0x00000080  /* Invert Loss-Of Signal */
+#define E1000_CTRL_SPD_SEL  0x00000300  /* Speed Select Mask */
+#define E1000_CTRL_SPD_10   0x00000000  /* Force 10Mb */
+#define E1000_CTRL_SPD_100  0x00000100  /* Force 100Mb */
+#define E1000_CTRL_SPD_1000 0x00000200  /* Force 1Gb */
+#define E1000_CTRL_BEM32    0x00000400  /* Big Endian 32 mode */
+#define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
+#define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
+#define E1000_CTRL_D_UD_EN  0x00002000  /* Dock/Undock enable */
+#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock 
indication in SDP[0] */
+#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through 
PHYRST_N pin */
+#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external 
LINK_0 and LINK_1 pins */
+#define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
+#define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
+#define E1000_CTRL_SWDPIN2  0x00100000  /* SWDPIN 2 value */
+#define E1000_CTRL_SWDPIN3  0x00200000  /* SWDPIN 3 value */
+#define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */
+#define E1000_CTRL_SWDPIO1  0x00800000  /* SWDPIN 1 input or output */
+#define E1000_CTRL_SWDPIO2  0x01000000  /* SWDPIN 2 input or output */
+#define E1000_CTRL_SWDPIO3  0x02000000  /* SWDPIN 3 input or output */
+#define E1000_CTRL_RST      0x04000000  /* Global reset */
+#define E1000_CTRL_RFCE     0x08000000  /* Receive Flow Control enable */
+#define E1000_CTRL_TFCE     0x10000000  /* Transmit flow control enable */
+#define E1000_CTRL_RTE      0x20000000  /* Routing tag enable */
+#define E1000_CTRL_VME      0x40000000  /* IEEE VLAN mode enable */
+#define E1000_CTRL_PHY_RST  0x80000000  /* PHY Reset */
+#define E1000_CTRL_SW2FW_INT 0x02000000  /* Initiate an interrupt to 
manageability engine */
+
+/* Device Status */
+#define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
+#define E1000_STATUS_FUNC_MASK  0x0000000C      /* PCI Function Mask */
+#define E1000_STATUS_FUNC_SHIFT 2
+#define E1000_STATUS_FUNC_0     0x00000000      /* Function 0 */
+#define E1000_STATUS_FUNC_1     0x00000004      /* Function 1 */
+#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
+#define E1000_STATUS_TBIMODE    0x00000020      /* TBI mode */
+#define E1000_STATUS_SPEED_MASK 0x000000C0
+#define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
+#define E1000_STATUS_LAN_INIT_DONE 0x00000200   /* Lan Init Completion
+                                                   by EEPROM/Flash */
+#define E1000_STATUS_ASDV       0x00000300      /* Auto speed detect value */
+#define E1000_STATUS_DOCK_CI    0x00000800      /* Change in Dock/Undock 
state. Clear on write '0'. */
+#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master 
requests. */
+#define E1000_STATUS_MTXCKOK    0x00000400      /* MTX clock running OK */
+#define E1000_STATUS_PCI66      0x00000800      /* In 66Mhz slot */
+#define E1000_STATUS_BUS64      0x00001000      /* In 64 bit slot */
+#define E1000_STATUS_PCIX_MODE  0x00002000      /* PCI-X mode */
+#define E1000_STATUS_PCIX_SPEED 0x0000C000      /* PCI-X bus speed */
+#define E1000_STATUS_BMC_SKU_0  0x00100000 /* BMC USB redirect disabled */
+#define E1000_STATUS_BMC_SKU_1  0x00200000 /* BMC SRAM disabled */
+#define E1000_STATUS_BMC_SKU_2  0x00400000 /* BMC SDRAM disabled */
+#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */
+#define E1000_STATUS_BMC_LITE   0x01000000 /* BMC external code execution 
disabled */
+#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */
+#define E1000_STATUS_FUSE_8       0x04000000
+#define E1000_STATUS_FUSE_9       0x08000000
+#define E1000_STATUS_SERDES0_DIS  0x10000000 /* SERDES disabled on port 0 */
+#define E1000_STATUS_SERDES1_DIS  0x20000000 /* SERDES disabled on port 1 */
+
+/* EEPROM/Flash Control */
+#define E1000_EECD_SK        0x00000001 /* EEPROM Clock */
+#define E1000_EECD_CS        0x00000002 /* EEPROM Chip Select */
+#define E1000_EECD_DI        0x00000004 /* EEPROM Data In */
+#define E1000_EECD_DO        0x00000008 /* EEPROM Data Out */
+#define E1000_EECD_FWE_MASK  0x00000030
+#define E1000_EECD_FWE_DIS   0x00000010 /* Disable FLASH writes */
+#define E1000_EECD_FWE_EN    0x00000020 /* Enable FLASH writes */
+#define E1000_EECD_FWE_SHIFT 4
+#define E1000_EECD_REQ       0x00000040 /* EEPROM Access Request */
+#define E1000_EECD_GNT       0x00000080 /* EEPROM Access Grant */
+#define E1000_EECD_PRES      0x00000100 /* EEPROM Present */
+#define E1000_EECD_SIZE      0x00000200 /* EEPROM Size (0=64 word 1=256 word) 
*/
+#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
+                                         * (0-small, 1-large) */
+#define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
+#ifndef E1000_EEPROM_GRANT_ATTEMPTS
+#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
+#endif
+#define E1000_EECD_AUTO_RD          0x00000200  /* EEPROM Auto Read done */
+#define E1000_EECD_SIZE_EX_MASK     0x00007800  /* EEprom Size */
+#define E1000_EECD_SIZE_EX_SHIFT    11
+#define E1000_EECD_NVADDS    0x00018000 /* NVM Address Size */
+#define E1000_EECD_SELSHAD   0x00020000 /* Select Shadow RAM */
+#define E1000_EECD_INITSRAM  0x00040000 /* Initialize Shadow RAM */
+#define E1000_EECD_FLUPD     0x00080000 /* Update FLASH */
+#define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
+#define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
+#define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
+#define E1000_EECD_SECVAL_SHIFT      22
+#define E1000_STM_OPCODE     0xDB00
+#define E1000_HICR_FW_RESET  0xC0
+
+#define E1000_SHADOW_RAM_WORDS     2048
+#define E1000_ICH_NVM_SIG_WORD     0x13
+#define E1000_ICH_NVM_SIG_MASK     0xC0
+
+/* MDI Control */
+#define E1000_MDIC_DATA_MASK 0x0000FFFF
+#define E1000_MDIC_REG_MASK  0x001F0000
+#define E1000_MDIC_REG_SHIFT 16
+#define E1000_MDIC_PHY_MASK  0x03E00000
+#define E1000_MDIC_PHY_SHIFT 21
+#define E1000_MDIC_OP_WRITE  0x04000000
+#define E1000_MDIC_OP_READ   0x08000000
+#define E1000_MDIC_READY     0x10000000
+#define E1000_MDIC_INT_EN    0x20000000
+#define E1000_MDIC_ERROR     0x40000000
+
+/* EEPROM Commands - Microwire */
+#define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
+#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7  /* EEPROM erase opcode */
+#define EEPROM_EWEN_OPCODE_MICROWIRE  0x13 /* EEPROM erase/write enable */
+#define EEPROM_EWDS_OPCODE_MICROWIRE  0x10 /* EEPROM erast/write disable */
+
+/* EEPROM Word Offsets */
+#define EEPROM_COMPAT                 0x0003
+#define EEPROM_ID_LED_SETTINGS        0x0004
+#define EEPROM_VERSION                0x0005
+#define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude 
adjustment. */
+#define EEPROM_PHY_CLASS_WORD         0x0007
+#define EEPROM_INIT_CONTROL1_REG      0x000A
+#define EEPROM_INIT_CONTROL2_REG      0x000F
+#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
+#define EEPROM_INIT_CONTROL3_PORT_B   0x0014
+#define EEPROM_INIT_3GIO_3            0x001A
+#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
+#define EEPROM_INIT_CONTROL3_PORT_A   0x0024
+#define EEPROM_CFG                    0x0012
+#define EEPROM_FLASH_VERSION          0x0032
+#define EEPROM_CHECKSUM_REG           0x003F
+
+#define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
+#define E1000_EEPROM_CFG_DONE_PORT_1  0x00080000   /* ...for second port */
+
+/* Transmit Descriptor */
+struct e1000_tx_desc {
+    uint64_t buffer_addr;       /* Address of the descriptor's data buffer */
+    union {
+        uint32_t data;
+        struct {
+            uint16_t length;    /* Data buffer length */
+            uint8_t cso;        /* Checksum offset */
+            uint8_t cmd;        /* Descriptor control */
+        } flags;
+    } lower;
+    union {
+        uint32_t data;
+        struct {
+            uint8_t status;     /* Descriptor status */
+            uint8_t css;        /* Checksum start */
+            uint16_t special;
+        } fields;
+    } upper;
+};
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_DTYP_D     0x00100000 /* Data Descriptor */
+#define E1000_TXD_DTYP_C     0x00000000 /* Context Descriptor */
+#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_EOP    0x01000000 /* End of Packet */
+#define E1000_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_TXD_CMD_IC     0x04000000 /* Insert Checksum */
+#define E1000_TXD_CMD_RS     0x08000000 /* Report Status */
+#define E1000_TXD_CMD_RPS    0x10000000 /* Report Packet Sent */
+#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
+#define E1000_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
+#define E1000_TXD_CMD_IDE    0x80000000 /* Enable Tidv register */
+#define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */
+#define E1000_TXD_STAT_EC    0x00000002 /* Excess Collisions */
+#define E1000_TXD_STAT_LC    0x00000004 /* Late Collisions */
+#define E1000_TXD_STAT_TU    0x00000008 /* Transmit underrun */
+#define E1000_TXD_CMD_TCP    0x01000000 /* TCP packet */
+#define E1000_TXD_CMD_IP     0x02000000 /* IP packet */
+#define E1000_TXD_CMD_TSE    0x04000000 /* TCP Seg enable */
+#define E1000_TXD_STAT_TC    0x00000004 /* Tx Underrun */
+
+/* Transmit Control */
+#define E1000_TCTL_RST    0x00000001    /* software reset */
+#define E1000_TCTL_EN     0x00000002    /* enable tx */
+#define E1000_TCTL_BCE    0x00000004    /* busy check enable */
+#define E1000_TCTL_PSP    0x00000008    /* pad short packets */
+#define E1000_TCTL_CT     0x00000ff0    /* collision threshold */
+#define E1000_TCTL_COLD   0x003ff000    /* collision distance */
+#define E1000_TCTL_SWXOFF 0x00400000    /* SW Xoff transmission */
+#define E1000_TCTL_PBE    0x00800000    /* Packet Burst Enable */
+#define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
+#define E1000_TCTL_NRTU   0x02000000    /* No Re-transmit on underrun */
+#define E1000_TCTL_MULR   0x10000000    /* Multiple request support */
+
+/* Receive Descriptor */
+struct e1000_rx_desc {
+    uint64_t buffer_addr; /* Address of the descriptor's data buffer */
+    uint16_t length;     /* Length of data DMAed into data buffer */
+    uint16_t csum;       /* Packet checksum */
+    uint8_t status;      /* Descriptor status */
+    uint8_t errors;      /* Descriptor Errors */
+    uint16_t special;
+};
+
+/* Receive Decriptor bit definitions */
+#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
+#define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
+#define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
+#define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum caculated */
+#define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
+#define E1000_RXD_STAT_PIF      0x80    /* passed in-exact filter */
+#define E1000_RXD_STAT_IPIDV    0x200   /* IP identification valid */
+#define E1000_RXD_STAT_UDPV     0x400   /* Valid UDP checksum */
+#define E1000_RXD_STAT_ACK      0x8000  /* ACK Packet indication */
+#define E1000_RXD_ERR_CE        0x01    /* CRC Error */
+#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
+#define E1000_RXD_ERR_SEQ       0x04    /* Sequence Error */
+#define E1000_RXD_ERR_CXE       0x10    /* Carrier Extension Error */
+#define E1000_RXD_ERR_TCPE      0x20    /* TCP/UDP Checksum Error */
+#define E1000_RXD_ERR_IPE       0x40    /* IP Checksum Error */
+#define E1000_RXD_ERR_RXE       0x80    /* Rx Data Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
+#define E1000_RXD_SPC_PRI_MASK  0xE000  /* Priority is in upper 3 bits */
+#define E1000_RXD_SPC_PRI_SHIFT 13
+#define E1000_RXD_SPC_CFI_MASK  0x1000  /* CFI is bit 12 */
+#define E1000_RXD_SPC_CFI_SHIFT 12
+
+#define E1000_RXDEXT_STATERR_CE    0x01000000
+#define E1000_RXDEXT_STATERR_SE    0x02000000
+#define E1000_RXDEXT_STATERR_SEQ   0x04000000
+#define E1000_RXDEXT_STATERR_CXE   0x10000000
+#define E1000_RXDEXT_STATERR_TCPE  0x20000000
+#define E1000_RXDEXT_STATERR_IPE   0x40000000
+#define E1000_RXDEXT_STATERR_RXE   0x80000000
+
+#define E1000_RXDPS_HDRSTAT_HDRSP        0x00008000
+#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK  0x000003FF
+
+/* Receive Address */
+#define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
+
+/* Offload Context Descriptor */
+struct e1000_context_desc {
+    union {
+        uint32_t ip_config;
+        struct {
+            uint8_t ipcss;      /* IP checksum start */
+            uint8_t ipcso;      /* IP checksum offset */
+            uint16_t ipcse;     /* IP checksum end */
+        } ip_fields;
+    } lower_setup;
+    union {
+        uint32_t tcp_config;
+        struct {
+            uint8_t tucss;      /* TCP checksum start */
+            uint8_t tucso;      /* TCP checksum offset */
+            uint16_t tucse;     /* TCP checksum end */
+        } tcp_fields;
+    } upper_setup;
+    uint32_t cmd_and_length;    /* */
+    union {
+        uint32_t data;
+        struct {
+            uint8_t status;     /* Descriptor status */
+            uint8_t hdr_len;    /* Header length */
+            uint16_t mss;       /* Maximum segment size */
+        } fields;
+    } tcp_seg_setup;
+};
+
+/* Offload data descriptor */
+struct e1000_data_desc {
+    uint64_t buffer_addr;       /* Address of the descriptor's buffer address 
*/
+    union {
+        uint32_t data;
+        struct {
+            uint16_t length;    /* Data buffer length */
+            uint8_t typ_len_ext;        /* */
+            uint8_t cmd;        /* */
+        } flags;
+    } lower;
+    union {
+        uint32_t data;
+        struct {
+            uint8_t status;     /* Descriptor status */
+            uint8_t popts;      /* Packet Options */
+            uint16_t special;   /* */
+        } fields;
+    } upper;
+};
+
+/* Management Control */
+#define E1000_MANC_SMBUS_EN      0x00000001 /* SMBus Enabled - RO */
+#define E1000_MANC_ASF_EN        0x00000002 /* ASF Enabled - RO */
+#define E1000_MANC_R_ON_FORCE    0x00000004 /* Reset on Force TCO - RO */
+#define E1000_MANC_RMCP_EN       0x00000100 /* Enable RCMP 026Fh Filtering */
+#define E1000_MANC_0298_EN       0x00000200 /* Enable RCMP 0298h Filtering */
+#define E1000_MANC_IPV4_EN       0x00000400 /* Enable IPv4 */
+#define E1000_MANC_IPV6_EN       0x00000800 /* Enable IPv6 */
+#define E1000_MANC_SNAP_EN       0x00001000 /* Accept LLC/SNAP */
+#define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
+#define E1000_MANC_NEIGHBOR_EN   0x00004000 /* Enable Neighbor Discovery
+                                             * Filtering */
+#define E1000_MANC_ARP_RES_EN    0x00008000 /* Enable ARP response Filtering */
+#define E1000_MANC_TCO_RESET     0x00010000 /* TCO Reset Occurred */
+#define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
+#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
+#define E1000_MANC_RCV_ALL       0x00080000 /* Receive All Enabled */
+#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
+#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000 /* Enable MAC address
+                                                    * filtering */
+#define E1000_MANC_EN_MNG2HOST   0x00200000 /* Enable MNG packets to host
+                                             * memory */
+#define E1000_MANC_EN_IP_ADDR_FILTER    0x00400000 /* Enable IP address
+                                                    * filtering */
+#define E1000_MANC_EN_XSUM_FILTER   0x00800000 /* Enable checksum filtering */
+#define E1000_MANC_BR_EN         0x01000000 /* Enable broadcast filtering */
+#define E1000_MANC_SMB_REQ       0x01000000 /* SMBus Request */
+#define E1000_MANC_SMB_GNT       0x02000000 /* SMBus Grant */
+#define E1000_MANC_SMB_CLK_IN    0x04000000 /* SMBus Clock In */
+#define E1000_MANC_SMB_DATA_IN   0x08000000 /* SMBus Data In */
+#define E1000_MANC_SMB_DATA_OUT  0x10000000 /* SMBus Data Out */
+#define E1000_MANC_SMB_CLK_OUT   0x20000000 /* SMBus Clock Out */
+
+#define E1000_MANC_SMB_DATA_OUT_SHIFT  28 /* SMBus Data Out Shift */
+#define E1000_MANC_SMB_CLK_OUT_SHIFT   29 /* SMBus Clock Out Shift */
+
+/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
+#define EEPROM_SUM 0xBABA
+
+#endif /* _E1000_HW_H_ */
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/pci.c
--- a/tools/ioemu/hw/pci.c      Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/ioemu/hw/pci.c      Tue Feb 26 10:12:04 2008 -0700
@@ -574,6 +574,8 @@ void pci_nic_init(PCIBus *bus, NICInfo *
         pci_pcnet_init(bus, nd, devfn);
     } else if (strcmp(nd->model, "e100") == 0) {
         pci_e100_init(bus, nd);
+    } else if (strcmp(nd->model, "e1000") == 0) {
+        pci_e1000_init(bus, nd, devfn);
     } else {
         fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
         exit (1);
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/xen_console.c
--- a/tools/ioemu/hw/xen_console.c      Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/ioemu/hw/xen_console.c      Tue Feb 26 10:12:04 2008 -0700
@@ -381,7 +381,7 @@ static void xencons_startup(void *opaque
        qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, NULL, NULL, NULL);
 
        fprintf(stderr, "Console: connected to guest frontend\n");
-       if (qemu_set_fd_handler2(dom->xce_handle, NULL, xencons_ring_read, 
NULL, dom) < 0)
+       if (qemu_set_fd_handler2(xc_evtchn_fd(dom->xce_handle), NULL, 
xencons_ring_read, NULL, dom) < 0)
                return;
 
        qemu_chr_add_handlers(dom->chr, xencons_can_receive, xencons_receive,
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c    Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/ioemu/hw/xenfb.c    Tue Feb 26 10:12:04 2008 -0700
@@ -1160,7 +1160,7 @@ static int xenfb_register_console(struct
                             xenfb);
        dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
 
-       if (qemu_set_fd_handler2(xenfb->evt_xch, NULL, xenfb_dispatch_channel, 
NULL, xenfb) < 0)
+       if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, 
xenfb_dispatch_channel, NULL, xenfb) < 0)
                return -1;
        if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, 
xenfb_dispatch_store, NULL, xenfb) < 0)
                return -1;
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/osdep.c
--- a/tools/ioemu/osdep.c       Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/ioemu/osdep.c       Tue Feb 26 10:12:04 2008 -0700
@@ -178,7 +178,7 @@ void kqemu_vfree(void *ptr)
 
 void *qemu_memalign(size_t alignment, size_t size)
 {
-#if defined(_POSIX_C_SOURCE)
+#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
     int ret;
     void *ptr;
     ret = posix_memalign(&ptr, alignment, size);
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/ioemu/vl.h  Tue Feb 26 10:12:04 2008 -0700
@@ -1055,6 +1055,11 @@ void pcnet_h_reset(void *opaque);
 void pcnet_h_reset(void *opaque);
 void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque);
 
+/* e100.c */
+void pci_e100_init(PCIBus *bus, NICInfo *nd);
+
+/* e1000.c */
+void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
 
 /* pckbd.c */
 
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/ioemu/vnc.c Tue Feb 26 10:12:04 2008 -0700
@@ -137,6 +137,23 @@ enum {
 
 #endif /* CONFIG_VNC_TLS */
 
+#define QUEUE_ALLOC_UNIT 10
+
+typedef struct _QueueItem
+{
+    int x, y, w, h;
+    int32_t enc;
+    struct _QueueItem *next;
+} QueueItem;
+
+typedef struct _Queue
+{
+    QueueItem *queue_start;
+    int start_count;
+    QueueItem *queue_end;
+    int end_count;
+} Queue;
+
 struct VncState
 {
     QEMUTimer *timer;
@@ -152,6 +169,9 @@ struct VncState
     uint64_t *update_row;      /* outstanding updates */
     int has_update;            /* there's outstanding updates in the
                                 * visible area */
+
+    int update_requested;       /* the client requested an update */
+
     uint8_t *old_data;
     int depth; /* internal VNC frame buffer byte per pixel */
     int has_resize;
@@ -186,6 +206,9 @@ struct VncState
 
     Buffer output;
     Buffer input;
+    
+    Queue upqueue;
+
     kbd_layout_t *kbd_layout;
     /* current output mode information */
     VncWritePixels *write_pixels;
@@ -248,6 +271,11 @@ static void vnc_update_client(void *opaq
 static void vnc_update_client(void *opaque);
 static void vnc_client_read(void *opaque);
 static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
+static void pixel_format_message (VncState *vs);
+static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int 
h, int32_t encoding);
+static void dequeue_framebuffer_update(VncState *vs);
+static int is_empty_queue(VncState *vs);
+static void free_queue(VncState *vs);
 
 #if 0
 static inline void vnc_set_bit(uint32_t *d, int k)
@@ -370,13 +398,18 @@ static void vnc_dpy_resize(DisplayState 
     ds->height = h;
     ds->linesize = w * vs->depth;
     if (vs->csock != -1 && vs->has_resize && size_changed) {
-       vnc_write_u8(vs, 0);  /* msg id */
-       vnc_write_u8(vs, 0);
-       vnc_write_u16(vs, 1); /* number of rects */
-       vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
-       vnc_flush(vs);
-       vs->width = ds->width;
-       vs->height = ds->height;
+        vs->width = ds->width;
+        vs->height = ds->height;
+        if (vs->update_requested) {
+           vnc_write_u8(vs, 0);  /* msg id */
+           vnc_write_u8(vs, 0);
+           vnc_write_u16(vs, 1); /* number of rects */
+           vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
+           vnc_flush(vs);
+            vs->update_requested--;
+        } else {
+            enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
+        }
     }
     vs->dirty_pixel_shift = 0;
     for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
@@ -553,7 +586,8 @@ static void vnc_copy(DisplayState *ds, i
         return;
     }
 
-    if (src_x < vs->visible_x || src_y < vs->visible_y ||
+    if (!vs->update_requested ||
+        src_x < vs->visible_x || src_y < vs->visible_y ||
        dst_x < vs->visible_x || dst_y < vs->visible_y ||
        (src_x + w) > (vs->visible_x + vs->visible_w) ||
        (src_y + h) > (vs->visible_y + vs->visible_h) ||
@@ -592,6 +626,7 @@ static void vnc_copy(DisplayState *ds, i
        vnc_write_u16(vs, src_x);
        vnc_write_u16(vs, src_y);
        vnc_flush(vs);
+        vs->update_requested--;
     } else
        framebuffer_set_updated(vs, dst_x, dst_y, w, h);
 }
@@ -624,8 +659,21 @@ static void _vnc_update_client(void *opa
     int maxx, maxy;
     int tile_bytes = vs->depth * DP2X(vs, 1);
 
-    if (vs->csock == -1)
+    if (!vs->update_requested || vs->csock == -1)
        return;
+    while (!is_empty_queue(vs) && vs->update_requested) {
+        int enc = vs->upqueue.queue_end->enc; 
+        dequeue_framebuffer_update(vs);
+        switch (enc) {
+            case 0x574D5669:
+                pixel_format_message(vs);
+                break;
+            default:
+                break;
+        }
+        vs->update_requested--;
+    }
+    if (!vs->update_requested) return;
 
     now = qemu_get_clock(rt_clock);
 
@@ -717,8 +765,11 @@ static void _vnc_update_client(void *opa
     vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
     vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
 
-    if (n_rectangles == 0)
+    if (n_rectangles == 0) {
+        vs->output.offset = saved_offset - 2;
        goto backoff;
+    } else
+        vs->update_requested--;
 
     vs->has_update = 0;
     vnc_flush(vs);
@@ -735,7 +786,8 @@ static void _vnc_update_client(void *opa
     vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
     if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
        vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
-       if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
+       if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL &&
+            vs->update_requested) {
            /* Send a null update.  If the client is no longer
               interested (e.g. minimised) it'll ignore this, and we
               can stop scanning the buffer until it sends another
@@ -752,6 +804,7 @@ static void _vnc_update_client(void *opa
            send_framebuffer_update(vs, 0, 0, 1, 1);
            vnc_flush(vs);
            vs->last_update_time = now;
+            vs->update_requested--;
            return;
        }
     }
@@ -821,6 +874,88 @@ static void buffer_append(Buffer *buffer
     buffer->offset += len;
 }
 
+static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int 
h,
+                                   int32_t encoding)
+{
+    Queue *q = &vs->upqueue; 
+    if (q->queue_end != NULL) {
+        if (q->queue_end != q->queue_start || q->start_count != q->end_count) {
+            if (q->queue_end->next == NULL) {
+                q->queue_end->next = (QueueItem *) qemu_mallocz 
(sizeof(QueueItem) * QUEUE_ALLOC_UNIT);
+                q->end_count = QUEUE_ALLOC_UNIT;
+            }
+            q->queue_end = q->queue_end->next;
+        }
+    } else {
+        q->queue_end = (QueueItem *) qemu_mallocz (sizeof(QueueItem) * 
QUEUE_ALLOC_UNIT);
+        q->queue_start = q->queue_end;
+        q->start_count = QUEUE_ALLOC_UNIT;
+        q->end_count = QUEUE_ALLOC_UNIT;
+    }
+    q->end_count--;
+
+    q->queue_end->x = x;
+    q->queue_end->y = y;
+    q->queue_end->w = w;
+    q->queue_end->h = h;
+    q->queue_end->enc = encoding;
+    q->queue_end->next = (q->end_count > 0) ? (q->queue_end + 1) : NULL;
+}
+
+static void dequeue_framebuffer_update(VncState *vs)
+{
+    Queue *q = &vs->upqueue;
+    if (q->queue_start == NULL || 
+            (q->queue_end == q->queue_start && q->start_count == q->end_count))
+        return;
+
+    vnc_write_u8(vs, 0);
+    vnc_write_u8(vs, 0);
+    vnc_write_u16(vs, 1);
+    vnc_framebuffer_update(vs, q->queue_start->x, q->queue_start->y,
+            q->queue_start->w, q->queue_start->h, q->queue_start->enc);
+
+    q->start_count--;
+    if (q->queue_end != q->queue_start) {
+        if (!q->start_count) {
+            QueueItem *i = q->queue_start;
+            q->queue_start = q->queue_start->next;
+            q->start_count = QUEUE_ALLOC_UNIT;
+            free (i - QUEUE_ALLOC_UNIT + 1);
+        } else
+            q->queue_start = q->queue_start->next;
+    } else {
+        q->queue_end = q->queue_end - QUEUE_ALLOC_UNIT + q->end_count + 1;
+        q->queue_start = q->queue_end;
+        q->end_count = QUEUE_ALLOC_UNIT;
+        q->start_count = QUEUE_ALLOC_UNIT;
+    }
+}
+
+static int is_empty_queue(VncState *vs)
+{
+    Queue *q = &vs->upqueue;
+    if (q->queue_end == NULL) return 1;
+    if (q->queue_end == q->queue_start && q->start_count == q->end_count) 
return 1;
+    return 0;
+}
+
+static void free_queue(VncState *vs)
+{
+    Queue *q = &vs->upqueue;
+    while (q->queue_start != NULL) {
+        QueueItem *i;
+        q->queue_start = q->queue_start + q->start_count - 1;
+        i = q->queue_start;
+        q->queue_start = q->queue_start->next;
+        free(i - QUEUE_ALLOC_UNIT + 1);
+        q->start_count = QUEUE_ALLOC_UNIT;
+    }
+    q->queue_end = NULL;
+    q->start_count = 0;
+    q->end_count = 0;
+}
+
 static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
 {
     if (ret == 0 || ret == -1) {
@@ -833,6 +968,8 @@ static int vnc_client_io_error(VncState 
        vs->csock = -1;
        buffer_reset(&vs->input);
        buffer_reset(&vs->output);
+        free_queue(vs);
+        vs->update_requested = 0;
 #if CONFIG_VNC_TLS
        if (vs->tls_session) {
            gnutls_deinit(vs->tls_session);
@@ -1044,12 +1181,18 @@ static void check_pointer_type_change(Vn
 static void check_pointer_type_change(VncState *vs, int absolute)
 {
     if (vs->has_pointer_type_change && vs->absolute != absolute) {
-       vnc_write_u8(vs, 0);
-       vnc_write_u8(vs, 0);
-       vnc_write_u16(vs, 1);
-       vnc_framebuffer_update(vs, absolute, 0,
+        if (vs->update_requested) {
+           vnc_write_u8(vs, 0);
+           vnc_write_u8(vs, 0);
+           vnc_write_u16(vs, 1);
+           vnc_framebuffer_update(vs, absolute, 0,
                               vs->ds->width, vs->ds->height, -257);
-       vnc_flush(vs);
+           vnc_flush(vs);
+            vs->update_requested--;
+        } else {
+            enqueue_framebuffer_update(vs, absolute, 0,
+                               vs->ds->width, vs->ds->height, -257);
+        }
     }
     vs->absolute = absolute;
 }
@@ -1316,6 +1459,7 @@ static void framebuffer_update_request(V
     vs->visible_w = w;
     vs->visible_h = h;
 
+    vs->update_requested++;
     qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
 }
 
@@ -1536,12 +1680,17 @@ static void vnc_dpy_colourdepth(DisplayS
         vnc_client_error(vs);
     } else if (vs->csock != -1 && vs->has_WMVi) {
         /* Sending a WMVi message to notify the client*/
-        vnc_write_u8(vs, 0);  /* msg id */
-        vnc_write_u8(vs, 0);
-        vnc_write_u16(vs, 1); /* number of rects */
-        vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
-        pixel_format_message(vs);
-        vnc_flush(vs);
+        if (vs->update_requested) {
+            vnc_write_u8(vs, 0);  /* msg id */
+            vnc_write_u8(vs, 0);
+            vnc_write_u16(vs, 1); /* number of rects */
+            vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 
0x574D5669);
+            pixel_format_message(vs);
+            vnc_flush(vs);
+            vs->update_requested--;
+        } else {
+            enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, 
0x574D5669);
+        }
     } else {
         if (vs->pix_bpp == 4 && vs->depth == 4 &&
             host_big_endian_flag == vs->pix_big_endian &&
@@ -2291,6 +2440,7 @@ static void vnc_listen_read(void *opaque
        framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height);
        vs->has_resize = 0;
        vs->has_hextile = 0;
+        vs->update_requested = 0;
        vs->ds->dpy_copy = NULL;
        vnc_timer_init(vs);
     }
@@ -2413,6 +2563,8 @@ void vnc_display_close(DisplayState *ds)
        vs->csock = -1;
        buffer_reset(&vs->input);
        buffer_reset(&vs->output);
+        free_queue(vs);
+        vs->update_requested = 0;
 #if CONFIG_VNC_TLS
        if (vs->tls_session) {
            gnutls_deinit(vs->tls_session);
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Tue Feb 26 10:12:04 2008 -0700
@@ -764,7 +764,8 @@ static PyObject *pyxc_physinfo(XcObject 
     xc_physinfo_t info;
     char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
     int i, j, max_cpu_id;
-    PyObject *ret_obj, *node_to_cpu_obj;
+    uint64_t free_heap;
+    PyObject *ret_obj, *node_to_cpu_obj, *node_to_memory_obj;
     xc_cpu_to_node_t map[MAX_CPU_ID + 1];
 
     set_xen_guest_handle(info.cpu_to_node, map);
@@ -812,7 +813,17 @@ static PyObject *pyxc_physinfo(XcObject 
         PyList_Append(node_to_cpu_obj, cpus); 
     }
 
+    node_to_memory_obj = PyList_New(0);
+
+    for ( i = 0; i < info.nr_nodes; i++ )
+    {
+       xc_availheap(self->xc_handle, 0, 0, i, &free_heap);
+       PyList_Append(node_to_memory_obj,
+           PyInt_FromLong(free_heap / 1024));
+    }
+       
     PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
+    PyDict_SetItemString(ret_obj, "node_to_memory", node_to_memory_obj);
  
     return ret_obj;
 #undef MAX_CPU_ID
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Feb 26 10:12:04 2008 -0700
@@ -906,6 +906,7 @@ class XendDomainInfo:
         log.debug("Setting memory maximum of domain %s (%s) to %d MiB.",
                   self.info['name_label'], str(self.domid), limit)
 
+        maxmem_cur = self.get_memory_static_max()
         MiB = 1024 * 1024
         self._safe_set_memory('memory_static_max', limit * MiB)
 
@@ -914,6 +915,7 @@ class XendDomainInfo:
             try:
                 return xc.domain_setmaxmem(self.domid, maxmem)
             except Exception, ex:
+                self._safe_set_memory('memory_static_max', maxmem_cur)
                 raise XendError(str(ex))
         xen.xend.XendDomain.instance().managed_config_save(self)
 
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/python/xen/xend/XendNode.py Tue Feb 26 10:12:04 2008 -0700
@@ -573,6 +573,20 @@ class XendNode:
         except:
             str='none\n'
         return str[:-1];
+    def format_node_to_memory(self, pinfo):
+        str=''
+        whitespace=''
+        try:
+            node_to_memory=pinfo['node_to_memory']
+            for i in range(0, pinfo['nr_nodes']):
+                str+='%snode%d:%d\n' % (whitespace,
+                                        i,
+                                        node_to_memory[i] / 1024)
+                whitespace='%25s' % ''
+        except:
+            str='none\n'
+        return str[:-1];
+
 
     def physinfo(self):
         info = self.xc.physinfo()
@@ -583,6 +597,7 @@ class XendNode:
         info['total_memory'] = info['total_memory'] / 1024
         info['free_memory']  = info['free_memory'] / 1024
         info['node_to_cpu']  = self.format_node_to_cpu(info)
+        info['node_to_memory'] = self.format_node_to_memory(info)
 
         ITEM_ORDER = ['nr_cpus',
                       'nr_nodes',
@@ -592,7 +607,8 @@ class XendNode:
                       'hw_caps',
                       'total_memory',
                       'free_memory',
-                      'node_to_cpu'
+                      'node_to_cpu',
+                      'node_to_memory'
                       ]
 
         return [[k, info[k]] for k in ITEM_ORDER]
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/python/xen/xend/image.py    Tue Feb 26 10:12:04 2008 -0700
@@ -390,7 +390,7 @@ class LinuxImageHandler(ImageHandler):
         ImageHandler.configure(self, vmConfig)
         rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
         if rtc_timeoffset is not None:
-            xc.domain_set_time_offset(self.vm.getDomid(), rtc_timeoffset)
+            xc.domain_set_time_offset(self.vm.getDomid(), int(rtc_timeoffset))
 
     def buildDomain(self):
         store_evtchn = self.vm.getStorePort()
diff -r 7e8334e651c4 -r f97a0b6152c3 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Mon Feb 25 06:29:01 2008 -0700
+++ b/tools/xentrace/xentrace.c Tue Feb 26 10:12:04 2008 -0700
@@ -15,6 +15,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/vfs.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -53,7 +54,10 @@ typedef struct settings_st {
     uint32_t evt_mask;
     uint32_t cpu_mask;
     unsigned long tbuf_size;
-    uint8_t discard:1;
+    unsigned long disk_rsvd;
+    unsigned long timeout;
+    uint8_t discard:1,
+        disable_tracing:1;
 } settings_t;
 
 settings_t opts;
@@ -83,8 +87,36 @@ void write_buffer(unsigned int cpu, unsi
 void write_buffer(unsigned int cpu, unsigned char *start, int size,
                int total_size, int outfd)
 {
+    struct statfs stat;
     size_t written = 0;
     
+    if ( opts.disk_rsvd != 0 )
+    {
+        unsigned long long freespace;
+
+        /* Check that filesystem has enough space. */
+        if ( fstatfs (outfd, &stat) )
+        {
+                fprintf(stderr, "Statfs failed!\n");
+                goto fail;
+        }
+
+        freespace = stat.f_bsize * (unsigned long long)stat.f_bfree;
+
+        if ( total_size )
+            freespace -= total_size;
+        else
+            freespace -= size;
+
+        freespace >>= 20; /* Convert to MB */
+
+        if ( freespace <= opts.disk_rsvd )
+        {
+                fprintf(stderr, "Disk space limit reached (free space: %lluMB, 
limit: %luMB).\n", freespace, opts.disk_rsvd);
+                exit (EXIT_FAILURE);
+        }
+    }
+
     /* Write a CPU_BUF record on each buffer "window" written.  Wrapped
      * windows may involve two writes, so only write the record on the
      * first write. */
@@ -126,6 +158,28 @@ void write_buffer(unsigned int cpu, unsi
  fail:
     PERROR("Failed to write trace data");
     exit(EXIT_FAILURE);
+}
+
+static void disable_tbufs(void)
+{
+    int xc_handle = xc_interface_open();
+    int ret;
+
+    if ( xc_handle < 0 ) 
+    {
+        perror("Couldn't open xc handle to disable tbufs.");
+        goto out;
+    }
+
+    ret = xc_tbuf_disable(xc_handle);
+
+    if ( ret != 0 )
+    {
+        perror("Couldn't disable trace buffers");
+    }
+
+out:
+    xc_interface_close(xc_handle);
 }
 
 static void get_tbufs(unsigned long *mfn, unsigned long *size)
@@ -435,6 +489,9 @@ int monitor_tbufs(int outfd)
         wait_for_event_or_timeout(opts.poll_sleep);
     }
 
+    if(opts.disable_tracing)
+        disable_tbufs();
+
     /* cleanup */
     free(meta);
     free(data);
@@ -471,6 +528,14 @@ void usage(void)
 "                          N.B. that the trace buffer cannot be resized.\n" \
 "                          if it has already been set this boot cycle,\n" \
 "                          this argument will be ignored.\n" \
+"  -D  --discard-buffers   Discard all records currently in the trace\n" \
+"                          buffers before beginning.\n" \
+"  -x  --dont-disable-tracing\n" \
+"                          By default, xentrace will disable tracing when\n" \
+"                          it exits. Selecting this option will tell it to\n" \
+"                          keep tracing on.  Traces will be collected in\n" \
+"                          Xen's trace buffers until they become full.\n" \
+"  -T  --time-interval=s   Run xentrace for s seconds and quit.\n" \
 "  -?, --help              Show this message\n" \
 "  -V, --version           Print program version\n" \
 "\n" \
@@ -539,6 +604,10 @@ void parse_args(int argc, char **argv)
         { "cpu-mask",       required_argument, 0, 'c' },
         { "evt-mask",       required_argument, 0, 'e' },
         { "trace-buf-size", required_argument, 0, 'S' },
+        { "reserve-disk-space", required_argument, 0, 'r' },
+        { "time-interval",  required_argument, 0, 'T' },
+        { "discard-buffers", no_argument,      0, 'D' },
+        { "dont-disable-tracing", no_argument, 0, 'x' },
         { "help",           no_argument,       0, '?' },
         { "version",        no_argument,       0, 'V' },
         { 0, 0, 0, 0 }
@@ -569,7 +638,23 @@ void parse_args(int argc, char **argv)
             printf("%s\n", program_version);
             exit(EXIT_SUCCESS);
             break;
-            
+
+        case 'D': /* Discard traces currently in buffer */
+            opts.discard = 1;
+            break;
+
+        case 'r': /* Disk-space reservation */
+            opts.disk_rsvd = argtol(optarg, 0);
+            break;
+
+        case 'x': /* Don't disable tracing */
+            opts.disable_tracing = 0;
+            break;
+
+        case 'T':
+            opts.timeout = argtol(optarg, 0);
+            break;
+
         default:
             usage();
         }
@@ -581,7 +666,6 @@ void parse_args(int argc, char **argv)
 
     opts.outfile = argv[optind];
 }
-
 
 /* *BSD has no O_LARGEFILE */
 #ifndef O_LARGEFILE
@@ -597,6 +681,9 @@ int main(int argc, char **argv)
     opts.poll_sleep = POLL_SLEEP_MILLIS;
     opts.evt_mask = 0;
     opts.cpu_mask = 0;
+    opts.disk_rsvd = 0;
+    opts.disable_tracing = 1;
+    opts.timeout = 0;
 
     parse_args(argc, argv);
 
@@ -612,6 +699,9 @@ int main(int argc, char **argv)
 
     if ( opts.cpu_mask != 0 )
         set_mask(opts.cpu_mask, 1);
+
+    if ( opts.timeout != 0 ) 
+        alarm(opts.timeout);
 
     if ( opts.outfile )
         outfd = open(opts.outfile,
@@ -637,6 +727,7 @@ int main(int argc, char **argv)
     sigaction(SIGHUP,  &act, NULL);
     sigaction(SIGTERM, &act, NULL);
     sigaction(SIGINT,  &act, NULL);
+    sigaction(SIGALRM, &act, NULL);
 
     ret = monitor_tbufs(outfd);
 
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/emulate.c
--- a/xen/arch/x86/hvm/emulate.c        Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/emulate.c        Tue Feb 26 10:12:04 2008 -0700
@@ -124,8 +124,9 @@ static int hvmemul_virtual_to_linear(
 
     if ( !okay )
     {
-        hvmemul_ctxt->flags.exn_pending = 1;
+        hvmemul_ctxt->exn_pending = 1;
         hvmemul_ctxt->exn_vector = TRAP_gp_fault;
+        hvmemul_ctxt->exn_error_code = 0;
         hvmemul_ctxt->exn_insn_len = 0;
         return X86EMUL_EXCEPTION;
     }
@@ -438,9 +439,6 @@ static int hvmemul_write_segment(
     struct hvm_emulate_ctxt *hvmemul_ctxt =
         container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
     struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
-
-    if ( seg == x86_seg_ss )
-        hvmemul_ctxt->flags.mov_ss = 1;
 
     memcpy(sreg, reg, sizeof(struct segment_register));
     __set_bit(seg, &hvmemul_ctxt->seg_reg_dirty);
@@ -571,17 +569,6 @@ static int hvmemul_write_msr(
     return hvm_funcs.msr_write_intercept(&_regs);
 }
 
-static int hvmemul_write_rflags(
-    unsigned long val,
-    struct x86_emulate_ctxt *ctxt)
-{
-    struct hvm_emulate_ctxt *hvmemul_ctxt =
-        container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
-    if ( (val & X86_EFLAGS_IF) && !(ctxt->regs->eflags & X86_EFLAGS_IF) )
-        hvmemul_ctxt->flags.sti = 1;
-    return X86EMUL_OKAY;
-}
-
 static int hvmemul_wbinvd(
     struct x86_emulate_ctxt *ctxt)
 {
@@ -600,28 +587,17 @@ static int hvmemul_cpuid(
     return X86EMUL_OKAY;
 }
 
-static int hvmemul_hlt(
-    struct x86_emulate_ctxt *ctxt)
-{
-    struct hvm_emulate_ctxt *hvmemul_ctxt =
-        container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
-    hvmemul_ctxt->flags.hlt = 1;
-    return X86EMUL_OKAY;
-}
-
 static int hvmemul_inject_hw_exception(
     uint8_t vector,
-    uint16_t error_code,
-    struct x86_emulate_ctxt *ctxt)
-{
-    struct hvm_emulate_ctxt *hvmemul_ctxt =
-        container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
-
-    if ( error_code != 0 )
-        return X86EMUL_UNHANDLEABLE;
-
-    hvmemul_ctxt->flags.exn_pending = 1;
+    int32_t error_code,
+    struct x86_emulate_ctxt *ctxt)
+{
+    struct hvm_emulate_ctxt *hvmemul_ctxt =
+        container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
+
+    hvmemul_ctxt->exn_pending = 1;
     hvmemul_ctxt->exn_vector = vector;
+    hvmemul_ctxt->exn_error_code = error_code;
     hvmemul_ctxt->exn_insn_len = 0;
 
     return X86EMUL_OKAY;
@@ -635,8 +611,9 @@ static int hvmemul_inject_sw_interrupt(
     struct hvm_emulate_ctxt *hvmemul_ctxt =
         container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
 
-    hvmemul_ctxt->flags.exn_pending = 1;
+    hvmemul_ctxt->exn_pending = 1;
     hvmemul_ctxt->exn_vector = vector;
+    hvmemul_ctxt->exn_error_code = -1;
     hvmemul_ctxt->exn_insn_len = insn_len;
 
     return X86EMUL_OKAY;
@@ -684,10 +661,8 @@ static struct x86_emulate_ops hvm_emulat
     .write_cr      = hvmemul_write_cr,
     .read_msr      = hvmemul_read_msr,
     .write_msr     = hvmemul_write_msr,
-    .write_rflags  = hvmemul_write_rflags,
     .wbinvd        = hvmemul_wbinvd,
     .cpuid         = hvmemul_cpuid,
-    .hlt           = hvmemul_hlt,
     .inject_hw_exception = hvmemul_inject_hw_exception,
     .inject_sw_interrupt = hvmemul_inject_sw_interrupt,
     .load_fpu_ctxt = hvmemul_load_fpu_ctxt,
@@ -698,7 +673,9 @@ int hvm_emulate_one(
     struct hvm_emulate_ctxt *hvmemul_ctxt)
 {
     struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs;
+    uint32_t new_intr_shadow;
     unsigned long addr;
+    int rc;
 
     hvmemul_ctxt->ctxt.addr_size =
         hvmemul_ctxt->seg_reg[x86_seg_cs].attr.fields.db ? 32 : 16;
@@ -715,15 +692,46 @@ int hvm_emulate_one(
              hvmemul_ctxt->insn_buf, addr, sizeof(hvmemul_ctxt->insn_buf)))
         ? sizeof(hvmemul_ctxt->insn_buf) : 0;
 
-    hvmemul_ctxt->flag_word = 0;
-
-    return x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops);
+    hvmemul_ctxt->exn_pending = 0;
+
+    rc = x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops);
+    if ( rc != X86EMUL_OKAY )
+        return rc;
+
+    new_intr_shadow = hvmemul_ctxt->intr_shadow;
+
+    /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */
+    if ( hvmemul_ctxt->ctxt.retire.flags.mov_ss )
+        new_intr_shadow ^= HVM_INTR_SHADOW_MOV_SS;
+    else
+        new_intr_shadow &= ~HVM_INTR_SHADOW_MOV_SS;
+
+    /* STI instruction toggles STI shadow, else we just clear it. */
+    if ( hvmemul_ctxt->ctxt.retire.flags.sti )
+        new_intr_shadow ^= HVM_INTR_SHADOW_STI;
+    else
+        new_intr_shadow &= ~HVM_INTR_SHADOW_STI;
+
+    if ( hvmemul_ctxt->intr_shadow != new_intr_shadow )
+    {
+        hvmemul_ctxt->intr_shadow = new_intr_shadow;
+        hvm_funcs.set_interrupt_shadow(current, new_intr_shadow);
+    }
+
+    if ( hvmemul_ctxt->ctxt.retire.flags.hlt &&
+         !hvm_local_events_need_delivery(current) )
+    {
+        hvm_hlt(regs->eflags);
+    }
+
+    return X86EMUL_OKAY;
 }
 
 void hvm_emulate_prepare(
     struct hvm_emulate_ctxt *hvmemul_ctxt,
     struct cpu_user_regs *regs)
 {
+    hvmemul_ctxt->intr_shadow = hvm_funcs.get_interrupt_shadow(current);
     hvmemul_ctxt->ctxt.regs = regs;
     hvmemul_ctxt->ctxt.force_writeback = 1;
     hvmemul_ctxt->seg_reg_accessed = 0;
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/hvm.c    Tue Feb 26 10:12:04 2008 -0700
@@ -1640,12 +1640,22 @@ void hvm_cpuid(unsigned int input, unsig
 
 enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
 {
-    enum hvm_intblk r;
+    unsigned long intr_shadow;
+
     ASSERT(v == current);
 
-    r = hvm_funcs.interrupt_blocked(v, intack);
-    if ( r != hvm_intblk_none )
-        return r;
+    if ( (intack.source != hvm_intsrc_nmi) &&
+         !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
+        return hvm_intblk_rflags_ie;
+
+    intr_shadow = hvm_funcs.get_interrupt_shadow(v);
+
+    if ( intr_shadow & (HVM_INTR_SHADOW_STI|HVM_INTR_SHADOW_MOV_SS) )
+        return hvm_intblk_shadow;
+
+    if ( intack.source == hvm_intsrc_nmi )
+        return ((intr_shadow & HVM_INTR_SHADOW_NMI) ?
+                hvm_intblk_nmi_iret : hvm_intblk_none);
 
     if ( intack.source == hvm_intsrc_lapic )
     {
@@ -1654,7 +1664,7 @@ enum hvm_intblk hvm_interrupt_blocked(st
             return hvm_intblk_tpr;
     }
 
-    return r;
+    return hvm_intblk_none;
 }
 
 static long hvm_grant_table_op(
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c     Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/io.c     Tue Feb 26 10:12:04 2008 -0700
@@ -262,8 +262,8 @@ int handle_mmio(void)
                  ctxt.insn_buf[4], ctxt.insn_buf[5]);
         return 0;
     case X86EMUL_EXCEPTION:
-        if ( ctxt.flags.exn_pending )
-            hvm_inject_exception(ctxt.exn_vector, 0, 0);
+        if ( ctxt.exn_pending )
+            hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
         break;
     default:
         break;
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Feb 26 10:12:04 2008 -0700
@@ -366,24 +366,18 @@ static void svm_fpu_leave(struct vcpu *v
     }
 }
 
-static enum hvm_intblk svm_interrupt_blocked(
-    struct vcpu *v, struct hvm_intack intack)
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    if ( vmcb->interrupt_shadow )
-        return hvm_intblk_shadow;
-
-    if ( intack.source == hvm_intsrc_nmi )
-        return hvm_intblk_none;
-
-    ASSERT((intack.source == hvm_intsrc_pic) ||
-           (intack.source == hvm_intsrc_lapic));
-
-    if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
-        return hvm_intblk_rflags_ie;
-
-    return hvm_intblk_none;
+static unsigned int svm_get_interrupt_shadow(struct vcpu *v)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    return (vmcb->interrupt_shadow ?
+            (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI) : 0);
+}
+
+static void svm_set_interrupt_shadow(struct vcpu *v, unsigned int intr_shadow)
+{
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+    vmcb->interrupt_shadow =
+        !!(intr_shadow & (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI));
 }
 
 static int svm_guest_x86_mode(struct vcpu *v)
@@ -779,7 +773,8 @@ static struct hvm_function_table svm_fun
     .vcpu_destroy         = svm_vcpu_destroy,
     .save_cpu_ctxt        = svm_save_vmcb_ctxt,
     .load_cpu_ctxt        = svm_load_vmcb_ctxt,
-    .interrupt_blocked    = svm_interrupt_blocked,
+    .get_interrupt_shadow = svm_get_interrupt_shadow,
+    .set_interrupt_shadow = svm_set_interrupt_shadow,
     .guest_x86_mode       = svm_guest_x86_mode,
     .get_segment_register = svm_get_segment_register,
     .set_segment_register = svm_set_segment_register,
@@ -1176,7 +1171,7 @@ static void svm_vmexit_do_hlt(struct vmc
     /* Check for pending exception or new interrupt. */
     if ( vmcb->eventinj.fields.v ||
          ((intack.source != hvm_intsrc_none) &&
-          !svm_interrupt_blocked(current, intack)) )
+          !hvm_interrupt_blocked(current, intack)) )
     {
         HVMTRACE_1D(HLT, curr, /*int pending=*/ 1);
         return;
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/intr.c       Tue Feb 26 10:12:04 2008 -0700
@@ -65,10 +65,6 @@
  * Injecting a virtual NMI sets the NMI-blocking interruptibility flag only
  * if the 'virtual NMIs' control is set. Injecting *any* kind of event clears
  * the STI- and MOV-SS-blocking interruptibility-state flags.
- * 
- * If MOV/POP SS is executed while MOV-SS-blocking is in effect, the effect
- * is cleared. If STI is executed while MOV-SS- or STI-blocking is in effect,
- * the effect is cleared. (i.e., MOV-SS-blocking 'dominates' STI-blocking).
  */
 
 static void enable_intr_window(struct vcpu *v, struct hvm_intack intack)
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/realmode.c
--- a/xen/arch/x86/hvm/vmx/realmode.c   Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/realmode.c   Tue Feb 26 10:12:04 2008 -0700
@@ -21,25 +21,20 @@
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/hvm/vmx/vmcs.h>
 
-struct realmode_emulate_ctxt {
-    struct hvm_emulate_ctxt hvm;
-    uint32_t intr_shadow;
-};
-
 static void realmode_deliver_exception(
     unsigned int vector,
     unsigned int insn_len,
-    struct realmode_emulate_ctxt *rm_ctxt)
+    struct hvm_emulate_ctxt *hvmemul_ctxt)
 {
     struct segment_register *idtr, *csr;
-    struct cpu_user_regs *regs = rm_ctxt->hvm.ctxt.regs;
+    struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs;
     uint32_t cs_eip, pstk;
     uint16_t frame[3];
     unsigned int last_byte;
 
-    idtr = hvmemul_get_seg_reg(x86_seg_idtr, &rm_ctxt->hvm);
-    csr  = hvmemul_get_seg_reg(x86_seg_cs,   &rm_ctxt->hvm);
-    __set_bit(x86_seg_cs, &rm_ctxt->hvm.seg_reg_dirty);
+    idtr = hvmemul_get_seg_reg(x86_seg_idtr, hvmemul_ctxt);
+    csr  = hvmemul_get_seg_reg(x86_seg_cs,   hvmemul_ctxt);
+    __set_bit(x86_seg_cs, &hvmemul_ctxt->seg_reg_dirty);
 
  again:
     last_byte = (vector * 4) + 3;
@@ -74,7 +69,7 @@ static void realmode_deliver_exception(
     frame[1] = csr->sel;
     frame[2] = regs->eflags & ~X86_EFLAGS_RF;
 
-    if ( rm_ctxt->hvm.ctxt.addr_size == 32 )
+    if ( hvmemul_ctxt->ctxt.addr_size == 32 )
     {
         regs->esp -= 6;
         pstk = regs->esp;
@@ -86,7 +81,7 @@ static void realmode_deliver_exception(
         regs->esp |= pstk;
     }
 
-    pstk += hvmemul_get_seg_reg(x86_seg_ss, &rm_ctxt->hvm)->base;
+    pstk += hvmemul_get_seg_reg(x86_seg_ss, hvmemul_ctxt)->base;
     (void)hvm_copy_to_guest_phys(pstk, frame, sizeof(frame));
 
     csr->sel  = cs_eip >> 16;
@@ -95,41 +90,42 @@ static void realmode_deliver_exception(
     regs->eflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF | X86_EFLAGS_RF);
 
     /* Exception delivery clears STI and MOV-SS blocking. */
-    if ( rm_ctxt->intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
-    {
-        rm_ctxt->intr_shadow &= ~(VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS);
-        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, rm_ctxt->intr_shadow);
-    }
-}
-
-static void realmode_emulate_one(struct realmode_emulate_ctxt *rm_ctxt)
-{
-    struct cpu_user_regs *regs = rm_ctxt->hvm.ctxt.regs;
+    if ( hvmemul_ctxt->intr_shadow &
+         (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
+    {
+        hvmemul_ctxt->intr_shadow &=
+            ~(VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS);
+        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, hvmemul_ctxt->intr_shadow);
+    }
+}
+
+static void realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt)
+{
     struct vcpu *curr = current;
     unsigned long seg_reg_dirty;
-    uint32_t new_intr_shadow, intr_info;
+    uint32_t intr_info;
     int rc;
 
-    seg_reg_dirty = rm_ctxt->hvm.seg_reg_dirty;
-    rm_ctxt->hvm.seg_reg_dirty = 0;
-
-    rc = hvm_emulate_one(&rm_ctxt->hvm);
-
-    if ( test_bit(x86_seg_cs, &rm_ctxt->hvm.seg_reg_dirty) )
+    seg_reg_dirty = hvmemul_ctxt->seg_reg_dirty;
+    hvmemul_ctxt->seg_reg_dirty = 0;
+
+    rc = hvm_emulate_one(hvmemul_ctxt);
+
+    if ( test_bit(x86_seg_cs, &hvmemul_ctxt->seg_reg_dirty) )
     {
         curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_CS;
-        if ( hvmemul_get_seg_reg(x86_seg_cs, &rm_ctxt->hvm)->sel & 3 )
+        if ( hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt)->sel & 3 )
             curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_CS;
     }
 
-    if ( test_bit(x86_seg_ss, &rm_ctxt->hvm.seg_reg_dirty) )
+    if ( test_bit(x86_seg_ss, &hvmemul_ctxt->seg_reg_dirty) )
     {
         curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_SS;
-        if ( hvmemul_get_seg_reg(x86_seg_ss, &rm_ctxt->hvm)->sel & 3 )
+        if ( hvmemul_get_seg_reg(x86_seg_ss, hvmemul_ctxt)->sel & 3 )
             curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_SS;
     }
 
-    rm_ctxt->hvm.seg_reg_dirty |= seg_reg_dirty;
+    hvmemul_ctxt->seg_reg_dirty |= seg_reg_dirty;
 
     if ( rc == X86EMUL_UNHANDLEABLE )
     {
@@ -137,33 +133,9 @@ static void realmode_emulate_one(struct 
         goto fail;
     }
 
-    if ( rc == X86EMUL_RETRY )
-        return;
-
-    new_intr_shadow = rm_ctxt->intr_shadow;
-
-    /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */
-    if ( rm_ctxt->hvm.flags.mov_ss )
-        new_intr_shadow ^= VMX_INTR_SHADOW_MOV_SS;
-    else
-        new_intr_shadow &= ~VMX_INTR_SHADOW_MOV_SS;
-
-    /* STI instruction toggles STI shadow, else we just clear it. */
-    if ( rm_ctxt->hvm.flags.sti )
-        new_intr_shadow ^= VMX_INTR_SHADOW_STI;
-    else
-        new_intr_shadow &= ~VMX_INTR_SHADOW_STI;
-
-    /* Update interrupt shadow information in VMCS only if it changes. */
-    if ( rm_ctxt->intr_shadow != new_intr_shadow )
-    {
-        rm_ctxt->intr_shadow = new_intr_shadow;
-        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, rm_ctxt->intr_shadow);
-    }
-
     if ( rc == X86EMUL_EXCEPTION )
     {
-        if ( !rm_ctxt->hvm.flags.exn_pending )
+        if ( !hvmemul_ctxt->exn_pending )
         {
             intr_info = __vmread(VM_ENTRY_INTR_INFO);
             __vmwrite(VM_ENTRY_INTR_INFO, 0);
@@ -172,23 +144,21 @@ static void realmode_emulate_one(struct 
                 gdprintk(XENLOG_ERR, "Exception pending but no info.\n");
                 goto fail;
             }
-            rm_ctxt->hvm.exn_vector = (uint8_t)intr_info;
-            rm_ctxt->hvm.exn_insn_len = 0;
+            hvmemul_ctxt->exn_vector = (uint8_t)intr_info;
+            hvmemul_ctxt->exn_insn_len = 0;
         }
 
         if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
         {
             gdprintk(XENLOG_ERR, "Exception %02x in protected mode.\n",
-                     rm_ctxt->hvm.exn_vector);
+                     hvmemul_ctxt->exn_vector);
             goto fail;
         }
 
         realmode_deliver_exception(
-            rm_ctxt->hvm.exn_vector, rm_ctxt->hvm.exn_insn_len, rm_ctxt);
-    }
-    else if ( rm_ctxt->hvm.flags.hlt && !hvm_local_events_need_delivery(curr) )
-    {
-        hvm_hlt(regs->eflags);
+            hvmemul_ctxt->exn_vector,
+            hvmemul_ctxt->exn_insn_len,
+            hvmemul_ctxt);
     }
 
     return;
@@ -197,18 +167,18 @@ static void realmode_emulate_one(struct 
     gdprintk(XENLOG_ERR,
              "Real-mode emulation failed @ %04x:%08lx: "
              "%02x %02x %02x %02x %02x %02x\n",
-             hvmemul_get_seg_reg(x86_seg_cs, &rm_ctxt->hvm)->sel,
-             rm_ctxt->hvm.insn_buf_eip,
-             rm_ctxt->hvm.insn_buf[0], rm_ctxt->hvm.insn_buf[1],
-             rm_ctxt->hvm.insn_buf[2], rm_ctxt->hvm.insn_buf[3],
-             rm_ctxt->hvm.insn_buf[4], rm_ctxt->hvm.insn_buf[5]);
+             hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt)->sel,
+             hvmemul_ctxt->insn_buf_eip,
+             hvmemul_ctxt->insn_buf[0], hvmemul_ctxt->insn_buf[1],
+             hvmemul_ctxt->insn_buf[2], hvmemul_ctxt->insn_buf[3],
+             hvmemul_ctxt->insn_buf[4], hvmemul_ctxt->insn_buf[5]);
     domain_crash_synchronous();
 }
 
 void vmx_realmode(struct cpu_user_regs *regs)
 {
     struct vcpu *curr = current;
-    struct realmode_emulate_ctxt rm_ctxt;
+    struct hvm_emulate_ctxt hvmemul_ctxt;
     struct segment_register *sreg;
     unsigned long intr_info;
     unsigned int emulations = 0;
@@ -218,17 +188,16 @@ void vmx_realmode(struct cpu_user_regs *
     if ( intr_info & INTR_INFO_VALID_MASK )
         __vmwrite(VM_ENTRY_INTR_INFO, 0);
 
-    hvm_emulate_prepare(&rm_ctxt.hvm, regs);
-    rm_ctxt.intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
+    hvm_emulate_prepare(&hvmemul_ctxt, regs);
 
     if ( curr->arch.hvm_vcpu.io_completed )
-        realmode_emulate_one(&rm_ctxt);
+        realmode_emulate_one(&hvmemul_ctxt);
 
     /* Only deliver interrupts into emulated real mode. */
     if ( !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) &&
          (intr_info & INTR_INFO_VALID_MASK) )
     {
-        realmode_deliver_exception((uint8_t)intr_info, 0, &rm_ctxt);
+        realmode_deliver_exception((uint8_t)intr_info, 0, &hvmemul_ctxt);
         intr_info = 0;
     }
 
@@ -245,7 +214,7 @@ void vmx_realmode(struct cpu_user_regs *
              !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) &&
              hvm_local_events_need_delivery(curr) )
             break;
-        realmode_emulate_one(&rm_ctxt);
+        realmode_emulate_one(&hvmemul_ctxt);
     }
 
     if ( !curr->arch.hvm_vmx.vmxemul )
@@ -255,20 +224,20 @@ void vmx_realmode(struct cpu_user_regs *
          * At this point CS.RPL == SS.RPL == CS.DPL == SS.DPL == 0. For
          * DS, ES, FS and GS the most uninvasive trick is to set DPL == RPL.
          */
-        sreg = hvmemul_get_seg_reg(x86_seg_ds, &rm_ctxt.hvm);
-        sreg->attr.fields.dpl = sreg->sel & 3;
-        sreg = hvmemul_get_seg_reg(x86_seg_es, &rm_ctxt.hvm);
-        sreg->attr.fields.dpl = sreg->sel & 3;
-        sreg = hvmemul_get_seg_reg(x86_seg_fs, &rm_ctxt.hvm);
-        sreg->attr.fields.dpl = sreg->sel & 3;
-        sreg = hvmemul_get_seg_reg(x86_seg_gs, &rm_ctxt.hvm);
-        sreg->attr.fields.dpl = sreg->sel & 3;
-        rm_ctxt.hvm.seg_reg_dirty |=
+        sreg = hvmemul_get_seg_reg(x86_seg_ds, &hvmemul_ctxt);
+        sreg->attr.fields.dpl = sreg->sel & 3;
+        sreg = hvmemul_get_seg_reg(x86_seg_es, &hvmemul_ctxt);
+        sreg->attr.fields.dpl = sreg->sel & 3;
+        sreg = hvmemul_get_seg_reg(x86_seg_fs, &hvmemul_ctxt);
+        sreg->attr.fields.dpl = sreg->sel & 3;
+        sreg = hvmemul_get_seg_reg(x86_seg_gs, &hvmemul_ctxt);
+        sreg->attr.fields.dpl = sreg->sel & 3;
+        hvmemul_ctxt.seg_reg_dirty |=
             (1ul << x86_seg_ds) | (1ul << x86_seg_es) |
             (1ul << x86_seg_fs) | (1ul << x86_seg_gs);
     }
 
-    hvm_emulate_writeback(&rm_ctxt.hvm);
+    hvm_emulate_writeback(&hvmemul_ctxt);
 
     /* Re-instate VM_ENTRY_INTR_INFO if we did not discharge it. */
     if ( intr_info & INTR_INFO_VALID_MASK )
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Feb 26 10:12:04 2008 -0700
@@ -890,32 +890,14 @@ static void vmx_init_hypercall_page(stru
     *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
 }
 
-static enum hvm_intblk vmx_interrupt_blocked(
-    struct vcpu *v, struct hvm_intack intack)
-{
-    unsigned long intr_shadow;
-
-    /*
-     * Test EFLAGS.IF first. It is often the most likely reason for interrupt
-     * blockage, and is the cheapest to test (because no VMREAD is required).
-     */
-    if ( (intack.source != hvm_intsrc_nmi) &&
-         !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
-        return hvm_intblk_rflags_ie;
-
-    intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
-
-    if ( intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
-        return hvm_intblk_shadow;
-
-    if ( intack.source == hvm_intsrc_nmi )
-        return ((intr_shadow & VMX_INTR_SHADOW_NMI) ?
-                hvm_intblk_nmi_iret : hvm_intblk_none);
-
-    ASSERT((intack.source == hvm_intsrc_pic) ||
-           (intack.source == hvm_intsrc_lapic));
-
-    return hvm_intblk_none;
+static unsigned int vmx_get_interrupt_shadow(struct vcpu *v)
+{
+    return __vmread(GUEST_INTERRUPTIBILITY_INFO);
+}
+
+static void vmx_set_interrupt_shadow(struct vcpu *v, unsigned int intr_shadow)
+{
+    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
 }
 
 static void vmx_update_host_cr3(struct vcpu *v)
@@ -1038,7 +1020,8 @@ static struct hvm_function_table vmx_fun
     .vcpu_destroy         = vmx_vcpu_destroy,
     .save_cpu_ctxt        = vmx_save_vmcs_ctxt,
     .load_cpu_ctxt        = vmx_load_vmcs_ctxt,
-    .interrupt_blocked    = vmx_interrupt_blocked,
+    .get_interrupt_shadow = vmx_get_interrupt_shadow,
+    .set_interrupt_shadow = vmx_set_interrupt_shadow,
     .guest_x86_mode       = vmx_guest_x86_mode,
     .get_segment_register = vmx_get_segment_register,
     .set_segment_register = vmx_set_segment_register,
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/x86_32/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_32/exits.S       Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S       Tue Feb 26 10:12:04 2008 -0700
@@ -89,7 +89,7 @@ ENTRY(vmx_asm_vmexit_handler)
 
         ALIGN
 vmx_process_softirqs:
-        sti       
+        sti
         call do_softirq
         jmp vmx_asm_do_vmentry
 
@@ -104,6 +104,10 @@ ENTRY(vmx_asm_do_vmentry)
         jnz  vmx_process_softirqs
 
         call vmx_intr_assist
+
+        testb $0xff,VCPU_vmx_emul(%ebx)
+        jnz  vmx_goto_realmode
+
         movl VCPU_hvm_guest_cr2(%ebx),%eax
         movl %eax,%cr2
         call vmx_trace_vmentry
@@ -114,9 +118,6 @@ ENTRY(vmx_asm_do_vmentry)
         VMWRITE(UREGS_esp)
         movl $GUEST_RFLAGS,%eax
         VMWRITE(UREGS_eflags)
-
-        testb $0xff,VCPU_vmx_emul(%ebx)
-        jnz  vmx_goto_realmode
 
         cmpb $0,VCPU_vmx_launched(%ebx)
         je   vmx_launch
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/x86_64/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_64/exits.S       Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S       Tue Feb 26 10:12:04 2008 -0700
@@ -105,7 +105,7 @@ ENTRY(vmx_asm_vmexit_handler)
 
         ALIGN
 vmx_process_softirqs:
-        sti       
+        sti
         call do_softirq
         jmp vmx_asm_do_vmentry
 
@@ -121,6 +121,10 @@ ENTRY(vmx_asm_do_vmentry)
         jnz   vmx_process_softirqs
 
         call vmx_intr_assist
+
+        testb $0xff,VCPU_vmx_emul(%rbx)
+        jnz  vmx_goto_realmode
+
         movq VCPU_hvm_guest_cr2(%rbx),%rax
         movq %rax,%cr2
         call vmx_trace_vmentry
@@ -133,9 +137,6 @@ ENTRY(vmx_asm_do_vmentry)
         VMWRITE(UREGS_rsp)
         movl $GUEST_RFLAGS,%eax
         VMWRITE(UREGS_eflags)
-
-        testb $0xff,VCPU_vmx_emul(%rbx)
-        jnz  vmx_goto_realmode
 
         cmpb $0,VCPU_vmx_launched(%rbx)
         je   vmx_launch
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c    Tue Feb 26 10:12:04 2008 -0700
@@ -761,7 +761,7 @@ _sh_propagate(struct vcpu *v,
             sflags |= get_pat_flags(v,
                                     gflags,
                                     gfn_to_paddr(target_gfn),
-                                    mfn_x(target_mfn) << PAGE_SHIFT);
+                                    ((paddr_t)mfn_x(target_mfn)) << 
PAGE_SHIFT);
     }
 
     // Set the A&D bits for higher level shadows.
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c  Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/oprofile/xenoprof.c  Tue Feb 26 10:12:04 2008 -0700
@@ -11,6 +11,9 @@
 #include <xen/guest_access.h>
 #include <xen/sched.h>
 #include <public/xenoprof.h>
+#ifdef CONFIG_COMPAT
+#include <compat/xenoprof.h>
+#endif
 #include <asm/hvm/support.h>
 
 #include "op_counter.h"
@@ -35,6 +38,28 @@ int xenoprof_arch_counter(XEN_GUEST_HAND
     return 0;
 }
 
+#ifdef CONFIG_COMPAT
+int compat_oprof_arch_counter(XEN_GUEST_HANDLE(void) arg)
+{
+    struct compat_oprof_counter counter;
+
+    if ( copy_from_guest(&counter, arg, 1) )
+        return -EFAULT;
+
+    if ( counter.ind > OP_MAX_COUNTER )
+        return -E2BIG;
+
+    counter_config[counter.ind].count     = counter.count;
+    counter_config[counter.ind].enabled   = counter.enabled;
+    counter_config[counter.ind].event     = counter.event;
+    counter_config[counter.ind].kernel    = counter.kernel;
+    counter_config[counter.ind].user      = counter.user;
+    counter_config[counter.ind].unit_mask = counter.unit_mask;
+
+    return 0;
+}
+#endif
+
 int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs)
 {
     if ( !guest_mode(regs) )
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/arch/x86/x86_emulate.c        Tue Feb 26 10:12:04 2008 -0700
@@ -482,7 +482,7 @@ do{ asm volatile (                      
    if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
    _regs.eip += (_size); /* real hardware doesn't truncate */           \
    generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15,   \
-                         EXC_GP);                                       \
+                         EXC_GP, 0);                                    \
    rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \
    if ( rc ) goto done;                                                 \
    _x;                                                                  \
@@ -505,12 +505,12 @@ do {                                    
     if ( rc ) goto done;                                \
 } while (0)
 
-#define generate_exception_if(p, e)                                      \
-({  if ( (p) ) {                                                         \
-        fail_if(ops->inject_hw_exception == NULL);                       \
-        rc = ops->inject_hw_exception(e, 0, ctxt) ? : X86EMUL_EXCEPTION; \
-        goto done;                                                       \
-    }                                                                    \
+#define generate_exception_if(p, e, ec)                                   \
+({  if ( (p) ) {                                                          \
+        fail_if(ops->inject_hw_exception == NULL);                        \
+        rc = ops->inject_hw_exception(e, ec, ctxt) ? : X86EMUL_EXCEPTION; \
+        goto done;                                                        \
+    }                                                                     \
 })
 
 /*
@@ -1023,6 +1023,8 @@ x86_emulate(
     ea.mem.seg = x86_seg_ds;
     ea.mem.off = 0;
 
+    ctxt->retire.byte = 0;
+
     op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8;
     if ( op_bytes == 8 )
     {
@@ -1105,7 +1107,7 @@ x86_emulate(
     }
 
     /* Lock prefix is allowed only on RMW instructions. */
-    generate_exception_if((d & Mov) && lock_prefix, EXC_GP);
+    generate_exception_if((d & Mov) && lock_prefix, EXC_GP, 0);
 
     /* ModRM and SIB bytes. */
     if ( d & ModRM )
@@ -1393,7 +1395,7 @@ x86_emulate(
     }
 
     /* LOCK prefix allowed only on instructions with memory destination. */
-    generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP);
+    generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP, 0);
 
     if ( twobyte )
         goto twobyte_insn;
@@ -1459,14 +1461,15 @@ x86_emulate(
     case 0x62: /* bound */ {
         unsigned long src_val2;
         int lb, ub, idx;
-        generate_exception_if(mode_64bit() || (src.type != OP_MEM), EXC_UD);
+        generate_exception_if(mode_64bit() || (src.type != OP_MEM),
+                              EXC_UD, -1);
         if ( (rc = ops->read(src.mem.seg, src.mem.off + op_bytes,
                              &src_val2, op_bytes, ctxt)) )
             goto done;
         ub  = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2;
         lb  = (op_bytes == 2) ? (int16_t)src.val  : (int32_t)src.val;
         idx = (op_bytes == 2) ? (int16_t)dst.val  : (int32_t)dst.val;
-        generate_exception_if((idx < lb) || (idx > ub), EXC_BR);
+        generate_exception_if((idx < lb) || (idx > ub), EXC_BR, -1);
         dst.type = OP_NONE;
         break;
     }
@@ -1493,7 +1496,7 @@ x86_emulate(
                 dst.val  = (dst.val & ~3) | (src_val & 3);
             else
                 dst.type = OP_NONE;
-            generate_exception_if(in_realmode(ctxt, ops), EXC_UD);
+            generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1);
         }
         break;
 
@@ -1534,7 +1537,7 @@ x86_emulate(
     }
 
     case 0x82: /* Grp1 (x86/32 only) */
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
     case 0x80: case 0x81: case 0x83: /* Grp1 */
         switch ( modrm_reg & 7 )
         {
@@ -1571,7 +1574,7 @@ x86_emulate(
         break;
 
     case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
-        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
+        generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1);
     case 0x88 ... 0x8b: /* mov */
         dst.val = src.val;
         break;
@@ -1579,7 +1582,7 @@ x86_emulate(
     case 0x8c: /* mov Sreg,r/m */ {
         struct segment_register reg;
         enum x86_segment seg = decode_segment(modrm_reg);
-        generate_exception_if(seg == decode_segment_failed, EXC_UD);
+        generate_exception_if(seg == decode_segment_failed, EXC_UD, -1);
         fail_if(ops->read_segment == NULL);
         if ( (rc = ops->read_segment(seg, &reg, ctxt)) != 0 )
             goto done;
@@ -1591,9 +1594,11 @@ x86_emulate(
 
     case 0x8e: /* mov r/m,Sreg */ {
         enum x86_segment seg = decode_segment(modrm_reg);
-        generate_exception_if(seg == decode_segment_failed, EXC_UD);
+        generate_exception_if(seg == decode_segment_failed, EXC_UD, -1);
         if ( (rc = load_seg(seg, (uint16_t)src.val, ctxt, ops)) != 0 )
             goto done;
+        if ( seg == x86_seg_ss )
+            ctxt->retire.flags.mov_ss = 1;
         dst.type = OP_NONE;
         break;
     }
@@ -1603,7 +1608,7 @@ x86_emulate(
         break;
 
     case 0x8f: /* pop (sole member of Grp1a) */
-        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
+        generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1);
         /* 64-bit mode: POP defaults to a 64-bit operand. */
         if ( mode_64bit() && (dst.bytes == 4) )
             dst.bytes = 8;
@@ -1659,7 +1664,7 @@ x86_emulate(
         unsigned long sel;
         dst.val = x86_seg_es;
     les: /* dst.val identifies the segment */
-        generate_exception_if(src.type != OP_MEM, EXC_UD);
+        generate_exception_if(src.type != OP_MEM, EXC_UD, -1);
         if ( (rc = ops->read(src.mem.seg, src.mem.off + src.bytes,
                              &sel, 2, ctxt)) != 0 )
             goto done;
@@ -1797,7 +1802,7 @@ x86_emulate(
                 v    = (uint8_t)src.val;
                 generate_exception_if(
                     div_dbl(u, v) || ((uint8_t)u[0] != (uint16_t)u[0]),
-                    EXC_DE);
+                    EXC_DE, -1);
                 dst.val = (uint8_t)u[0];
                 ((uint8_t *)&_regs.eax)[1] = u[1];
                 break;
@@ -1807,7 +1812,7 @@ x86_emulate(
                 v    = (uint16_t)src.val;
                 generate_exception_if(
                     div_dbl(u, v) || ((uint16_t)u[0] != (uint32_t)u[0]),
-                    EXC_DE);
+                    EXC_DE, -1);
                 dst.val = (uint16_t)u[0];
                 *(uint16_t *)&_regs.edx = u[1];
                 break;
@@ -1818,7 +1823,7 @@ x86_emulate(
                 v    = (uint32_t)src.val;
                 generate_exception_if(
                     div_dbl(u, v) || ((uint32_t)u[0] != u[0]),
-                    EXC_DE);
+                    EXC_DE, -1);
                 dst.val   = (uint32_t)u[0];
                 _regs.edx = (uint32_t)u[1];
                 break;
@@ -1827,7 +1832,7 @@ x86_emulate(
                 u[0] = _regs.eax;
                 u[1] = _regs.edx;
                 v    = src.val;
-                generate_exception_if(div_dbl(u, v), EXC_DE);
+                generate_exception_if(div_dbl(u, v), EXC_DE, -1);
                 dst.val   = u[0];
                 _regs.edx = u[1];
                 break;
@@ -1847,7 +1852,7 @@ x86_emulate(
                 v    = (int8_t)src.val;
                 generate_exception_if(
                     idiv_dbl(u, v) || ((int8_t)u[0] != (int16_t)u[0]),
-                    EXC_DE);
+                    EXC_DE, -1);
                 dst.val = (int8_t)u[0];
                 ((int8_t *)&_regs.eax)[1] = u[1];
                 break;
@@ -1857,7 +1862,7 @@ x86_emulate(
                 v    = (int16_t)src.val;
                 generate_exception_if(
                     idiv_dbl(u, v) || ((int16_t)u[0] != (int32_t)u[0]),
-                    EXC_DE);
+                    EXC_DE, -1);
                 dst.val = (int16_t)u[0];
                 *(int16_t *)&_regs.edx = u[1];
                 break;
@@ -1868,7 +1873,7 @@ x86_emulate(
                 v    = (int32_t)src.val;
                 generate_exception_if(
                     idiv_dbl(u, v) || ((int32_t)u[0] != u[0]),
-                    EXC_DE);
+                    EXC_DE, -1);
                 dst.val   = (int32_t)u[0];
                 _regs.edx = (uint32_t)u[1];
                 break;
@@ -1877,7 +1882,7 @@ x86_emulate(
                 u[0] = _regs.eax;
                 u[1] = _regs.edx;
                 v    = src.val;
-                generate_exception_if(idiv_dbl(u, v), EXC_DE);
+                generate_exception_if(idiv_dbl(u, v), EXC_DE, -1);
                 dst.val   = u[0];
                 _regs.edx = u[1];
                 break;
@@ -1890,7 +1895,7 @@ x86_emulate(
         break;
 
     case 0xfe: /* Grp4 */
-        generate_exception_if((modrm_reg & 7) >= 2, EXC_UD);
+        generate_exception_if((modrm_reg & 7) >= 2, EXC_UD, -1);
     case 0xff: /* Grp5 */
         switch ( modrm_reg & 7 )
         {
@@ -1921,7 +1926,7 @@ x86_emulate(
         case 5: /* jmp (far, absolute indirect) */ {
             unsigned long sel;
 
-            generate_exception_if(dst.type != OP_MEM, EXC_UD);
+            generate_exception_if(dst.type != OP_MEM, EXC_UD, -1);
 
             if ( (rc = ops->read(dst.mem.seg, dst.mem.off+dst.bytes,
                                  &sel, 2, ctxt)) )
@@ -1963,7 +1968,7 @@ x86_emulate(
             dst.type = OP_NONE;
             break;
         case 7:
-            generate_exception_if(1, EXC_UD);
+            generate_exception_if(1, EXC_UD, -1);
         default:
             goto cannot_emulate;
         }
@@ -2003,11 +2008,9 @@ x86_emulate(
     /* Commit shadow register state. */
     _regs.eflags &= ~EFLG_RF;
     *ctxt->regs = _regs;
-
-    if ( (_regs.eflags & EFLG_TF) &&
-         (rc == X86EMUL_OKAY) &&
+    if ( (_regs.eflags & EFLG_TF) && (rc == X86EMUL_OKAY) &&
          (ops->inject_hw_exception != NULL) )
-        rc = ops->inject_hw_exception(EXC_DB, 0, ctxt) ? : X86EMUL_EXCEPTION;
+        rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION;
 
  done:
     return rc;
@@ -2022,7 +2025,7 @@ x86_emulate(
     generate_exception_if(lock_prefix &&
                           ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */
                           (b != 0xc7),                  /* CMPXCHG{8,16}B */
-                          EXC_GP);
+                          EXC_GP, 0);
 
     if ( twobyte )
         goto twobyte_special_insn;
@@ -2069,6 +2072,7 @@ x86_emulate(
 
     case 0x17: /* pop %%ss */
         src.val = x86_seg_ss;
+        ctxt->retire.flags.mov_ss = 1;
         goto pop_seg;
 
     case 0x1e: /* push %%ds */
@@ -2082,7 +2086,7 @@ x86_emulate(
     case 0x27: /* daa */ {
         uint8_t al = _regs.eax;
         unsigned long eflags = _regs.eflags;
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         _regs.eflags &= ~(EFLG_CF|EFLG_AF);
         if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
         {
@@ -2104,7 +2108,7 @@ x86_emulate(
     case 0x2f: /* das */ {
         uint8_t al = _regs.eax;
         unsigned long eflags = _regs.eflags;
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         _regs.eflags &= ~(EFLG_CF|EFLG_AF);
         if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
         {
@@ -2127,7 +2131,7 @@ x86_emulate(
 
     case 0x37: /* aaa */
     case 0x3f: /* aas */
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         _regs.eflags &= ~EFLG_CF;
         if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) )
         {
@@ -2171,7 +2175,7 @@ x86_emulate(
         unsigned long regs[] = {
             _regs.eax, _regs.ecx, _regs.edx, _regs.ebx,
             _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         for ( i = 0; i < 8; i++ )
             if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
                                   regs[i], op_bytes, ctxt)) != 0 )
@@ -2186,7 +2190,7 @@ x86_emulate(
             (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp,
             (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx,
             (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         for ( i = 0; i < 8; i++ )
         {
             if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
@@ -2224,7 +2228,7 @@ x86_emulate(
 
     case 0x6c ... 0x6d: /* ins %dx,%es:%edi */ {
         unsigned long nr_reps = get_rep_prefix();
-        generate_exception_if(!mode_iopl(), EXC_GP);
+        generate_exception_if(!mode_iopl(), EXC_GP, 0);
         dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
         dst.mem.seg = x86_seg_es;
         dst.mem.off = truncate_ea(_regs.edi);
@@ -2254,7 +2258,7 @@ x86_emulate(
 
     case 0x6e ... 0x6f: /* outs %esi,%dx */ {
         unsigned long nr_reps = get_rep_prefix();
-        generate_exception_if(!mode_iopl(), EXC_GP);
+        generate_exception_if(!mode_iopl(), EXC_GP, 0);
         dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
         if ( (nr_reps > 1) && (ops->rep_outs != NULL) &&
              ((rc = ops->rep_outs(ea.mem.seg, truncate_ea(_regs.esi),
@@ -2333,7 +2337,7 @@ x86_emulate(
         uint32_t eip;
 
         fail_if(ops->read_segment == NULL);
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
 
         eip = insn_fetch_bytes(op_bytes);
         sel = insn_fetch_type(uint16_t);
@@ -2359,7 +2363,6 @@ x86_emulate(
         uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM;
         if ( !mode_iopl() )
             mask |= EFLG_IOPL;
-        fail_if(ops->write_rflags == NULL);
         /* 64-bit mode: POP defaults to a 64-bit operand. */
         if ( mode_64bit() && (op_bytes == 4) )
             op_bytes = 8;
@@ -2371,8 +2374,6 @@ x86_emulate(
         dst.val &= 0x257fd5;
         _regs.eflags &= mask;
         _regs.eflags |= (uint32_t)(dst.val & ~mask) | 0x02;
-        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
-            goto done;
         break;
     }
 
@@ -2597,7 +2598,7 @@ x86_emulate(
         goto done;
 
     case 0xce: /* into */
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         if ( !(_regs.eflags & EFLG_OF) )
             break;
         src.val = EXC_OF;
@@ -2609,7 +2610,6 @@ x86_emulate(
         if ( !mode_iopl() )
             mask |= EFLG_IOPL;
         fail_if(!in_realmode(ctxt, ops));
-        fail_if(ops->write_rflags == NULL);
         if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
                              &eip, op_bytes, ctxt)) ||
              (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
@@ -2622,8 +2622,6 @@ x86_emulate(
         eflags &= 0x257fd5;
         _regs.eflags &= mask;
         _regs.eflags |= (uint32_t)(eflags & ~mask) | 0x02;
-        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
-            goto done;
         _regs.eip = eip;
         if ( (rc = load_seg(x86_seg_cs, (uint16_t)cs, ctxt, ops)) != 0 )
             goto done;
@@ -2633,8 +2631,8 @@ x86_emulate(
     case 0xd4: /* aam */ {
         unsigned int base = insn_fetch_type(uint8_t);
         uint8_t al = _regs.eax;
-        generate_exception_if(mode_64bit(), EXC_UD);
-        generate_exception_if(base == 0, EXC_DE);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
+        generate_exception_if(base == 0, EXC_DE, -1);
         *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
         _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
         _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
@@ -2646,7 +2644,7 @@ x86_emulate(
     case 0xd5: /* aad */ {
         unsigned int base = insn_fetch_type(uint8_t);
         uint16_t ax = _regs.eax;
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
         _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
         _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
@@ -2656,7 +2654,7 @@ x86_emulate(
     }
 
     case 0xd6: /* salc */
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00;
         break;
 
@@ -2673,7 +2671,7 @@ x86_emulate(
         fail_if(ops->load_fpu_ctxt == NULL);
         ops->load_fpu_ctxt(ctxt);
         fail_if((modrm_reg & 7) != 7);
-        fail_if(modrm_reg >= 0xc0);
+        fail_if(modrm >= 0xc0);
         /* fnstcw m2byte */
         ea.bytes = 2;
         dst = ea;
@@ -2692,7 +2690,7 @@ x86_emulate(
         fail_if(ops->load_fpu_ctxt == NULL);
         ops->load_fpu_ctxt(ctxt);
         fail_if((modrm_reg & 7) != 7);
-        fail_if(modrm_reg >= 0xc0);
+        fail_if(modrm >= 0xc0);
         /* fnstsw m2byte */
         ea.bytes = 2;
         dst = ea;
@@ -2743,7 +2741,7 @@ x86_emulate(
         unsigned int port = ((b < 0xe8)
                              ? insn_fetch_type(uint8_t)
                              : (uint16_t)_regs.edx);
-        generate_exception_if(!mode_iopl(), EXC_GP);
+        generate_exception_if(!mode_iopl(), EXC_GP, 0);
         op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
         if ( b & 2 )
         {
@@ -2787,7 +2785,7 @@ x86_emulate(
     case 0xea: /* jmp (far, absolute) */ {
         uint16_t sel;
         uint32_t eip;
-        generate_exception_if(mode_64bit(), EXC_UD);
+        generate_exception_if(mode_64bit(), EXC_UD, -1);
         eip = insn_fetch_bytes(op_bytes);
         sel = insn_fetch_type(uint16_t);
         if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 )
@@ -2807,9 +2805,7 @@ x86_emulate(
         goto swint;
 
     case 0xf4: /* hlt */
-        fail_if(ops->hlt == NULL);
-        if ( (rc = ops->hlt(ctxt)) != 0 )
-            goto done;
+        ctxt->retire.flags.hlt = 1;
         break;
 
     case 0xf5: /* cmc */
@@ -2825,14 +2821,17 @@ x86_emulate(
         break;
 
     case 0xfa: /* cli */
+        generate_exception_if(!mode_iopl(), EXC_GP, 0);
+        _regs.eflags &= ~EFLG_IF;
+        break;
+
     case 0xfb: /* sti */
-        generate_exception_if(!mode_iopl(), EXC_GP);
-        fail_if(ops->write_rflags == NULL);
-        _regs.eflags &= ~EFLG_IF;
-        if ( b == 0xfb ) /* sti */
+        generate_exception_if(!mode_iopl(), EXC_GP, 0);
+        if ( !(_regs.eflags & EFLG_IF) )
+        {
             _regs.eflags |= EFLG_IF;
-        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
-            goto done;
+            ctxt->retire.flags.sti = 1;
+        }
         break;
 
     case 0xfc: /* cld */
@@ -3001,7 +3000,7 @@ x86_emulate(
         case 5: goto bts;
         case 6: goto btr;
         case 7: goto btc;
-        default: generate_exception_if(1, EXC_UD);
+        default: generate_exception_if(1, EXC_UD, -1);
         }
         break;
 
@@ -3038,8 +3037,8 @@ x86_emulate(
 
         if ( modrm == 0xdf ) /* invlpga */
         {
-            generate_exception_if(in_realmode(ctxt, ops), EXC_UD);
-            generate_exception_if(!mode_ring0(), EXC_GP);
+            generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1);
+            generate_exception_if(!mode_ring0(), EXC_GP, 0);
             fail_if(ops->invlpg == NULL);
             if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax),
                                    ctxt)) )
@@ -3051,7 +3050,7 @@ x86_emulate(
         {
         case 0: /* sgdt */
         case 1: /* sidt */
-            generate_exception_if(ea.type != OP_MEM, EXC_UD);
+            generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
             fail_if(ops->read_segment == NULL);
             if ( (rc = ops->read_segment((modrm_reg & 1) ?
                                          x86_seg_idtr : x86_seg_gdtr,
@@ -3067,7 +3066,7 @@ x86_emulate(
             break;
         case 2: /* lgdt */
         case 3: /* lidt */
-            generate_exception_if(ea.type != OP_MEM, EXC_UD);
+            generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
             fail_if(ops->write_segment == NULL);
             memset(&reg, 0, sizeof(reg));
             if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0,
@@ -3108,8 +3107,8 @@ x86_emulate(
                 goto done;
             break;
         case 7: /* invlpg */
-            generate_exception_if(!mode_ring0(), EXC_GP);
-            generate_exception_if(ea.type != OP_MEM, EXC_UD);
+            generate_exception_if(!mode_ring0(), EXC_GP, 0);
+            generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
             fail_if(ops->invlpg == NULL);
             if ( (rc = ops->invlpg(ea.mem.seg, ea.mem.off, ctxt)) )
                 goto done;
@@ -3121,7 +3120,7 @@ x86_emulate(
     }
 
     case 0x06: /* clts */
-        generate_exception_if(!mode_ring0(), EXC_GP);
+        generate_exception_if(!mode_ring0(), EXC_GP, 0);
         fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL));
         if ( (rc = ops->read_cr(0, &dst.val, ctxt)) ||
              (rc = ops->write_cr(0, dst.val&~8, ctxt)) )
@@ -3130,7 +3129,7 @@ x86_emulate(
 
     case 0x08: /* invd */
     case 0x09: /* wbinvd */
-        generate_exception_if(!mode_ring0(), EXC_GP);
+        generate_exception_if(!mode_ring0(), EXC_GP, 0);
         fail_if(ops->wbinvd == NULL);
         if ( (rc = ops->wbinvd(ctxt)) != 0 )
             goto done;
@@ -3145,7 +3144,7 @@ x86_emulate(
     case 0x21: /* mov dr,reg */
     case 0x22: /* mov reg,cr */
     case 0x23: /* mov reg,dr */
-        generate_exception_if(!mode_ring0(), EXC_GP);
+        generate_exception_if(!mode_ring0(), EXC_GP, 0);
         modrm_rm  |= (rex_prefix & 1) << 3;
         modrm_reg |= lock_prefix << 3;
         if ( b & 2 )
@@ -3182,7 +3181,7 @@ x86_emulate(
 
     case 0x30: /* wrmsr */ {
         uint64_t val = ((uint64_t)_regs.edx << 32) | (uint32_t)_regs.eax;
-        generate_exception_if(!mode_ring0(), EXC_GP);
+        generate_exception_if(!mode_ring0(), EXC_GP, 0);
         fail_if(ops->write_msr == NULL);
         if ( (rc = ops->write_msr((uint32_t)_regs.ecx, val, ctxt)) != 0 )
             goto done;
@@ -3195,7 +3194,7 @@ x86_emulate(
         fail_if(ops->read_cr == NULL);
         if ( (rc = ops->read_cr(4, &cr4, ctxt)) )
             goto done;
-        generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP);
+        generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP, 0);
         fail_if(ops->read_msr == NULL);
         if ( (rc = ops->read_msr(MSR_TSC, &val, ctxt)) != 0 )
             goto done;
@@ -3206,7 +3205,7 @@ x86_emulate(
 
     case 0x32: /* rdmsr */ {
         uint64_t val;
-        generate_exception_if(!mode_ring0(), EXC_GP);
+        generate_exception_if(!mode_ring0(), EXC_GP, 0);
         fail_if(ops->read_msr == NULL);
         if ( (rc = ops->read_msr((uint32_t)_regs.ecx, &val, ctxt)) != 0 )
             goto done;
@@ -3255,8 +3254,8 @@ x86_emulate(
 #if defined(__i386__)
     {
         unsigned long old_lo, old_hi;
-        generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
-        generate_exception_if(ea.type != OP_MEM, EXC_UD);
+        generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1);
+        generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
         if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &old_lo, 4, ctxt)) ||
              (rc = ops->read(ea.mem.seg, ea.mem.off+4, &old_hi, 4, ctxt)) )
             goto done;
@@ -3283,8 +3282,8 @@ x86_emulate(
 #elif defined(__x86_64__)
     {
         unsigned long old, new;
-        generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
-        generate_exception_if(ea.type != OP_MEM, EXC_UD);
+        generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1);
+        generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
         if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 )
             goto done;
         if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/common/compat/xenoprof.c
--- a/xen/common/compat/xenoprof.c      Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/common/compat/xenoprof.c      Tue Feb 26 10:12:04 2008 -0700
@@ -14,6 +14,7 @@ CHECK_oprof_init;
 
 #define xenoprof_get_buffer compat_oprof_get_buffer
 #define xenoprof_op_get_buffer compat_oprof_op_get_buffer
+#define xenoprof_arch_counter compat_oprof_arch_counter
 
 #define xen_domid_t domid_t
 #define compat_domid_t domid_compat_t
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/common/grant_table.c  Tue Feb 26 10:12:04 2008 -0700
@@ -350,10 +350,10 @@ __gnttab_map_grant_ref(
     else
     {
         if ( unlikely(!mfn_valid(frame)) ||
-             unlikely(!((op->flags & GNTMAP_readonly) ?
-                        get_page(mfn_to_page(frame), rd) :
+             unlikely(!(gnttab_host_mapping_get_page_type(op, ld, rd) ?
                         get_page_and_type(mfn_to_page(frame), rd,
-                                          PGT_writable_page))) )
+                                          PGT_writable_page) :
+                        get_page(mfn_to_page(frame), rd))) )
         {
             if ( !rd->is_dying )
                 gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n",
@@ -367,7 +367,7 @@ __gnttab_map_grant_ref(
             rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0);
             if ( rc != GNTST_okay )
             {
-                if ( !(op->flags & GNTMAP_readonly) )
+                if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
                     put_page_type(mfn_to_page(frame));
                 put_page(mfn_to_page(frame));
                 goto undo_out;
@@ -604,7 +604,7 @@ __gnttab_unmap_common_complete(struct gn
 
         if ( !is_iomem_page(op->frame) ) 
         {
-            if ( !(op->flags & GNTMAP_readonly) )
+            if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
                 put_page_type(mfn_to_page(op->frame));
             put_page(mfn_to_page(op->frame));
         }
@@ -1662,8 +1662,9 @@ gnttab_release_mappings(
             {
                 BUG_ON(!(act->pin & GNTPIN_hstr_mask));
                 act->pin -= GNTPIN_hstr_inc;
-                if ( !is_iomem_page(act->frame) )
-                    gnttab_release_put_page(mfn_to_page(act->frame));
+                if ( gnttab_release_host_mappings &&
+                     !is_iomem_page(act->frame) )
+                    put_page(mfn_to_page(act->frame));
             }
         }
         else
@@ -1680,8 +1681,13 @@ gnttab_release_mappings(
             {
                 BUG_ON(!(act->pin & GNTPIN_hstw_mask));
                 act->pin -= GNTPIN_hstw_inc;
-                if ( !is_iomem_page(act->frame) )
-                    gnttab_release_put_page_and_type(mfn_to_page(act->frame));
+                if ( gnttab_release_host_mappings &&
+                     !is_iomem_page(act->frame) )
+                {
+                    if ( gnttab_host_mapping_get_page_type(map, d, rd) )
+                        put_page_type(mfn_to_page(act->frame));
+                    put_page(mfn_to_page(act->frame));
+                }
             }
 
             if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-ia64/grant_table.h
--- a/xen/include/asm-ia64/grant_table.h        Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/asm-ia64/grant_table.h        Tue Feb 26 10:12:04 2008 -0700
@@ -65,8 +65,10 @@ static inline void gnttab_clear_flag(uns
        clear_bit(nr, addr);
 }
 
-#define gnttab_release_put_page(page)           put_page((page))
-#define gnttab_release_put_page_and_type(page)  put_page_and_type((page))
+#define gnttab_host_mapping_get_page_type(op, ld, rd)   \
+    (!((op)->flags & GNTMAP_readonly))
+
+#define gnttab_release_host_mappings 1
 
 static inline int replace_grant_supported(void)
 {
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-powerpc/grant_table.h
--- a/xen/include/asm-powerpc/grant_table.h     Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/asm-powerpc/grant_table.h     Tue Feb 26 10:12:04 2008 -0700
@@ -76,17 +76,14 @@ static inline uint cpu_foreign_map_order
     return 34 - PAGE_SHIFT;
 }
 
-#if 0
+#define gnttab_host_mapping_get_page_type(op, ld, rd)   \
+    (!((op)->flags & GNTMAP_readonly))
+
 /*
  * without put_page()/put_page_and_type() page might be leaked.
  * with put_page()/put_page_and_type() freed page might be accessed.
  */
-#define gnttab_release_put_page(page)           put_page((page))
-#define gnttab_release_put_page_and_type(page)  put_page_and_type((page))
-#else
-#define gnttab_release_put_page(page)           do { } while (0)
-#define gnttab_release_put_page_and_type(page)  do { } while (0)
-#endif
+#define gnttab_release_host_mappings 0
 
 static inline int replace_grant_supported(void)
 {
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/grant_table.h
--- a/xen/include/asm-x86/grant_table.h Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/asm-x86/grant_table.h Tue Feb 26 10:12:04 2008 -0700
@@ -38,15 +38,13 @@ static inline void gnttab_clear_flag(uns
     clear_bit(nr, addr);
 }
 
-#define gnttab_release_put_page(page)                           \
-    do {                                                        \
-        /* Done implicitly when page tables are destroyed. */   \
-    } while (0)
+/* Foreign mappings of HHVM-guest pages do not modify the type count. */
+#define gnttab_host_mapping_get_page_type(op, ld, rd)   \
+    (!((op)->flags & GNTMAP_readonly) &&                \
+     (((ld) == (rd)) || !paging_mode_external(rd)))
 
-#define gnttab_release_put_page_and_type(page)                  \
-    do {                                                        \
-        /* Done implicitly when page tables are destroyed. */   \
-    } while (0)
+/* Done implicitly when page tables are destroyed. */
+#define gnttab_release_host_mappings 0
 
 static inline int replace_grant_supported(void)
 {
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/hvm/emulate.h
--- a/xen/include/asm-x86/hvm/emulate.h Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/asm-x86/hvm/emulate.h Tue Feb 26 10:12:04 2008 -0700
@@ -27,18 +27,12 @@ struct hvm_emulate_ctxt {
     unsigned long seg_reg_accessed;
     unsigned long seg_reg_dirty;
 
-    union {
-        struct {
-            unsigned int hlt:1;
-            unsigned int mov_ss:1;
-            unsigned int sti:1;
-            unsigned int exn_pending:1;
-        } flags;
-        unsigned int flag_word;
-    };
-
+    bool_t exn_pending;
     uint8_t exn_vector;
     uint8_t exn_insn_len;
+    int32_t exn_error_code;
+
+    uint32_t intr_shadow;
 };
 
 int hvm_emulate_one(
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/asm-x86/hvm/hvm.h     Tue Feb 26 10:12:04 2008 -0700
@@ -49,6 +49,12 @@ enum hvm_intblk {
     hvm_intblk_nmi_iret   /* NMI blocked until IRET */
 };
 
+/* These happen to be the same as the VMX interrupt shadow definitions. */
+#define HVM_INTR_SHADOW_STI    0x00000001
+#define HVM_INTR_SHADOW_MOV_SS 0x00000002
+#define HVM_INTR_SHADOW_SMI    0x00000004
+#define HVM_INTR_SHADOW_NMI    0x00000008
+
 /*
  * The hardware virtual machine (HVM) interface abstracts away from the
  * x86/x86_64 CPU virtualization assist specifics. Currently this interface
@@ -72,14 +78,9 @@ struct hvm_function_table {
     void (*save_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
     int (*load_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
 
-    /*
-     * Examine specifics of the guest state:
-     * 1) determine whether interrupts are enabled or not
-     * 2) determine the mode the guest is running in
-     * 3) return the current guest segment descriptor base
-     * 4) return the current guest segment descriptor
-     */
-    enum hvm_intblk (*interrupt_blocked)(struct vcpu *v, struct hvm_intack);
+    /* Examine specifics of the guest state. */
+    unsigned int (*get_interrupt_shadow)(struct vcpu *v);
+    void (*set_interrupt_shadow)(struct vcpu *v, unsigned int intr_shadow);
     int (*guest_x86_mode)(struct vcpu *v);
     void (*get_segment_register)(struct vcpu *v, enum x86_segment seg,
                                  struct segment_register *reg);
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/x86_emulate.h
--- a/xen/include/asm-x86/x86_emulate.h Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/asm-x86/x86_emulate.h Tue Feb 26 10:12:04 2008 -0700
@@ -318,11 +318,6 @@ struct x86_emulate_ops
         uint64_t val,
         struct x86_emulate_ctxt *ctxt);
 
-    /* write_rflags: Modify privileged bits in RFLAGS. */
-    int (*write_rflags)(
-        unsigned long val,
-        struct x86_emulate_ctxt *ctxt);
-
     /* wbinvd: Write-back and invalidate cache contents. */
     int (*wbinvd)(
         struct x86_emulate_ctxt *ctxt);
@@ -335,14 +330,10 @@ struct x86_emulate_ops
         unsigned int *edx,
         struct x86_emulate_ctxt *ctxt);
 
-    /* hlt: Emulate HLT. */
-    int (*hlt)(
-        struct x86_emulate_ctxt *ctxt);
-
     /* inject_hw_exception */
     int (*inject_hw_exception)(
         uint8_t vector,
-        uint16_t error_code,
+        int32_t error_code,
         struct x86_emulate_ctxt *ctxt);
 
     /* inject_sw_interrupt */
@@ -376,7 +367,17 @@ struct x86_emulate_ctxt
     unsigned int sp_size;
 
     /* Set this if writes may have side effects. */
-    int force_writeback;
+    uint8_t force_writeback;
+
+    /* Retirement state, set by the emulator (valid only on X86EMUL_OKAY). */
+    union {
+        struct {
+            uint8_t hlt:1;          /* Instruction HLTed. */
+            uint8_t mov_ss:1;       /* Instruction sets MOV-SS irq shadow. */
+            uint8_t sti:1;          /* Instruction sets STI irq shadow. */
+        } flags;
+        uint8_t byte;
+    } retire;
 };
 
 /*
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/xenoprof.h
--- a/xen/include/asm-x86/xenoprof.h    Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/asm-x86/xenoprof.h    Tue Feb 26 10:12:04 2008 -0700
@@ -41,6 +41,7 @@ int xenoprof_arch_init(int *num_events, 
 #define xenoprof_arch_release_counters()        nmi_release_counters()
 
 int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
+int compat_oprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
 
 struct vcpu;
 struct cpu_user_regs;
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/public/io/protocols.h
--- a/xen/include/public/io/protocols.h Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/public/io/protocols.h Tue Feb 26 10:12:04 2008 -0700
@@ -1,3 +1,25 @@
+/******************************************************************************
+ * protocols.h
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #ifndef __XEN_PROTOCOLS_H__
 #define __XEN_PROTOCOLS_H__
 
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/public/kexec.h
--- a/xen/include/public/kexec.h        Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/public/kexec.h        Tue Feb 26 10:12:04 2008 -0700
@@ -1,5 +1,23 @@
 /******************************************************************************
  * kexec.h - Public portion
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  * 
  * Xen port written by:
  * - Simon 'Horms' Horman <horms@xxxxxxxxxxxx>
diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/public/libelf.h
--- a/xen/include/public/libelf.h       Mon Feb 25 06:29:01 2008 -0700
+++ b/xen/include/public/libelf.h       Tue Feb 26 10:12:04 2008 -0700
@@ -1,3 +1,25 @@
+/******************************************************************************
+ * libelf.h
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #ifndef __XC_LIBELF__
 #define __XC_LIBELF__ 1
 

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.