ia64/xen-unstable

changeset 17132:f97a0b6152c3

merge with xen-unstable.hg
author Alex Williamson <alex.williamson@hp.com>
date Tue Feb 26 10:12:04 2008 -0700 (2008-02-26)
parents 7e8334e651c4 2a8eaba24bf0
children daf39fc8038a
files tools/ioemu/Makefile.target
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/extras/mini-os/fbfront.c	Tue Feb 26 10:12:04 2008 -0700
     1.3 @@ -0,0 +1,468 @@
     1.4 +/*
     1.5 + * Frame Buffer + Keyboard driver for Mini-OS. 
     1.6 + * Samuel Thibault <samuel.thibault@eu.citrix.com>, 2008
     1.7 + * Based on blkfront.c.
     1.8 + */
     1.9 +
    1.10 +#include <os.h>
    1.11 +#include <xenbus.h>
    1.12 +#include <events.h>
    1.13 +#include <xen/io/kbdif.h>
    1.14 +#include <xen/io/fbif.h>
    1.15 +#include <xen/io/protocols.h>
    1.16 +#include <gnttab.h>
    1.17 +#include <xmalloc.h>
    1.18 +#include <fbfront.h>
    1.19 +#include <lib.h>
    1.20 +
    1.21 +DECLARE_WAIT_QUEUE_HEAD(kbdfront_queue);
    1.22 +
    1.23 +
    1.24 +
    1.25 +
    1.26 +
    1.27 +
    1.28 +struct kbdfront_dev {
    1.29 +    domid_t dom;
    1.30 +
    1.31 +    struct xenkbd_page *page;
    1.32 +    evtchn_port_t evtchn, local_port;
    1.33 +
    1.34 +    char *nodename;
    1.35 +    char *backend;
    1.36 +
    1.37 +    char *data;
    1.38 +    int width;
    1.39 +    int height;
    1.40 +    int depth;
    1.41 +    int line_length;
    1.42 +    int mem_length;
    1.43 +
    1.44 +#ifdef HAVE_LIBC
    1.45 +    int fd;
    1.46 +#endif
    1.47 +};
    1.48 +
    1.49 +void kbdfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
    1.50 +{
    1.51 +#ifdef HAVE_LIBC
    1.52 +    struct kbdfront_dev *dev = data;
    1.53 +    int fd = dev->fd;
    1.54 +
    1.55 +    files[fd].read = 1;
    1.56 +#endif
    1.57 +    wake_up(&kbdfront_queue);
    1.58 +}
    1.59 +
    1.60 +struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer)
    1.61 +{
    1.62 +    xenbus_transaction_t xbt;
    1.63 +    char* err;
    1.64 +    char* message=NULL;
    1.65 +    struct xenkbd_page *s;
    1.66 +    int retry=0;
    1.67 +    char* msg;
    1.68 +
    1.69 +    struct kbdfront_dev *dev;
    1.70 +
    1.71 +    if (!nodename)
    1.72 +        nodename = "device/vkbd/0";
    1.73 +
    1.74 +    char path[strlen(nodename) + 1 + 10 + 1];
    1.75 +
    1.76 +    printk("******************* KBDFRONT for %s **********\n\n\n", nodename);
    1.77 +
    1.78 +    dev = malloc(sizeof(*dev));
    1.79 +    dev->nodename = strdup(nodename);
    1.80 +
    1.81 +    evtchn_alloc_unbound_t op;
    1.82 +    op.dom = DOMID_SELF;
    1.83 +    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    1.84 +    dev->dom = op.remote_dom = xenbus_read_integer(path); 
    1.85 +    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
    1.86 +    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
    1.87 +    dev->local_port = bind_evtchn(op.port, kbdfront_handler, dev);
    1.88 +    dev->evtchn=op.port;
    1.89 +
    1.90 +    dev->page = s = (struct xenkbd_page*) alloc_page();
    1.91 +    memset(s,0,PAGE_SIZE);
    1.92 +
    1.93 +    s->in_cons = s->in_prod = 0;
    1.94 +    s->out_cons = s->out_prod = 0;
    1.95 +
    1.96 +    // FIXME: proper frees on failures
    1.97 +again:
    1.98 +    err = xenbus_transaction_start(&xbt);
    1.99 +    if (err) {
   1.100 +        printk("starting transaction\n");
   1.101 +    }
   1.102 +
   1.103 +    err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s));
   1.104 +    if (err) {
   1.105 +        message = "writing page-ref";
   1.106 +        goto abort_transaction;
   1.107 +    }
   1.108 +    err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
   1.109 +    if (err) {
   1.110 +        message = "writing event-channel";
   1.111 +        goto abort_transaction;
   1.112 +    }
   1.113 +    if (abs_pointer) {
   1.114 +        err = xenbus_printf(xbt, nodename, "request-abs-pointer", "1");
   1.115 +        if (err) {
   1.116 +            message = "writing event-channel";
   1.117 +            goto abort_transaction;
   1.118 +        }
   1.119 +    }
   1.120 +
   1.121 +    err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */
   1.122 +    if (err)
   1.123 +        printk("error writing initialized: %s\n", err);
   1.124 +
   1.125 +
   1.126 +    err = xenbus_transaction_end(xbt, 0, &retry);
   1.127 +    if (retry) {
   1.128 +            goto again;
   1.129 +        printk("completing transaction\n");
   1.130 +    }
   1.131 +
   1.132 +    goto done;
   1.133 +
   1.134 +abort_transaction:
   1.135 +    xenbus_transaction_end(xbt, 1, &retry);
   1.136 +    return NULL;
   1.137 +
   1.138 +done:
   1.139 +
   1.140 +    snprintf(path, sizeof(path), "%s/backend", nodename);
   1.141 +    msg = xenbus_read(XBT_NIL, path, &dev->backend);
   1.142 +    if (msg) {
   1.143 +        printk("Error %s when reading the backend path %s\n", msg, path);
   1.144 +        return NULL;
   1.145 +    }
   1.146 +
   1.147 +    printk("backend at %s\n", dev->backend);
   1.148 +
   1.149 +    {
   1.150 +        char path[strlen(dev->backend) + 1 + 6 + 1];
   1.151 +
   1.152 +        snprintf(path, sizeof(path), "%s/state", dev->backend);
   1.153 +
   1.154 +        xenbus_watch_path(XBT_NIL, path);
   1.155 +
   1.156 +        xenbus_wait_for_value(path,"4");
   1.157 +
   1.158 +        xenbus_unwatch_path(XBT_NIL, path);
   1.159 +
   1.160 +        printk("%s connected\n", dev->backend);
   1.161 +
   1.162 +        err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */
   1.163 +    }
   1.164 +
   1.165 +    printk("************************** KBDFRONT\n");
   1.166 +
   1.167 +    return dev;
   1.168 +}
   1.169 +
   1.170 +int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n)
   1.171 +{
   1.172 +    struct xenkbd_page *page = dev->page;
   1.173 +    uint32_t prod, cons;
   1.174 +    int i;
   1.175 +
   1.176 +#ifdef HAVE_LIBC
   1.177 +    files[dev->fd].read = 0;
   1.178 +    mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
   1.179 +#endif
   1.180 +
   1.181 +    prod = page->in_prod;
   1.182 +
   1.183 +    if (prod == page->in_cons)
   1.184 +        return 0;
   1.185 +
   1.186 +    rmb();      /* ensure we see ring contents up to prod */
   1.187 +
   1.188 +    for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++)
   1.189 +        memcpy(buf + i, &XENKBD_IN_RING_REF(page, cons), sizeof(*buf));
   1.190 +
   1.191 +    mb();       /* ensure we got ring contents */
   1.192 +    page->in_cons = cons;
   1.193 +    notify_remote_via_evtchn(dev->evtchn);
   1.194 +
   1.195 +#ifdef HAVE_LIBC
   1.196 +    if (cons != prod)
   1.197 +        /* still some events to read */
   1.198 +        files[dev->fd].read = 1;
   1.199 +#endif
   1.200 +
   1.201 +    return i;
   1.202 +}
   1.203 +
   1.204 +
   1.205 +void shutdown_kbdfront(struct kbdfront_dev *dev)
   1.206 +{
   1.207 +    char* err;
   1.208 +    char *nodename = dev->nodename;
   1.209 +
   1.210 +    char path[strlen(dev->backend) + 1 + 5 + 1];
   1.211 +
   1.212 +    printk("close kbd: backend at %s\n",dev->backend);
   1.213 +
   1.214 +    snprintf(path, sizeof(path), "%s/state", dev->backend);
   1.215 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
   1.216 +    xenbus_wait_for_value(path,"5");
   1.217 +
   1.218 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
   1.219 +    xenbus_wait_for_value(path,"6");
   1.220 +
   1.221 +    unbind_evtchn(dev->local_port);
   1.222 +
   1.223 +    free_pages(dev->page,0);
   1.224 +    free(nodename);
   1.225 +    free(dev->backend);
   1.226 +    free(dev);
   1.227 +}
   1.228 +
   1.229 +#ifdef HAVE_LIBC
   1.230 +int kbdfront_open(struct kbdfront_dev *dev)
   1.231 +{
   1.232 +    dev->fd = alloc_fd(FTYPE_KBD);
   1.233 +    printk("kbd_open(%s) -> %d\n", dev->nodename, dev->fd);
   1.234 +    files[dev->fd].kbd.dev = dev;
   1.235 +    return dev->fd;
   1.236 +}
   1.237 +#endif
   1.238 +
   1.239 +
   1.240 +
   1.241 +
   1.242 +
   1.243 +DECLARE_WAIT_QUEUE_HEAD(fbfront_queue);
   1.244 +
   1.245 +
   1.246 +
   1.247 +
   1.248 +
   1.249 +
   1.250 +struct fbfront_dev {
   1.251 +    domid_t dom;
   1.252 +
   1.253 +    struct xenfb_page *page;
   1.254 +    evtchn_port_t evtchn, local_port;
   1.255 +
   1.256 +    char *nodename;
   1.257 +    char *backend;
   1.258 +
   1.259 +    char *data;
   1.260 +    int width;
   1.261 +    int height;
   1.262 +    int depth;
   1.263 +    int line_length;
   1.264 +    int mem_length;
   1.265 +};
   1.266 +
   1.267 +void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
   1.268 +{
   1.269 +    wake_up(&fbfront_queue);
   1.270 +}
   1.271 +
   1.272 +struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int height, int depth, int line_length, int mem_length)
   1.273 +{
   1.274 +    xenbus_transaction_t xbt;
   1.275 +    char* err;
   1.276 +    char* message=NULL;
   1.277 +    struct xenfb_page *s;
   1.278 +    int retry=0;
   1.279 +    char* msg;
   1.280 +    int i, j;
   1.281 +    struct fbfront_dev *dev;
   1.282 +
   1.283 +    if (!nodename)
   1.284 +        nodename = "device/vfb/0";
   1.285 +
   1.286 +    char path[strlen(nodename) + 1 + 10 + 1];
   1.287 +
   1.288 +    printk("******************* FBFRONT for %s **********\n\n\n", nodename);
   1.289 +
   1.290 +    dev = malloc(sizeof(*dev));
   1.291 +    dev->nodename = strdup(nodename);
   1.292 +
   1.293 +    evtchn_alloc_unbound_t op;
   1.294 +    op.dom = DOMID_SELF;
   1.295 +    snprintf(path, sizeof(path), "%s/backend-id", nodename);
   1.296 +    dev->dom = op.remote_dom = xenbus_read_integer(path); 
   1.297 +    HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
   1.298 +    clear_evtchn(op.port);        /* Without, handler gets invoked now! */
   1.299 +    dev->local_port = bind_evtchn(op.port, fbfront_handler, dev);
   1.300 +    dev->evtchn=op.port;
   1.301 +
   1.302 +    dev->page = s = (struct xenfb_page*) alloc_page();
   1.303 +    memset(s,0,PAGE_SIZE);
   1.304 +
   1.305 +    s->in_cons = s->in_prod = 0;
   1.306 +    s->out_cons = s->out_prod = 0;
   1.307 +    dev->width = s->width = width;
   1.308 +    dev->height = s->height = height;
   1.309 +    dev->depth = s->depth = depth;
   1.310 +    dev->line_length = s->line_length = line_length;
   1.311 +    dev->mem_length = s->mem_length = mem_length;
   1.312 +
   1.313 +    ASSERT(!((unsigned long)data & ~PAGE_MASK));
   1.314 +    dev->data = data;
   1.315 +
   1.316 +    const int max_pd = sizeof(s->pd) / sizeof(s->pd[0]);
   1.317 +    unsigned long mapped = 0;
   1.318 +
   1.319 +    for (i = 0; mapped < mem_length && i < max_pd; i++) {
   1.320 +        unsigned long *pd = (unsigned long *) alloc_page();
   1.321 +        for (j = 0; mapped < mem_length && j < PAGE_SIZE / sizeof(unsigned long); j++) {
   1.322 +            pd[j] = virt_to_mfn((unsigned long) data + mapped);
   1.323 +            mapped += PAGE_SIZE;
   1.324 +        }
   1.325 +        for ( ; j < PAGE_SIZE / sizeof(unsigned long); j++)
   1.326 +            pd[j] = 0;
   1.327 +        s->pd[i] = virt_to_mfn(pd);
   1.328 +    }
   1.329 +    for ( ; i < max_pd; i++)
   1.330 +        s->pd[i] = 0;
   1.331 +
   1.332 +
   1.333 +    // FIXME: proper frees on failures
   1.334 +again:
   1.335 +    err = xenbus_transaction_start(&xbt);
   1.336 +    if (err) {
   1.337 +        printk("starting transaction\n");
   1.338 +    }
   1.339 +
   1.340 +    err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s));
   1.341 +    if (err) {
   1.342 +        message = "writing page-ref";
   1.343 +        goto abort_transaction;
   1.344 +    }
   1.345 +    err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
   1.346 +    if (err) {
   1.347 +        message = "writing event-channel";
   1.348 +        goto abort_transaction;
   1.349 +    }
   1.350 +    err = xenbus_printf(xbt, nodename, "protocol", "%s",
   1.351 +                        XEN_IO_PROTO_ABI_NATIVE);
   1.352 +    if (err) {
   1.353 +        message = "writing event-channel";
   1.354 +        goto abort_transaction;
   1.355 +    }
   1.356 +    err = xenbus_printf(xbt, nodename, "feature-update", "1");
   1.357 +    if (err) {
   1.358 +        message = "writing event-channel";
   1.359 +        goto abort_transaction;
   1.360 +    }
   1.361 +
   1.362 +    err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */
   1.363 +
   1.364 +
   1.365 +    err = xenbus_transaction_end(xbt, 0, &retry);
   1.366 +    if (retry) {
   1.367 +            goto again;
   1.368 +        printk("completing transaction\n");
   1.369 +    }
   1.370 +
   1.371 +    goto done;
   1.372 +
   1.373 +abort_transaction:
   1.374 +    xenbus_transaction_end(xbt, 1, &retry);
   1.375 +    return NULL;
   1.376 +
   1.377 +done:
   1.378 +
   1.379 +    snprintf(path, sizeof(path), "%s/backend", nodename);
   1.380 +    msg = xenbus_read(XBT_NIL, path, &dev->backend);
   1.381 +    if (msg) {
   1.382 +        printk("Error %s when reading the backend path %s\n", msg, path);
   1.383 +        return NULL;
   1.384 +    }
   1.385 +
   1.386 +    printk("backend at %s\n", dev->backend);
   1.387 +
   1.388 +    {
   1.389 +        char path[strlen(dev->backend) + 1 + 6 + 1];
   1.390 +
   1.391 +        snprintf(path, sizeof(path), "%s/state", dev->backend);
   1.392 +
   1.393 +        xenbus_watch_path(XBT_NIL, path);
   1.394 +
   1.395 +        xenbus_wait_for_value(path,"4");
   1.396 +
   1.397 +        printk("%s connected\n", dev->backend);
   1.398 +
   1.399 +        xenbus_unwatch_path(XBT_NIL, path);
   1.400 +
   1.401 +        err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */
   1.402 +    }
   1.403 +
   1.404 +    printk("************************** FBFRONT\n");
   1.405 +
   1.406 +    return dev;
   1.407 +}
   1.408 +
   1.409 +void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height)
   1.410 +{
   1.411 +    struct xenfb_page *page = dev->page;
   1.412 +    uint32_t prod;
   1.413 +    DEFINE_WAIT(w);
   1.414 +
   1.415 +    if (x < 0) {
   1.416 +        width += x;
   1.417 +        x = 0;
   1.418 +    }
   1.419 +    if (x + width > dev->width)
   1.420 +        width = dev->width - x;
   1.421 +
   1.422 +    if (y < 0) {
   1.423 +        height += y;
   1.424 +        y = 0;
   1.425 +    }
   1.426 +    if (y + height > dev->height)
   1.427 +        height = dev->height - y;
   1.428 +
   1.429 +    if (width <= 0 || height <= 0)
   1.430 +        return;
   1.431 +
   1.432 +    add_waiter(w, fbfront_queue);
   1.433 +    while (page->out_prod - page->out_cons == XENFB_OUT_RING_LEN)
   1.434 +        schedule();
   1.435 +    remove_waiter(w);
   1.436 +
   1.437 +    prod = page->out_prod;
   1.438 +    mb(); /* ensure ring space available */
   1.439 +    XENFB_OUT_RING_REF(page, prod).type = XENFB_TYPE_UPDATE;
   1.440 +    XENFB_OUT_RING_REF(page, prod).update.x = x;
   1.441 +    XENFB_OUT_RING_REF(page, prod).update.y = y;
   1.442 +    XENFB_OUT_RING_REF(page, prod).update.width = width;
   1.443 +    XENFB_OUT_RING_REF(page, prod).update.height = height;
   1.444 +    wmb(); /* ensure ring contents visible */
   1.445 +    page->out_prod = prod + 1;
   1.446 +    notify_remote_via_evtchn(dev->evtchn);
   1.447 +}
   1.448 +
   1.449 +void shutdown_fbfront(struct fbfront_dev *dev)
   1.450 +{
   1.451 +    char* err;
   1.452 +    char *nodename = dev->nodename;
   1.453 +
   1.454 +    char path[strlen(dev->backend) + 1 + 5 + 1];
   1.455 +
   1.456 +    printk("close fb: backend at %s\n",dev->backend);
   1.457 +
   1.458 +    snprintf(path, sizeof(path), "%s/state", dev->backend);
   1.459 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
   1.460 +    xenbus_wait_for_value(path,"5");
   1.461 +
   1.462 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
   1.463 +    xenbus_wait_for_value(path,"6");
   1.464 +
   1.465 +    unbind_evtchn(dev->local_port);
   1.466 +
   1.467 +    free_pages(dev->page,0);
   1.468 +    free(nodename);
   1.469 +    free(dev->backend);
   1.470 +    free(dev);
   1.471 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/extras/mini-os/include/fbfront.h	Tue Feb 26 10:12:04 2008 -0700
     2.3 @@ -0,0 +1,38 @@
     2.4 +#include <xen/io/kbdif.h>
     2.5 +#include <wait.h>
     2.6 +
     2.7 +/* from <linux/input.h> */
     2.8 +#ifndef BTN_LEFT
     2.9 +#define BTN_LEFT 0x110
    2.10 +#endif
    2.11 +#ifndef BTN_RIGHT
    2.12 +#define BTN_RIGHT 0x111
    2.13 +#endif
    2.14 +#ifndef BTN_MIDDLE
    2.15 +#define BTN_MIDDLE 0x112
    2.16 +#endif
    2.17 +#ifndef KEY_Q
    2.18 +#define KEY_Q 16
    2.19 +#endif
    2.20 +
    2.21 +
    2.22 +struct kbdfront_dev;
    2.23 +struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer);
    2.24 +#ifdef HAVE_LIBC
    2.25 +int kbdfront_open(struct kbdfront_dev *dev);
    2.26 +#endif
    2.27 +
    2.28 +int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n);
    2.29 +extern struct wait_queue_head kbdfront_queue;
    2.30 +
    2.31 +void shutdown_kbdfront(struct kbdfront_dev *dev);
    2.32 +
    2.33 +
    2.34 +struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int height, int depth, int line_length, int mem_length);
    2.35 +#ifdef HAVE_LIBC
    2.36 +int fbfront_open(struct fbfront_dev *dev);
    2.37 +#endif
    2.38 +
    2.39 +void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height);
    2.40 +
    2.41 +void shutdown_fbfront(struct fbfront_dev *dev);
     3.1 --- a/extras/mini-os/include/lib.h	Mon Feb 25 06:29:01 2008 -0700
     3.2 +++ b/extras/mini-os/include/lib.h	Tue Feb 26 10:12:04 2008 -0700
     3.3 @@ -140,6 +140,7 @@ enum fd_type {
     3.4      FTYPE_SOCKET,
     3.5      FTYPE_TAP,
     3.6      FTYPE_BLK,
     3.7 +    FTYPE_KBD,
     3.8  };
     3.9  
    3.10  #define MAX_EVTCHN_PORTS 16
    3.11 @@ -171,6 +172,9 @@ extern struct file {
    3.12  	struct {
    3.13  	    struct blkfront_dev *dev;
    3.14  	} blk;
    3.15 +	struct {
    3.16 +	    struct kbdfront_dev *dev;
    3.17 +	} kbd;
    3.18          struct {
    3.19              /* To each xenbus FD is associated a queue of watch events for this
    3.20               * FD.  */
     4.1 --- a/extras/mini-os/kernel.c	Mon Feb 25 06:29:01 2008 -0700
     4.2 +++ b/extras/mini-os/kernel.c	Tue Feb 26 10:12:04 2008 -0700
     4.3 @@ -39,6 +39,7 @@
     4.4  #include <gnttab.h>
     4.5  #include <netfront.h>
     4.6  #include <blkfront.h>
     4.7 +#include <fbfront.h>
     4.8  #include <fs.h>
     4.9  #include <xmalloc.h>
    4.10  #include <fcntl.h>
    4.11 @@ -248,6 +249,152 @@ static void blkfront_thread(void *p)
    4.12      }
    4.13  }
    4.14  
    4.15 +#define WIDTH 800
    4.16 +#define HEIGHT 600
    4.17 +#define DEPTH 32
    4.18 +
    4.19 +static uint32_t *fb;
    4.20 +static struct fbfront_dev *fb_dev;
    4.21 +static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0);
    4.22 +
    4.23 +static void fbfront_drawvert(int x, int y1, int y2, uint32_t color)
    4.24 +{
    4.25 +    int y;
    4.26 +    if (x < 0)
    4.27 +        return;
    4.28 +    if (x >= WIDTH)
    4.29 +        return;
    4.30 +    if (y1 < 0)
    4.31 +        y1 = 0;
    4.32 +    if (y2 >= HEIGHT)
    4.33 +        y2 = HEIGHT-1;
    4.34 +    for (y = y1; y <= y2; y++)
    4.35 +        fb[x + y*WIDTH] ^= color;
    4.36 +}
    4.37 +
    4.38 +static void fbfront_drawhoriz(int x1, int x2, int y, uint32_t color)
    4.39 +{
    4.40 +    int x;
    4.41 +    if (y < 0)
    4.42 +        return;
    4.43 +    if (y >= HEIGHT)
    4.44 +        return;
    4.45 +    if (x1 < 0)
    4.46 +        x1 = 0;
    4.47 +    if (x2 >= WIDTH)
    4.48 +        x2 = WIDTH-1;
    4.49 +    for (x = x1; x <= x2; x++)
    4.50 +        fb[x + y*WIDTH] ^= color;
    4.51 +}
    4.52 +
    4.53 +static void fbfront_thread(void *p)
    4.54 +{
    4.55 +    size_t line_length = WIDTH * (DEPTH / 8);
    4.56 +    size_t memsize = HEIGHT * line_length;
    4.57 +
    4.58 +    fb = _xmalloc(memsize, PAGE_SIZE);
    4.59 +    fb_dev = init_fbfront(NULL, fb, WIDTH, HEIGHT, DEPTH, line_length, memsize);
    4.60 +    if (!fb_dev) {
    4.61 +        xfree(fb);
    4.62 +        return;
    4.63 +    }
    4.64 +    up(&fbfront_sem);
    4.65 +}
    4.66 +
    4.67 +static void clip_cursor(int *x, int *y)
    4.68 +{
    4.69 +    if (*x < 0)
    4.70 +        *x = 0;
    4.71 +    if (*x >= WIDTH)
    4.72 +        *x = WIDTH - 1;
    4.73 +    if (*y < 0)
    4.74 +        *y = 0;
    4.75 +    if (*y >= HEIGHT)
    4.76 +        *y = HEIGHT - 1;
    4.77 +}
    4.78 +
    4.79 +static void refresh_cursor(int new_x, int new_y)
    4.80 +{
    4.81 +    static int old_x = -1, old_y = -1;
    4.82 +    if (old_x != -1 && old_y != -1) {
    4.83 +        fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff);
    4.84 +        fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff);
    4.85 +        fbfront_update(fb_dev, old_x, old_y, 9, 9);
    4.86 +    }
    4.87 +    old_x = new_x;
    4.88 +    old_y = new_y;
    4.89 +    fbfront_drawvert(new_x, new_y + 1, new_y + 8, 0xffffffff);
    4.90 +    fbfront_drawhoriz(new_x + 1, new_x + 8, new_y, 0xffffffff);
    4.91 +    fbfront_update(fb_dev, new_x, new_y, 9, 9);
    4.92 +}
    4.93 +
    4.94 +static void kbdfront_thread(void *p)
    4.95 +{
    4.96 +    struct kbdfront_dev *kbd_dev;
    4.97 +    DEFINE_WAIT(w);
    4.98 +    int x = WIDTH / 2, y = HEIGHT / 2, z;
    4.99 +
   4.100 +    kbd_dev = init_kbdfront(NULL, 1);
   4.101 +    if (!kbd_dev)
   4.102 +        return;
   4.103 +
   4.104 +    down(&fbfront_sem);
   4.105 +    refresh_cursor(x, y);
   4.106 +    while (1) {
   4.107 +        union xenkbd_in_event event;
   4.108 +
   4.109 +        add_waiter(w, kbdfront_queue);
   4.110 +
   4.111 +        if (kbdfront_receive(kbd_dev, &event, 1) == 0)
   4.112 +            schedule();
   4.113 +        else switch(event.type) {
   4.114 +            case XENKBD_TYPE_MOTION:
   4.115 +                printk("motion x:%d y:%d z:%d\n",
   4.116 +                        event.motion.rel_x,
   4.117 +                        event.motion.rel_y,
   4.118 +                        event.motion.rel_z);
   4.119 +                x += event.motion.rel_x;
   4.120 +                y += event.motion.rel_y;
   4.121 +                z += event.motion.rel_z;
   4.122 +                clip_cursor(&x, &y);
   4.123 +                refresh_cursor(x, y);
   4.124 +                break;
   4.125 +            case XENKBD_TYPE_POS:
   4.126 +                printk("pos x:%d y:%d z:%d\n",
   4.127 +                        event.pos.abs_x,
   4.128 +                        event.pos.abs_y,
   4.129 +                        event.pos.abs_z);
   4.130 +                x = event.pos.abs_x;
   4.131 +                y = event.pos.abs_y;
   4.132 +                z = event.pos.abs_z;
   4.133 +                clip_cursor(&x, &y);
   4.134 +                refresh_cursor(x, y);
   4.135 +                break;
   4.136 +            case XENKBD_TYPE_KEY:
   4.137 +                printk("key %d %s\n",
   4.138 +                        event.key.keycode,
   4.139 +                        event.key.pressed ? "pressed" : "released");
   4.140 +                if (event.key.keycode == BTN_LEFT) {
   4.141 +                    printk("mouse %s at (%d,%d,%d)\n",
   4.142 +                            event.key.pressed ? "clic" : "release", x, y, z);
   4.143 +                    if (event.key.pressed) {
   4.144 +                        uint32_t color = rand();
   4.145 +                        fbfront_drawvert(x - 16, y - 16, y + 15, color);
   4.146 +                        fbfront_drawhoriz(x - 16, x + 15, y + 16, color);
   4.147 +                        fbfront_drawvert(x + 16, y - 15, y + 16, color);
   4.148 +                        fbfront_drawhoriz(x - 15, x + 16, y - 16, color);
   4.149 +                        fbfront_update(fb_dev, x - 16, y - 16, 33, 33);
   4.150 +                    }
   4.151 +                } else if (event.key.keycode == KEY_Q) {
   4.152 +                    struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
   4.153 +                    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
   4.154 +                    do_exit();
   4.155 +                }
   4.156 +                break;
   4.157 +        }
   4.158 +    }
   4.159 +}
   4.160 +
   4.161  static void fs_thread(void *p)
   4.162  {
   4.163      init_fs_frontend();
   4.164 @@ -261,6 +408,8 @@ static void fs_thread(void *p)
   4.165      create_thread("periodic_thread", periodic_thread, si);
   4.166      create_thread("netfront", netfront_thread, si);
   4.167      create_thread("blkfront", blkfront_thread, si);
   4.168 +    create_thread("fbfront", fbfront_thread, si);
   4.169 +    create_thread("kbdfront", kbdfront_thread, si);
   4.170      create_thread("fs-frontend", fs_thread, si);
   4.171      return 0;
   4.172  }
     5.1 --- a/extras/mini-os/lib/math.c	Mon Feb 25 06:29:01 2008 -0700
     5.2 +++ b/extras/mini-os/lib/math.c	Tue Feb 26 10:12:04 2008 -0700
     5.3 @@ -388,6 +388,29 @@ u_quad_t
     5.4          return (r);
     5.5  }
     5.6  
     5.7 +/*
     5.8 + * Return remainder after dividing two signed quads.
     5.9 + *
    5.10 + * XXX
    5.11 + * If -1/2 should produce -1 on this machine, this code is wrong.
    5.12 + */
    5.13 +quad_t
    5.14 +__moddi3(quad_t a, quad_t b)
    5.15 +{
    5.16 +	u_quad_t ua, ub, ur;
    5.17 +	int neg;
    5.18 +
    5.19 +	if (a < 0)
    5.20 +		ua = -(u_quad_t)a, neg = 1;
    5.21 +	else
    5.22 +		ua = a, neg = 0;
    5.23 +	if (b < 0)
    5.24 +		ub = -(u_quad_t)b;
    5.25 +	else
    5.26 +		ub = b;
    5.27 +	(void)__qdivrem(ua, ub, &ur);
    5.28 +	return (neg ? -ur : ur);
    5.29 +}
    5.30  #endif /* !defined(__ia64__) */
    5.31  
    5.32  #ifndef HAVE_LIBC
     6.1 --- a/extras/mini-os/lib/sys.c	Mon Feb 25 06:29:01 2008 -0700
     6.2 +++ b/extras/mini-os/lib/sys.c	Tue Feb 26 10:12:04 2008 -0700
     6.3 @@ -26,6 +26,7 @@
     6.4  #include <wait.h>
     6.5  #include <netfront.h>
     6.6  #include <blkfront.h>
     6.7 +#include <fbfront.h>
     6.8  #include <xenbus.h>
     6.9  #include <xs.h>
    6.10  
    6.11 @@ -221,6 +222,16 @@ int read(int fd, void *buf, size_t nbyte
    6.12  	    }
    6.13  	    return ret;
    6.14  	}
    6.15 +        case FTYPE_KBD: {
    6.16 +            int ret, n;
    6.17 +            n = nbytes / sizeof(union xenkbd_in_event);
    6.18 +            ret = kbdfront_receive(files[fd].kbd.dev, buf, n);
    6.19 +	    if (ret <= 0) {
    6.20 +		errno = EAGAIN;
    6.21 +		return -1;
    6.22 +	    }
    6.23 +	    return ret * sizeof(union xenkbd_in_event);
    6.24 +        }
    6.25  	case FTYPE_NONE:
    6.26  	case FTYPE_XENBUS:
    6.27  	case FTYPE_EVTCHN:
    6.28 @@ -261,6 +272,7 @@ int write(int fd, const void *buf, size_
    6.29  	case FTYPE_XENBUS:
    6.30  	case FTYPE_EVTCHN:
    6.31  	case FTYPE_BLK:
    6.32 +	case FTYPE_KBD:
    6.33  	    break;
    6.34      }
    6.35      printk("write(%d): Bad descriptor\n", fd);
    6.36 @@ -318,6 +330,7 @@ int fsync(int fd) {
    6.37  	case FTYPE_EVTCHN:
    6.38  	case FTYPE_TAP:
    6.39  	case FTYPE_BLK:
    6.40 +	case FTYPE_KBD:
    6.41  	    break;
    6.42      }
    6.43      printk("fsync(%d): Bad descriptor\n", fd);
    6.44 @@ -360,6 +373,10 @@ int close(int fd)
    6.45              shutdown_blkfront(files[fd].blk.dev);
    6.46  	    files[fd].type = FTYPE_NONE;
    6.47  	    return 0;
    6.48 +	case FTYPE_KBD:
    6.49 +            shutdown_kbdfront(files[fd].kbd.dev);
    6.50 +            files[fd].type = FTYPE_NONE;
    6.51 +            return 0;
    6.52  	case FTYPE_NONE:
    6.53  	    break;
    6.54      }
    6.55 @@ -450,6 +467,7 @@ int fstat(int fd, struct stat *buf)
    6.56  	case FTYPE_EVTCHN:
    6.57  	case FTYPE_TAP:
    6.58  	case FTYPE_BLK:
    6.59 +	case FTYPE_KBD:
    6.60  	    break;
    6.61      }
    6.62  
    6.63 @@ -477,6 +495,7 @@ int ftruncate(int fd, off_t length)
    6.64  	case FTYPE_EVTCHN:
    6.65  	case FTYPE_TAP:
    6.66  	case FTYPE_BLK:
    6.67 +	case FTYPE_KBD:
    6.68  	    break;
    6.69      }
    6.70  
    6.71 @@ -587,6 +606,7 @@ static const char file_types[] = {
    6.72      [FTYPE_SOCKET]	= 'S',
    6.73      [FTYPE_TAP]		= 'T',
    6.74      [FTYPE_BLK]		= 'B',
    6.75 +    [FTYPE_KBD]		= 'K',
    6.76  };
    6.77  #ifdef LIBC_DEBUG
    6.78  static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
    6.79 @@ -694,6 +714,7 @@ static int select_poll(int nfds, fd_set 
    6.80  	case FTYPE_EVTCHN:
    6.81  	case FTYPE_TAP:
    6.82  	case FTYPE_BLK:
    6.83 +	case FTYPE_KBD:
    6.84  	    if (FD_ISSET(i, readfds)) {
    6.85  		if (files[i].read)
    6.86  		    n++;
    6.87 @@ -775,6 +796,7 @@ int select(int nfds, fd_set *readfds, fd
    6.88      DEFINE_WAIT(w2);
    6.89      DEFINE_WAIT(w3);
    6.90      DEFINE_WAIT(w4);
    6.91 +    DEFINE_WAIT(w5);
    6.92  
    6.93      assert(thread == main_thread);
    6.94  
    6.95 @@ -795,6 +817,7 @@ int select(int nfds, fd_set *readfds, fd
    6.96      add_waiter(w2, event_queue);
    6.97      add_waiter(w3, blkfront_queue);
    6.98      add_waiter(w4, xenbus_watch_queue);
    6.99 +    add_waiter(w5, kbdfront_queue);
   6.100  
   6.101      myread = *readfds;
   6.102      mywrite = *writefds;
   6.103 @@ -860,6 +883,7 @@ out:
   6.104      remove_waiter(w2);
   6.105      remove_waiter(w3);
   6.106      remove_waiter(w4);
   6.107 +    remove_waiter(w5);
   6.108      return ret;
   6.109  }
   6.110  
     7.1 --- a/stubdom/README	Mon Feb 25 06:29:01 2008 -0700
     7.2 +++ b/stubdom/README	Tue Feb 26 10:12:04 2008 -0700
     7.3 @@ -16,10 +16,12 @@ ln -s /usr/share/qemu/keymaps /exports/u
     7.4  
     7.5  In your HVM config "hvmconfig",
     7.6  
     7.7 -- use VNC, set vnclisten to "172.30.206.1" for instance:
     7.8 +- use VNC, set vnclisten to "172.30.206.1" for instance.  Do not use a host name
     7.9 +as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since then you
    7.10 +will not be able to connect to it.
    7.11  
    7.12 -vnc=1 
    7.13 -vnclisten="172.30.206.1" 
    7.14 +vnc = 1
    7.15 +vnclisten = "172.30.206.1"
    7.16  
    7.17  - use /usr/lib/xen/bin/stubdom-dm as dm script
    7.18  
    7.19 @@ -28,14 +30,15 @@ device_model = '/usr/lib/xen/bin/stubdom
    7.20  - comment the disk statement:
    7.21  #disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
    7.22  
    7.23 -Create /etc/xen/stubdom-hvmconfig ("hvmconfig" must match your main config file)
    7.24 -with
    7.25 +Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is your HVM guest domain
    7.26 +name) with
    7.27  
    7.28 -kernel="/usr/lib/xen/boot/stubdom.gz"
    7.29 -vif=[ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
    7.30 +kernel = "/usr/lib/xen/boot/stubdom.gz"
    7.31 +vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
    7.32  disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
    7.33  
    7.34  where
    7.35  - 172.30.206.1 is the IP for vnc,
    7.36 -- 'ip=10.0.1.1,mac=' is the same net configuration as in the hvmconfig script,
    7.37 +- 'ip=10.0.1.1,mac= etc...' is the same net configuration as in the hvmconfig
    7.38 +script,
    7.39  - and disk = is the same block configuration as in the hvmconfig script.
     8.1 --- a/stubdom/stubdom-dm	Mon Feb 25 06:29:01 2008 -0700
     8.2 +++ b/stubdom/stubdom-dm	Tue Feb 26 10:12:04 2008 -0700
     8.3 @@ -62,11 +62,12 @@ done
     8.4  
     8.5  creation="xm create -c stubdom-$domname target=$domid memory=32"
     8.6  
     8.7 -(while true ; do sleep 60 ; done) | $creation &
     8.8 +(while true ; do sleep 60 ; done) | $creation > /var/log/xen/qemu-dm-$domid.log &
     8.9  #xterm -geometry +0+0 -e /bin/sh -c "$creation ; echo ; echo press ENTER to shut down ; read" &
    8.10  consolepid=$!
    8.11  
    8.12  
    8.13 +# Wait for vnc server to appear
    8.14  while ! vnc_port=`xenstore-read /local/domain/$domid/console/vnc-port`
    8.15  do
    8.16          # Check that the stubdom job is still alive
     9.1 --- a/tools/blktap/drivers/block-aio.c	Mon Feb 25 06:29:01 2008 -0700
     9.2 +++ b/tools/blktap/drivers/block-aio.c	Tue Feb 26 10:12:04 2008 -0700
     9.3 @@ -52,28 +52,11 @@
     9.4  #define O_LARGEFILE	0
     9.5  #endif
     9.6  
     9.7 -struct pending_aio {
     9.8 -	td_callback_t cb;
     9.9 -	int id;
    9.10 -	void *private;
    9.11 -	uint64_t lsec;
    9.12 -};
    9.13 -
    9.14  struct tdaio_state {
    9.15  	int fd;
    9.16 -	
    9.17 -	/* libaio state */
    9.18 -	tap_aio_context_t  aio_ctx;
    9.19 -	struct iocb        iocb_list  [MAX_AIO_REQS];
    9.20 -	struct iocb       *iocb_free  [MAX_AIO_REQS];
    9.21 -	struct pending_aio pending_aio[MAX_AIO_REQS];
    9.22 -	int                iocb_free_count;
    9.23 -	struct iocb       *iocb_queue[MAX_AIO_REQS];
    9.24 -	int                iocb_queued;
    9.25 -	struct io_event    aio_events[MAX_AIO_REQS];
    9.26 +	tap_aio_context_t aio;
    9.27  };
    9.28  
    9.29 -#define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list)
    9.30  
    9.31  /*Get Image size, secsize*/
    9.32  static int get_image_info(struct td_state *s, int fd)
    9.33 @@ -131,7 +114,7 @@ static inline void init_fds(struct disk_
    9.34  	for(i = 0; i < MAX_IOFD; i++) 
    9.35  		dd->io_fd[i] = 0;
    9.36  
    9.37 -	dd->io_fd[0] = prv->aio_ctx.pollfd;
    9.38 +	dd->io_fd[0] = prv->aio.aio_ctx.pollfd;
    9.39  }
    9.40  
    9.41  /* Open the disk file and initialize aio state. */
    9.42 @@ -142,27 +125,11 @@ int tdaio_open (struct disk_driver *dd, 
    9.43  	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
    9.44  
    9.45  	DPRINTF("block-aio open('%s')", name);
    9.46 -	/* Initialize AIO */
    9.47 -	prv->iocb_free_count = MAX_AIO_REQS;
    9.48 -	prv->iocb_queued     = 0;
    9.49  
    9.50 -	ret = tap_aio_setup(&prv->aio_ctx, prv->aio_events, MAX_AIO_REQS);
    9.51 -	if (ret < 0) {
    9.52 -                if (ret == -EAGAIN) {
    9.53 -                        DPRINTF("Couldn't setup AIO context.  If you are "
    9.54 -                                "trying to concurrently use a large number "
    9.55 -                                "of blktap-based disks, you may need to "
    9.56 -                                "increase the system-wide aio request limit. "
    9.57 -                                "(e.g. 'echo echo 1048576 > /proc/sys/fs/"
    9.58 -                                "aio-max-nr')\n");
    9.59 -                } else {
    9.60 -                        DPRINTF("Couldn't setup AIO context.\n");
    9.61 -                }
    9.62 -		goto done;
    9.63 -	}
    9.64 -
    9.65 -	for (i=0;i<MAX_AIO_REQS;i++)
    9.66 -		prv->iocb_free[i] = &prv->iocb_list[i];
    9.67 +	/* Initialize AIO */
    9.68 +	ret = tap_aio_init(&prv->aio, 0, MAX_AIO_REQS);
    9.69 +	if (ret != 0)
    9.70 +		return ret;
    9.71  
    9.72  	/* Open the file */
    9.73  	o_flags = O_DIRECT | O_LARGEFILE | 
    9.74 @@ -198,87 +165,40 @@ int tdaio_queue_read(struct disk_driver 
    9.75  		     int nb_sectors, char *buf, td_callback_t cb,
    9.76  		     int id, void *private)
    9.77  {
    9.78 -	struct   iocb *io;
    9.79 -	struct   pending_aio *pio;
    9.80  	struct   td_state    *s   = dd->td_state;
    9.81  	struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
    9.82  	int      size    = nb_sectors * s->sector_size;
    9.83  	uint64_t offset  = sector * (uint64_t)s->sector_size;
    9.84 -	long     ioidx;
    9.85 -	
    9.86 -	if (prv->iocb_free_count == 0)
    9.87 -		return -ENOMEM;
    9.88 -	io = prv->iocb_free[--prv->iocb_free_count];
    9.89 -	
    9.90 -	ioidx = IOCB_IDX(prv, io);
    9.91 -	pio = &prv->pending_aio[ioidx];
    9.92 -	pio->cb = cb;
    9.93 -	pio->id = id;
    9.94 -	pio->private = private;
    9.95 -	pio->lsec = sector;
    9.96 -	
    9.97 -	io_prep_pread(io, prv->fd, buf, size, offset);
    9.98 -	io->data = (void *)ioidx;
    9.99 -	
   9.100 -	prv->iocb_queue[prv->iocb_queued++] = io;
   9.101  
   9.102 -	return 0;
   9.103 +	return tap_aio_read(&prv->aio, prv->fd, size, offset, buf, 
   9.104 +		cb, id, sector, private);
   9.105  }
   9.106  			
   9.107  int tdaio_queue_write(struct disk_driver *dd, uint64_t sector,
   9.108  		      int nb_sectors, char *buf, td_callback_t cb,
   9.109  		      int id, void *private)
   9.110  {
   9.111 -	struct   iocb *io;
   9.112 -	struct   pending_aio *pio;
   9.113  	struct   td_state    *s   = dd->td_state;
   9.114  	struct   tdaio_state *prv = (struct tdaio_state *)dd->private;
   9.115  	int      size    = nb_sectors * s->sector_size;
   9.116  	uint64_t offset  = sector * (uint64_t)s->sector_size;
   9.117 -	long     ioidx;
   9.118 -	
   9.119 -	if (prv->iocb_free_count == 0)
   9.120 -		return -ENOMEM;
   9.121 -	io = prv->iocb_free[--prv->iocb_free_count];
   9.122 -	
   9.123 -	ioidx = IOCB_IDX(prv, io);
   9.124 -	pio = &prv->pending_aio[ioidx];
   9.125 -	pio->cb = cb;
   9.126 -	pio->id = id;
   9.127 -	pio->private = private;
   9.128 -	pio->lsec = sector;
   9.129 -	
   9.130 -	io_prep_pwrite(io, prv->fd, buf, size, offset);
   9.131 -	io->data = (void *)ioidx;
   9.132 -	
   9.133 -	prv->iocb_queue[prv->iocb_queued++] = io;
   9.134  
   9.135 -	return 0;
   9.136 +	return tap_aio_write(&prv->aio, prv->fd, size, offset, buf,
   9.137 +		cb, id, sector, private);
   9.138 +}
   9.139 +
   9.140 +int tdaio_submit(struct disk_driver *dd)
   9.141 +{
   9.142 +	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
   9.143 +
   9.144 +	return tap_aio_submit(&prv->aio);
   9.145  }
   9.146  			
   9.147 -int tdaio_submit(struct disk_driver *dd)
   9.148 -{
   9.149 -	int ret;
   9.150 -	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
   9.151 -
   9.152 -	if (!prv->iocb_queued)
   9.153 -		return 0;
   9.154 -
   9.155 -	ret = io_submit(prv->aio_ctx.aio_ctx, prv->iocb_queued, prv->iocb_queue);
   9.156 -	
   9.157 -	/* XXX: TODO: Handle error conditions here. */
   9.158 -	
   9.159 -	/* Success case: */
   9.160 -	prv->iocb_queued = 0;
   9.161 -	
   9.162 -	return 0;
   9.163 -}
   9.164 -
   9.165  int tdaio_close(struct disk_driver *dd)
   9.166  {
   9.167  	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
   9.168  	
   9.169 -	io_destroy(prv->aio_ctx.aio_ctx);
   9.170 +	io_destroy(prv->aio.aio_ctx.aio_ctx);
   9.171  	close(prv->fd);
   9.172  
   9.173  	return 0;
   9.174 @@ -290,26 +210,26 @@ int tdaio_do_callbacks(struct disk_drive
   9.175  	struct io_event *ep;
   9.176  	struct tdaio_state *prv = (struct tdaio_state *)dd->private;
   9.177  
   9.178 -	nr_events = tap_aio_get_events(&prv->aio_ctx);
   9.179 +	nr_events = tap_aio_get_events(&prv->aio.aio_ctx);
   9.180  repeat:
   9.181 -	for (ep = prv->aio_events, i = nr_events; i-- > 0; ep++) {
   9.182 +	for (ep = prv->aio.aio_events, i = nr_events; i-- > 0; ep++) {
   9.183  		struct iocb        *io  = ep->obj;
   9.184  		struct pending_aio *pio;
   9.185  		
   9.186 -		pio = &prv->pending_aio[(long)io->data];
   9.187 +		pio = &prv->aio.pending_aio[(long)io->data];
   9.188  		rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1,
   9.189 -			       pio->lsec, io->u.c.nbytes >> 9, 
   9.190 +			       pio->sector, io->u.c.nbytes >> 9, 
   9.191  			       pio->id, pio->private);
   9.192  
   9.193 -		prv->iocb_free[prv->iocb_free_count++] = io;
   9.194 +		prv->aio.iocb_free[prv->aio.iocb_free_count++] = io;
   9.195  	}
   9.196  
   9.197  	if (nr_events) {
   9.198 -		nr_events = tap_aio_more_events(&prv->aio_ctx);
   9.199 +		nr_events = tap_aio_more_events(&prv->aio.aio_ctx);
   9.200  		goto repeat;
   9.201  	}
   9.202  
   9.203 -	tap_aio_continue(&prv->aio_ctx);
   9.204 +	tap_aio_continue(&prv->aio.aio_ctx);
   9.205  
   9.206  	return rsp;
   9.207  }
    10.1 --- a/tools/blktap/drivers/block-qcow.c	Mon Feb 25 06:29:01 2008 -0700
    10.2 +++ b/tools/blktap/drivers/block-qcow.c	Tue Feb 26 10:12:04 2008 -0700
    10.3 @@ -59,15 +59,7 @@
    10.4          (l + (s - 1)) - ((l + (s - 1)) % s)); \
    10.5  })
    10.6  
    10.7 -struct pending_aio {
    10.8 -        td_callback_t cb;
    10.9 -        int id;
   10.10 -        void *private;
   10.11 -	int nb_sectors;
   10.12 -	char *buf;
   10.13 -	uint64_t sector;
   10.14 -};
   10.15 -
   10.16 +#undef IOCB_IDX
   10.17  #define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list)
   10.18  
   10.19  #define ZERO_TEST(_b) (_b | 0x00)
   10.20 @@ -140,110 +132,19 @@ struct tdqcow_state {
   10.21  	uint32_t l2_cache_counts[L2_CACHE_SIZE];      /*Cache access record*/
   10.22  	uint8_t *cluster_cache;          
   10.23  	uint8_t *cluster_data;
   10.24 -	uint8_t *sector_lock;          /*Locking bitmap for AIO reads/writes*/
   10.25  	uint64_t cluster_cache_offset; /**/
   10.26  	uint32_t crypt_method;         /*current crypt method, 0 if no 
   10.27  					*key yet */
   10.28  	uint32_t crypt_method_header;  /**/
   10.29  	AES_KEY aes_encrypt_key;       /*AES key*/
   10.30  	AES_KEY aes_decrypt_key;       /*AES key*/
   10.31 -        /* libaio state */
   10.32 -        tap_aio_context_t   aio_ctx;
   10.33 -        int                 max_aio_reqs;
   10.34 -        struct iocb        *iocb_list;
   10.35 -        struct iocb       **iocb_free;
   10.36 -        struct pending_aio *pending_aio;
   10.37 -        int                 iocb_free_count;
   10.38 -        struct iocb       **iocb_queue;
   10.39 -        int                 iocb_queued;
   10.40 -        struct io_event    *aio_events;
   10.41 +        
   10.42 +	/* libaio state */
   10.43 +	tap_aio_context_t	aio;
   10.44  };
   10.45  
   10.46  static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset);
   10.47  
   10.48 -static void free_aio_state(struct disk_driver *dd)
   10.49 -{
   10.50 -        struct tdqcow_state *s = (struct tdqcow_state *)dd->private;
   10.51 -
   10.52 -        if (s->sector_lock)
   10.53 -                free(s->sector_lock);
   10.54 -        if (s->iocb_list)
   10.55 -                free(s->iocb_list);
   10.56 -        if (s->pending_aio)
   10.57 -                free(s->pending_aio);
   10.58 -        if (s->aio_events)
   10.59 -                free(s->aio_events);
   10.60 -        if (s->iocb_free)
   10.61 -                free(s->iocb_free);
   10.62 -        if (s->iocb_queue)
   10.63 -                free(s->iocb_queue);
   10.64 -}
   10.65 -
   10.66 -static int init_aio_state(struct disk_driver *dd)
   10.67 -{
   10.68 -	int i, ret;
   10.69 -	struct td_state     *bs = dd->td_state;
   10.70 -	struct tdqcow_state  *s = (struct tdqcow_state *)dd->private;
   10.71 -        long     ioidx;
   10.72 -
   10.73 -        s->iocb_list = NULL;
   10.74 -        s->pending_aio = NULL;
   10.75 -        s->aio_events = NULL;
   10.76 -        s->iocb_free = NULL;
   10.77 -        s->iocb_queue = NULL;
   10.78 -
   10.79 -        /*Initialize Locking bitmap*/
   10.80 -	s->sector_lock = calloc(1, bs->size);
   10.81 -	
   10.82 -	if (!s->sector_lock) {
   10.83 -		DPRINTF("Failed to allocate sector lock\n");
   10.84 -		goto fail;
   10.85 -	}
   10.86 -
   10.87 -        /* A segment (i.e. a page) can span multiple clusters */
   10.88 -        s->max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
   10.89 -            MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
   10.90 -
   10.91 -        /* Initialize AIO */
   10.92 -        s->iocb_free_count = s->max_aio_reqs;
   10.93 -        s->iocb_queued     = 0;
   10.94 -
   10.95 -        if (!(s->iocb_list = malloc(sizeof(struct iocb) * s->max_aio_reqs)) ||
   10.96 -            !(s->pending_aio = malloc(sizeof(struct pending_aio) * s->max_aio_reqs)) ||
   10.97 -            !(s->aio_events = malloc(sizeof(struct io_event) * s->max_aio_reqs)) ||
   10.98 -            !(s->iocb_free = malloc(sizeof(struct iocb *) * s->max_aio_reqs)) ||
   10.99 -            !(s->iocb_queue = malloc(sizeof(struct iocb *) * s->max_aio_reqs))) {
  10.100 -                DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
  10.101 -                        s->max_aio_reqs);
  10.102 -                goto fail;
  10.103 -        }
  10.104 -
  10.105 -	ret = tap_aio_setup(&s->aio_ctx, s->aio_events, s->max_aio_reqs);
  10.106 -	if (ret < 0) {
  10.107 -                if (ret == -EAGAIN) {
  10.108 -                        DPRINTF("Couldn't setup AIO context.  If you are "
  10.109 -                                "trying to concurrently use a large number "
  10.110 -                                "of blktap-based disks, you may need to "
  10.111 -                                "increase the system-wide aio request limit. "
  10.112 -                                "(e.g. 'echo echo 1048576 > /proc/sys/fs/"
  10.113 -                                "aio-max-nr')\n");
  10.114 -                } else {
  10.115 -                        DPRINTF("Couldn't setup AIO context.\n");
  10.116 -                }
  10.117 -		goto fail;
  10.118 -	}
  10.119 -
  10.120 -        for (i=0;i<s->max_aio_reqs;i++)
  10.121 -                s->iocb_free[i] = &s->iocb_list[i];
  10.122 -
  10.123 -        DPRINTF("AIO state initialised\n");
  10.124 -
  10.125 -        return 0;
  10.126 -
  10.127 - fail:
  10.128 -	return -1;
  10.129 -}
  10.130 -
  10.131  static uint32_t gen_cksum(char *ptr, int len)
  10.132  {
  10.133  	unsigned char *md;
  10.134 @@ -339,79 +240,6 @@ static int qcow_set_key(struct tdqcow_st
  10.135  	return 0;
  10.136  }
  10.137  
  10.138 -static int async_read(struct tdqcow_state *s, int size, 
  10.139 -		      uint64_t offset, char *buf, td_callback_t cb,
  10.140 -		      int id, uint64_t sector, void *private)
  10.141 -{
  10.142 -        struct   iocb *io;
  10.143 -        struct   pending_aio *pio;
  10.144 -	long     ioidx;
  10.145 -
  10.146 -        io = s->iocb_free[--s->iocb_free_count];
  10.147 -
  10.148 -        ioidx = IOCB_IDX(s, io);
  10.149 -        pio = &s->pending_aio[ioidx];
  10.150 -        pio->cb = cb;
  10.151 -        pio->id = id;
  10.152 -        pio->private = private;
  10.153 -	pio->nb_sectors = size/512;
  10.154 -	pio->buf = buf;
  10.155 -	pio->sector = sector;
  10.156 -
  10.157 -        io_prep_pread(io, s->fd, buf, size, offset);
  10.158 -        io->data = (void *)ioidx;
  10.159 -
  10.160 -        s->iocb_queue[s->iocb_queued++] = io;
  10.161 -
  10.162 -        return 1;
  10.163 -}
  10.164 -
  10.165 -static int async_write(struct tdqcow_state *s, int size,
  10.166 -		       uint64_t offset, char *buf, td_callback_t cb,
  10.167 -		       int id, uint64_t sector, void *private)
  10.168 -{
  10.169 -        struct   iocb *io;
  10.170 -        struct   pending_aio *pio;
  10.171 -	long     ioidx;
  10.172 -
  10.173 -        io = s->iocb_free[--s->iocb_free_count];
  10.174 -
  10.175 -        ioidx = IOCB_IDX(s, io);
  10.176 -        pio = &s->pending_aio[ioidx];
  10.177 -        pio->cb = cb;
  10.178 -        pio->id = id;
  10.179 -        pio->private = private;
  10.180 -	pio->nb_sectors = size/512;
  10.181 -	pio->buf = buf;
  10.182 -	pio->sector = sector;
  10.183 -
  10.184 -        io_prep_pwrite(io, s->fd, buf, size, offset);
  10.185 -        io->data = (void *)ioidx;
  10.186 -
  10.187 -        s->iocb_queue[s->iocb_queued++] = io;
  10.188 -
  10.189 -        return 1;
  10.190 -}
  10.191 -
  10.192 -/*TODO: Fix sector span!*/
  10.193 -static int aio_can_lock(struct tdqcow_state *s, uint64_t sector)
  10.194 -{
  10.195 -	return (s->sector_lock[sector] ? 0 : 1);
  10.196 -}
  10.197 -
  10.198 -static int aio_lock(struct tdqcow_state *s, uint64_t sector)
  10.199 -{
  10.200 -	return ++s->sector_lock[sector];
  10.201 -}
  10.202 -
  10.203 -static void aio_unlock(struct tdqcow_state *s, uint64_t sector)
  10.204 -{
  10.205 -	if (!s->sector_lock[sector]) return;
  10.206 -
  10.207 -	--s->sector_lock[sector];
  10.208 -	return;
  10.209 -}
  10.210 -
  10.211  /* 
  10.212   * The crypt function is compatible with the linux cryptoloop
  10.213   * algorithm for < 4 GB images. NOTE: out_buf == in_buf is
  10.214 @@ -841,13 +669,14 @@ static inline void init_fds(struct disk_
  10.215  	for(i = 0; i < MAX_IOFD; i++) 
  10.216  		dd->io_fd[i] = 0;
  10.217  
  10.218 -	dd->io_fd[0] = s->aio_ctx.pollfd;
  10.219 +	dd->io_fd[0] = s->aio.aio_ctx.pollfd;
  10.220  }
  10.221  
  10.222  /* Open the disk file and initialize qcow state. */
  10.223  int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags)
  10.224  {
  10.225  	int fd, len, i, shift, ret, size, l1_table_size, o_flags;
  10.226 +	int max_aio_reqs;
  10.227  	struct td_state     *bs = dd->td_state;
  10.228  	struct tdqcow_state *s  = (struct tdqcow_state *)dd->private;
  10.229  	char *buf;
  10.230 @@ -996,9 +825,14 @@ int tdqcow_open (struct disk_driver *dd,
  10.231  	}
  10.232  
  10.233   end_xenhdr:
  10.234 -	if (init_aio_state(dd)!=0) {
  10.235 + 	
  10.236 +	/* A segment (i.e. a page) can span multiple clusters */
  10.237 +	max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
  10.238 +		MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
  10.239 +
  10.240 +	if (tap_aio_init(&s->aio, bs->size, max_aio_reqs)!=0) {
  10.241  		DPRINTF("Unable to initialise AIO state\n");
  10.242 -                free_aio_state(dd);
  10.243 +                tap_aio_free(&s->aio);
  10.244  		goto fail;
  10.245  	}
  10.246  	init_fds(dd);
  10.247 @@ -1015,7 +849,7 @@ int tdqcow_open (struct disk_driver *dd,
  10.248  	
  10.249  fail:
  10.250  	DPRINTF("QCOW Open failed\n");
  10.251 -	free_aio_state(dd);
  10.252 +	tap_aio_free(&s->aio);
  10.253  	free(s->l1_table);
  10.254  	free(s->l2_cache);
  10.255  	free(s->cluster_cache);
  10.256 @@ -1037,7 +871,7 @@ int tdqcow_queue_read(struct disk_driver
  10.257  
  10.258  	/*Check we can get a lock*/
  10.259  	for (i = 0; i < nb_sectors; i++) 
  10.260 -		if (!aio_can_lock(s, sector + i)) 
  10.261 +		if (!tap_aio_can_lock(&s->aio, sector + i)) 
  10.262  			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  10.263  
  10.264  	/*We store a local record of the request*/
  10.265 @@ -1049,11 +883,11 @@ int tdqcow_queue_read(struct disk_driver
  10.266  		if (n > nb_sectors)
  10.267  			n = nb_sectors;
  10.268  
  10.269 -		if (s->iocb_free_count == 0 || !aio_lock(s, sector)) 
  10.270 +		if (s->aio.iocb_free_count == 0 || !tap_aio_lock(&s->aio, sector)) 
  10.271  			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  10.272  		
  10.273  		if(!cluster_offset) {
  10.274 -			aio_unlock(s, sector);
  10.275 +			tap_aio_unlock(&s->aio, sector);
  10.276  			ret = cb(dd, BLK_NOT_ALLOCATED, 
  10.277  				 sector, n, id, private);
  10.278  			if (ret == -EBUSY) {
  10.279 @@ -1064,7 +898,7 @@ int tdqcow_queue_read(struct disk_driver
  10.280  			} else
  10.281  				rsp += ret;
  10.282  		} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
  10.283 -			aio_unlock(s, sector);
  10.284 +			tap_aio_unlock(&s->aio, sector);
  10.285  			if (decompress_cluster(s, cluster_offset) < 0) {
  10.286  				rsp += cb(dd, -EIO, sector, 
  10.287  					  nb_sectors, id, private);
  10.288 @@ -1074,7 +908,7 @@ int tdqcow_queue_read(struct disk_driver
  10.289  			       512 * n);
  10.290  			rsp += cb(dd, 0, sector, n, id, private);
  10.291  		} else {
  10.292 -			async_read(s, n * 512, 
  10.293 +			tap_aio_read(&s->aio, s->fd, n * 512, 
  10.294  				   (cluster_offset + index_in_cluster * 512),
  10.295  				   buf, cb, id, sector, private);
  10.296  		}
  10.297 @@ -1099,7 +933,7 @@ int tdqcow_queue_write(struct disk_drive
  10.298  
  10.299  	/*Check we can get a lock*/
  10.300  	for (i = 0; i < nb_sectors; i++)
  10.301 -		if (!aio_can_lock(s, sector + i))  
  10.302 +		if (!tap_aio_can_lock(&s->aio, sector + i))  
  10.303  			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  10.304  		   
  10.305  	/*We store a local record of the request*/
  10.306 @@ -1109,7 +943,7 @@ int tdqcow_queue_write(struct disk_drive
  10.307  		if (n > nb_sectors)
  10.308  			n = nb_sectors;
  10.309  
  10.310 -		if (s->iocb_free_count == 0 || !aio_lock(s, sector))
  10.311 +		if (s->aio.iocb_free_count == 0 || !tap_aio_lock(&s->aio, sector))
  10.312  			return cb(dd, -EBUSY, sector, nb_sectors, id, private);
  10.313  
  10.314  		cluster_offset = get_cluster_offset(s, sector << 9, 1, 0,
  10.315 @@ -1117,7 +951,7 @@ int tdqcow_queue_write(struct disk_drive
  10.316  						    index_in_cluster+n);
  10.317  		if (!cluster_offset) {
  10.318  			DPRINTF("Ooops, no write cluster offset!\n");
  10.319 -			aio_unlock(s, sector);
  10.320 +			tap_aio_unlock(&s->aio, sector);
  10.321  			return cb(dd, -EIO, sector, nb_sectors, id, private);
  10.322  		}
  10.323  
  10.324 @@ -1125,12 +959,12 @@ int tdqcow_queue_write(struct disk_drive
  10.325  			encrypt_sectors(s, sector, s->cluster_data, 
  10.326  					(unsigned char *)buf, n, 1,
  10.327  					&s->aes_encrypt_key);
  10.328 -			async_write(s, n * 512, 
  10.329 +			tap_aio_write(&s->aio, s->fd, n * 512, 
  10.330  				    (cluster_offset + index_in_cluster*512),
  10.331  				    (char *)s->cluster_data, cb, id, sector, 
  10.332  				    private);
  10.333  		} else {
  10.334 -			async_write(s, n * 512, 
  10.335 +			tap_aio_write(&s->aio, s->fd, n * 512, 
  10.336  				    (cluster_offset + index_in_cluster*512),
  10.337  				    buf, cb, id, sector, private);
  10.338  		}
  10.339 @@ -1146,20 +980,9 @@ int tdqcow_queue_write(struct disk_drive
  10.340   		
  10.341  int tdqcow_submit(struct disk_driver *dd)
  10.342  {
  10.343 -        int ret;
  10.344 -        struct   tdqcow_state *prv = (struct tdqcow_state *)dd->private;
  10.345 -
  10.346 -	if (!prv->iocb_queued)
  10.347 -		return 0;
  10.348 +        struct tdqcow_state *prv = (struct tdqcow_state *)dd->private;
  10.349  
  10.350 -	ret = io_submit(prv->aio_ctx.aio_ctx, prv->iocb_queued, prv->iocb_queue);
  10.351 -
  10.352 -        /* XXX: TODO: Handle error conditions here. */
  10.353 -
  10.354 -        /* Success case: */
  10.355 -        prv->iocb_queued = 0;
  10.356 -
  10.357 -        return 0;
  10.358 +	return tap_aio_submit(&prv->aio);
  10.359  }
  10.360  
  10.361  int tdqcow_close(struct disk_driver *dd)
  10.362 @@ -1180,7 +1003,7 @@ int tdqcow_close(struct disk_driver *dd)
  10.363  		close(fd);
  10.364  	}
  10.365  
  10.366 -	io_destroy(s->aio_ctx.aio_ctx);
  10.367 +	io_destroy(s->aio.aio_ctx.aio_ctx);
  10.368  	free(s->name);
  10.369  	free(s->l1_table);
  10.370  	free(s->l2_cache);
  10.371 @@ -1198,15 +1021,15 @@ int tdqcow_do_callbacks(struct disk_driv
  10.372  
  10.373          if (sid > MAX_IOFD) return 1;
  10.374  
  10.375 -        nr_events = tap_aio_get_events(&prv->aio_ctx);
  10.376 +        nr_events = tap_aio_get_events(&prv->aio.aio_ctx);
  10.377  repeat:
  10.378 -        for (ep = prv->aio_events, i = nr_events; i-- > 0; ep++) {
  10.379 +        for (ep = prv->aio.aio_events, i = nr_events; i-- > 0; ep++) {
  10.380                  struct iocb        *io  = ep->obj;
  10.381                  struct pending_aio *pio;
  10.382  
  10.383 -                pio = &prv->pending_aio[(long)io->data];
  10.384 +                pio = &prv->aio.pending_aio[(long)io->data];
  10.385  
  10.386 -		aio_unlock(prv, pio->sector);
  10.387 +		tap_aio_unlock(&prv->aio, pio->sector);
  10.388  
  10.389  		if (prv->crypt_method)
  10.390  			encrypt_sectors(prv, pio->sector, 
  10.391 @@ -1219,15 +1042,15 @@ repeat:
  10.392  			       pio->sector, pio->nb_sectors,
  10.393  			       pio->id, pio->private);
  10.394  
  10.395 -                prv->iocb_free[prv->iocb_free_count++] = io;
  10.396 +                prv->aio.iocb_free[prv->aio.iocb_free_count++] = io;
  10.397          }
  10.398  
  10.399          if (nr_events) {
  10.400 -                nr_events = tap_aio_more_events(&prv->aio_ctx);
  10.401 +                nr_events = tap_aio_more_events(&prv->aio.aio_ctx);
  10.402                  goto repeat;
  10.403          }
  10.404  
  10.405 -        tap_aio_continue(&prv->aio_ctx);
  10.406 +        tap_aio_continue(&prv->aio.aio_ctx);
  10.407  
  10.408          return rsp;
  10.409  }
    11.1 --- a/tools/blktap/drivers/block-qcow2.c	Mon Feb 25 06:29:01 2008 -0700
    11.2 +++ b/tools/blktap/drivers/block-qcow2.c	Tue Feb 26 10:12:04 2008 -0700
    11.3 @@ -145,20 +145,7 @@ typedef struct BDRVQcowState {
    11.4  
    11.5  	int64_t total_sectors;
    11.6  
    11.7 -
    11.8 -	struct {
    11.9 -		tap_aio_context_t    aio_ctx;
   11.10 -		int                  max_aio_reqs;
   11.11 -		struct iocb         *iocb_list;
   11.12 -		struct iocb        **iocb_free;
   11.13 -		struct pending_aio  *pending_aio;
   11.14 -		int                  iocb_free_count;
   11.15 -		struct iocb        **iocb_queue;
   11.16 -		int	             iocb_queued;
   11.17 -		struct io_event     *aio_events;
   11.18 -		
   11.19 -		uint8_t *sector_lock;		   /*Locking bitmap for AIO reads/writes*/
   11.20 -	} async;
   11.21 +	tap_aio_context_t async;
   11.22  
   11.23  	/* Original qemu variables */
   11.24  	int cluster_bits;
   11.25 @@ -222,9 +209,6 @@ static void free_clusters(struct disk_dr
   11.26  static void check_refcounts(struct disk_driver *bs);
   11.27  #endif
   11.28  
   11.29 -static int init_aio_state(struct disk_driver *bs);
   11.30 -static void free_aio_state(struct disk_driver *bs);
   11.31 -
   11.32  static int qcow_sync_read(struct disk_driver *dd, uint64_t sector,
   11.33  		int nb_sectors, char *buf, td_callback_t cb,
   11.34  		int id, void *prv);
   11.35 @@ -309,7 +293,7 @@ static int qcow_probe(const uint8_t *buf
   11.36  static int qcow_open(struct disk_driver *bs, const char *filename, td_flag_t flags)
   11.37  {
   11.38  	BDRVQcowState *s = bs->private;
   11.39 -	int len, i, shift, ret;
   11.40 +	int len, i, shift, ret, max_aio_reqs;
   11.41  	QCowHeader header;
   11.42  
   11.43  	int fd, o_flags;
   11.44 @@ -475,9 +459,14 @@ static int qcow_open(struct disk_driver 
   11.45  
   11.46  #ifdef USE_AIO
   11.47  	/* Initialize AIO */
   11.48 -	if (init_aio_state(bs)!=0) {
   11.49 +
   11.50 +	/* A segment (i.e. a page) can span multiple clusters */
   11.51 +	max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
   11.52 +		MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
   11.53 +
   11.54 +	if (tap_aio_init(&s->async, bs->td_state->size, max_aio_reqs)) {
   11.55  		DPRINTF("Unable to initialise AIO state\n");
   11.56 -		free_aio_state(bs);
   11.57 +		tap_aio_free(&s->async);
   11.58  		goto fail;
   11.59  	}
   11.60  
   11.61 @@ -496,7 +485,7 @@ static int qcow_open(struct disk_driver 
   11.62  	DPRINTF("qcow_open failed\n");
   11.63  
   11.64  #ifdef USE_AIO	
   11.65 -	free_aio_state(bs);
   11.66 +	tap_aio_free(&s->async);
   11.67  #endif
   11.68  
   11.69  	qcow_free_snapshots(bs);
   11.70 @@ -1070,200 +1059,6 @@ static int qcow_write(struct disk_driver
   11.71  #ifdef USE_AIO
   11.72  
   11.73  /*
   11.74 - * General AIO helper functions
   11.75 - */
   11.76 -
   11.77 -#define IOCB_IDX(_s, _io) ((_io) - (_s)->async.iocb_list)
   11.78 -
   11.79 -struct pending_aio {
   11.80 -	td_callback_t cb;
   11.81 -	int id;
   11.82 -	void *private;
   11.83 -	int nb_sectors;
   11.84 -	char *buf;
   11.85 -	uint64_t sector;
   11.86 -};
   11.87 -
   11.88 -
   11.89 -static int init_aio_state(struct disk_driver *dd)
   11.90 -{
   11.91 -	int i, ret;
   11.92 -	struct td_state *bs = dd->td_state;
   11.93 -	struct BDRVQcowState *s = (struct BDRVQcowState*) dd->private;
   11.94 -	long ioidx;
   11.95 -
   11.96 -	s->async.iocb_list = NULL;
   11.97 -	s->async.pending_aio = NULL;
   11.98 -	s->async.aio_events = NULL;
   11.99 -	s->async.iocb_free = NULL;
  11.100 -	s->async.iocb_queue = NULL;
  11.101 -
  11.102 -	/*Initialize Locking bitmap*/
  11.103 -	s->async.sector_lock = calloc(1, bs->size);
  11.104 -		
  11.105 -	if (!s->async.sector_lock) {
  11.106 -		DPRINTF("Failed to allocate sector lock\n");
  11.107 -		goto fail;
  11.108 -	}
  11.109 -
  11.110 -	/* A segment (i.e. a page) can span multiple clusters */
  11.111 -	s->async.max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) *
  11.112 -		MAX_SEGMENTS_PER_REQ * MAX_REQUESTS;
  11.113 -
  11.114 -	/* Initialize AIO */
  11.115 -	s->async.iocb_free_count = s->async.max_aio_reqs;
  11.116 -	s->async.iocb_queued	 = 0;
  11.117 -
  11.118 -	if (!(s->async.iocb_list = malloc(sizeof(struct iocb) * s->async.max_aio_reqs)) ||
  11.119 -		!(s->async.pending_aio = malloc(sizeof(struct pending_aio) * s->async.max_aio_reqs)) ||
  11.120 -		!(s->async.aio_events = malloc(sizeof(struct io_event) * s->async.max_aio_reqs)) ||
  11.121 -		!(s->async.iocb_free = malloc(sizeof(struct iocb *) * s->async.max_aio_reqs)) ||
  11.122 -		!(s->async.iocb_queue = malloc(sizeof(struct iocb *) * s->async.max_aio_reqs))) 
  11.123 -	{
  11.124 -		DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
  11.125 -				s->async.max_aio_reqs);
  11.126 -		goto fail;
  11.127 -	}
  11.128 -
  11.129 -	ret = tap_aio_setup(&s->async.aio_ctx, s->async.aio_events, s->async.max_aio_reqs);
  11.130 -	if (ret < 0) {
  11.131 -		if (ret == -EAGAIN) {
  11.132 -			DPRINTF("Couldn't setup AIO context.  If you are "
  11.133 -				"trying to concurrently use a large number "
  11.134 -				"of blktap-based disks, you may need to "
  11.135 -				"increase the system-wide aio request limit. "
  11.136 -				"(e.g. 'echo echo 1048576 > /proc/sys/fs/"
  11.137 -				"aio-max-nr')\n");
  11.138 -		} else {
  11.139 -			DPRINTF("Couldn't setup AIO context.\n");
  11.140 -		}
  11.141 -		goto fail;
  11.142 -	}
  11.143 -
  11.144 -	for (i=0;i<s->async.max_aio_reqs;i++)
  11.145 -			s->async.iocb_free[i] = &s->async.iocb_list[i];
  11.146 -
  11.147 -	DPRINTF("AIO state initialised\n");
  11.148 -
  11.149 -	return 0;
  11.150 -
  11.151 -fail:
  11.152 -	return -1;
  11.153 -}
  11.154 -
  11.155 -static void free_aio_state(struct disk_driver *dd)
  11.156 -{
  11.157 -	struct BDRVQcowState *s = (struct BDRVQcowState*) dd->private;
  11.158 -
  11.159 -	if (s->async.sector_lock)
  11.160 -		free(s->async.sector_lock);
  11.161 -	if (s->async.iocb_list)
  11.162 -		free(s->async.iocb_list);
  11.163 -	if (s->async.pending_aio)
  11.164 -		free(s->async.pending_aio);
  11.165 -	if (s->async.aio_events)
  11.166 -		free(s->async.aio_events);
  11.167 -	if (s->async.iocb_free)
  11.168 -		free(s->async.iocb_free);
  11.169 -	if (s->async.iocb_queue)
  11.170 -		free(s->async.iocb_queue);
  11.171 -}
  11.172 -
  11.173 -static int async_read(struct BDRVQcowState *s, int size, 
  11.174 -		uint64_t offset, char *buf, td_callback_t cb,
  11.175 -		int id, uint64_t sector, void *private)
  11.176 -{
  11.177 -	struct	 iocb *io;
  11.178 -	struct	 pending_aio *pio;
  11.179 -	long	 ioidx;
  11.180 -
  11.181 -	io = s->async.iocb_free[--s->async.iocb_free_count];
  11.182 -
  11.183 -	ioidx = IOCB_IDX(s, io);
  11.184 -	pio = &s->async.pending_aio[ioidx];
  11.185 -	pio->cb = cb;
  11.186 -	pio->id = id;
  11.187 -	pio->private = private;
  11.188 -	pio->nb_sectors = size/512;
  11.189 -	pio->buf = buf;
  11.190 -	pio->sector = sector;
  11.191 -
  11.192 -	io_prep_pread(io, s->fd, buf, size, offset);
  11.193 -	io->data = (void *)ioidx;
  11.194 -
  11.195 -	s->async.iocb_queue[s->async.iocb_queued++] = io;
  11.196 -
  11.197 -	return 1;
  11.198 -}
  11.199 -
  11.200 -static int async_write(struct BDRVQcowState *s, int size,
  11.201 -		uint64_t offset, char *buf, td_callback_t cb,
  11.202 -		int id, uint64_t sector, void *private)
  11.203 -{
  11.204 -	struct	 iocb *io;
  11.205 -	struct	 pending_aio *pio;
  11.206 -	long	 ioidx;
  11.207 -
  11.208 -	io = s->async.iocb_free[--s->async.iocb_free_count];
  11.209 -
  11.210 -	ioidx = IOCB_IDX(s, io);
  11.211 -	pio = &s->async.pending_aio[ioidx];
  11.212 -	pio->cb = cb;
  11.213 -	pio->id = id;
  11.214 -	pio->private = private;
  11.215 -	pio->nb_sectors = size/512;
  11.216 -	pio->buf = buf;
  11.217 -	pio->sector = sector;
  11.218 -
  11.219 -	io_prep_pwrite(io, s->fd, buf, size, offset);
  11.220 -	io->data = (void *)ioidx;
  11.221 -
  11.222 -	s->async.iocb_queue[s->async.iocb_queued++] = io;
  11.223 -
  11.224 -	return 1;
  11.225 -}
  11.226 -
  11.227 -static int async_submit(struct disk_driver *dd)
  11.228 -{
  11.229 -	int ret;
  11.230 -	struct BDRVQcowState *prv = (struct BDRVQcowState*) dd->private;
  11.231 -
  11.232 -	if (!prv->async.iocb_queued)
  11.233 -		return 0;
  11.234 -
  11.235 -	ret = io_submit(prv->async.aio_ctx.aio_ctx, prv->async.iocb_queued, prv->async.iocb_queue);
  11.236 -
  11.237 -	/* XXX: TODO: Handle error conditions here. */
  11.238 -
  11.239 -	/* Success case: */
  11.240 -	prv->async.iocb_queued = 0;
  11.241 -
  11.242 -	return 0;
  11.243 -}
  11.244 -
  11.245 -/*TODO: Fix sector span!*/
  11.246 -static int aio_can_lock(struct BDRVQcowState *s, uint64_t sector)
  11.247 -{
  11.248 -	return (s->async.sector_lock[sector] ? 0 : 1);
  11.249 -}
  11.250 -
  11.251 -static int aio_lock(struct BDRVQcowState *s, uint64_t sector)
  11.252 -{
  11.253 -	return ++s->async.sector_lock[sector];
  11.254 -}
  11.255 -
  11.256 -static void aio_unlock(struct BDRVQcowState *s, uint64_t sector)
  11.257 -{
  11.258 -	if (!s->async.sector_lock[sector]) return;
  11.259 -
  11.260 -	--s->async.sector_lock[sector];
  11.261 -	return;
  11.262 -}
  11.263 -
  11.264 -
  11.265 -
  11.266 -
  11.267 -/*
  11.268   * QCOW2 specific AIO functions
  11.269   */
  11.270  
  11.271 @@ -1278,7 +1073,7 @@ static int qcow_queue_read(struct disk_d
  11.272  
  11.273  	/*Check we can get a lock*/
  11.274  	for (i = 0; i < nb_sectors; i++) 
  11.275 -		if (!aio_can_lock(s, sector + i)) 
  11.276 +		if (!tap_aio_can_lock(&s->async, sector + i)) 
  11.277  			return cb(bs, -EBUSY, sector, nb_sectors, id, private);
  11.278  
  11.279  	while (nb_sectors > 0) {
  11.280 @@ -1290,13 +1085,13 @@ static int qcow_queue_read(struct disk_d
  11.281  		if (n > nb_sectors)
  11.282  			n = nb_sectors;
  11.283  
  11.284 -		if (s->async.iocb_free_count == 0 || !aio_lock(s, sector)) 
  11.285 +		if (s->async.iocb_free_count == 0 || !tap_aio_lock(&s->async, sector)) 
  11.286  			return cb(bs, -EBUSY, sector, nb_sectors, id, private);
  11.287  
  11.288  		if (!cluster_offset) {
  11.289  
  11.290  			/* The requested sector is not allocated */
  11.291 -			aio_unlock(s, sector);
  11.292 +			tap_aio_unlock(&s->async, sector);
  11.293  			ret = cb(bs, BLK_NOT_ALLOCATED, 
  11.294  					sector, n, id, private);
  11.295  			if (ret == -EBUSY) {
  11.296 @@ -1311,7 +1106,7 @@ static int qcow_queue_read(struct disk_d
  11.297  		} else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
  11.298  
  11.299  			/* sync read for compressed clusters */
  11.300 -			aio_unlock(s, sector);
  11.301 +			tap_aio_unlock(&s->async, sector);
  11.302  			if (decompress_cluster(s, cluster_offset) < 0) {
  11.303  				rsp += cb(bs, -EIO, sector, nb_sectors, id, private);
  11.304  				goto done;
  11.305 @@ -1323,7 +1118,7 @@ static int qcow_queue_read(struct disk_d
  11.306  		} else {
  11.307  
  11.308  			/* async read */
  11.309 -			async_read(s, n * 512, 
  11.310 +			tap_aio_read(&s->async, s->fd, n * 512, 
  11.311  					(cluster_offset + index_in_cluster * 512),
  11.312  					buf, cb, id, sector, private);
  11.313  		}
  11.314 @@ -1351,7 +1146,7 @@ static int qcow_queue_write(struct disk_
  11.315  	
  11.316  	/*Check we can get a lock*/
  11.317  	for (i = 0; i < nb_sectors; i++) 
  11.318 -		if (!aio_can_lock(s, sector + i)) 
  11.319 +		if (!tap_aio_can_lock(&s->async, sector + i)) 
  11.320  			return cb(bs, -EBUSY, sector, nb_sectors, id, private);
  11.321  
  11.322  
  11.323 @@ -1362,7 +1157,7 @@ static int qcow_queue_write(struct disk_
  11.324  		if (n > nb_sectors)
  11.325  			n = nb_sectors;
  11.326  
  11.327 -		if (s->async.iocb_free_count == 0 || !aio_lock(s, sector))
  11.328 +		if (s->async.iocb_free_count == 0 || !tap_aio_lock(&s->async, sector))
  11.329  			return cb(bs, -EBUSY, sector, nb_sectors, id, private);
  11.330  
  11.331  
  11.332 @@ -1372,14 +1167,14 @@ static int qcow_queue_write(struct disk_
  11.333  
  11.334  		if (!cluster_offset) {
  11.335  			DPRINTF("Ooops, no write cluster offset!\n");
  11.336 -			aio_unlock(s, sector);
  11.337 +			tap_aio_unlock(&s->async, sector);
  11.338  			return cb(bs, -EIO, sector, nb_sectors, id, private);
  11.339  		}
  11.340  
  11.341  
  11.342  		// TODO Encryption
  11.343  
  11.344 -		async_write(s, n * 512, 
  11.345 +		tap_aio_write(&s->async, s->fd, n * 512, 
  11.346  				(cluster_offset + index_in_cluster*512),
  11.347  				buf, cb, id, sector, private);
  11.348  
  11.349 @@ -1402,9 +1197,14 @@ static int qcow_queue_write(struct disk_
  11.350  static int qcow_close(struct disk_driver *bs)
  11.351  {
  11.352  	BDRVQcowState *s = bs->private;
  11.353 -		
  11.354 +	
  11.355 +#ifdef USE_AIO	
  11.356 +	io_destroy(s->async.aio_ctx.aio_ctx);
  11.357 +	tap_aio_free(&s->async);
  11.358 +#else		
  11.359  	close(s->poll_pipe[0]);
  11.360 -		close(s->poll_pipe[1]);
  11.361 +	close(s->poll_pipe[1]);
  11.362 +#endif		
  11.363  
  11.364  	qemu_free(s->l1_table);
  11.365  	qemu_free(s->l2_cache);
  11.366 @@ -1606,23 +1406,10 @@ static int qcow_write_compressed(struct 
  11.367  
  11.368  static int qcow_submit(struct disk_driver *bs)
  11.369  {
  11.370 -	int ret;
  11.371 -	struct	 BDRVQcowState *prv = (struct BDRVQcowState*)bs->private;
  11.372 -
  11.373 -
  11.374 -	fsync(prv->fd);
  11.375 +	struct BDRVQcowState *s = (struct BDRVQcowState*) bs->private;
  11.376  
  11.377 -	if (!prv->async.iocb_queued)
  11.378 -		return 0;
  11.379 -
  11.380 -	ret = io_submit(prv->async.aio_ctx.aio_ctx, prv->async.iocb_queued, prv->async.iocb_queue);
  11.381 -
  11.382 -	/* XXX: TODO: Handle error conditions here. */
  11.383 -
  11.384 -	/* Success case: */
  11.385 -	prv->async.iocb_queued = 0;
  11.386 -
  11.387 -	return 0;
  11.388 +	fsync(s->fd);
  11.389 +	return tap_aio_submit(&s->async);
  11.390  }
  11.391  
  11.392  
  11.393 @@ -2246,7 +2033,7 @@ repeat:
  11.394  
  11.395  		pio = &prv->async.pending_aio[(long)io->data];
  11.396  
  11.397 -		aio_unlock(prv, pio->sector);
  11.398 +		tap_aio_unlock(&prv->async, pio->sector);
  11.399  
  11.400  		if (prv->crypt_method)
  11.401  			encrypt_sectors(prv, pio->sector, 
    12.1 --- a/tools/blktap/drivers/tapaio.c	Mon Feb 25 06:29:01 2008 -0700
    12.2 +++ b/tools/blktap/drivers/tapaio.c	Tue Feb 26 10:12:04 2008 -0700
    12.3 @@ -32,6 +32,7 @@
    12.4  #include <unistd.h>
    12.5  #include <errno.h>
    12.6  #include <string.h>
    12.7 +#include <stdlib.h>
    12.8  
    12.9  /**
   12.10   * We used a kernel patch to return an fd associated with the AIO context
   12.11 @@ -62,7 +63,7 @@
   12.12  static void *
   12.13  tap_aio_completion_thread(void *arg)
   12.14  {
   12.15 -	tap_aio_context_t *ctx = (tap_aio_context_t *) arg;
   12.16 +	tap_aio_internal_context_t *ctx = (tap_aio_internal_context_t *) arg;
   12.17  	int command;
   12.18  	int nr_events;
   12.19  	int rc;
   12.20 @@ -84,7 +85,7 @@ tap_aio_completion_thread(void *arg)
   12.21  }
   12.22  
   12.23  void
   12.24 -tap_aio_continue(tap_aio_context_t *ctx)
   12.25 +tap_aio_continue(tap_aio_internal_context_t *ctx)
   12.26  {
   12.27          int cmd = 0;
   12.28  
   12.29 @@ -95,8 +96,8 @@ tap_aio_continue(tap_aio_context_t *ctx)
   12.30                  DPRINTF("Cannot write to command pipe\n");
   12.31  }
   12.32  
   12.33 -int
   12.34 -tap_aio_setup(tap_aio_context_t *ctx,
   12.35 +static int
   12.36 +tap_aio_setup(tap_aio_internal_context_t *ctx,
   12.37                struct io_event *aio_events,
   12.38                int max_aio_events)
   12.39  {
   12.40 @@ -144,7 +145,7 @@ tap_aio_setup(tap_aio_context_t *ctx,
   12.41  }
   12.42  
   12.43  int
   12.44 -tap_aio_get_events(tap_aio_context_t *ctx)
   12.45 +tap_aio_get_events(tap_aio_internal_context_t *ctx)
   12.46  {
   12.47          int nr_events = 0;
   12.48  
   12.49 @@ -171,10 +172,185 @@ tap_aio_get_events(tap_aio_context_t *ct
   12.50          return nr_events;
   12.51  }
   12.52  
   12.53 -int tap_aio_more_events(tap_aio_context_t *ctx)
   12.54 +int tap_aio_more_events(tap_aio_internal_context_t *ctx)
   12.55  {
   12.56          return io_getevents(ctx->aio_ctx, 0,
   12.57                              ctx->max_aio_events, ctx->aio_events, NULL);
   12.58  }
   12.59  
   12.60 +int tap_aio_init(tap_aio_context_t *ctx, uint64_t sectors,
   12.61 +		int max_aio_reqs)
   12.62 +{
   12.63 +	int i, ret;
   12.64 +	long ioidx;
   12.65  
   12.66 +	ctx->iocb_list = NULL;
   12.67 +	ctx->pending_aio = NULL;
   12.68 +	ctx->aio_events = NULL;
   12.69 +	ctx->iocb_free = NULL;
   12.70 +	ctx->iocb_queue = NULL;
   12.71 +
   12.72 +	/*Initialize Locking bitmap*/
   12.73 +	ctx->sector_lock = calloc(1, sectors);
   12.74 +		
   12.75 +	if (!ctx->sector_lock) {
   12.76 +		DPRINTF("Failed to allocate sector lock\n");
   12.77 +		goto fail;
   12.78 +	}
   12.79 +
   12.80 +
   12.81 +	/* Initialize AIO */
   12.82 +	ctx->max_aio_reqs = max_aio_reqs;
   12.83 +	ctx->iocb_free_count = ctx->max_aio_reqs;
   12.84 +	ctx->iocb_queued	 = 0;
   12.85 +
   12.86 +	if (!(ctx->iocb_list = malloc(sizeof(struct iocb) * ctx->max_aio_reqs)) ||
   12.87 +		!(ctx->pending_aio = malloc(sizeof(struct pending_aio) * ctx->max_aio_reqs)) ||
   12.88 +		!(ctx->aio_events = malloc(sizeof(struct io_event) * ctx->max_aio_reqs)) ||
   12.89 +		!(ctx->iocb_free = malloc(sizeof(struct iocb *) * ctx->max_aio_reqs)) ||
   12.90 +		!(ctx->iocb_queue = malloc(sizeof(struct iocb *) * ctx->max_aio_reqs))) 
   12.91 +	{
   12.92 +		DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n",
   12.93 +				ctx->max_aio_reqs);
   12.94 +		goto fail;
   12.95 +	}
   12.96 +
   12.97 +	ret = tap_aio_setup(&ctx->aio_ctx, ctx->aio_events, ctx->max_aio_reqs);
   12.98 +	if (ret < 0) {
   12.99 +		if (ret == -EAGAIN) {
  12.100 +			DPRINTF("Couldn't setup AIO context.  If you are "
  12.101 +				"trying to concurrently use a large number "
  12.102 +				"of blktap-based disks, you may need to "
  12.103 +				"increase the system-wide aio request limit. "
  12.104 +				"(e.g. 'echo echo 1048576 > /proc/sys/fs/"
  12.105 +				"aio-max-nr')\n");
  12.106 +		} else {
  12.107 +			DPRINTF("Couldn't setup AIO context.\n");
  12.108 +		}
  12.109 +		goto fail;
  12.110 +	}
  12.111 +
  12.112 +	for (i=0;i<ctx->max_aio_reqs;i++)
  12.113 +		ctx->iocb_free[i] = &ctx->iocb_list[i];
  12.114 +
  12.115 +	DPRINTF("AIO state initialised\n");
  12.116 +
  12.117 +	return 0;
  12.118 +
  12.119 +fail:
  12.120 +	return -1;
  12.121 +}
  12.122 +
  12.123 +void tap_aio_free(tap_aio_context_t *ctx)
  12.124 +{
  12.125 +	if (ctx->sector_lock)
  12.126 +		free(ctx->sector_lock);
  12.127 +	if (ctx->iocb_list)
  12.128 +		free(ctx->iocb_list);
  12.129 +	if (ctx->pending_aio)
  12.130 +		free(ctx->pending_aio);
  12.131 +	if (ctx->aio_events)
  12.132 +		free(ctx->aio_events);
  12.133 +	if (ctx->iocb_free)
  12.134 +		free(ctx->iocb_free);
  12.135 +	if (ctx->iocb_queue)
  12.136 +		free(ctx->iocb_queue);
  12.137 +}
  12.138 +
  12.139 +/*TODO: Fix sector span!*/
  12.140 +int tap_aio_can_lock(tap_aio_context_t *ctx, uint64_t sector)
  12.141 +{
  12.142 +	return (ctx->sector_lock[sector] ? 0 : 1);
  12.143 +}
  12.144 +
  12.145 +int tap_aio_lock(tap_aio_context_t *ctx, uint64_t sector)
  12.146 +{
  12.147 +	return ++ctx->sector_lock[sector];
  12.148 +}
  12.149 +
  12.150 +void tap_aio_unlock(tap_aio_context_t *ctx, uint64_t sector)
  12.151 +{
  12.152 +	if (!ctx->sector_lock[sector]) return;
  12.153 +
  12.154 +	--ctx->sector_lock[sector];
  12.155 +	return;
  12.156 +}
  12.157 +
  12.158 +
  12.159 +int tap_aio_read(tap_aio_context_t *ctx, int fd, int size, 
  12.160 +		uint64_t offset, char *buf, td_callback_t cb,
  12.161 +		int id, uint64_t sector, void *private)
  12.162 +{
  12.163 +	struct	 iocb *io;
  12.164 +	struct	 pending_aio *pio;
  12.165 +	long	 ioidx;
  12.166 +
  12.167 +	if (ctx->iocb_free_count == 0)
  12.168 +		return -ENOMEM;
  12.169 +
  12.170 +	io = ctx->iocb_free[--ctx->iocb_free_count];
  12.171 +
  12.172 +	ioidx = IOCB_IDX(ctx, io);
  12.173 +	pio = &ctx->pending_aio[ioidx];
  12.174 +	pio->cb = cb;
  12.175 +	pio->id = id;
  12.176 +	pio->private = private;
  12.177 +	pio->nb_sectors = size/512;
  12.178 +	pio->buf = buf;
  12.179 +	pio->sector = sector;
  12.180 +
  12.181 +	io_prep_pread(io, fd, buf, size, offset);
  12.182 +	io->data = (void *)ioidx;
  12.183 +
  12.184 +	ctx->iocb_queue[ctx->iocb_queued++] = io;
  12.185 +
  12.186 +	return 0;
  12.187 +}
  12.188 +
  12.189 +int tap_aio_write(tap_aio_context_t *ctx, int fd, int size,
  12.190 +		uint64_t offset, char *buf, td_callback_t cb,
  12.191 +		int id, uint64_t sector, void *private)
  12.192 +{
  12.193 +	struct	 iocb *io;
  12.194 +	struct	 pending_aio *pio;
  12.195 +	long	 ioidx;
  12.196 +
  12.197 +	if (ctx->iocb_free_count == 0)
  12.198 +		return -ENOMEM;
  12.199 +
  12.200 +	io = ctx->iocb_free[--ctx->iocb_free_count];
  12.201 +
  12.202 +	ioidx = IOCB_IDX(ctx, io);
  12.203 +	pio = &ctx->pending_aio[ioidx];
  12.204 +	pio->cb = cb;
  12.205 +	pio->id = id;
  12.206 +	pio->private = private;
  12.207 +	pio->nb_sectors = size/512;
  12.208 +	pio->buf = buf;
  12.209 +	pio->sector = sector;
  12.210 +
  12.211 +	io_prep_pwrite(io, fd, buf, size, offset);
  12.212 +	io->data = (void *)ioidx;
  12.213 +
  12.214 +	ctx->iocb_queue[ctx->iocb_queued++] = io;
  12.215 +
  12.216 +	return 0;
  12.217 +}
  12.218 +
  12.219 +int tap_aio_submit(tap_aio_context_t *ctx)
  12.220 +{
  12.221 +	int ret;
  12.222 +
  12.223 +	if (!ctx->iocb_queued)
  12.224 +		return 0;
  12.225 +
  12.226 +	ret = io_submit(ctx->aio_ctx.aio_ctx, ctx->iocb_queued, ctx->iocb_queue);
  12.227 +
  12.228 +	/* XXX: TODO: Handle error conditions here. */
  12.229 +
  12.230 +	/* Success case: */
  12.231 +	ctx->iocb_queued = 0;
  12.232 +
  12.233 +	return 0;
  12.234 +}
  12.235 +
    13.1 --- a/tools/blktap/drivers/tapaio.h	Mon Feb 25 06:29:01 2008 -0700
    13.2 +++ b/tools/blktap/drivers/tapaio.h	Tue Feb 26 10:12:04 2008 -0700
    13.3 @@ -32,8 +32,13 @@
    13.4  
    13.5  #include <pthread.h>
    13.6  #include <libaio.h>
    13.7 +#include <stdint.h>
    13.8  
    13.9 -struct tap_aio_context {
   13.10 +#include "tapdisk.h"
   13.11 +
   13.12 +#define IOCB_IDX(_ctx, _io) ((_io) - (_ctx)->iocb_list)
   13.13 +
   13.14 +struct tap_aio_internal_context {
   13.15          io_context_t     aio_ctx;
   13.16  
   13.17          struct io_event *aio_events;
   13.18 @@ -45,14 +50,59 @@ struct tap_aio_context {
   13.19          int              pollfd;
   13.20          unsigned int     poll_in_thread : 1;
   13.21  };
   13.22 +	
   13.23 +
   13.24 +typedef struct tap_aio_internal_context tap_aio_internal_context_t;
   13.25 +
   13.26 +
   13.27 +struct pending_aio {
   13.28 +	td_callback_t cb;
   13.29 +	int id;
   13.30 +	void *private;
   13.31 +	int nb_sectors;
   13.32 +	char *buf;
   13.33 +	uint64_t sector;
   13.34 +};
   13.35 +
   13.36 +	
   13.37 +struct tap_aio_context {
   13.38 +	tap_aio_internal_context_t    aio_ctx;
   13.39 +
   13.40 +	int                  max_aio_reqs;
   13.41 +	struct iocb         *iocb_list;
   13.42 +	struct iocb        **iocb_free;
   13.43 +	struct pending_aio  *pending_aio;
   13.44 +	int                  iocb_free_count;
   13.45 +	struct iocb        **iocb_queue;
   13.46 +	int	             iocb_queued;
   13.47 +	struct io_event     *aio_events;
   13.48 +
   13.49 +	/* Locking bitmap for AIO reads/writes */
   13.50 +	uint8_t *sector_lock;		   
   13.51 +};
   13.52  
   13.53  typedef struct tap_aio_context tap_aio_context_t;
   13.54  
   13.55 -int  tap_aio_setup      (tap_aio_context_t *ctx,
   13.56 -                         struct io_event *aio_events,
   13.57 -                         int max_aio_events);
   13.58 -void tap_aio_continue   (tap_aio_context_t *ctx);
   13.59 -int  tap_aio_get_events (tap_aio_context_t *ctx);
   13.60 -int  tap_aio_more_events(tap_aio_context_t *ctx);
   13.61 +void tap_aio_continue   (tap_aio_internal_context_t *ctx);
   13.62 +int  tap_aio_get_events (tap_aio_internal_context_t *ctx);
   13.63 +int  tap_aio_more_events(tap_aio_internal_context_t *ctx);
   13.64 +
   13.65 +
   13.66 +int tap_aio_init(tap_aio_context_t *ctx, uint64_t sectors,
   13.67 +		int max_aio_reqs);
   13.68 +void tap_aio_free(tap_aio_context_t *ctx);
   13.69 +
   13.70 +int tap_aio_can_lock(tap_aio_context_t *ctx, uint64_t sector);
   13.71 +int tap_aio_lock(tap_aio_context_t *ctx, uint64_t sector);
   13.72 +void tap_aio_unlock(tap_aio_context_t *ctx, uint64_t sector);
   13.73 +
   13.74 +
   13.75 +int tap_aio_read(tap_aio_context_t *ctx, int fd, int size, 
   13.76 +		uint64_t offset, char *buf, td_callback_t cb,
   13.77 +		int id, uint64_t sector, void *private);
   13.78 +int tap_aio_write(tap_aio_context_t *ctx, int fd, int size,
   13.79 +		uint64_t offset, char *buf, td_callback_t cb,
   13.80 +		int id, uint64_t sector, void *private);
   13.81 +int tap_aio_submit(tap_aio_context_t *ctx);
   13.82  
   13.83  #endif /* __TAPAIO_H__ */
    14.1 --- a/tools/examples/vtpm-common.sh	Mon Feb 25 06:29:01 2008 -0700
    14.2 +++ b/tools/examples/vtpm-common.sh	Tue Feb 26 10:12:04 2008 -0700
    14.3 @@ -407,7 +407,7 @@ function vtpm_domid_from_name () {
    14.4  	local id name ids
    14.5  	ids=$(xenstore-list /local/domain)
    14.6  	for id in $ids; do
    14.7 -		name=$(xenstore_read /local/domain/$id/name)
    14.8 +		name=$(xenstore-read /local/domain/$id/name)
    14.9  		if [ "$name" == "$1" ]; then
   14.10  			echo "$id"
   14.11  			return
   14.12 @@ -416,16 +416,33 @@ function vtpm_domid_from_name () {
   14.13  	echo "-1"
   14.14  }
   14.15  
   14.16 +#Determine the virtual TPM's instance number using the domain ID.
   14.17 +#1st parm: domain ID
   14.18 +function vtpm_uuid_by_domid() {
   14.19 +	echo $(xenstore-read /local/domain/0/backend/vtpm/$1/0/uuid)
   14.20 +}
   14.21 +
   14.22 +
   14.23 +# Determine the vTPM's UUID by the name of the VM
   14.24 +function vtpm_uuid_from_vmname() {
   14.25 +	local domid=$(vtpm_domid_from_name $1)
   14.26 +	if [ "$domid" != "-1" ]; then
   14.27 +		echo $(vtpm_uuid_by_domid $domid)
   14.28 +		return
   14.29 +	fi
   14.30 +	echo ""
   14.31 +}
   14.32  
   14.33  #Add a virtual TPM instance number and its associated domain name
   14.34  #to the VTPMDB file and activate usage of this virtual TPM instance
   14.35  #by writing the instance number into the xenstore
   14.36  #1st parm: name of virtual machine
   14.37 -#2nd parm: instance of assoicate virtual TPM
   14.38 +#2nd parm: instance of associated virtual TPM
   14.39  function vtpm_add_and_activate() {
   14.40  	local domid=$(vtpm_domid_from_name $1)
   14.41 -	if [ "$domid" != "-1" ]; then
   14.42 -		vtpmdb_add_instance $1 $2
   14.43 +	local vtpm_uuid=$(vtpm_uuid_from_vmname $1)
   14.44 +	if [ "$vtpm_uuid" != "" -a "$domid" != "-1" ]; then
   14.45 +		vtpmdb_add_instance $vtpm_uuid $2
   14.46  		xenstore-write backend/vtpm/$domid/0/instance $2
   14.47  	fi
   14.48  }
    15.1 --- a/tools/examples/vtpm-delete	Mon Feb 25 06:29:01 2008 -0700
    15.2 +++ b/tools/examples/vtpm-delete	Tue Feb 26 10:12:04 2008 -0700
    15.3 @@ -1,9 +1,18 @@
    15.4  #!/bin/bash
    15.5  
    15.6  # This scripts must be called the following way:
    15.7 -# vtpm-delete <domain name>
    15.8 +# vtpm-delete <vtpm uuid>
    15.9 +# or
   15.10 +# vtpm-delete --vmname <vm name>
   15.11  
   15.12  dir=$(dirname "$0")
   15.13  . "$dir/vtpm-common.sh"
   15.14  
   15.15 -vtpm_delete_instance $1
   15.16 +if [ "$1" == "--vmname" ]; then
   15.17 +	vtpm_uuid=$(vtpm_uuid_from_vmname $2)
   15.18 +	if [ "$vtpm_uuid" != "" ];then
   15.19 +		vtpm_delete_instance $vtpm_uuid
   15.20 +	fi
   15.21 +else
   15.22 +	vtpm_delete_instance $1
   15.23 +fi
    16.1 --- a/tools/firmware/hvmloader/acpi/build.c	Mon Feb 25 06:29:01 2008 -0700
    16.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Tue Feb 26 10:12:04 2008 -0700
    16.3 @@ -189,80 +189,6 @@ static int construct_hpet(struct acpi_20
    16.4      return offset;
    16.5  }
    16.6  
    16.7 -static int construct_processor_objects(uint8_t *buf)
    16.8 -{
    16.9 -    static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 };
   16.10 -    static const char hex[] = "0123456789ABCDEF";
   16.11 -    static const char pr_scope[] = "\\_PR_";
   16.12 -    unsigned int i, length, nr_cpus = get_vcpu_nr();
   16.13 -    struct acpi_header *hdr;
   16.14 -    uint8_t *p = buf;
   16.15 -
   16.16 -    /*
   16.17 -     * 1. Table Header.
   16.18 -     */
   16.19 -
   16.20 -    hdr = (struct acpi_header *)p;
   16.21 -    hdr->signature = ASCII32('S','S','D','T');
   16.22 -    hdr->revision  = 2;
   16.23 -    fixed_strcpy(hdr->oem_id, ACPI_OEM_ID);
   16.24 -    fixed_strcpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID);
   16.25 -    hdr->oem_revision = ACPI_OEM_REVISION;
   16.26 -    hdr->creator_id = ACPI_CREATOR_ID;
   16.27 -    hdr->creator_revision = ACPI_CREATOR_REVISION;
   16.28 -    p += sizeof(*hdr);
   16.29 -
   16.30 -    /*
   16.31 -     * 2. Scope Definition.
   16.32 -     */
   16.33 -
   16.34 -    /* ScopeOp */
   16.35 -    *p++ = 0x10;
   16.36 -
   16.37 -    /* PkgLength (includes length bytes!). */
   16.38 -    length = 1 + strlen(pr_scope) + (nr_cpus * sizeof(pdat));
   16.39 -    if ( length <= 0x3f )
   16.40 -    {
   16.41 -        *p++ = length;
   16.42 -    }
   16.43 -    else if ( ++length <= 0xfff )
   16.44 -    {
   16.45 -        *p++ = 0x40 | (length & 0xf);
   16.46 -        *p++ = length >> 4;
   16.47 -    }
   16.48 -    else
   16.49 -    {
   16.50 -        length++;
   16.51 -        *p++ = 0x80 | (length & 0xf);
   16.52 -        *p++ = (length >>  4) & 0xff;
   16.53 -        *p++ = (length >> 12) & 0xff;
   16.54 -    }
   16.55 -
   16.56 -    /* NameString */
   16.57 -    strncpy((char *)p, pr_scope, strlen(pr_scope));
   16.58 -    p += strlen(pr_scope);
   16.59 -
   16.60 -    /*
   16.61 -     * 3. Processor Objects.
   16.62 -     */
   16.63 -
   16.64 -    for ( i = 0; i < nr_cpus; i++ )
   16.65 -    {
   16.66 -        memcpy(p, pdat, sizeof(pdat));
   16.67 -        /* ProcessorName */
   16.68 -        p[5] = hex[(i>>4)&15];
   16.69 -        p[6] = hex[(i>>0)&15];
   16.70 -        /* ProcessorID */
   16.71 -        p[7] = i;
   16.72 -        p += sizeof(pdat);
   16.73 -    }
   16.74 -
   16.75 -    hdr->length = p - buf;
   16.76 -    set_checksum(hdr, offsetof(struct acpi_header, checksum), hdr->length);
   16.77 -
   16.78 -    return hdr->length;
   16.79 -}
   16.80 -
   16.81  static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
   16.82  {
   16.83      int offset = 0, nr_tables = 0;
   16.84 @@ -288,10 +214,6 @@ static int construct_secondary_tables(ui
   16.85          table_ptrs[nr_tables++] = (unsigned long)hpet;
   16.86      }
   16.87  
   16.88 -    /* Processor Object SSDT. */
   16.89 -    table_ptrs[nr_tables++] = (unsigned long)&buf[offset];
   16.90 -    offset += construct_processor_objects(&buf[offset]);
   16.91 -
   16.92      /* TPM TCPA and SSDT. */
   16.93      tis_hdr = (uint16_t *)0xFED40F00;
   16.94      if ( (tis_hdr[0] == tis_signature[0]) &&
    17.1 --- a/tools/firmware/hvmloader/acpi/dsdt.asl	Mon Feb 25 06:29:01 2008 -0700
    17.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl	Tue Feb 26 10:12:04 2008 -0700
    17.3 @@ -27,6 +27,26 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
    17.4      Name (\APCL, 0x00010000)
    17.5      Name (\PUID, 0x00)
    17.6  
    17.7 +    Scope (\_PR)
    17.8 +    {
    17.9 +        Processor (PR00, 0x00, 0x0000, 0x00) {}
   17.10 +        Processor (PR01, 0x01, 0x0000, 0x00) {}
   17.11 +        Processor (PR02, 0x02, 0x0000, 0x00) {}
   17.12 +        Processor (PR03, 0x03, 0x0000, 0x00) {}
   17.13 +        Processor (PR04, 0x00, 0x0000, 0x00) {}
   17.14 +        Processor (PR05, 0x01, 0x0000, 0x00) {}
   17.15 +        Processor (PR06, 0x02, 0x0000, 0x00) {}
   17.16 +        Processor (PR07, 0x03, 0x0000, 0x00) {}
   17.17 +        Processor (PR08, 0x00, 0x0000, 0x00) {}
   17.18 +        Processor (PR09, 0x01, 0x0000, 0x00) {}
   17.19 +        Processor (PR0A, 0x02, 0x0000, 0x00) {}
   17.20 +        Processor (PR0B, 0x03, 0x0000, 0x00) {}
   17.21 +        Processor (PR0C, 0x00, 0x0000, 0x00) {}
   17.22 +        Processor (PR0D, 0x01, 0x0000, 0x00) {}
   17.23 +        Processor (PR0E, 0x02, 0x0000, 0x00) {}
   17.24 +        Processor (PR0F, 0x03, 0x0000, 0x00) {}
   17.25 +    }
   17.26 +
   17.27      /* S4 (STD) and S5 (power-off) type codes: must match piix4 emulation. */
   17.28      Name (\_S4, Package (0x04)
   17.29      {
    18.1 --- a/tools/firmware/hvmloader/acpi/dsdt.c	Mon Feb 25 06:29:01 2008 -0700
    18.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.c	Tue Feb 26 10:12:04 2008 -0700
    18.3 @@ -5,15 +5,15 @@
    18.4   * Copyright (C) 2000 - 2006 Intel Corporation
    18.5   * Supports ACPI Specification Revision 3.0a
    18.6   * 
    18.7 - * Compilation of "dsdt.asl" - Fri Feb 15 14:07:57 2008
    18.8 + * Compilation of "dsdt.asl" - Mon Feb 25 10:54:06 2008
    18.9   * 
   18.10   * C source code output
   18.11   *
   18.12   */
   18.13  unsigned char AmlCode[] =
   18.14  {
   18.15 -    0x44,0x53,0x44,0x54,0x5A,0x10,0x00,0x00,  /* 00000000    "DSDTZ..." */
   18.16 -    0x02,0xCC,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
   18.17 +    0x44,0x53,0x44,0x54,0x31,0x11,0x00,0x00,  /* 00000000    "DSDT1..." */
   18.18 +    0x02,0xC7,0x58,0x65,0x6E,0x00,0x00,0x00,  /* 00000008    "..Xen..." */
   18.19      0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00,  /* 00000010    "HVM....." */
   18.20      0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
   18.21      0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    "... .PMB" */
   18.22 @@ -23,518 +23,545 @@ unsigned char AmlCode[] =
   18.23      0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0,  /* 00000040    "APCB...." */
   18.24      0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00,  /* 00000048    "..APCL.." */
   18.25      0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44,  /* 00000050    "....PUID" */
   18.26 -    0x00,0x08,0x5F,0x53,0x34,0x5F,0x12,0x08,  /* 00000058    ".._S4_.." */
   18.27 -    0x04,0x0A,0x06,0x0A,0x06,0x00,0x00,0x08,  /* 00000060    "........" */
   18.28 -    0x5F,0x53,0x35,0x5F,0x12,0x08,0x04,0x0A,  /* 00000068    "_S5_...." */
   18.29 -    0x07,0x0A,0x07,0x00,0x00,0x08,0x50,0x49,  /* 00000070    "......PI" */
   18.30 -    0x43,0x44,0x00,0x14,0x0C,0x5F,0x50,0x49,  /* 00000078    "CD..._PI" */
   18.31 -    0x43,0x01,0x70,0x68,0x50,0x49,0x43,0x44,  /* 00000080    "C.phPICD" */
   18.32 -    0x10,0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B,  /* 00000088    ".B._SB_[" */
   18.33 -    0x80,0x42,0x49,0x4F,0x53,0x00,0x0C,0x00,  /* 00000090    ".BIOS..." */
   18.34 -    0xA0,0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21,  /* 00000098    ".....[.!" */
   18.35 -    0x42,0x49,0x4F,0x53,0x01,0x55,0x41,0x52,  /* 000000A0    "BIOS.UAR" */
   18.36 -    0x31,0x01,0x55,0x41,0x52,0x32,0x01,0x48,  /* 000000A8    "1.UAR2.H" */
   18.37 -    0x50,0x45,0x54,0x01,0x00,0x1D,0x50,0x4D,  /* 000000B0    "PET...PM" */
   18.38 -    0x49,0x4E,0x20,0x50,0x4C,0x45,0x4E,0x20,  /* 000000B8    "IN PLEN " */
   18.39 -    0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D,0x30,  /* 000000C0    "[.I.MEM0" */
   18.40 -    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000000C8    "._HID.A." */
   18.41 -    0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 000000D0    "..._CRS." */
   18.42 -    0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00,0x0D,  /* 000000D8    "3.0.+..." */
   18.43 -    0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E0    "........" */
   18.44 -    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E8    "........" */
   18.45 -    0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,0x00,  /* 000000F0    "........" */
   18.46 -    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000F8    "........" */
   18.47 -    0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,  /* 00000100    "........" */
   18.48 -    0x00,0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50,  /* 00000108    ".y.[.N.P" */
   18.49 -    0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 00000110    "CI0._HID" */
   18.50 -    0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55,  /* 00000118    ".A...._U" */
   18.51 -    0x49,0x44,0x00,0x08,0x5F,0x41,0x44,0x52,  /* 00000120    "ID.._ADR" */
   18.52 -    0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x14,  /* 00000128    ".._BBN.." */
   18.53 -    0x4E,0x0C,0x5F,0x43,0x52,0x53,0x00,0x08,  /* 00000130    "N._CRS.." */
   18.54 -    0x50,0x52,0x54,0x30,0x11,0x42,0x07,0x0A,  /* 00000138    "PRT0.B.." */
   18.55 -    0x6E,0x88,0x0D,0x00,0x02,0x0E,0x00,0x00,  /* 00000140    "n......." */
   18.56 -    0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,  /* 00000148    "........" */
   18.57 -    0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,  /* 00000150    ".G......" */
   18.58 -    0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,  /* 00000158    "........" */
   18.59 -    0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,  /* 00000160    "........" */
   18.60 -    0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,  /* 00000168    "........" */
   18.61 -    0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,  /* 00000170    "........" */
   18.62 -    0xF3,0x87,0x17,0x00,0x00,0x0C,0x03,0x00,  /* 00000178    "........" */
   18.63 -    0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,  /* 00000180    "........" */
   18.64 -    0xFF,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000188    "........" */
   18.65 -    0x00,0x02,0x00,0x87,0x17,0x00,0x00,0x0C,  /* 00000190    "........" */
   18.66 -    0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000198    "........" */
   18.67 -    0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00,  /* 000001A0    "........" */
   18.68 -    0x00,0x00,0x00,0x00,0x05,0x79,0x00,0x8A,  /* 000001A8    ".....y.." */
   18.69 -    0x50,0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D,  /* 000001B0    "PRT0.\MM" */
   18.70 -    0x49,0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A,  /* 000001B8    "IN.PRT0." */
   18.71 -    0x60,0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52,  /* 000001C0    "`MMAX.PR" */
   18.72 -    0x54,0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E,  /* 000001C8    "T0.hMLEN" */
   18.73 -    0x70,0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49,  /* 000001D0    "pPMINMMI" */
   18.74 -    0x4E,0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C,  /* 000001D8    "NpPLENML" */
   18.75 -    0x45,0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D,  /* 000001E0    "ENrMMINM" */
   18.76 -    0x4C,0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74,  /* 000001E8    "LENMMAXt" */
   18.77 -    0x4D,0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41,  /* 000001F0    "MMAX.MMA" */
   18.78 -    0x58,0xA4,0x50,0x52,0x54,0x30,0x08,0x42,  /* 000001F8    "X.PRT0.B" */
   18.79 -    0x55,0x46,0x41,0x11,0x09,0x0A,0x06,0x23,  /* 00000200    "UFA....#" */
   18.80 -    0x20,0x0C,0x18,0x79,0x00,0x08,0x42,0x55,  /* 00000208    " ..y..BU" */
   18.81 -    0x46,0x42,0x11,0x09,0x0A,0x06,0x23,0x00,  /* 00000210    "FB....#." */
   18.82 -    0x00,0x18,0x79,0x00,0x8B,0x42,0x55,0x46,  /* 00000218    "..y..BUF" */
   18.83 -    0x42,0x01,0x49,0x52,0x51,0x56,0x5B,0x82,  /* 00000220    "B.IRQV[." */
   18.84 -    0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,  /* 00000228    "H.LNKA._" */
   18.85 -    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 00000230    "HID.A..." */
   18.86 -    0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,  /* 00000238    "._UID..." */
   18.87 -    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 00000240    "_STA.{PI" */
   18.88 -    0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000248    "RA..`..." */
   18.89 -    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000250    "`......." */
   18.90 -    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000258    "....._PR" */
   18.91 -    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000260    "S..BUFA." */
   18.92 -    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000268    "._DIS.}P" */
   18.93 -    0x49,0x52,0x41,0x0A,0x80,0x50,0x49,0x52,  /* 00000270    "IRA..PIR" */
   18.94 -    0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000278    "A.._CRS." */
   18.95 -    0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,  /* 00000280    "{PIRA..`" */
   18.96 -    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 00000288    "y.`IRQV." */
   18.97 -    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 00000290    "BUFB.._S" */
   18.98 -    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 00000298    "RS..h.IR" */
   18.99 -    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 000002A0    "Q1.IRQ1`" */
  18.100 -    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x41,  /* 000002A8    "v`p`PIRA" */
  18.101 -    0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,  /* 000002B0    "[.I.LNKB" */
  18.102 -    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000002B8    "._HID.A." */
  18.103 -    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 000002C0    "..._UID." */
  18.104 -    0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,  /* 000002C8    "..._STA." */
  18.105 -    0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,0x60,  /* 000002D0    "{PIRB..`" */
  18.106 -    0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,  /* 000002D8    "...`...." */
  18.107 -    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,  /* 000002E0    "........" */
  18.108 -    0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55,  /* 000002E8    "_PRS..BU" */
  18.109 -    0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 000002F0    "FA.._DIS" */
  18.110 -    0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 000002F8    ".}PIRB.." */
  18.111 -    0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,  /* 00000300    "PIRB.._C" */
  18.112 -    0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x42,  /* 00000308    "RS.{PIRB" */
  18.113 -    0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52,  /* 00000310    "..`y.`IR" */
  18.114 -    0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14,  /* 00000318    "QV.BUFB." */
  18.115 -    0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00000320    "._SRS..h" */
  18.116 -    0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52,  /* 00000328    ".IRQ1.IR" */
  18.117 -    0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50,  /* 00000330    "Q1`v`p`P" */
  18.118 -    0x49,0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,  /* 00000338    "IRB[.I.L" */
  18.119 -    0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,  /* 00000340    "NKC._HID" */
  18.120 -    0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,  /* 00000348    ".A...._U" */
  18.121 -    0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,  /* 00000350    "ID...._S" */
  18.122 -    0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x43,  /* 00000358    "TA.{PIRC" */
  18.123 -    0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,  /* 00000360    "..`...`." */
  18.124 -    0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,  /* 00000368    "........" */
  18.125 -    0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,  /* 00000370    "..._PRS." */
  18.126 -    0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F,  /* 00000378    ".BUFA.._" */
  18.127 -    0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52,  /* 00000380    "DIS.}PIR" */
  18.128 -    0x43,0x0A,0x80,0x50,0x49,0x52,0x43,0x14,  /* 00000388    "C..PIRC." */
  18.129 -    0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,  /* 00000390    "._CRS.{P" */
  18.130 -    0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,  /* 00000398    "IRC..`y." */
  18.131 -    0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55,  /* 000003A0    "`IRQV.BU" */
  18.132 -    0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,  /* 000003A8    "FB.._SRS" */
  18.133 -    0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31,  /* 000003B0    "..h.IRQ1" */
  18.134 -    0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60,  /* 000003B8    ".IRQ1`v`" */
  18.135 -    0x70,0x60,0x50,0x49,0x52,0x43,0x5B,0x82,  /* 000003C0    "p`PIRC[." */
  18.136 -    0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,  /* 000003C8    "I.LNKD._" */
  18.137 -    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 000003D0    "HID.A..." */
  18.138 -    0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,  /* 000003D8    "._UID..." */
  18.139 -    0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,  /* 000003E0    "._STA.{P" */
  18.140 -    0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,  /* 000003E8    "IRD..`.." */
  18.141 -    0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,  /* 000003F0    ".`......" */
  18.142 -    0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,  /* 000003F8    "......_P" */
  18.143 -    0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41,  /* 00000400    "RS..BUFA" */
  18.144 -    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 00000408    ".._DIS.}" */
  18.145 -    0x50,0x49,0x52,0x44,0x0A,0x80,0x50,0x49,  /* 00000410    "PIRD..PI" */
  18.146 -    0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000418    "RD.._CRS" */
  18.147 -    0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,  /* 00000420    ".{PIRD.." */
  18.148 -    0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56,  /* 00000428    "`y.`IRQV" */
  18.149 -    0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,  /* 00000430    ".BUFB.._" */
  18.150 -    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00000438    "SRS..h.I" */
  18.151 -    0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31,  /* 00000440    "RQ1.IRQ1" */
  18.152 -    0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52,  /* 00000448    "`v`p`PIR" */
  18.153 -    0x44,0x5B,0x82,0x44,0x05,0x48,0x50,0x45,  /* 00000450    "D[.D.HPE" */
  18.154 -    0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000458    "T._HID.A" */
  18.155 -    0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44,  /* 00000460    "...._UID" */
  18.156 -    0x00,0x14,0x18,0x5F,0x53,0x54,0x41,0x00,  /* 00000468    "..._STA." */
  18.157 -    0xA0,0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50,  /* 00000470    "...^^^HP" */
  18.158 -    0x45,0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4,  /* 00000478    "ET......" */
  18.159 -    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000480    "..._CRS." */
  18.160 -    0x1F,0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,  /* 00000488    "........" */
  18.161 -    0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,  /* 00000490    "........" */
  18.162 -    0xFE,0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,  /* 00000498    "........" */
  18.163 -    0x00,0x00,0x04,0x00,0x00,0x79,0x00,0x14,  /* 000004A0    ".....y.." */
  18.164 -    0x16,0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,  /* 000004A8    "._PRT..." */
  18.165 -    0x50,0x49,0x43,0x44,0xA4,0x50,0x52,0x54,  /* 000004B0    "PICD.PRT" */
  18.166 -    0x41,0xA4,0x50,0x52,0x54,0x50,0x08,0x50,  /* 000004B8    "A.PRTP.P" */
  18.167 -    0x52,0x54,0x50,0x12,0x49,0x36,0x3C,0x12,  /* 000004C0    "RTP.I6<." */
  18.168 -    0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,  /* 000004C8    "........" */
  18.169 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000004D0    "LNKB...." */
  18.170 -    0x0C,0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,  /* 000004D8    "......LN" */
  18.171 -    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000004E0    "KC......" */
  18.172 -    0xFF,0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000004E8    ".....LNK" */
  18.173 -    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000004F0    "D......." */
  18.174 -    0x01,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000004F8    "....LNKA" */
  18.175 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,  /* 00000500    "........" */
  18.176 -    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000508    "..LNKC.." */
  18.177 -    0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,  /* 00000510    "........" */
  18.178 -    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000518    "LNKD...." */
  18.179 -    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,  /* 00000520    ".......L" */
  18.180 -    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000528    "NKA....." */
  18.181 -    0xFF,0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000530    "......LN" */
  18.182 -    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000538    "KB......" */
  18.183 -    0xFF,0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000540    "....LNKD" */
  18.184 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000548    "........" */
  18.185 -    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000550    "..LNKA.." */
  18.186 -    0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 00000558    "........" */
  18.187 -    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000560    ".LNKB..." */
  18.188 -    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,  /* 00000568    "........" */
  18.189 -    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000570    "LNKC...." */
  18.190 -    0x0C,0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,  /* 00000578    "......LN" */
  18.191 -    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000580    "KA......" */
  18.192 -    0xFF,0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000588    "....LNKB" */
  18.193 -    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,  /* 00000590    "........" */
  18.194 -    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000598    "...LNKC." */
  18.195 -    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000005A0    "........" */
  18.196 -    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000005A8    "..LNKD.." */
  18.197 -    0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,  /* 000005B0    "........" */
  18.198 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000005B8    "LNKB...." */
  18.199 -    0x0C,0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,  /* 000005C0    "......LN" */
  18.200 -    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000005C8    "KC......" */
  18.201 -    0xFF,0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000005D0    ".....LNK" */
  18.202 -    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000005D8    "D......." */
  18.203 -    0x05,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000005E0    "....LNKA" */
  18.204 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,  /* 000005E8    "........" */
  18.205 -    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000005F0    "..LNKC.." */
  18.206 -    0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,  /* 000005F8    "........" */
  18.207 -    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000600    "LNKD...." */
  18.208 -    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,  /* 00000608    ".......L" */
  18.209 -    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000610    "NKA....." */
  18.210 -    0xFF,0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000618    "......LN" */
  18.211 -    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000620    "KB......" */
  18.212 -    0xFF,0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000628    "....LNKD" */
  18.213 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000630    "........" */
  18.214 -    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000638    "..LNKA.." */
  18.215 -    0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 00000640    "........" */
  18.216 -    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000648    ".LNKB..." */
  18.217 -    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,  /* 00000650    "........" */
  18.218 -    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000658    "LNKC...." */
  18.219 -    0x0C,0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,  /* 00000660    "......LN" */
  18.220 -    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000668    "KA......" */
  18.221 -    0xFF,0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000670    "....LNKB" */
  18.222 -    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,  /* 00000678    "........" */
  18.223 -    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000680    "...LNKC." */
  18.224 -    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000688    "........" */
  18.225 -    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000690    "..LNKD.." */
  18.226 -    0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,  /* 00000698    "........" */
  18.227 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 000006A0    "LNKB...." */
  18.228 -    0x0C,0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,  /* 000006A8    "......LN" */
  18.229 -    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000006B0    "KC......" */
  18.230 -    0xFF,0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000006B8    ".....LNK" */
  18.231 -    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000006C0    "D......." */
  18.232 -    0x09,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000006C8    "....LNKA" */
  18.233 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,  /* 000006D0    "........" */
  18.234 -    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000006D8    "..LNKC.." */
  18.235 -    0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,  /* 000006E0    "........" */
  18.236 -    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 000006E8    "LNKD...." */
  18.237 -    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,  /* 000006F0    ".......L" */
  18.238 -    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000006F8    "NKA....." */
  18.239 -    0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,  /* 00000700    "......LN" */
  18.240 -    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000708    "KB......" */
  18.241 -    0xFF,0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 00000710    "....LNKD" */
  18.242 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000718    "........" */
  18.243 -    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000720    "..LNKA.." */
  18.244 -    0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 00000728    "........" */
  18.245 -    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000730    ".LNKB..." */
  18.246 -    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,  /* 00000738    "........" */
  18.247 -    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,  /* 00000740    "LNKC...." */
  18.248 -    0x0C,0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,  /* 00000748    "......LN" */
  18.249 -    0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000750    "KA......" */
  18.250 -    0xFF,0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,  /* 00000758    "....LNKB" */
  18.251 -    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,  /* 00000760    "........" */
  18.252 -    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000768    "...LNKC." */
  18.253 -    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000770    "........" */
  18.254 -    0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 00000778    "..LNKD.." */
  18.255 -    0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,  /* 00000780    "........" */
  18.256 -    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,  /* 00000788    "LNKB...." */
  18.257 -    0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,  /* 00000790    "......LN" */
  18.258 -    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000798    "KC......" */
  18.259 -    0xFF,0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 000007A0    ".....LNK" */
  18.260 -    0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000007A8    "D......." */
  18.261 -    0x0D,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,  /* 000007B0    "....LNKA" */
  18.262 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,  /* 000007B8    "........" */
  18.263 -    0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000007C0    "..LNKC.." */
  18.264 -    0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,  /* 000007C8    "........" */
  18.265 -    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 000007D0    "LNKD...." */
  18.266 -    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,  /* 000007D8    ".......L" */
  18.267 -    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 000007E0    "NKA....." */
  18.268 -    0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,  /* 000007E8    "......LN" */
  18.269 -    0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000007F0    "KB......" */
  18.270 -    0xFF,0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,  /* 000007F8    "....LNKD" */
  18.271 -    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000800    "........" */
  18.272 -    0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,  /* 00000808    "..LNKA.." */
  18.273 -    0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000810    "........" */
  18.274 -    0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000818    ".LNKB..." */
  18.275 -    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,  /* 00000820    "........" */
  18.276 -    0x4C,0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,  /* 00000828    "LNKC..PR" */
  18.277 -    0x54,0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,  /* 00000830    "TA.A/<.." */
  18.278 -    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,  /* 00000838    "........" */
  18.279 -    0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000840    "........" */
  18.280 -    0x01,0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,  /* 00000848    "........" */
  18.281 -    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,  /* 00000850    "........" */
  18.282 -    0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000858    "........" */
  18.283 -    0xFF,0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,  /* 00000860    "........" */
  18.284 -    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000868    "........" */
  18.285 -    0x00,0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,  /* 00000870    "........" */
  18.286 -    0xFF,0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,  /* 00000878    "........" */
  18.287 -    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000880    "........" */
  18.288 -    0x0A,0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,  /* 00000888    "........" */
  18.289 -    0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,  /* 00000890    "........" */
  18.290 -    0x0A,0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000898    "........" */
  18.291 -    0x03,0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,  /* 000008A0    "........" */
  18.292 -    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,  /* 000008A8    "........" */
  18.293 -    0x0A,0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000008B0    "........" */
  18.294 -    0x03,0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,  /* 000008B8    "........" */
  18.295 -    0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,  /* 000008C0    "........" */
  18.296 -    0x03,0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,  /* 000008C8    "........" */
  18.297 -    0xFF,0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,  /* 000008D0    "....... " */
  18.298 -    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000008D8    "........" */
  18.299 -    0x01,0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,  /* 000008E0    "...!...." */
  18.300 -    0xFF,0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,  /* 000008E8    "........" */
  18.301 -    0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,  /* 000008F0    ""......." */
  18.302 -    0x00,0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,  /* 000008F8    ".....#.." */
  18.303 -    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,  /* 00000900    "........" */
  18.304 -    0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000908    ".$......" */
  18.305 -    0x05,0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,  /* 00000910    ".....%.." */
  18.306 -    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,  /* 00000918    "........" */
  18.307 -    0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000920    "..&....." */
  18.308 -    0xFF,0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,  /* 00000928    ".......'" */
  18.309 -    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000930    "........" */
  18.310 -    0x00,0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,  /* 00000938    "...(...." */
  18.311 -    0xFF,0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,  /* 00000940    ".......)" */
  18.312 -    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 00000948    "........" */
  18.313 -    0x0A,0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,  /* 00000950    "....*..." */
  18.314 -    0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,  /* 00000958    "........" */
  18.315 -    0x0A,0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000960    ".+......" */
  18.316 -    0x07,0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,  /* 00000968    ".....,.." */
  18.317 -    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,  /* 00000970    "........" */
  18.318 -    0x0A,0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000978    ".-......" */
  18.319 -    0x07,0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,  /* 00000980    "........" */
  18.320 -    0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,  /* 00000988    "........" */
  18.321 -    0x03,0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,  /* 00000990    ".../...." */
  18.322 -    0xFF,0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,  /* 00000998    "........" */
  18.323 -    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 000009A0    "........" */
  18.324 -    0x01,0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,  /* 000009A8    "........" */
  18.325 -    0xFF,0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,  /* 000009B0    "........" */
  18.326 -    0x13,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,  /* 000009B8    "........" */
  18.327 -    0x00,0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,  /* 000009C0    "........" */
  18.328 -    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,  /* 000009C8    "........" */
  18.329 -    0x0A,0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 000009D0    "........" */
  18.330 -    0x09,0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,  /* 000009D8    "........" */
  18.331 -    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,  /* 000009E0    "........" */
  18.332 -    0x00,0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,  /* 000009E8    "........" */
  18.333 -    0xFF,0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,  /* 000009F0    "........" */
  18.334 -    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 000009F8    "........" */
  18.335 -    0x00,0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,  /* 00000A00    "........" */
  18.336 -    0xFF,0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,  /* 00000A08    "........" */
  18.337 -    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 00000A10    "........" */
  18.338 -    0x0A,0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,  /* 00000A18    "........" */
  18.339 -    0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,  /* 00000A20    "........" */
  18.340 -    0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000A28    "........" */
  18.341 -    0x0B,0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,  /* 00000A30    "........" */
  18.342 -    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,  /* 00000A38    "........" */
  18.343 -    0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000A40    "........" */
  18.344 -    0x0B,0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,  /* 00000A48    "........" */
  18.345 -    0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,  /* 00000A50    "........" */
  18.346 -    0x03,0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,  /* 00000A58    "... ...." */
  18.347 -    0xFF,0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,  /* 00000A60    ".......!" */
  18.348 -    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000A68    "........" */
  18.349 -    0x01,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,  /* 00000A70    "..."...." */
  18.350 -    0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,  /* 00000A78    "........" */
  18.351 -    0x23,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,  /* 00000A80    "#......." */
  18.352 -    0x00,0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,  /* 00000A88    ".....$.." */
  18.353 -    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,  /* 00000A90    "........" */
  18.354 -    0x0A,0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000A98    ".%......" */
  18.355 -    0x0D,0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,  /* 00000AA0    ".....&.." */
  18.356 -    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,  /* 00000AA8    "........" */
  18.357 -    0x00,0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000AB0    "..'....." */
  18.358 -    0xFF,0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,  /* 00000AB8    ".......(" */
  18.359 -    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000AC0    "........" */
  18.360 -    0x00,0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,  /* 00000AC8    "...)...." */
  18.361 -    0xFF,0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,  /* 00000AD0    ".......*" */
  18.362 -    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000AD8    "........" */
  18.363 -    0x0A,0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,  /* 00000AE0    "....+..." */
  18.364 -    0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,  /* 00000AE8    "........" */
  18.365 -    0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,  /* 00000AF0    ".,......" */
  18.366 -    0x0F,0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,  /* 00000AF8    ".....-.." */
  18.367 -    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,  /* 00000B00    "........" */
  18.368 -    0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000B08    "........" */
  18.369 -    0x0F,0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,  /* 00000B10    "....../." */
  18.370 -    0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,  /* 00000B18    "........" */
  18.371 -    0x03,0x00,0x0A,0x10,0x5B,0x82,0x46,0x37,  /* 00000B20    "....[.F7" */
  18.372 -    0x49,0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,  /* 00000B28    "ISA_._AD" */
  18.373 -    0x52,0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,  /* 00000B30    "R.....[." */
  18.374 -    0x50,0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,  /* 00000B38    "PIRQ..`." */
  18.375 -    0x04,0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,  /* 00000B40    "...\.[.)" */
  18.376 -    0x5C,0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,  /* 00000B48    "\/._SB_P" */
  18.377 -    0x43,0x49,0x30,0x49,0x53,0x41,0x5F,0x50,  /* 00000B50    "CI0ISA_P" */
  18.378 -    0x49,0x52,0x51,0x01,0x50,0x49,0x52,0x41,  /* 00000B58    "IRQ.PIRA" */
  18.379 -    0x08,0x50,0x49,0x52,0x42,0x08,0x50,0x49,  /* 00000B60    ".PIRB.PI" */
  18.380 -    0x52,0x43,0x08,0x50,0x49,0x52,0x44,0x08,  /* 00000B68    "RC.PIRD." */
  18.381 -    0x5B,0x82,0x46,0x0B,0x53,0x59,0x53,0x52,  /* 00000B70    "[.F.SYSR" */
  18.382 -    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000B78    "._HID.A." */
  18.383 -    0x0C,0x02,0x08,0x5F,0x55,0x49,0x44,0x01,  /* 00000B80    "..._UID." */
  18.384 -    0x08,0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,  /* 00000B88    ".CRS_.N." */
  18.385 -    0x0A,0x8A,0x47,0x01,0x10,0x00,0x10,0x00,  /* 00000B90    "..G....." */
  18.386 -    0x00,0x10,0x47,0x01,0x22,0x00,0x22,0x00,  /* 00000B98    "..G."."." */
  18.387 -    0x00,0x0C,0x47,0x01,0x30,0x00,0x30,0x00,  /* 00000BA0    "..G.0.0." */
  18.388 -    0x00,0x10,0x47,0x01,0x44,0x00,0x44,0x00,  /* 00000BA8    "..G.D.D." */
  18.389 -    0x00,0x1C,0x47,0x01,0x62,0x00,0x62,0x00,  /* 00000BB0    "..G.b.b." */
  18.390 -    0x00,0x02,0x47,0x01,0x65,0x00,0x65,0x00,  /* 00000BB8    "..G.e.e." */
  18.391 -    0x00,0x0B,0x47,0x01,0x72,0x00,0x72,0x00,  /* 00000BC0    "..G.r.r." */
  18.392 -    0x00,0x0E,0x47,0x01,0x80,0x00,0x80,0x00,  /* 00000BC8    "..G....." */
  18.393 -    0x00,0x01,0x47,0x01,0x84,0x00,0x84,0x00,  /* 00000BD0    "..G....." */
  18.394 -    0x00,0x03,0x47,0x01,0x88,0x00,0x88,0x00,  /* 00000BD8    "..G....." */
  18.395 -    0x00,0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,  /* 00000BE0    "..G....." */
  18.396 -    0x00,0x03,0x47,0x01,0x90,0x00,0x90,0x00,  /* 00000BE8    "..G....." */
  18.397 -    0x00,0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,  /* 00000BF0    "..G....." */
  18.398 -    0x00,0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,  /* 00000BF8    "..G....." */
  18.399 -    0x00,0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,  /* 00000C00    "..G....." */
  18.400 -    0x00,0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,  /* 00000C08    "..G....." */
  18.401 -    0x00,0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,  /* 00000C10    "..G....." */
  18.402 -    0x00,0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,  /* 00000C18    "..y..._C" */
  18.403 -    0x52,0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,  /* 00000C20    "RS..CRS_" */
  18.404 -    0x5B,0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,  /* 00000C28    "[.+PIC_." */
  18.405 -    0x5F,0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,  /* 00000C30    "_HID.A.." */
  18.406 -    0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,0x15,  /* 00000C38    "_CRS...." */
  18.407 -    0x47,0x01,0x20,0x00,0x20,0x00,0x01,0x02,  /* 00000C40    "G. . ..." */
  18.408 -    0x47,0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,  /* 00000C48    "G......." */
  18.409 -    0x22,0x04,0x00,0x79,0x00,0x5B,0x82,0x47,  /* 00000C50    ""..y.[.G" */
  18.410 -    0x05,0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,  /* 00000C58    ".DMA0._H" */
  18.411 -    0x49,0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,  /* 00000C60    "ID.A...." */
  18.412 -    0x5F,0x43,0x52,0x53,0x11,0x41,0x04,0x0A,  /* 00000C68    "_CRS.A.." */
  18.413 -    0x3D,0x2A,0x10,0x04,0x47,0x01,0x00,0x00,  /* 00000C70    "=*..G..." */
  18.414 -    0x00,0x00,0x00,0x10,0x47,0x01,0x81,0x00,  /* 00000C78    "....G..." */
  18.415 -    0x81,0x00,0x00,0x03,0x47,0x01,0x87,0x00,  /* 00000C80    "....G..." */
  18.416 -    0x87,0x00,0x00,0x01,0x47,0x01,0x89,0x00,  /* 00000C88    "....G..." */
  18.417 -    0x89,0x00,0x00,0x03,0x47,0x01,0x8F,0x00,  /* 00000C90    "....G..." */
  18.418 -    0x8F,0x00,0x00,0x01,0x47,0x01,0xC0,0x00,  /* 00000C98    "....G..." */
  18.419 -    0xC0,0x00,0x00,0x20,0x47,0x01,0x80,0x04,  /* 00000CA0    "... G..." */
  18.420 -    0x80,0x04,0x00,0x10,0x79,0x00,0x5B,0x82,  /* 00000CA8    "....y.[." */
  18.421 -    0x25,0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,  /* 00000CB0    "%TMR_._H" */
  18.422 -    0x49,0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,  /* 00000CB8    "ID.A...." */
  18.423 -    0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,  /* 00000CC0    "_CRS...." */
  18.424 -    0x47,0x01,0x40,0x00,0x40,0x00,0x00,0x04,  /* 00000CC8    "G.@.@..." */
  18.425 -    0x22,0x01,0x00,0x79,0x00,0x5B,0x82,0x25,  /* 00000CD0    ""..y.[.%" */
  18.426 -    0x52,0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,  /* 00000CD8    "RTC_._HI" */
  18.427 -    0x44,0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,  /* 00000CE0    "D.A...._" */
  18.428 -    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000CE8    "CRS....G" */
  18.429 -    0x01,0x70,0x00,0x70,0x00,0x00,0x02,0x22,  /* 00000CF0    ".p.p..."" */
  18.430 -    0x00,0x01,0x79,0x00,0x5B,0x82,0x22,0x53,  /* 00000CF8    "..y.[."S" */
  18.431 -    0x50,0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,  /* 00000D00    "PKR._HID" */
  18.432 -    0x0C,0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,  /* 00000D08    ".A...._C" */
  18.433 -    0x52,0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,  /* 00000D10    "RS....G." */
  18.434 -    0x61,0x00,0x61,0x00,0x00,0x01,0x79,0x00,  /* 00000D18    "a.a...y." */
  18.435 -    0x5B,0x82,0x31,0x50,0x53,0x32,0x4D,0x08,  /* 00000D20    "[.1PS2M." */
  18.436 -    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,  /* 00000D28    "_HID.A.." */
  18.437 -    0x13,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,  /* 00000D30    ".._CID.A" */
  18.438 -    0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,  /* 00000D38    "....._ST" */
  18.439 -    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000D40    "A....._C" */
  18.440 -    0x52,0x53,0x11,0x08,0x0A,0x05,0x22,0x00,  /* 00000D48    "RS...."." */
  18.441 -    0x10,0x79,0x00,0x5B,0x82,0x42,0x04,0x50,  /* 00000D50    ".y.[.B.P" */
  18.442 -    0x53,0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,  /* 00000D58    "S2K._HID" */
  18.443 -    0x0C,0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,  /* 00000D60    ".A...._C" */
  18.444 -    0x49,0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,  /* 00000D68    "ID.A...." */
  18.445 -    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000D70    "._STA..." */
  18.446 -    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x18,  /* 00000D78    ".._CRS.." */
  18.447 -    0x0A,0x15,0x47,0x01,0x60,0x00,0x60,0x00,  /* 00000D80    "..G.`.`." */
  18.448 -    0x00,0x01,0x47,0x01,0x64,0x00,0x64,0x00,  /* 00000D88    "..G.d.d." */
  18.449 -    0x00,0x01,0x22,0x02,0x00,0x79,0x00,0x5B,  /* 00000D90    ".."..y.[" */
  18.450 -    0x82,0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,  /* 00000D98    ".:FDC0._" */
  18.451 -    0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,  /* 00000DA0    "HID.A..." */
  18.452 -    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 00000DA8    ".._STA.." */
  18.453 -    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 00000DB0    "..._CRS." */
  18.454 -    0x1B,0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,  /* 00000DB8    "...G...." */
  18.455 -    0x03,0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,  /* 00000DC0    "...G...." */
  18.456 -    0x03,0x01,0x01,0x22,0x40,0x00,0x2A,0x04,  /* 00000DC8    "..."@.*." */
  18.457 -    0x00,0x79,0x00,0x5B,0x82,0x46,0x04,0x55,  /* 00000DD0    ".y.[.F.U" */
  18.458 -    0x41,0x52,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00000DD8    "AR1._HID" */
  18.459 -    0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,  /* 00000DE0    ".A...._U" */
  18.460 -    0x49,0x44,0x01,0x14,0x19,0x5F,0x53,0x54,  /* 00000DE8    "ID..._ST" */
  18.461 -    0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,  /* 00000DF0    "A....^^^" */
  18.462 -    0x5E,0x55,0x41,0x52,0x31,0x00,0xA4,0x00,  /* 00000DF8    "^UAR1..." */
  18.463 -    0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000E00    "......_C" */
  18.464 -    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000E08    "RS....G." */
  18.465 -    0xF8,0x03,0xF8,0x03,0x08,0x08,0x22,0x10,  /* 00000E10    "......"." */
  18.466 -    0x00,0x79,0x00,0x5B,0x82,0x47,0x04,0x55,  /* 00000E18    ".y.[.G.U" */
  18.467 -    0x41,0x52,0x32,0x08,0x5F,0x48,0x49,0x44,  /* 00000E20    "AR2._HID" */
  18.468 -    0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,  /* 00000E28    ".A...._U" */
  18.469 -    0x49,0x44,0x0A,0x02,0x14,0x19,0x5F,0x53,  /* 00000E30    "ID...._S" */
  18.470 -    0x54,0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,  /* 00000E38    "TA....^^" */
  18.471 -    0x5E,0x5E,0x55,0x41,0x52,0x32,0x00,0xA4,  /* 00000E40    "^^UAR2.." */
  18.472 -    0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000E48    "......._" */
  18.473 -    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000E50    "CRS....G" */
  18.474 -    0x01,0xF8,0x02,0xF8,0x02,0x08,0x08,0x22,  /* 00000E58    "......."" */
  18.475 -    0x08,0x00,0x79,0x00,0x5B,0x82,0x36,0x4C,  /* 00000E60    "..y.[.6L" */
  18.476 -    0x54,0x50,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00000E68    "TP1._HID" */
  18.477 -    0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F,0x55,  /* 00000E70    ".A...._U" */
  18.478 -    0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53,  /* 00000E78    "ID...._S" */
  18.479 -    0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000E80    "TA....._" */
  18.480 -    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000E88    "CRS....G" */
  18.481 -    0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22,  /* 00000E90    ".x.x..."" */
  18.482 -    0x80,0x00,0x79,0x00,0x5B,0x82,0x4D,0x07,  /* 00000E98    "..y.[.M." */
  18.483 -    0x53,0x31,0x46,0x30,0x08,0x5F,0x41,0x44,  /* 00000EA0    "S1F0._AD" */
  18.484 -    0x52,0x0C,0x00,0x00,0x06,0x00,0x08,0x5F,  /* 00000EA8    "R......_" */
  18.485 -    0x53,0x55,0x4E,0x01,0x14,0x13,0x5F,0x50,  /* 00000EB0    "SUN..._P" */
  18.486 -    0x53,0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E,  /* 00000EB8    "S0.p..\." */
  18.487 -    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000EC0    "_GPEDPT2" */
  18.488 -    0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70,  /* 00000EC8    ".._PS3.p" */
  18.489 -    0x0A,0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000ED0    "..\._GPE" */
  18.490 -    0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,  /* 00000ED8    "DPT2.._E" */
  18.491 -    0x4A,0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E,  /* 00000EE0    "J0.p..\." */
  18.492 -    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000EE8    "_GPEDPT2" */
  18.493 -    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000EF0    "p.\._GPE" */
  18.494 -    0x50,0x48,0x50,0x31,0x14,0x1E,0x5F,0x53,  /* 00000EF8    "PHP1.._S" */
  18.495 -    0x54,0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E,  /* 00000F00    "TA.p..\." */
  18.496 -    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F08    "_GPEDPT2" */
  18.497 -    0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000F10    ".\._GPEP" */
  18.498 -    0x48,0x50,0x31,0x5B,0x82,0x4E,0x07,0x53,  /* 00000F18    "HP1[.N.S" */
  18.499 -    0x32,0x46,0x30,0x08,0x5F,0x41,0x44,0x52,  /* 00000F20    "2F0._ADR" */
  18.500 -    0x0C,0x00,0x00,0x07,0x00,0x08,0x5F,0x53,  /* 00000F28    "......_S" */
  18.501 -    0x55,0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50,  /* 00000F30    "UN...._P" */
  18.502 -    0x53,0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E,  /* 00000F38    "S0.p..\." */
  18.503 -    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F40    "_GPEDPT2" */
  18.504 -    0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70,  /* 00000F48    ".._PS3.p" */
  18.505 -    0x0A,0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000F50    "..\._GPE" */
  18.506 -    0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,  /* 00000F58    "DPT2.._E" */
  18.507 -    0x4A,0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E,  /* 00000F60    "J0.p..\." */
  18.508 -    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F68    "_GPEDPT2" */
  18.509 -    0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,  /* 00000F70    "p.\._GPE" */
  18.510 -    0x50,0x48,0x50,0x32,0x14,0x1E,0x5F,0x53,  /* 00000F78    "PHP2.._S" */
  18.511 -    0x54,0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E,  /* 00000F80    "TA.p..\." */
  18.512 -    0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32,  /* 00000F88    "_GPEDPT2" */
  18.513 -    0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000F90    ".\._GPEP" */
  18.514 -    0x48,0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47,  /* 00000F98    "HP2.N._G" */
  18.515 -    0x50,0x45,0x5B,0x80,0x50,0x48,0x50,0x5F,  /* 00000FA0    "PE[.PHP_" */
  18.516 -    0x01,0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81,  /* 00000FA8    "......[." */
  18.517 -    0x15,0x50,0x48,0x50,0x5F,0x01,0x50,0x53,  /* 00000FB0    ".PHP_.PS" */
  18.518 -    0x54,0x41,0x08,0x50,0x48,0x50,0x31,0x08,  /* 00000FB8    "TA.PHP1." */
  18.519 -    0x50,0x48,0x50,0x32,0x08,0x5B,0x80,0x44,  /* 00000FC0    "PHP2.[.D" */
  18.520 -    0x47,0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A,  /* 00000FC8    "G1_..D.." */
  18.521 -    0x04,0x5B,0x81,0x10,0x44,0x47,0x31,0x5F,  /* 00000FD0    ".[..DG1_" */
  18.522 -    0x01,0x44,0x50,0x54,0x31,0x08,0x44,0x50,  /* 00000FD8    ".DPT1.DP" */
  18.523 -    0x54,0x32,0x08,0x14,0x46,0x07,0x5F,0x4C,  /* 00000FE0    "T2..F._L" */
  18.524 -    0x30,0x33,0x00,0x08,0x53,0x4C,0x54,0x5F,  /* 00000FE8    "03..SLT_" */
  18.525 -    0x00,0x08,0x45,0x56,0x54,0x5F,0x00,0x70,  /* 00000FF0    "..EVT_.p" */
  18.526 -    0x50,0x53,0x54,0x41,0x61,0x7A,0x61,0x0A,  /* 00000FF8    "PSTAaza." */
  18.527 -    0x04,0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A,  /* 00001000    ".SLT_{a." */
  18.528 -    0x0F,0x45,0x56,0x54,0x5F,0x70,0x53,0x4C,  /* 00001008    ".EVT_pSL" */
  18.529 -    0x54,0x5F,0x44,0x50,0x54,0x31,0x70,0x45,  /* 00001010    "T_DPT1pE" */
  18.530 -    0x56,0x54,0x5F,0x44,0x50,0x54,0x32,0xA0,  /* 00001018    "VT_DPT2." */
  18.531 -    0x1B,0x93,0x53,0x4C,0x54,0x5F,0x01,0x86,  /* 00001020    "..SLT_.." */
  18.532 -    0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,  /* 00001028    "\/._SB_P" */
  18.533 -    0x43,0x49,0x30,0x53,0x31,0x46,0x30,0x45,  /* 00001030    "CI0S1F0E" */
  18.534 -    0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93,  /* 00001038    "VT_....." */
  18.535 -    0x53,0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C,  /* 00001040    "SLT_...\" */
  18.536 -    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00001048    "/._SB_PC" */
  18.537 -    0x49,0x30,0x53,0x32,0x46,0x30,0x45,0x56,  /* 00001050    "I0S2F0EV" */
  18.538 -    0x54,0x5F,
  18.539 +    0x00,0x10,0x46,0x0D,0x5F,0x50,0x52,0x5F,  /* 00000058    "..F._PR_" */
  18.540 +    0x5B,0x83,0x0B,0x50,0x52,0x30,0x30,0x00,  /* 00000060    "[..PR00." */
  18.541 +    0x00,0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,  /* 00000068    ".....[.." */
  18.542 +    0x50,0x52,0x30,0x31,0x01,0x00,0x00,0x00,  /* 00000070    "PR01...." */
  18.543 +    0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,  /* 00000078    "..[..PR0" */
  18.544 +    0x32,0x02,0x00,0x00,0x00,0x00,0x00,0x5B,  /* 00000080    "2......[" */
  18.545 +    0x83,0x0B,0x50,0x52,0x30,0x33,0x03,0x00,  /* 00000088    "..PR03.." */
  18.546 +    0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,  /* 00000090    "....[..P" */
  18.547 +    0x52,0x30,0x34,0x00,0x00,0x00,0x00,0x00,  /* 00000098    "R04....." */
  18.548 +    0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,0x35,  /* 000000A0    ".[..PR05" */
  18.549 +    0x01,0x00,0x00,0x00,0x00,0x00,0x5B,0x83,  /* 000000A8    "......[." */
  18.550 +    0x0B,0x50,0x52,0x30,0x36,0x02,0x00,0x00,  /* 000000B0    ".PR06..." */
  18.551 +    0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,  /* 000000B8    "...[..PR" */
  18.552 +    0x30,0x37,0x03,0x00,0x00,0x00,0x00,0x00,  /* 000000C0    "07......" */
  18.553 +    0x5B,0x83,0x0B,0x50,0x52,0x30,0x38,0x00,  /* 000000C8    "[..PR08." */
  18.554 +    0x00,0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,  /* 000000D0    ".....[.." */
  18.555 +    0x50,0x52,0x30,0x39,0x01,0x00,0x00,0x00,  /* 000000D8    "PR09...." */
  18.556 +    0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,  /* 000000E0    "..[..PR0" */
  18.557 +    0x41,0x02,0x00,0x00,0x00,0x00,0x00,0x5B,  /* 000000E8    "A......[" */
  18.558 +    0x83,0x0B,0x50,0x52,0x30,0x42,0x03,0x00,  /* 000000F0    "..PR0B.." */
  18.559 +    0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,  /* 000000F8    "....[..P" */
  18.560 +    0x52,0x30,0x43,0x00,0x00,0x00,0x00,0x00,  /* 00000100    "R0C....." */
  18.561 +    0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,0x44,  /* 00000108    ".[..PR0D" */
  18.562 +    0x01,0x00,0x00,0x00,0x00,0x00,0x5B,0x83,  /* 00000110    "......[." */
  18.563 +    0x0B,0x50,0x52,0x30,0x45,0x02,0x00,0x00,  /* 00000118    ".PR0E..." */
  18.564 +    0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,  /* 00000120    "...[..PR" */
  18.565 +    0x30,0x46,0x03,0x00,0x00,0x00,0x00,0x00,  /* 00000128    "0F......" */
  18.566 +    0x08,0x5F,0x53,0x34,0x5F,0x12,0x08,0x04,  /* 00000130    "._S4_..." */
  18.567 +    0x0A,0x06,0x0A,0x06,0x00,0x00,0x08,0x5F,  /* 00000138    "......._" */
  18.568 +    0x53,0x35,0x5F,0x12,0x08,0x04,0x0A,0x07,  /* 00000140    "S5_....." */
  18.569 +    0x0A,0x07,0x00,0x00,0x08,0x50,0x49,0x43,  /* 00000148    ".....PIC" */
  18.570 +    0x44,0x00,0x14,0x0C,0x5F,0x50,0x49,0x43,  /* 00000150    "D..._PIC" */
  18.571 +    0x01,0x70,0x68,0x50,0x49,0x43,0x44,0x10,  /* 00000158    ".phPICD." */
  18.572 +    0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B,0x80,  /* 00000160    "B._SB_[." */
  18.573 +    0x42,0x49,0x4F,0x53,0x00,0x0C,0x00,0xA0,  /* 00000168    "BIOS...." */
  18.574 +    0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21,0x42,  /* 00000170    "....[.!B" */
  18.575 +    0x49,0x4F,0x53,0x01,0x55,0x41,0x52,0x31,  /* 00000178    "IOS.UAR1" */
  18.576 +    0x01,0x55,0x41,0x52,0x32,0x01,0x48,0x50,  /* 00000180    ".UAR2.HP" */
  18.577 +    0x45,0x54,0x01,0x00,0x1D,0x50,0x4D,0x49,  /* 00000188    "ET...PMI" */
  18.578 +    0x4E,0x20,0x50,0x4C,0x45,0x4E,0x20,0x5B,  /* 00000190    "N PLEN [" */
  18.579 +    0x82,0x49,0x04,0x4D,0x45,0x4D,0x30,0x08,  /* 00000198    ".I.MEM0." */
  18.580 +    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 000001A0    "_HID.A.." */
  18.581 +    0x02,0x08,0x5F,0x43,0x52,0x53,0x11,0x33,  /* 000001A8    ".._CRS.3" */
  18.582 +    0x0A,0x30,0x8A,0x2B,0x00,0x00,0x0D,0x03,  /* 000001B0    ".0.+...." */
  18.583 +    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001B8    "........" */
  18.584 +    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001C0    "........" */
  18.585 +    0xFF,0xFF,0x09,0x00,0x00,0x00,0x00,0x00,  /* 000001C8    "........" */
  18.586 +    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001D0    "........" */
  18.587 +    0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,  /* 000001D8    "........" */
  18.588 +    0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50,0x43,  /* 000001E0    "y.[.N.PC" */
  18.589 +    0x49,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 000001E8    "I0._HID." */
  18.590 +    0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55,0x49,  /* 000001F0    "A...._UI" */
  18.591 +    0x44,0x00,0x08,0x5F,0x41,0x44,0x52,0x00,  /* 000001F8    "D.._ADR." */
  18.592 +    0x08,0x5F,0x42,0x42,0x4E,0x00,0x14,0x4E,  /* 00000200    "._BBN..N" */
  18.593 +    0x0C,0x5F,0x43,0x52,0x53,0x00,0x08,0x50,  /* 00000208    "._CRS..P" */
  18.594 +    0x52,0x54,0x30,0x11,0x42,0x07,0x0A,0x6E,  /* 00000210    "RT0.B..n" */
  18.595 +    0x88,0x0D,0x00,0x02,0x0E,0x00,0x00,0x00,  /* 00000218    "........" */
  18.596 +    0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,  /* 00000220    "........" */
  18.597 +    0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,0x08,  /* 00000228    "G......." */
  18.598 +    0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,  /* 00000230    "........" */
  18.599 +    0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,0x0C,  /* 00000238    "........" */
  18.600 +    0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00,  /* 00000240    "........" */
  18.601 +    0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,0xF3,  /* 00000248    "........" */
  18.602 +    0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00,  /* 00000250    "........" */
  18.603 +    0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,0xFF,  /* 00000258    "........" */
  18.604 +    0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000260    "........" */
  18.605 +    0x02,0x00,0x87,0x17,0x00,0x00,0x0C,0x03,  /* 00000268    "........" */
  18.606 +    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,  /* 00000270    "........" */
  18.607 +    0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00,0x00,  /* 00000278    "........" */
  18.608 +    0x00,0x00,0x00,0x05,0x79,0x00,0x8A,0x50,  /* 00000280    "....y..P" */
  18.609 +    0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D,0x49,  /* 00000288    "RT0.\MMI" */
  18.610 +    0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A,0x60,  /* 00000290    "N.PRT0.`" */
  18.611 +    0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52,0x54,  /* 00000298    "MMAX.PRT" */
  18.612 +    0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E,0x70,  /* 000002A0    "0.hMLENp" */
  18.613 +    0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49,0x4E,  /* 000002A8    "PMINMMIN" */
  18.614 +    0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C,0x45,  /* 000002B0    "pPLENMLE" */
  18.615 +    0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D,0x4C,  /* 000002B8    "NrMMINML" */
  18.616 +    0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74,0x4D,  /* 000002C0    "ENMMAXtM" */
  18.617 +    0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41,0x58,  /* 000002C8    "MAX.MMAX" */
  18.618 +    0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55,  /* 000002D0    ".PRT0.BU" */
  18.619 +    0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x20,  /* 000002D8    "FA....# " */
  18.620 +    0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46,  /* 000002E0    "..y..BUF" */
  18.621 +    0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00,  /* 000002E8    "B....#.." */
  18.622 +    0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42,  /* 000002F0    ".y..BUFB" */
  18.623 +    0x01,0x49,0x52,0x51,0x56,0x5B,0x82,0x48,  /* 000002F8    ".IRQV[.H" */
  18.624 +    0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48,  /* 00000300    ".LNKA._H" */
  18.625 +    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000308    "ID.A...." */
  18.626 +    0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F,  /* 00000310    "_UID..._" */
  18.627 +    0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52,  /* 00000318    "STA.{PIR" */
  18.628 +    0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,  /* 00000320    "A..`...`" */
  18.629 +    0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,  /* 00000328    "........" */
  18.630 +    0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,  /* 00000330    "...._PRS" */
  18.631 +    0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11,  /* 00000338    "..BUFA.." */
  18.632 +    0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49,  /* 00000340    "_DIS.}PI" */
  18.633 +    0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41,  /* 00000348    "RA..PIRA" */
  18.634 +    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,  /* 00000350    ".._CRS.{" */
  18.635 +    0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,0x79,  /* 00000358    "PIRA..`y" */
  18.636 +    0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42,  /* 00000360    ".`IRQV.B" */
  18.637 +    0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,  /* 00000368    "UFB.._SR" */
  18.638 +    0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51,  /* 00000370    "S..h.IRQ" */
  18.639 +    0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76,  /* 00000378    "1.IRQ1`v" */
  18.640 +    0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B,  /* 00000380    "`p`PIRA[" */
  18.641 +    0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08,  /* 00000388    ".I.LNKB." */
  18.642 +    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000390    "_HID.A.." */
  18.643 +    0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,  /* 00000398    ".._UID.." */
  18.644 +    0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,  /* 000003A0    ".._STA.{" */
  18.645 +    0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0,  /* 000003A8    "PIRB..`." */
  18.646 +    0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,  /* 000003B0    "..`....." */
  18.647 +    0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,  /* 000003B8    "......._" */
  18.648 +    0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46,  /* 000003C0    "PRS..BUF" */
  18.649 +    0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00,  /* 000003C8    "A.._DIS." */
  18.650 +    0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50,  /* 000003D0    "}PIRB..P" */
  18.651 +    0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52,  /* 000003D8    "IRB.._CR" */
  18.652 +    0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A,  /* 000003E0    "S.{PIRB." */
  18.653 +    0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51,  /* 000003E8    ".`y.`IRQ" */
  18.654 +    0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,  /* 000003F0    "V.BUFB.." */
  18.655 +    0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01,  /* 000003F8    "_SRS..h." */
  18.656 +    0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51,  /* 00000400    "IRQ1.IRQ" */
  18.657 +    0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49,  /* 00000408    "1`v`p`PI" */
  18.658 +    0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E,  /* 00000410    "RB[.I.LN" */
  18.659 +    0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000418    "KC._HID." */
  18.660 +    0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,  /* 00000420    "A...._UI" */
  18.661 +    0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54,  /* 00000428    "D...._ST" */
  18.662 +    0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A,  /* 00000430    "A.{PIRC." */
  18.663 +    0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,  /* 00000438    ".`...`.." */
  18.664 +    0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,  /* 00000440    "........" */
  18.665 +    0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,  /* 00000448    ".._PRS.." */
  18.666 +    0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44,  /* 00000450    "BUFA.._D" */
  18.667 +    0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43,  /* 00000458    "IS.}PIRC" */
  18.668 +    0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A,  /* 00000460    "..PIRC.." */
  18.669 +    0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49,  /* 00000468    "_CRS.{PI" */
  18.670 +    0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60,  /* 00000470    "RC..`y.`" */
  18.671 +    0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46,  /* 00000478    "IRQV.BUF" */
  18.672 +    0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,  /* 00000480    "B.._SRS." */
  18.673 +    0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82,  /* 00000488    ".h.IRQ1." */
  18.674 +    0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70,  /* 00000490    "IRQ1`v`p" */
  18.675 +    0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49,  /* 00000498    "`PIRC[.I" */
  18.676 +    0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,  /* 000004A0    ".LNKD._H" */
  18.677 +    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 000004A8    "ID.A...." */
  18.678 +    0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C,  /* 000004B0    "_UID...." */
  18.679 +    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 000004B8    "_STA.{PI" */
  18.680 +    0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 000004C0    "RD..`..." */
  18.681 +    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 000004C8    "`......." */
  18.682 +    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 000004D0    "....._PR" */
  18.683 +    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 000004D8    "S..BUFA." */
  18.684 +    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 000004E0    "._DIS.}P" */
  18.685 +    0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52,  /* 000004E8    "IRD..PIR" */
  18.686 +    0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 000004F0    "D.._CRS." */
  18.687 +    0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60,  /* 000004F8    "{PIRD..`" */
  18.688 +    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 00000500    "y.`IRQV." */
  18.689 +    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 00000508    "BUFB.._S" */
  18.690 +    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 00000510    "RS..h.IR" */
  18.691 +    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 00000518    "Q1.IRQ1`" */
  18.692 +    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44,  /* 00000520    "v`p`PIRD" */
  18.693 +    0x5B,0x82,0x44,0x05,0x48,0x50,0x45,0x54,  /* 00000528    "[.D.HPET" */
  18.694 +    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000530    "._HID.A." */
  18.695 +    0x01,0x03,0x08,0x5F,0x55,0x49,0x44,0x00,  /* 00000538    "..._UID." */
  18.696 +    0x14,0x18,0x5F,0x53,0x54,0x41,0x00,0xA0,  /* 00000540    ".._STA.." */
  18.697 +    0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50,0x45,  /* 00000548    "..^^^HPE" */
  18.698 +    0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A,  /* 00000550    "T......." */
  18.699 +    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1F,  /* 00000558    ".._CRS.." */
  18.700 +    0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,0x01,  /* 00000560    "........" */
  18.701 +    0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFE,  /* 00000568    "........" */
  18.702 +    0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,0x00,  /* 00000570    "........" */
  18.703 +    0x00,0x04,0x00,0x00,0x79,0x00,0x14,0x16,  /* 00000578    "....y..." */
  18.704 +    0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,0x50,  /* 00000580    "_PRT...P" */
  18.705 +    0x49,0x43,0x44,0xA4,0x50,0x52,0x54,0x41,  /* 00000588    "ICD.PRTA" */
  18.706 +    0xA4,0x50,0x52,0x54,0x50,0x08,0x50,0x52,  /* 00000590    ".PRTP.PR" */
  18.707 +    0x54,0x50,0x12,0x49,0x36,0x3C,0x12,0x0D,  /* 00000598    "TP.I6<.." */
  18.708 +    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C,  /* 000005A0    ".......L" */
  18.709 +    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 000005A8    "NKB....." */
  18.710 +    0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B,  /* 000005B0    ".....LNK" */
  18.711 +    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000005B8    "C......." */
  18.712 +    0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 000005C0    "....LNKD" */
  18.713 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,  /* 000005C8    "........" */
  18.714 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 000005D0    "...LNKA." */
  18.715 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 000005D8    "........" */
  18.716 +    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000005E0    ".LNKC..." */
  18.717 +    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x4C,  /* 000005E8    ".......L" */
  18.718 +    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000005F0    "NKD....." */
  18.719 +    0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,0x4E,  /* 000005F8    "......LN" */
  18.720 +    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000600    "KA......" */
  18.721 +    0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000608    ".....LNK" */
  18.722 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000610    "B......." */
  18.723 +    0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000618    "...LNKD." */
  18.724 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000620    "........" */
  18.725 +    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000628    ".LNKA..." */
  18.726 +    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,  /* 00000630    "........" */
  18.727 +    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 00000638    "LNKB...." */
  18.728 +    0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,0x4C,  /* 00000640    ".......L" */
  18.729 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000648    "NKC....." */
  18.730 +    0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000650    ".....LNK" */
  18.731 +    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000658    "A......." */
  18.732 +    0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000660    "...LNKB." */
  18.733 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 00000668    "........" */
  18.734 +    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000670    "..LNKC.." */
  18.735 +    0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,  /* 00000678    "........" */
  18.736 +    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000680    ".LNKD..." */
  18.737 +    0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x4C,  /* 00000688    ".......L" */
  18.738 +    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000690    "NKB....." */
  18.739 +    0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000698    ".....LNK" */
  18.740 +    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000006A0    "C......." */
  18.741 +    0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 000006A8    "....LNKD" */
  18.742 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,  /* 000006B0    "........" */
  18.743 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 000006B8    "...LNKA." */
  18.744 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,  /* 000006C0    "........" */
  18.745 +    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000006C8    ".LNKC..." */
  18.746 +    0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x4C,  /* 000006D0    ".......L" */
  18.747 +    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000006D8    "NKD....." */
  18.748 +    0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,0x4E,  /* 000006E0    "......LN" */
  18.749 +    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000006E8    "KA......" */
  18.750 +    0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000006F0    ".....LNK" */
  18.751 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000006F8    "B......." */
  18.752 +    0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000700    "...LNKD." */
  18.753 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00,  /* 00000708    "........" */
  18.754 +    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000710    ".LNKA..." */
  18.755 +    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02,  /* 00000718    "........" */
  18.756 +    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 00000720    "LNKB...." */
  18.757 +    0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,0x4C,  /* 00000728    ".......L" */
  18.758 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000730    "NKC....." */
  18.759 +    0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000738    ".....LNK" */
  18.760 +    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000740    "A......." */
  18.761 +    0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000748    "...LNKB." */
  18.762 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000750    "........" */
  18.763 +    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000758    "..LNKC.." */
  18.764 +    0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,  /* 00000760    "........" */
  18.765 +    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000768    ".LNKD..." */
  18.766 +    0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x4C,  /* 00000770    ".......L" */
  18.767 +    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000778    "NKB....." */
  18.768 +    0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000780    ".....LNK" */
  18.769 +    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000788    "C......." */
  18.770 +    0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000790    "....LNKD" */
  18.771 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000798    "........" */
  18.772 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 000007A0    "...LNKA." */
  18.773 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 000007A8    "........" */
  18.774 +    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 000007B0    ".LNKC..." */
  18.775 +    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C,  /* 000007B8    ".......L" */
  18.776 +    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000007C0    "NKD....." */
  18.777 +    0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E,  /* 000007C8    "......LN" */
  18.778 +    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000007D0    "KA......" */
  18.779 +    0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000007D8    ".....LNK" */
  18.780 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000007E0    "B......." */
  18.781 +    0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000007E8    "...LNKD." */
  18.782 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00,  /* 000007F0    "........" */
  18.783 +    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000007F8    ".LNKA..." */
  18.784 +    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02,  /* 00000800    "........" */
  18.785 +    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 00000808    "LNKB...." */
  18.786 +    0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x4C,  /* 00000810    ".......L" */
  18.787 +    0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,  /* 00000818    "NKC....." */
  18.788 +    0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000820    ".....LNK" */
  18.789 +    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000828    "A......." */
  18.790 +    0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000830    "...LNKB." */
  18.791 +    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000838    "........" */
  18.792 +    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 00000840    "..LNKC.." */
  18.793 +    0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,  /* 00000848    "........" */
  18.794 +    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000850    ".LNKD..." */
  18.795 +    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x4C,  /* 00000858    ".......L" */
  18.796 +    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000860    "NKB....." */
  18.797 +    0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000868    ".....LNK" */
  18.798 +    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000870    "C......." */
  18.799 +    0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000878    "....LNKD" */
  18.800 +    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000880    "........" */
  18.801 +    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000888    "...LNKA." */
  18.802 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,  /* 00000890    "........" */
  18.803 +    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000898    ".LNKC..." */
  18.804 +    0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x4C,  /* 000008A0    ".......L" */
  18.805 +    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 000008A8    "NKD....." */
  18.806 +    0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,0x4E,  /* 000008B0    "......LN" */
  18.807 +    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 000008B8    "KA......" */
  18.808 +    0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 000008C0    ".....LNK" */
  18.809 +    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000008C8    "B......." */
  18.810 +    0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 000008D0    "...LNKD." */
  18.811 +    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00,  /* 000008D8    "........" */
  18.812 +    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 000008E0    ".LNKA..." */
  18.813 +    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02,  /* 000008E8    "........" */
  18.814 +    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000008F0    "LNKB...." */
  18.815 +    0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x4C,  /* 000008F8    ".......L" */
  18.816 +    0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,0x54,  /* 00000900    "NKC..PRT" */
  18.817 +    0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,0x04,  /* 00000908    "A.A/<..." */
  18.818 +    0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,0x0A,  /* 00000910    "........" */
  18.819 +    0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,  /* 00000918    "........" */
  18.820 +    0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,0x04,  /* 00000920    "........" */
  18.821 +    0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x00,  /* 00000928    "........" */
  18.822 +    0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000930    "........" */
  18.823 +    0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,0x12,  /* 00000938    "........" */
  18.824 +    0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,  /* 00000940    "........" */
  18.825 +    0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000948    "........" */
  18.826 +    0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,0x12,  /* 00000950    "........" */
  18.827 +    0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,  /* 00000958    "........" */
  18.828 +    0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C,  /* 00000960    "........" */
  18.829 +    0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,0x0A,  /* 00000968    "........" */
  18.830 +    0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000970    "........" */
  18.831 +    0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,0x04,  /* 00000978    "........" */
  18.832 +    0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,0x0A,  /* 00000980    "........" */
  18.833 +    0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000988    "........" */
  18.834 +    0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,0x0C,  /* 00000990    "........" */
  18.835 +    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,  /* 00000998    "........" */
  18.836 +    0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,0xFF,  /* 000009A0    "........" */
  18.837 +    0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,0x12,  /* 000009A8    "...... ." */
  18.838 +    0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,  /* 000009B0    "........" */
  18.839 +    0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,0xFF,  /* 000009B8    "..!....." */
  18.840 +    0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,0x22,  /* 000009C0    "......."" */
  18.841 +    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000009C8    "........" */
  18.842 +    0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,0x04,  /* 000009D0    "....#..." */
  18.843 +    0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,0x0A,  /* 000009D8    "........" */
  18.844 +    0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05,  /* 000009E0    "$......." */
  18.845 +    0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,0x04,  /* 000009E8    "....%..." */
  18.846 +    0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x00,  /* 000009F0    "........" */
  18.847 +    0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 000009F8    ".&......" */
  18.848 +    0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,0x12,  /* 00000A00    "......'." */
  18.849 +    0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,  /* 00000A08    "........" */
  18.850 +    0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A10    "..(....." */
  18.851 +    0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,0x12,  /* 00000A18    "......)." */
  18.852 +    0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,  /* 00000A20    "........" */
  18.853 +    0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C,  /* 00000A28    "...*...." */
  18.854 +    0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,0x0A,  /* 00000A30    "........" */
  18.855 +    0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000A38    "+......." */
  18.856 +    0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,0x04,  /* 00000A40    "....,..." */
  18.857 +    0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,0x0A,  /* 00000A48    "........" */
  18.858 +    0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07,  /* 00000A50    "-......." */
  18.859 +    0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,0x0C,  /* 00000A58    "........" */
  18.860 +    0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,  /* 00000A60    "........" */
  18.861 +    0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000A68    "../....." */
  18.862 +    0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,0x12,  /* 00000A70    "........" */
  18.863 +    0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01,  /* 00000A78    "........" */
  18.864 +    0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000A80    "........" */
  18.865 +    0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,0x13,  /* 00000A88    "........" */
  18.866 +    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00,  /* 00000A90    "........" */
  18.867 +    0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,0x04,  /* 00000A98    "........" */
  18.868 +    0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,0x0A,  /* 00000AA0    "........" */
  18.869 +    0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09,  /* 00000AA8    "........" */
  18.870 +    0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,0x04,  /* 00000AB0    "........" */
  18.871 +    0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x00,  /* 00000AB8    "........" */
  18.872 +    0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000AC0    "........" */
  18.873 +    0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,0x12,  /* 00000AC8    "........" */
  18.874 +    0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,  /* 00000AD0    "........" */
  18.875 +    0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000AD8    "........" */
  18.876 +    0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,0x12,  /* 00000AE0    "........" */
  18.877 +    0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,  /* 00000AE8    "........" */
  18.878 +    0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,0x0C,  /* 00000AF0    "........" */
  18.879 +    0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,0x0A,  /* 00000AF8    "........" */
  18.880 +    0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000B00    "........" */
  18.881 +    0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,0x04,  /* 00000B08    "........" */
  18.882 +    0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,0x0A,  /* 00000B10    "........" */
  18.883 +    0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B,  /* 00000B18    "........" */
  18.884 +    0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,0x0C,  /* 00000B20    "........" */
  18.885 +    0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,  /* 00000B28    "........" */
  18.886 +    0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000B30    ".. ....." */
  18.887 +    0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,0x12,  /* 00000B38    "......!." */
  18.888 +    0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01,  /* 00000B40    "........" */
  18.889 +    0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF,  /* 00000B48    ".."....." */
  18.890 +    0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,0x23,  /* 00000B50    ".......#" */
  18.891 +    0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00,  /* 00000B58    "........" */
  18.892 +    0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,0x04,  /* 00000B60    "....$..." */
  18.893 +    0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,0x0A,  /* 00000B68    "........" */
  18.894 +    0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D,  /* 00000B70    "%......." */
  18.895 +    0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,0x04,  /* 00000B78    "....&..." */
  18.896 +    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x00,  /* 00000B80    "........" */
  18.897 +    0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,0xFF,  /* 00000B88    ".'......" */
  18.898 +    0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,0x12,  /* 00000B90    "......(." */
  18.899 +    0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,  /* 00000B98    "........" */
  18.900 +    0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,0xFF,  /* 00000BA0    "..)....." */
  18.901 +    0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,0x12,  /* 00000BA8    "......*." */
  18.902 +    0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,  /* 00000BB0    "........" */
  18.903 +    0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,0x0C,  /* 00000BB8    "...+...." */
  18.904 +    0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,0x0A,  /* 00000BC0    "........" */
  18.905 +    0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000BC8    ",......." */
  18.906 +    0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,0x04,  /* 00000BD0    "....-..." */
  18.907 +    0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,0x0A,  /* 00000BD8    "........" */
  18.908 +    0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F,  /* 00000BE0    "........" */
  18.909 +    0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,0x0C,  /* 00000BE8    "...../.." */
  18.910 +    0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,  /* 00000BF0    "........" */
  18.911 +    0x00,0x0A,0x10,0x5B,0x82,0x46,0x37,0x49,  /* 00000BF8    "...[.F7I" */
  18.912 +    0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,0x52,  /* 00000C00    "SA_._ADR" */
  18.913 +    0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,0x50,  /* 00000C08    ".....[.P" */
  18.914 +    0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,0x04,  /* 00000C10    "IRQ..`.." */
  18.915 +    0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,0x5C,  /* 00000C18    "..\.[.)\" */
  18.916 +    0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00000C20    "/._SB_PC" */
  18.917 +    0x49,0x30,0x49,0x53,0x41,0x5F,0x50,0x49,  /* 00000C28    "I0ISA_PI" */
  18.918 +    0x52,0x51,0x01,0x50,0x49,0x52,0x41,0x08,  /* 00000C30    "RQ.PIRA." */
  18.919 +    0x50,0x49,0x52,0x42,0x08,0x50,0x49,0x52,  /* 00000C38    "PIRB.PIR" */
  18.920 +    0x43,0x08,0x50,0x49,0x52,0x44,0x08,0x5B,  /* 00000C40    "C.PIRD.[" */
  18.921 +    0x82,0x46,0x0B,0x53,0x59,0x53,0x52,0x08,  /* 00000C48    ".F.SYSR." */
  18.922 +    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,  /* 00000C50    "_HID.A.." */
  18.923 +    0x02,0x08,0x5F,0x55,0x49,0x44,0x01,0x08,  /* 00000C58    ".._UID.." */
  18.924 +    0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,0x0A,  /* 00000C60    "CRS_.N.." */
  18.925 +    0x8A,0x47,0x01,0x10,0x00,0x10,0x00,0x00,  /* 00000C68    ".G......" */
  18.926 +    0x10,0x47,0x01,0x22,0x00,0x22,0x00,0x00,  /* 00000C70    ".G.".".." */
  18.927 +    0x0C,0x47,0x01,0x30,0x00,0x30,0x00,0x00,  /* 00000C78    ".G.0.0.." */
  18.928 +    0x10,0x47,0x01,0x44,0x00,0x44,0x00,0x00,  /* 00000C80    ".G.D.D.." */
  18.929 +    0x1C,0x47,0x01,0x62,0x00,0x62,0x00,0x00,  /* 00000C88    ".G.b.b.." */
  18.930 +    0x02,0x47,0x01,0x65,0x00,0x65,0x00,0x00,  /* 00000C90    ".G.e.e.." */
  18.931 +    0x0B,0x47,0x01,0x72,0x00,0x72,0x00,0x00,  /* 00000C98    ".G.r.r.." */
  18.932 +    0x0E,0x47,0x01,0x80,0x00,0x80,0x00,0x00,  /* 00000CA0    ".G......" */
  18.933 +    0x01,0x47,0x01,0x84,0x00,0x84,0x00,0x00,  /* 00000CA8    ".G......" */
  18.934 +    0x03,0x47,0x01,0x88,0x00,0x88,0x00,0x00,  /* 00000CB0    ".G......" */
  18.935 +    0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,0x00,  /* 00000CB8    ".G......" */
  18.936 +    0x03,0x47,0x01,0x90,0x00,0x90,0x00,0x00,  /* 00000CC0    ".G......" */
  18.937 +    0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,0x00,  /* 00000CC8    ".G......" */
  18.938 +    0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,0x00,  /* 00000CD0    ".G......" */
  18.939 +    0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,0x00,  /* 00000CD8    ".G......" */
  18.940 +    0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,0x00,  /* 00000CE0    ".G......" */
  18.941 +    0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,0x00,  /* 00000CE8    ".G......" */
  18.942 +    0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,0x52,  /* 00000CF0    ".y..._CR" */
  18.943 +    0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,0x5B,  /* 00000CF8    "S..CRS_[" */
  18.944 +    0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,0x5F,  /* 00000D00    ".+PIC_._" */
  18.945 +    0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,0x5F,  /* 00000D08    "HID.A.._" */
  18.946 +    0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47,  /* 00000D10    "CRS....G" */
  18.947 +    0x01,0x20,0x00,0x20,0x00,0x01,0x02,0x47,  /* 00000D18    ". . ...G" */
  18.948 +    0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,0x22,  /* 00000D20    "......."" */
  18.949 +    0x04,0x00,0x79,0x00,0x5B,0x82,0x47,0x05,  /* 00000D28    "..y.[.G." */
  18.950 +    0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,0x49,  /* 00000D30    "DMA0._HI" */
  18.951 +    0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,0x5F,  /* 00000D38    "D.A...._" */
  18.952 +    0x43,0x52,0x53,0x11,0x41,0x04,0x0A,0x3D,  /* 00000D40    "CRS.A..=" */
  18.953 +    0x2A,0x10,0x04,0x47,0x01,0x00,0x00,0x00,  /* 00000D48    "*..G...." */
  18.954 +    0x00,0x00,0x10,0x47,0x01,0x81,0x00,0x81,  /* 00000D50    "...G...." */
  18.955 +    0x00,0x00,0x03,0x47,0x01,0x87,0x00,0x87,  /* 00000D58    "...G...." */
  18.956 +    0x00,0x00,0x01,0x47,0x01,0x89,0x00,0x89,  /* 00000D60    "...G...." */
  18.957 +    0x00,0x00,0x03,0x47,0x01,0x8F,0x00,0x8F,  /* 00000D68    "...G...." */
  18.958 +    0x00,0x00,0x01,0x47,0x01,0xC0,0x00,0xC0,  /* 00000D70    "...G...." */
  18.959 +    0x00,0x00,0x20,0x47,0x01,0x80,0x04,0x80,  /* 00000D78    ".. G...." */
  18.960 +    0x04,0x00,0x10,0x79,0x00,0x5B,0x82,0x25,  /* 00000D80    "...y.[.%" */
  18.961 +    0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,0x49,  /* 00000D88    "TMR_._HI" */
  18.962 +    0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,0x5F,  /* 00000D90    "D.A...._" */
  18.963 +    0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,  /* 00000D98    "CRS....G" */
  18.964 +    0x01,0x40,0x00,0x40,0x00,0x00,0x04,0x22,  /* 00000DA0    ".@.@..."" */
  18.965 +    0x01,0x00,0x79,0x00,0x5B,0x82,0x25,0x52,  /* 00000DA8    "..y.[.%R" */
  18.966 +    0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,  /* 00000DB0    "TC_._HID" */
  18.967 +    0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,0x43,  /* 00000DB8    ".A...._C" */
  18.968 +    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000DC0    "RS....G." */
  18.969 +    0x70,0x00,0x70,0x00,0x00,0x02,0x22,0x00,  /* 00000DC8    "p.p..."." */
  18.970 +    0x01,0x79,0x00,0x5B,0x82,0x22,0x53,0x50,  /* 00000DD0    ".y.[."SP" */
  18.971 +    0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000DD8    "KR._HID." */
  18.972 +    0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,0x52,  /* 00000DE0    "A...._CR" */
  18.973 +    0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,0x61,  /* 00000DE8    "S....G.a" */
  18.974 +    0x00,0x61,0x00,0x00,0x01,0x79,0x00,0x5B,  /* 00000DF0    ".a...y.[" */
  18.975 +    0x82,0x31,0x50,0x53,0x32,0x4D,0x08,0x5F,  /* 00000DF8    ".1PS2M._" */
  18.976 +    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,  /* 00000E00    "HID.A..." */
  18.977 +    0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,  /* 00000E08    "._CID.A." */
  18.978 +    0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,0x41,  /* 00000E10    "...._STA" */
  18.979 +    0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000E18    "....._CR" */
  18.980 +    0x53,0x11,0x08,0x0A,0x05,0x22,0x00,0x10,  /* 00000E20    "S....".." */
  18.981 +    0x79,0x00,0x5B,0x82,0x42,0x04,0x50,0x53,  /* 00000E28    "y.[.B.PS" */
  18.982 +    0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000E30    "2K._HID." */
  18.983 +    0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,0x49,  /* 00000E38    "A...._CI" */
  18.984 +    0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,0x09,  /* 00000E40    "D.A....." */
  18.985 +    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 00000E48    "_STA...." */
  18.986 +    0x08,0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,  /* 00000E50    "._CRS..." */
  18.987 +    0x15,0x47,0x01,0x60,0x00,0x60,0x00,0x00,  /* 00000E58    ".G.`.`.." */
  18.988 +    0x01,0x47,0x01,0x64,0x00,0x64,0x00,0x00,  /* 00000E60    ".G.d.d.." */
  18.989 +    0x01,0x22,0x02,0x00,0x79,0x00,0x5B,0x82,  /* 00000E68    "."..y.[." */
  18.990 +    0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,0x48,  /* 00000E70    ":FDC0._H" */
  18.991 +    0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,0x14,  /* 00000E78    "ID.A...." */
  18.992 +    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000E80    "._STA..." */
  18.993 +    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1B,  /* 00000E88    ".._CRS.." */
  18.994 +    0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,0x03,  /* 00000E90    "..G....." */
  18.995 +    0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,0x03,  /* 00000E98    "..G....." */
  18.996 +    0x01,0x01,0x22,0x40,0x00,0x2A,0x04,0x00,  /* 00000EA0    ".."@.*.." */
  18.997 +    0x79,0x00,0x5B,0x82,0x46,0x04,0x55,0x41,  /* 00000EA8    "y.[.F.UA" */
  18.998 +    0x52,0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000EB0    "R1._HID." */
  18.999 +    0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,  /* 00000EB8    "A...._UI" */
 18.1000 +    0x44,0x01,0x14,0x19,0x5F,0x53,0x54,0x41,  /* 00000EC0    "D..._STA" */
 18.1001 +    0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,0x5E,  /* 00000EC8    "....^^^^" */
 18.1002 +    0x55,0x41,0x52,0x31,0x00,0xA4,0x00,0xA1,  /* 00000ED0    "UAR1...." */
 18.1003 +    0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,  /* 00000ED8    "....._CR" */
 18.1004 +    0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8,  /* 00000EE0    "S....G.." */
 18.1005 +    0x03,0xF8,0x03,0x08,0x08,0x22,0x10,0x00,  /* 00000EE8    ".....".." */
 18.1006 +    0x79,0x00,0x5B,0x82,0x47,0x04,0x55,0x41,  /* 00000EF0    "y.[.G.UA" */
 18.1007 +    0x52,0x32,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000EF8    "R2._HID." */
 18.1008 +    0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,  /* 00000F00    "A...._UI" */
 18.1009 +    0x44,0x0A,0x02,0x14,0x19,0x5F,0x53,0x54,  /* 00000F08    "D...._ST" */
 18.1010 +    0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,  /* 00000F10    "A....^^^" */
 18.1011 +    0x5E,0x55,0x41,0x52,0x32,0x00,0xA4,0x00,  /* 00000F18    "^UAR2..." */
 18.1012 +    0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000F20    "......_C" */
 18.1013 +    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000F28    "RS....G." */
 18.1014 +    0xF8,0x02,0xF8,0x02,0x08,0x08,0x22,0x08,  /* 00000F30    "......"." */
 18.1015 +    0x00,0x79,0x00,0x5B,0x82,0x36,0x4C,0x54,  /* 00000F38    ".y.[.6LT" */
 18.1016 +    0x50,0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000F40    "P1._HID." */
 18.1017 +    0x41,0xD0,0x04,0x00,0x08,0x5F,0x55,0x49,  /* 00000F48    "A...._UI" */
 18.1018 +    0x44,0x0A,0x02,0x14,0x09,0x5F,0x53,0x54,  /* 00000F50    "D...._ST" */
 18.1019 +    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000F58    "A....._C" */
 18.1020 +    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000F60    "RS....G." */
 18.1021 +    0x78,0x03,0x78,0x03,0x08,0x08,0x22,0x80,  /* 00000F68    "x.x..."." */
 18.1022 +    0x00,0x79,0x00,0x5B,0x82,0x4D,0x07,0x53,  /* 00000F70    ".y.[.M.S" */
 18.1023 +    0x31,0x46,0x30,0x08,0x5F,0x41,0x44,0x52,  /* 00000F78    "1F0._ADR" */
 18.1024 +    0x0C,0x00,0x00,0x06,0x00,0x08,0x5F,0x53,  /* 00000F80    "......_S" */
 18.1025 +    0x55,0x4E,0x01,0x14,0x13,0x5F,0x50,0x53,  /* 00000F88    "UN..._PS" */
 18.1026 +    0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E,0x5F,  /* 00000F90    "0.p..\._" */
 18.1027 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00000F98    "GPEDPT2." */
 18.1028 +    0x13,0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,  /* 00000FA0    "._PS3.p." */
 18.1029 +    0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00000FA8    ".\._GPED" */
 18.1030 +    0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,  /* 00000FB0    "PT2.._EJ" */
 18.1031 +    0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E,0x5F,  /* 00000FB8    "0.p..\._" */
 18.1032 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x70,  /* 00000FC0    "GPEDPT2p" */
 18.1033 +    0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00000FC8    ".\._GPEP" */
 18.1034 +    0x48,0x50,0x31,0x14,0x1E,0x5F,0x53,0x54,  /* 00000FD0    "HP1.._ST" */
 18.1035 +    0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E,0x5F,  /* 00000FD8    "A.p..\._" */
 18.1036 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0xA4,  /* 00000FE0    "GPEDPT2." */
 18.1037 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,  /* 00000FE8    "\._GPEPH" */
 18.1038 +    0x50,0x31,0x5B,0x82,0x4E,0x07,0x53,0x32,  /* 00000FF0    "P1[.N.S2" */
 18.1039 +    0x46,0x30,0x08,0x5F,0x41,0x44,0x52,0x0C,  /* 00000FF8    "F0._ADR." */
 18.1040 +    0x00,0x00,0x07,0x00,0x08,0x5F,0x53,0x55,  /* 00001000    "....._SU" */
 18.1041 +    0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50,0x53,  /* 00001008    "N...._PS" */
 18.1042 +    0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E,0x5F,  /* 00001010    "0.p..\._" */
 18.1043 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14,  /* 00001018    "GPEDPT2." */
 18.1044 +    0x13,0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,  /* 00001020    "._PS3.p." */
 18.1045 +    0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,  /* 00001028    ".\._GPED" */
 18.1046 +    0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,  /* 00001030    "PT2.._EJ" */
 18.1047 +    0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E,0x5F,  /* 00001038    "0.p..\._" */
 18.1048 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x70,  /* 00001040    "GPEDPT2p" */
 18.1049 +    0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,  /* 00001048    ".\._GPEP" */
 18.1050 +    0x48,0x50,0x32,0x14,0x1E,0x5F,0x53,0x54,  /* 00001050    "HP2.._ST" */
 18.1051 +    0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E,0x5F,  /* 00001058    "A.p..\._" */
 18.1052 +    0x47,0x50,0x45,0x44,0x50,0x54,0x32,0xA4,  /* 00001060    "GPEDPT2." */
 18.1053 +    0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,  /* 00001068    "\._GPEPH" */
 18.1054 +    0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47,0x50,  /* 00001070    "P2.N._GP" */
 18.1055 +    0x45,0x5B,0x80,0x50,0x48,0x50,0x5F,0x01,  /* 00001078    "E[.PHP_." */
 18.1056 +    0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81,0x15,  /* 00001080    ".....[.." */
 18.1057 +    0x50,0x48,0x50,0x5F,0x01,0x50,0x53,0x54,  /* 00001088    "PHP_.PST" */
 18.1058 +    0x41,0x08,0x50,0x48,0x50,0x31,0x08,0x50,  /* 00001090    "A.PHP1.P" */
 18.1059 +    0x48,0x50,0x32,0x08,0x5B,0x80,0x44,0x47,  /* 00001098    "HP2.[.DG" */
 18.1060 +    0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A,0x04,  /* 000010A0    "1_..D..." */
 18.1061 +    0x5B,0x81,0x10,0x44,0x47,0x31,0x5F,0x01,  /* 000010A8    "[..DG1_." */
 18.1062 +    0x44,0x50,0x54,0x31,0x08,0x44,0x50,0x54,  /* 000010B0    "DPT1.DPT" */
 18.1063 +    0x32,0x08,0x14,0x46,0x07,0x5F,0x4C,0x30,  /* 000010B8    "2..F._L0" */
 18.1064 +    0x33,0x00,0x08,0x53,0x4C,0x54,0x5F,0x00,  /* 000010C0    "3..SLT_." */
 18.1065 +    0x08,0x45,0x56,0x54,0x5F,0x00,0x70,0x50,  /* 000010C8    ".EVT_.pP" */
 18.1066 +    0x53,0x54,0x41,0x61,0x7A,0x61,0x0A,0x04,  /* 000010D0    "STAaza.." */
 18.1067 +    0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A,0x0F,  /* 000010D8    "SLT_{a.." */
 18.1068 +    0x45,0x56,0x54,0x5F,0x70,0x53,0x4C,0x54,  /* 000010E0    "EVT_pSLT" */
 18.1069 +    0x5F,0x44,0x50,0x54,0x31,0x70,0x45,0x56,  /* 000010E8    "_DPT1pEV" */
 18.1070 +    0x54,0x5F,0x44,0x50,0x54,0x32,0xA0,0x1B,  /* 000010F0    "T_DPT2.." */
 18.1071 +    0x93,0x53,0x4C,0x54,0x5F,0x01,0x86,0x5C,  /* 000010F8    ".SLT_..\" */
 18.1072 +    0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,  /* 00001100    "/._SB_PC" */
 18.1073 +    0x49,0x30,0x53,0x31,0x46,0x30,0x45,0x56,  /* 00001108    "I0S1F0EV" */
 18.1074 +    0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93,0x53,  /* 00001110    "T_.....S" */
 18.1075 +    0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C,0x2F,  /* 00001118    "LT_...\/" */
 18.1076 +    0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,  /* 00001120    "._SB_PCI" */
 18.1077 +    0x30,0x53,0x32,0x46,0x30,0x45,0x56,0x54,  /* 00001128    "0S2F0EVT" */
 18.1078 +    0x5F,
 18.1079  };
 18.1080  int DsdtLen=sizeof(AmlCode);
    19.1 --- a/tools/ioemu/Makefile.target	Mon Feb 25 06:29:01 2008 -0700
    19.2 +++ b/tools/ioemu/Makefile.target	Tue Feb 26 10:12:04 2008 -0700
    19.3 @@ -357,7 +357,7 @@ VL_OBJS+=tap-win32.o
    19.4  endif
    19.5  
    19.6  ifdef CONFIG_STUBDOM
    19.7 -CONFIG_PASSTHROUGH=1
    19.8 +#CONFIG_PASSTHROUGH=1
    19.9  else
   19.10    ifeq (,$(wildcard /usr/include/pci))
   19.11  $(warning *** pciutils-devl package not found - missing /usr/include/pci)
   19.12 @@ -415,7 +415,7 @@ VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a
   19.13  VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
   19.14  
   19.15  # PCI network cards
   19.16 -VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o
   19.17 +VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o e1000.o
   19.18  
   19.19  ifeq ($(TARGET_BASE_ARCH), i386)
   19.20  # Hardware support
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/ioemu/hw/e1000.c	Tue Feb 26 10:12:04 2008 -0700
    20.3 @@ -0,0 +1,995 @@
    20.4 +/*
    20.5 + * QEMU e1000 emulation
    20.6 + *
    20.7 + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
    20.8 + * Copyright (c) 2008 Qumranet
    20.9 + * Based on work done by:
   20.10 + * Copyright (c) 2007 Dan Aloni
   20.11 + * Copyright (c) 2004 Antony T Curtis
   20.12 + *
   20.13 + * This library is free software; you can redistribute it and/or
   20.14 + * modify it under the terms of the GNU Lesser General Public
   20.15 + * License as published by the Free Software Foundation; either
   20.16 + * version 2 of the License, or (at your option) any later version.
   20.17 + *
   20.18 + * This library is distributed in the hope that it will be useful,
   20.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   20.21 + * Lesser General Public License for more details.
   20.22 + *
   20.23 + * You should have received a copy of the GNU Lesser General Public
   20.24 + * License along with this library; if not, write to the Free Software
   20.25 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   20.26 + */
   20.27 +
   20.28 +
   20.29 +#include "vl.h"
   20.30 +
   20.31 +#include "e1000_hw.h"
   20.32 +
   20.33 +#define DEBUG
   20.34 +
   20.35 +#ifdef DEBUG
   20.36 +enum {
   20.37 +    DEBUG_GENERAL,	DEBUG_IO,	DEBUG_MMIO,	DEBUG_INTERRUPT,
   20.38 +    DEBUG_RX,		DEBUG_TX,	DEBUG_MDIC,	DEBUG_EEPROM,
   20.39 +    DEBUG_UNKNOWN,	DEBUG_TXSUM,	DEBUG_TXERR,	DEBUG_RXERR,
   20.40 +    DEBUG_RXFILTER,	DEBUG_NOTYET,
   20.41 +};
   20.42 +#define DBGBIT(x)	(1<<DEBUG_##x)
   20.43 +static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
   20.44 +
   20.45 +#define	DBGOUT(what, fmt, params...) do { \
   20.46 +    if (debugflags & DBGBIT(what)) \
   20.47 +        fprintf(stderr, "e1000: " fmt, ##params); \
   20.48 +    } while (0)
   20.49 +#else
   20.50 +#define	DBGOUT(what, fmt, params...) do {} while (0)
   20.51 +#endif
   20.52 +
   20.53 +#define IOPORT_SIZE       0x40
   20.54 +#define PNPMMIO_SIZE      0x60000
   20.55 +
   20.56 +/*
   20.57 + * HW models:
   20.58 + *  E1000_DEV_ID_82540EM works with Windows and Linux
   20.59 + *  E1000_DEV_ID_82573L OK with windoze and Linux 2.6.22,
   20.60 + *	appears to perform better than 82540EM, but breaks with Linux 2.6.18
   20.61 + *  E1000_DEV_ID_82544GC_COPPER appears to work; not well tested
   20.62 + *  Others never tested
   20.63 + */
   20.64 +enum { E1000_DEVID = E1000_DEV_ID_82540EM };
   20.65 +
   20.66 +/*
   20.67 + * May need to specify additional MAC-to-PHY entries --
   20.68 + * Intel's Windows driver refuses to initialize unless they match
   20.69 + */
   20.70 +enum {
   20.71 +    PHY_ID2_INIT = E1000_DEVID == E1000_DEV_ID_82573L ?		0xcc2 :
   20.72 +                   E1000_DEVID == E1000_DEV_ID_82544GC_COPPER ?	0xc30 :
   20.73 +                   /* default to E1000_DEV_ID_82540EM */	0xc20
   20.74 +};
   20.75 +
   20.76 +typedef struct E1000State_st {
   20.77 +    PCIDevice dev;
   20.78 +    VLANClientState *vc;
   20.79 +    NICInfo *nd;
   20.80 +    uint32_t instance;
   20.81 +    uint32_t mmio_base;
   20.82 +    int mmio_index;
   20.83 +
   20.84 +    uint32_t mac_reg[0x8000];
   20.85 +    uint16_t phy_reg[0x20];
   20.86 +    uint16_t eeprom_data[64];
   20.87 +
   20.88 +    uint32_t rxbuf_size;
   20.89 +    uint32_t rxbuf_min_shift;
   20.90 +    int check_rxov;
   20.91 +    struct e1000_tx {
   20.92 +        unsigned char header[256];
   20.93 +        unsigned char data[0x10000];
   20.94 +        uint16_t size;
   20.95 +        unsigned char sum_needed;
   20.96 +        uint8_t ipcss;
   20.97 +        uint8_t ipcso;
   20.98 +        uint16_t ipcse;
   20.99 +        uint8_t tucss;
  20.100 +        uint8_t tucso;
  20.101 +        uint16_t tucse;
  20.102 +        uint8_t hdr_len;
  20.103 +        uint16_t mss;
  20.104 +        uint32_t paylen;
  20.105 +        uint16_t tso_frames;
  20.106 +        char tse;
  20.107 +        char ip;
  20.108 +        char tcp;
  20.109 +    } tx;
  20.110 +
  20.111 +    struct {
  20.112 +        uint32_t val_in;	// shifted in from guest driver
  20.113 +        uint16_t bitnum_in;
  20.114 +        uint16_t bitnum_out;
  20.115 +        uint16_t reading;
  20.116 +        uint32_t old_eecd;
  20.117 +    } eecd_state;
  20.118 +} E1000State;
  20.119 +
  20.120 +#define	defreg(x)	x = (E1000_##x>>2)
  20.121 +enum {
  20.122 +    defreg(CTRL),	defreg(EECD),	defreg(EERD),	defreg(GPRC),
  20.123 +    defreg(GPTC),	defreg(ICR),	defreg(ICS),	defreg(IMC),
  20.124 +    defreg(IMS),	defreg(LEDCTL),	defreg(MANC),	defreg(MDIC),
  20.125 +    defreg(MPC),	defreg(PBA),	defreg(RCTL),	defreg(RDBAH),
  20.126 +    defreg(RDBAL),	defreg(RDH),	defreg(RDLEN),	defreg(RDT),
  20.127 +    defreg(STATUS),	defreg(SWSM),	defreg(TCTL),	defreg(TDBAH),
  20.128 +    defreg(TDBAL),	defreg(TDH),	defreg(TDLEN),	defreg(TDT),
  20.129 +    defreg(TORH),	defreg(TORL),	defreg(TOTH),	defreg(TOTL),
  20.130 +    defreg(TPR),	defreg(TPT),	defreg(TXDCTL),	defreg(WUFC),
  20.131 +    defreg(RA),		defreg(MTA),	defreg(CRCERRS),
  20.132 +};
  20.133 +
  20.134 +enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W };
  20.135 +static char phy_regcap[0x20] = {
  20.136 +    [PHY_STATUS] = PHY_R,	[M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
  20.137 +    [PHY_ID1] = PHY_R,		[M88E1000_PHY_SPEC_CTRL] = PHY_RW,
  20.138 +    [PHY_CTRL] = PHY_RW,	[PHY_1000T_CTRL] = PHY_RW,
  20.139 +    [PHY_LP_ABILITY] = PHY_R,	[PHY_1000T_STATUS] = PHY_R,
  20.140 +    [PHY_AUTONEG_ADV] = PHY_RW,	[M88E1000_RX_ERR_CNTR] = PHY_R,
  20.141 +    [PHY_ID2] = PHY_R,
  20.142 +};
  20.143 +
  20.144 +static void
  20.145 +ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr,
  20.146 +           uint32_t size, int type)
  20.147 +{
  20.148 +    DBGOUT(IO, "e1000_ioport_map addr=0x%04x size=0x%08x\n", addr, size);
  20.149 +}
  20.150 +
  20.151 +static void
  20.152 +set_interrupt_cause(E1000State *s, int index, uint32_t val)
  20.153 +{
  20.154 +    if (val)
  20.155 +        val |= E1000_ICR_INT_ASSERTED;
  20.156 +    s->mac_reg[ICR] = val;
  20.157 +    pci_set_irq(&s->dev, 0, (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0);
  20.158 +}
  20.159 +
  20.160 +static void
  20.161 +set_ics(E1000State *s, int index, uint32_t val)
  20.162 +{
  20.163 +    DBGOUT(INTERRUPT, "set_ics %x, ICR %x, IMR %x\n", val, s->mac_reg[ICR],
  20.164 +        s->mac_reg[IMS]);
  20.165 +    set_interrupt_cause(s, 0, val | s->mac_reg[ICR]);
  20.166 +}
  20.167 +
  20.168 +static int
  20.169 +rxbufsize(uint32_t v)
  20.170 +{
  20.171 +    v &= E1000_RCTL_BSEX | E1000_RCTL_SZ_16384 | E1000_RCTL_SZ_8192 |
  20.172 +         E1000_RCTL_SZ_4096 | E1000_RCTL_SZ_2048 | E1000_RCTL_SZ_1024 |
  20.173 +         E1000_RCTL_SZ_512 | E1000_RCTL_SZ_256;
  20.174 +    switch (v) {
  20.175 +    case E1000_RCTL_BSEX | E1000_RCTL_SZ_16384:
  20.176 +        return 16384;
  20.177 +    case E1000_RCTL_BSEX | E1000_RCTL_SZ_8192:
  20.178 +        return 8192;
  20.179 +    case E1000_RCTL_BSEX | E1000_RCTL_SZ_4096:
  20.180 +        return 4096;
  20.181 +    case E1000_RCTL_SZ_1024:
  20.182 +        return 1024;
  20.183 +    case E1000_RCTL_SZ_512:
  20.184 +        return 512;
  20.185 +    case E1000_RCTL_SZ_256:
  20.186 +        return 256;
  20.187 +    }
  20.188 +    return 2048;
  20.189 +}
  20.190 +
  20.191 +static void
  20.192 +set_rx_control(E1000State *s, int index, uint32_t val)
  20.193 +{
  20.194 +    s->mac_reg[RCTL] = val;
  20.195 +    s->rxbuf_size = rxbufsize(val);
  20.196 +    s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
  20.197 +    DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
  20.198 +           s->mac_reg[RCTL]);
  20.199 +}
  20.200 +
  20.201 +static void
  20.202 +set_mdic(E1000State *s, int index, uint32_t val)
  20.203 +{
  20.204 +    uint32_t data = val & E1000_MDIC_DATA_MASK;
  20.205 +    uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
  20.206 +
  20.207 +    if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) // phy #
  20.208 +        val = s->mac_reg[MDIC] | E1000_MDIC_ERROR;
  20.209 +    else if (val & E1000_MDIC_OP_READ) {
  20.210 +        DBGOUT(MDIC, "MDIC read reg 0x%x\n", addr);
  20.211 +        if (!(phy_regcap[addr] & PHY_R)) {
  20.212 +            DBGOUT(MDIC, "MDIC read reg %x unhandled\n", addr);
  20.213 +            val |= E1000_MDIC_ERROR;
  20.214 +        } else
  20.215 +            val = (val ^ data) | s->phy_reg[addr];
  20.216 +    } else if (val & E1000_MDIC_OP_WRITE) {
  20.217 +        DBGOUT(MDIC, "MDIC write reg 0x%x, value 0x%x\n", addr, data);
  20.218 +        if (!(phy_regcap[addr] & PHY_W)) {
  20.219 +            DBGOUT(MDIC, "MDIC write reg %x unhandled\n", addr);
  20.220 +            val |= E1000_MDIC_ERROR;
  20.221 +        } else
  20.222 +            s->phy_reg[addr] = data;
  20.223 +    }
  20.224 +    s->mac_reg[MDIC] = val | E1000_MDIC_READY;
  20.225 +    set_ics(s, 0, E1000_ICR_MDAC);
  20.226 +}
  20.227 +
  20.228 +static uint32_t
  20.229 +get_eecd(E1000State *s, int index)
  20.230 +{
  20.231 +    uint32_t ret = E1000_EECD_PRES|E1000_EECD_GNT | s->eecd_state.old_eecd;
  20.232 +
  20.233 +    DBGOUT(EEPROM, "reading eeprom bit %d (reading %d)\n",
  20.234 +           s->eecd_state.bitnum_out, s->eecd_state.reading);
  20.235 +    if (!s->eecd_state.reading ||
  20.236 +        ((s->eeprom_data[(s->eecd_state.bitnum_out >> 4) & 0x3f] >>
  20.237 +          ((s->eecd_state.bitnum_out & 0xf) ^ 0xf))) & 1)
  20.238 +        ret |= E1000_EECD_DO;
  20.239 +    return ret;
  20.240 +}
  20.241 +
  20.242 +static void
  20.243 +set_eecd(E1000State *s, int index, uint32_t val)
  20.244 +{
  20.245 +    uint32_t oldval = s->eecd_state.old_eecd;
  20.246 +
  20.247 +    s->eecd_state.old_eecd = val & (E1000_EECD_SK | E1000_EECD_CS |
  20.248 +            E1000_EECD_DI|E1000_EECD_FWE_MASK|E1000_EECD_REQ);
  20.249 +    if (!(E1000_EECD_SK & (val ^ oldval)))	// no clock edge
  20.250 +        return;
  20.251 +    if (!(E1000_EECD_SK & val)) {		// falling edge
  20.252 +        s->eecd_state.bitnum_out++;
  20.253 +        return;
  20.254 +    }
  20.255 +    if (!(val & E1000_EECD_CS)) {		// rising, no CS (EEPROM reset)
  20.256 +        memset(&s->eecd_state, 0, sizeof s->eecd_state);
  20.257 +        return;
  20.258 +    }
  20.259 +    s->eecd_state.val_in <<= 1;
  20.260 +    if (val & E1000_EECD_DI)
  20.261 +        s->eecd_state.val_in |= 1;
  20.262 +    if (++s->eecd_state.bitnum_in == 9 && !s->eecd_state.reading) {
  20.263 +        s->eecd_state.bitnum_out = ((s->eecd_state.val_in & 0x3f)<<4)-1;
  20.264 +        s->eecd_state.reading = (((s->eecd_state.val_in >> 6) & 7) ==
  20.265 +            EEPROM_READ_OPCODE_MICROWIRE);
  20.266 +    }
  20.267 +    DBGOUT(EEPROM, "eeprom bitnum in %d out %d, reading %d\n",
  20.268 +           s->eecd_state.bitnum_in, s->eecd_state.bitnum_out,
  20.269 +           s->eecd_state.reading);
  20.270 +}
  20.271 +
  20.272 +static uint32_t
  20.273 +flash_eerd_read(E1000State *s, int x)
  20.274 +{
  20.275 +    unsigned int index, r = s->mac_reg[EERD] & ~E1000_EEPROM_RW_REG_START;
  20.276 +
  20.277 +    if ((index = r >> E1000_EEPROM_RW_ADDR_SHIFT) > EEPROM_CHECKSUM_REG)
  20.278 +        return 0;
  20.279 +    return (s->eeprom_data[index] << E1000_EEPROM_RW_REG_DATA) |
  20.280 +           E1000_EEPROM_RW_REG_DONE | r;
  20.281 +}
  20.282 +
  20.283 +static unsigned int
  20.284 +do_cksum(uint8_t *dp, uint8_t *de)
  20.285 +{
  20.286 +    unsigned int bsum[2] = {0, 0}, i, sum;
  20.287 +
  20.288 +    for (i = 1; dp < de; bsum[i^=1] += *dp++)
  20.289 +        ;
  20.290 +    sum = (bsum[0] << 8) + bsum[1];
  20.291 +    sum = (sum >> 16) + (sum & 0xffff);
  20.292 +    return ~(sum + (sum >> 16));
  20.293 +}
  20.294 +
  20.295 +static void
  20.296 +putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
  20.297 +{
  20.298 +    if (cse && cse < n)
  20.299 +        n = cse + 1;
  20.300 +    if (sloc < n-1)
  20.301 +        cpu_to_be16wu((uint16_t *)(data + sloc),
  20.302 +                      do_cksum(data + css, data + n));
  20.303 +}
  20.304 +
  20.305 +static void
  20.306 +xmit_seg(E1000State *s)
  20.307 +{
  20.308 +    uint16_t len, *sp;
  20.309 +    unsigned int frames = s->tx.tso_frames, css, sofar, n;
  20.310 +    struct e1000_tx *tp = &s->tx;
  20.311 +
  20.312 +    if (tp->tse) {
  20.313 +        css = tp->ipcss;
  20.314 +        DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",
  20.315 +               frames, tp->size, css);
  20.316 +        if (tp->ip) {		// IPv4
  20.317 +            cpu_to_be16wu((uint16_t *)(tp->data+css+2),
  20.318 +                          tp->size - css);
  20.319 +            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
  20.320 +                          be16_to_cpup((uint16_t *)(tp->data+css+4))+frames);
  20.321 +        } else			// IPv6
  20.322 +            cpu_to_be16wu((uint16_t *)(tp->data+css+4),
  20.323 +                          tp->size - css);
  20.324 +        css = tp->tucss;
  20.325 +        len = tp->size - css;
  20.326 +        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);
  20.327 +        if (tp->tcp) {
  20.328 +            sofar = frames * tp->mss;
  20.329 +            cpu_to_be32wu((uint32_t *)(tp->data+css+4),	// seq
  20.330 +                be32_to_cpup((uint32_t *)(tp->data+css+4))+sofar);
  20.331 +            if (tp->paylen - sofar > tp->mss)
  20.332 +                tp->data[css + 13] &= ~9;		// PSH, FIN
  20.333 +        } else	// UDP
  20.334 +            cpu_to_be16wu((uint16_t *)(tp->data+css+4), len);
  20.335 +        if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {
  20.336 +            // add pseudo-header length before checksum calculation
  20.337 +            sp = (uint16_t *)(tp->data + tp->tucso);
  20.338 +            cpu_to_be16wu(sp, be16_to_cpup(sp) + len);
  20.339 +        }
  20.340 +        tp->tso_frames++;
  20.341 +    }
  20.342 +
  20.343 +    if (tp->sum_needed & E1000_TXD_POPTS_TXSM)
  20.344 +        putsum(tp->data, tp->size, tp->tucso, tp->tucss, tp->tucse);
  20.345 +    if (tp->sum_needed & E1000_TXD_POPTS_IXSM)
  20.346 +        putsum(tp->data, tp->size, tp->ipcso, tp->ipcss, tp->ipcse);
  20.347 +    qemu_send_packet(s->vc, tp->data, tp->size);
  20.348 +    s->mac_reg[TPT]++;
  20.349 +    s->mac_reg[GPTC]++;
  20.350 +    n = s->mac_reg[TOTL];
  20.351 +    if ((s->mac_reg[TOTL] += s->tx.size) < n)
  20.352 +        s->mac_reg[TOTH]++;
  20.353 +}
  20.354 +
  20.355 +static void
  20.356 +process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
  20.357 +{
  20.358 +    uint32_t txd_lower = le32_to_cpu(dp->lower.data);
  20.359 +    uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D);
  20.360 +    unsigned int split_size = txd_lower & 0xffff, bytes, sz, op;
  20.361 +    unsigned int msh = 0xfffff, hdr = 0;
  20.362 +    uint64_t addr;
  20.363 +    struct e1000_context_desc *xp = (struct e1000_context_desc *)dp;
  20.364 +    struct e1000_tx *tp = &s->tx;
  20.365 +
  20.366 +    if (dtype == E1000_TXD_CMD_DEXT) {	// context descriptor
  20.367 +        op = le32_to_cpu(xp->cmd_and_length);
  20.368 +        tp->ipcss = xp->lower_setup.ip_fields.ipcss;
  20.369 +        tp->ipcso = xp->lower_setup.ip_fields.ipcso;
  20.370 +        tp->ipcse = le16_to_cpu(xp->lower_setup.ip_fields.ipcse);
  20.371 +        tp->tucss = xp->upper_setup.tcp_fields.tucss;
  20.372 +        tp->tucso = xp->upper_setup.tcp_fields.tucso;
  20.373 +        tp->tucse = le16_to_cpu(xp->upper_setup.tcp_fields.tucse);
  20.374 +        tp->paylen = op & 0xfffff;
  20.375 +        tp->hdr_len = xp->tcp_seg_setup.fields.hdr_len;
  20.376 +        tp->mss = le16_to_cpu(xp->tcp_seg_setup.fields.mss);
  20.377 +        tp->ip = (op & E1000_TXD_CMD_IP) ? 1 : 0;
  20.378 +        tp->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
  20.379 +        tp->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
  20.380 +        tp->tso_frames = 0;
  20.381 +        if (tp->tucso == 0) {	// this is probably wrong
  20.382 +            DBGOUT(TXSUM, "TCP/UDP: cso 0!\n");
  20.383 +            tp->tucso = tp->tucss + (tp->tcp ? 16 : 6);
  20.384 +        }
  20.385 +        return;
  20.386 +    } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D))
  20.387 +        tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8;
  20.388 +
  20.389 +    addr = le64_to_cpu(dp->buffer_addr);
  20.390 +    if (tp->tse) {
  20.391 +        hdr = tp->hdr_len;
  20.392 +        msh = hdr + tp->mss;
  20.393 +    }
  20.394 +    do {
  20.395 +        bytes = split_size;
  20.396 +        if (tp->size + bytes > msh)
  20.397 +            bytes = msh - tp->size;
  20.398 +        cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
  20.399 +        if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
  20.400 +            memmove(tp->header, tp->data, hdr);
  20.401 +        tp->size = sz;
  20.402 +        addr += bytes;
  20.403 +        if (sz == msh) {
  20.404 +            xmit_seg(s);
  20.405 +            memmove(tp->data, tp->header, hdr);
  20.406 +            tp->size = hdr;
  20.407 +        }
  20.408 +    } while (split_size -= bytes);
  20.409 +
  20.410 +    if (!(txd_lower & E1000_TXD_CMD_EOP))
  20.411 +        return;
  20.412 +    if (tp->size > hdr)
  20.413 +        xmit_seg(s);
  20.414 +    tp->tso_frames = 0;
  20.415 +    tp->sum_needed = 0;
  20.416 +    tp->size = 0;
  20.417 +}
  20.418 +
  20.419 +static uint32_t
  20.420 +txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
  20.421 +{
  20.422 +    uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data);
  20.423 +
  20.424 +    if (!(txd_lower & (E1000_TXD_CMD_RS|E1000_TXD_CMD_RPS)))
  20.425 +        return 0;
  20.426 +    txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) &
  20.427 +                ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU);
  20.428 +    dp->upper.data = cpu_to_le32(txd_upper);
  20.429 +    cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp),
  20.430 +                              (void *)&dp->upper, sizeof(dp->upper));
  20.431 +    return E1000_ICR_TXDW;
  20.432 +}
  20.433 +
  20.434 +static void
  20.435 +start_xmit(E1000State *s)
  20.436 +{
  20.437 +    target_phys_addr_t base;
  20.438 +    struct e1000_tx_desc desc;
  20.439 +    uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE;
  20.440 +
  20.441 +    if (!(s->mac_reg[TCTL] & E1000_TCTL_EN)) {
  20.442 +        DBGOUT(TX, "tx disabled\n");
  20.443 +        return;
  20.444 +    }
  20.445 +
  20.446 +    while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
  20.447 +        base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] +
  20.448 +               sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
  20.449 +        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
  20.450 +
  20.451 +        DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH],
  20.452 +               (void *)desc.buffer_addr, desc.lower.data,
  20.453 +               desc.upper.data);
  20.454 +
  20.455 +        process_tx_desc(s, &desc);
  20.456 +        cause |= txdesc_writeback(base, &desc);
  20.457 +
  20.458 +        if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN])
  20.459 +            s->mac_reg[TDH] = 0;
  20.460 +        /*
  20.461 +         * the following could happen only if guest sw assigns
  20.462 +         * bogus values to TDT/TDLEN.
  20.463 +         * there's nothing too intelligent we could do about this.
  20.464 +         */
  20.465 +        if (s->mac_reg[TDH] == tdh_start) {
  20.466 +            DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
  20.467 +                   tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
  20.468 +            break;
  20.469 +        }
  20.470 +    }
  20.471 +    set_ics(s, 0, cause);
  20.472 +}
  20.473 +
  20.474 +static int
  20.475 +receive_filter(E1000State *s, const uint8_t *buf, int size)
  20.476 +{
  20.477 +    static uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  20.478 +    static int mta_shift[] = {4, 3, 2, 0};
  20.479 +    uint32_t f, rctl = s->mac_reg[RCTL], ra[2], *rp;
  20.480 +
  20.481 +    if (rctl & E1000_RCTL_UPE)			// promiscuous
  20.482 +        return 1;
  20.483 +
  20.484 +    if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE))	// promiscuous mcast
  20.485 +        return 1;
  20.486 +
  20.487 +    if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast))
  20.488 +        return 1;
  20.489 +
  20.490 +    for (rp = s->mac_reg + RA; rp < s->mac_reg + RA + 32; rp += 2) {
  20.491 +        if (!(rp[1] & E1000_RAH_AV))
  20.492 +            continue;
  20.493 +        ra[0] = cpu_to_le32(rp[0]);
  20.494 +        ra[1] = cpu_to_le32(rp[1]);
  20.495 +        if (!memcmp(buf, (uint8_t *)ra, 6)) {
  20.496 +            DBGOUT(RXFILTER,
  20.497 +                   "unicast match[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n",
  20.498 +                   (int)(rp - s->mac_reg - RA)/2,
  20.499 +                   buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
  20.500 +            return 1;
  20.501 +        }
  20.502 +    }
  20.503 +    DBGOUT(RXFILTER, "unicast mismatch: %02x:%02x:%02x:%02x:%02x:%02x\n",
  20.504 +           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
  20.505 +
  20.506 +    f = mta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
  20.507 +    f = (((buf[5] << 8) | buf[4]) >> f) & 0xfff;
  20.508 +    if (s->mac_reg[MTA + (f >> 5)] & (1 << (f & 0x1f)))
  20.509 +        return 1;
  20.510 +    DBGOUT(RXFILTER,
  20.511 +           "dropping, inexact filter mismatch: %02x:%02x:%02x:%02x:%02x:%02x MO %d MTA[%d] %x\n",
  20.512 +           buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
  20.513 +           (rctl >> E1000_RCTL_MO_SHIFT) & 3, f >> 5,
  20.514 +           s->mac_reg[MTA + (f >> 5)]);
  20.515 +
  20.516 +    return 0;
  20.517 +}
  20.518 +
  20.519 +static int
  20.520 +e1000_can_receive(void *opaque)
  20.521 +{
  20.522 +    E1000State *s = opaque;
  20.523 +
  20.524 +    return (!(s->mac_reg[RCTL] & E1000_RCTL_EN) ||
  20.525 +            s->mac_reg[RDH] != s->mac_reg[RDT]);
  20.526 +}
  20.527 +
  20.528 +static void
  20.529 +e1000_receive(void *opaque, const uint8_t *buf, int size)
  20.530 +{
  20.531 +    E1000State *s = opaque;
  20.532 +    struct e1000_rx_desc desc;
  20.533 +    target_phys_addr_t base;
  20.534 +    unsigned int n, rdt;
  20.535 +    uint32_t rdh_start;
  20.536 +
  20.537 +    if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))
  20.538 +        return;
  20.539 +
  20.540 +    if (size > s->rxbuf_size) {
  20.541 +        DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size,
  20.542 +               s->rxbuf_size);
  20.543 +        return;
  20.544 +    }
  20.545 +
  20.546 +    if (!receive_filter(s, buf, size))
  20.547 +        return;
  20.548 +
  20.549 +    rdh_start = s->mac_reg[RDH];
  20.550 +    size += 4; // for the header
  20.551 +    do {
  20.552 +        if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {
  20.553 +            set_ics(s, 0, E1000_ICS_RXO);
  20.554 +            return;
  20.555 +        }
  20.556 +        base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
  20.557 +               sizeof(desc) * s->mac_reg[RDH];
  20.558 +        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
  20.559 +        desc.status |= E1000_RXD_STAT_DD;
  20.560 +        if (desc.buffer_addr) {
  20.561 +            cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
  20.562 +                                      (void *)buf, size);
  20.563 +            desc.length = cpu_to_le16(size);
  20.564 +            desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;
  20.565 +        } else // as per intel docs; skip descriptors with null buf addr
  20.566 +            DBGOUT(RX, "Null RX descriptor!!\n");
  20.567 +        cpu_physical_memory_write(base, (void *)&desc, sizeof(desc));
  20.568 +
  20.569 +        if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
  20.570 +            s->mac_reg[RDH] = 0;
  20.571 +        s->check_rxov = 1;
  20.572 +        /* see comment in start_xmit; same here */
  20.573 +        if (s->mac_reg[RDH] == rdh_start) {
  20.574 +            DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
  20.575 +                   rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
  20.576 +            set_ics(s, 0, E1000_ICS_RXO);
  20.577 +            return;
  20.578 +        }
  20.579 +    } while (desc.buffer_addr == 0);
  20.580 +
  20.581 +    s->mac_reg[GPRC]++;
  20.582 +    s->mac_reg[TPR]++;
  20.583 +    n = s->mac_reg[TORL];
  20.584 +    if ((s->mac_reg[TORL] += size) < n)
  20.585 +        s->mac_reg[TORH]++;
  20.586 +
  20.587 +    n = E1000_ICS_RXT0;
  20.588 +    if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])
  20.589 +        rdt += s->mac_reg[RDLEN] / sizeof(desc);
  20.590 +    if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >=
  20.591 +        s->mac_reg[RDLEN])
  20.592 +        n |= E1000_ICS_RXDMT0;
  20.593 +
  20.594 +    set_ics(s, 0, n);
  20.595 +}
  20.596 +
  20.597 +static uint32_t
  20.598 +mac_readreg(E1000State *s, int index)
  20.599 +{
  20.600 +    return s->mac_reg[index];
  20.601 +}
  20.602 +
  20.603 +static uint32_t
  20.604 +mac_icr_read(E1000State *s, int index)
  20.605 +{
  20.606 +    uint32_t ret = s->mac_reg[ICR];
  20.607 +
  20.608 +    DBGOUT(INTERRUPT, "ICR read: %x\n", ret);
  20.609 +    set_interrupt_cause(s, 0, 0);
  20.610 +    return ret;
  20.611 +}
  20.612 +
  20.613 +static uint32_t
  20.614 +mac_read_clr4(E1000State *s, int index)
  20.615 +{
  20.616 +    uint32_t ret = s->mac_reg[index];
  20.617 +
  20.618 +    s->mac_reg[index] = 0;
  20.619 +    return ret;
  20.620 +}
  20.621 +
  20.622 +static uint32_t
  20.623 +mac_read_clr8(E1000State *s, int index)
  20.624 +{
  20.625 +    uint32_t ret = s->mac_reg[index];
  20.626 +
  20.627 +    s->mac_reg[index] = 0;
  20.628 +    s->mac_reg[index-1] = 0;
  20.629 +    return ret;
  20.630 +}
  20.631 +
  20.632 +static void
  20.633 +mac_writereg(E1000State *s, int index, uint32_t val)
  20.634 +{
  20.635 +    s->mac_reg[index] = val;
  20.636 +}
  20.637 +
  20.638 +static void
  20.639 +set_rdt(E1000State *s, int index, uint32_t val)
  20.640 +{
  20.641 +    s->check_rxov = 0;
  20.642 +    s->mac_reg[index] = val & 0xffff;
  20.643 +}
  20.644 +
  20.645 +static void
  20.646 +set_16bit(E1000State *s, int index, uint32_t val)
  20.647 +{
  20.648 +    s->mac_reg[index] = val & 0xffff;
  20.649 +}
  20.650 +
  20.651 +static void
  20.652 +set_dlen(E1000State *s, int index, uint32_t val)
  20.653 +{
  20.654 +    s->mac_reg[index] = val & 0xfff80;
  20.655 +}
  20.656 +
  20.657 +static void
  20.658 +set_tctl(E1000State *s, int index, uint32_t val)
  20.659 +{
  20.660 +    s->mac_reg[index] = val;
  20.661 +    s->mac_reg[TDT] &= 0xffff;
  20.662 +    start_xmit(s);
  20.663 +}
  20.664 +
  20.665 +static void
  20.666 +set_icr(E1000State *s, int index, uint32_t val)
  20.667 +{
  20.668 +    DBGOUT(INTERRUPT, "set_icr %x\n", val);
  20.669 +    set_interrupt_cause(s, 0, s->mac_reg[ICR] & ~val);
  20.670 +}
  20.671 +
  20.672 +static void
  20.673 +set_imc(E1000State *s, int index, uint32_t val)
  20.674 +{
  20.675 +    s->mac_reg[IMS] &= ~val;
  20.676 +    set_ics(s, 0, 0);
  20.677 +}
  20.678 +
  20.679 +static void
  20.680 +set_ims(E1000State *s, int index, uint32_t val)
  20.681 +{
  20.682 +    s->mac_reg[IMS] |= val;
  20.683 +    set_ics(s, 0, 0);
  20.684 +}
  20.685 +
  20.686 +#define getreg(x)	[x] = mac_readreg
  20.687 +static uint32_t (*macreg_readops[])(E1000State *, int) = {
  20.688 +    getreg(PBA),	getreg(RCTL),	getreg(TDH),	getreg(TXDCTL),
  20.689 +    getreg(WUFC),	getreg(TDT),	getreg(CTRL),	getreg(LEDCTL),
  20.690 +    getreg(MANC),	getreg(MDIC),	getreg(SWSM),	getreg(STATUS),
  20.691 +    getreg(TORL),	getreg(TOTL),	getreg(IMS),	getreg(TCTL),
  20.692 +    getreg(RDH),	getreg(RDT),
  20.693 +
  20.694 +    [TOTH] = mac_read_clr8,	[TORH] = mac_read_clr8,	[GPRC] = mac_read_clr4,
  20.695 +    [GPTC] = mac_read_clr4,	[TPR] = mac_read_clr4,	[TPT] = mac_read_clr4,
  20.696 +    [ICR] = mac_icr_read,	[EECD] = get_eecd,	[EERD] = flash_eerd_read,
  20.697 +    [CRCERRS ... MPC] = &mac_readreg,
  20.698 +    [RA ... RA+31] = &mac_readreg,
  20.699 +    [MTA ... MTA+127] = &mac_readreg,
  20.700 +};
  20.701 +enum { NREADOPS = sizeof(macreg_readops) / sizeof(*macreg_readops) };
  20.702 +
  20.703 +#define putreg(x)	[x] = mac_writereg
  20.704 +static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
  20.705 +    putreg(PBA),	putreg(EERD),	putreg(SWSM),	putreg(WUFC),
  20.706 +    putreg(TDBAL),	putreg(TDBAH),	putreg(TXDCTL),	putreg(RDBAH),
  20.707 +    putreg(RDBAL),	putreg(LEDCTL),
  20.708 +    [TDLEN] = set_dlen,	[RDLEN] = set_dlen,	[TCTL] = set_tctl,
  20.709 +    [TDT] = set_tctl,	[MDIC] = set_mdic,	[ICS] = set_ics,
  20.710 +    [TDH] = set_16bit,	[RDH] = set_16bit,	[RDT] = set_rdt,
  20.711 +    [IMC] = set_imc,	[IMS] = set_ims,	[ICR] = set_icr,
  20.712 +    [EECD] = set_eecd,	[RCTL] = set_rx_control,
  20.713 +    [RA ... RA+31] = &mac_writereg,
  20.714 +    [MTA ... MTA+127] = &mac_writereg,
  20.715 +};
  20.716 +enum { NWRITEOPS = sizeof(macreg_writeops) / sizeof(*macreg_writeops) };
  20.717 +
  20.718 +static void
  20.719 +e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  20.720 +{
  20.721 +    E1000State *s = opaque;
  20.722 +    unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
  20.723 +
  20.724 +    if (index < NWRITEOPS && macreg_writeops[index])
  20.725 +        macreg_writeops[index](s, index, le32_to_cpu(val));
  20.726 +    else if (index < NREADOPS && macreg_readops[index])
  20.727 +        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
  20.728 +    else
  20.729 +        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
  20.730 +               index<<2, val);
  20.731 +}
  20.732 +
  20.733 +static void
  20.734 +e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
  20.735 +{
  20.736 +    // emulate hw without byte enables: no RMW
  20.737 +    e1000_mmio_writel(opaque, addr & ~3,
  20.738 +                      cpu_to_le32(le16_to_cpu(val & 0xffff) << (8*(addr & 3))));
  20.739 +}
  20.740 +
  20.741 +static void
  20.742 +e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  20.743 +{
  20.744 +    // emulate hw without byte enables: no RMW
  20.745 +    e1000_mmio_writel(opaque, addr & ~3,
  20.746 +                      cpu_to_le32((val & 0xff)  << (8*(addr & 3))));
  20.747 +}
  20.748 +
  20.749 +static uint32_t
  20.750 +e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
  20.751 +{
  20.752 +    E1000State *s = opaque;
  20.753 +    unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;
  20.754 +
  20.755 +    if (index < NREADOPS && macreg_readops[index])
  20.756 +        return cpu_to_le32(macreg_readops[index](s, index));
  20.757 +    DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2);
  20.758 +    return 0;
  20.759 +}
  20.760 +
  20.761 +static uint32_t
  20.762 +e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
  20.763 +{
  20.764 +    return (le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
  20.765 +            (8 * (addr & 3))) & 0xff;
  20.766 +}
  20.767 +
  20.768 +static uint32_t
  20.769 +e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
  20.770 +{
  20.771 +    return cpu_to_le16((le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>
  20.772 +                        (8 * (addr & 3))) & 0xffff);
  20.773 +}
  20.774 +
  20.775 +int mac_regtosave[] = {
  20.776 +    CTRL,	EECD,	EERD,	GPRC,	GPTC,	ICR,	ICS,	IMC,	IMS,
  20.777 +    LEDCTL,	MANC,	MDIC,	MPC,	PBA,	RCTL,	RDBAH,	RDBAL,	RDH,
  20.778 +    RDLEN,	RDT,	STATUS,	SWSM,	TCTL,	TDBAH,	TDBAL,	TDH,	TDLEN,
  20.779 +    TDT,	TORH,	TORL,	TOTH,	TOTL,	TPR,	TPT,	TXDCTL,	WUFC,
  20.780 +};
  20.781 +enum { MAC_NSAVE = sizeof mac_regtosave/sizeof *mac_regtosave };
  20.782 +
  20.783 +struct {
  20.784 +    int size;
  20.785 +    int array0;
  20.786 +} mac_regarraystosave[] = { {32, RA}, {128, MTA} };
  20.787 +enum { MAC_NARRAYS = sizeof mac_regarraystosave/sizeof *mac_regarraystosave };
  20.788 +
  20.789 +static void
  20.790 +nic_save(QEMUFile *f, void *opaque)
  20.791 +{
  20.792 +    E1000State *s = (E1000State *)opaque;
  20.793 +    int i, j;
  20.794 +
  20.795 +    pci_device_save(&s->dev, f);
  20.796 +    qemu_put_be32s(f, &s->instance);
  20.797 +    qemu_put_be32s(f, &s->mmio_base);
  20.798 +    qemu_put_be32s(f, &s->rxbuf_size);
  20.799 +    qemu_put_be32s(f, &s->rxbuf_min_shift);
  20.800 +    qemu_put_be32s(f, &s->eecd_state.val_in);
  20.801 +    qemu_put_be16s(f, &s->eecd_state.bitnum_in);
  20.802 +    qemu_put_be16s(f, &s->eecd_state.bitnum_out);
  20.803 +    qemu_put_be16s(f, &s->eecd_state.reading);
  20.804 +    qemu_put_be32s(f, &s->eecd_state.old_eecd);
  20.805 +    qemu_put_8s(f, &s->tx.ipcss);
  20.806 +    qemu_put_8s(f, &s->tx.ipcso);
  20.807 +    qemu_put_be16s(f, &s->tx.ipcse);
  20.808 +    qemu_put_8s(f, &s->tx.tucss);
  20.809 +    qemu_put_8s(f, &s->tx.tucso);
  20.810 +    qemu_put_be16s(f, &s->tx.tucse);
  20.811 +    qemu_put_be32s(f, &s->tx.paylen);
  20.812 +    qemu_put_8s(f, &s->tx.hdr_len);
  20.813 +    qemu_put_be16s(f, &s->tx.mss);
  20.814 +    qemu_put_be16s(f, &s->tx.size);
  20.815 +    qemu_put_be16s(f, &s->tx.tso_frames);
  20.816 +    qemu_put_8s(f, &s->tx.sum_needed);
  20.817 +    qemu_put_8s(f, &s->tx.ip);
  20.818 +    qemu_put_8s(f, &s->tx.tcp);
  20.819 +    qemu_put_buffer(f, s->tx.header, sizeof s->tx.header);
  20.820 +    qemu_put_buffer(f, s->tx.data, sizeof s->tx.data);
  20.821 +    for (i = 0; i < 64; i++)
  20.822 +        qemu_put_be16s(f, s->eeprom_data + i);
  20.823 +    for (i = 0; i < 0x20; i++)
  20.824 +        qemu_put_be16s(f, s->phy_reg + i);
  20.825 +    for (i = 0; i < MAC_NSAVE; i++)
  20.826 +        qemu_put_be32s(f, s->mac_reg + mac_regtosave[i]);
  20.827 +    for (i = 0; i < MAC_NARRAYS; i++)
  20.828 +        for (j = 0; j < mac_regarraystosave[i].size; j++)
  20.829 +            qemu_put_be32s(f,
  20.830 +                           s->mac_reg + mac_regarraystosave[i].array0 + j);
  20.831 +}
  20.832 +
  20.833 +static int
  20.834 +nic_load(QEMUFile *f, void *opaque, int version_id)
  20.835 +{
  20.836 +    E1000State *s = (E1000State *)opaque;
  20.837 +    int i, j, ret;
  20.838 +
  20.839 +    if ((ret = pci_device_load(&s->dev, f)) < 0)
  20.840 +        return ret;
  20.841 +    qemu_get_be32s(f, &s->instance);
  20.842 +    qemu_get_be32s(f, &s->mmio_base);
  20.843 +    qemu_get_be32s(f, &s->rxbuf_size);
  20.844 +    qemu_get_be32s(f, &s->rxbuf_min_shift);
  20.845 +    qemu_get_be32s(f, &s->eecd_state.val_in);
  20.846 +    qemu_get_be16s(f, &s->eecd_state.bitnum_in);
  20.847 +    qemu_get_be16s(f, &s->eecd_state.bitnum_out);
  20.848 +    qemu_get_be16s(f, &s->eecd_state.reading);
  20.849 +    qemu_get_be32s(f, &s->eecd_state.old_eecd);
  20.850 +    qemu_get_8s(f, &s->tx.ipcss);
  20.851 +    qemu_get_8s(f, &s->tx.ipcso);
  20.852 +    qemu_get_be16s(f, &s->tx.ipcse);
  20.853 +    qemu_get_8s(f, &s->tx.tucss);
  20.854 +    qemu_get_8s(f, &s->tx.tucso);
  20.855 +    qemu_get_be16s(f, &s->tx.tucse);
  20.856 +    qemu_get_be32s(f, &s->tx.paylen);
  20.857 +    qemu_get_8s(f, &s->tx.hdr_len);
  20.858 +    qemu_get_be16s(f, &s->tx.mss);
  20.859 +    qemu_get_be16s(f, &s->tx.size);
  20.860 +    qemu_get_be16s(f, &s->tx.tso_frames);
  20.861 +    qemu_get_8s(f, &s->tx.sum_needed);
  20.862 +    qemu_get_8s(f, &s->tx.ip);
  20.863 +    qemu_get_8s(f, &s->tx.tcp);
  20.864 +    qemu_get_buffer(f, s->tx.header, sizeof s->tx.header);
  20.865 +    qemu_get_buffer(f, s->tx.data, sizeof s->tx.data);
  20.866 +    for (i = 0; i < 64; i++)
  20.867 +        qemu_get_be16s(f, s->eeprom_data + i);
  20.868 +    for (i = 0; i < 0x20; i++)
  20.869 +        qemu_get_be16s(f, s->phy_reg + i);
  20.870 +    for (i = 0; i < MAC_NSAVE; i++)
  20.871 +        qemu_get_be32s(f, s->mac_reg + mac_regtosave[i]);
  20.872 +    for (i = 0; i < MAC_NARRAYS; i++)
  20.873 +        for (j = 0; j < mac_regarraystosave[i].size; j++)
  20.874 +            qemu_get_be32s(f,
  20.875 +                           s->mac_reg + mac_regarraystosave[i].array0 + j);
  20.876 +    return 0;
  20.877 +}
  20.878 +
  20.879 +static uint16_t e1000_eeprom_template[64] = {
  20.880 +    0x0000, 0x0000, 0x0000, 0x0000,      0xffff, 0x0000,      0x0000, 0x0000,
  20.881 +    0x3000, 0x1000, 0x6403, E1000_DEVID, 0x8086, E1000_DEVID, 0x8086, 0x3040,
  20.882 +    0x0008, 0x2000, 0x7e14, 0x0048,      0x1000, 0x00d8,      0x0000, 0x2700,
  20.883 +    0x6cc9, 0x3150, 0x0722, 0x040b,      0x0984, 0x0000,      0xc000, 0x0706,
  20.884 +    0x1008, 0x0000, 0x0f04, 0x7fff,      0x4d01, 0xffff,      0xffff, 0xffff,
  20.885 +    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,
  20.886 +    0x0100, 0x4000, 0x121c, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,
  20.887 +    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0x0000,
  20.888 +};
  20.889 +
  20.890 +static uint16_t phy_reg_init[] = {
  20.891 +    [PHY_CTRL] = 0x1140,			[PHY_STATUS] = 0x796d, // link initially up
  20.892 +    [PHY_ID1] = 0x141,				[PHY_ID2] = PHY_ID2_INIT,
  20.893 +    [PHY_1000T_CTRL] = 0x0e00,			[M88E1000_PHY_SPEC_CTRL] = 0x360,
  20.894 +    [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60,	[PHY_AUTONEG_ADV] = 0xde1,
  20.895 +    [PHY_LP_ABILITY] = 0x1e0,			[PHY_1000T_STATUS] = 0x3c00,
  20.896 +};
  20.897 +
  20.898 +static uint32_t mac_reg_init[] = {
  20.899 +    [PBA] =     0x00100030,
  20.900 +    [LEDCTL] =  0x602,
  20.901 +    [CTRL] =    E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN0 |
  20.902 +                E1000_CTRL_SPD_1000 | E1000_CTRL_SLU,
  20.903 +    [STATUS] =  0x80000000 | E1000_STATUS_GIO_MASTER_ENABLE |
  20.904 +                E1000_STATUS_ASDV | E1000_STATUS_MTXCKOK |
  20.905 +                E1000_STATUS_SPEED_1000 | E1000_STATUS_FD |
  20.906 +                E1000_STATUS_LU,
  20.907 +    [MANC] =    E1000_MANC_EN_MNG2HOST | E1000_MANC_RCV_TCO_EN |
  20.908 +                E1000_MANC_ARP_EN | E1000_MANC_0298_EN |
  20.909 +                E1000_MANC_RMCP_EN,
  20.910 +};
  20.911 +
  20.912 +/* PCI interface */
  20.913 +
  20.914 +static CPUWriteMemoryFunc *e1000_mmio_write[] = {
  20.915 +    e1000_mmio_writeb,	e1000_mmio_writew,	e1000_mmio_writel
  20.916 +};
  20.917 +
  20.918 +static CPUReadMemoryFunc *e1000_mmio_read[] = {
  20.919 +    e1000_mmio_readb,	e1000_mmio_readw,	e1000_mmio_readl
  20.920 +};
  20.921 +
  20.922 +static void
  20.923 +e1000_mmio_map(PCIDevice *pci_dev, int region_num,
  20.924 +                uint32_t addr, uint32_t size, int type)
  20.925 +{
  20.926 +    E1000State *d = (E1000State *)pci_dev;
  20.927 +
  20.928 +    DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size);
  20.929 +
  20.930 +    d->mmio_base = addr;
  20.931 +    cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
  20.932 +}
  20.933 +
  20.934 +void
  20.935 +pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
  20.936 +{
  20.937 +    E1000State *d;
  20.938 +    uint8_t *pci_conf;
  20.939 +    static int instance;
  20.940 +    uint16_t checksum = 0;
  20.941 +    char *info_str = "e1000";
  20.942 +    int i;
  20.943 +
  20.944 +    d = (E1000State *)pci_register_device(bus, "e1000",
  20.945 +                sizeof(E1000State), devfn, NULL, NULL);
  20.946 +
  20.947 +    pci_conf = d->dev.config;
  20.948 +    memset(pci_conf, 0, 256);
  20.949 +
  20.950 +    *(uint16_t *)(pci_conf+0x00) = cpu_to_le16(0x8086);
  20.951 +    *(uint16_t *)(pci_conf+0x02) = cpu_to_le16(E1000_DEVID);
  20.952 +    *(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407);
  20.953 +    *(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);
  20.954 +    pci_conf[0x08] = 0x03;
  20.955 +    pci_conf[0x0a] = 0x00; // ethernet network controller
  20.956 +    pci_conf[0x0b] = 0x02;
  20.957 +    pci_conf[0x0c] = 0x10;
  20.958 +
  20.959 +    pci_conf[0x3d] = 1; // interrupt pin 0
  20.960 +
  20.961 +    d->mmio_index = cpu_register_io_memory(0, e1000_mmio_read,
  20.962 +            e1000_mmio_write, d);
  20.963 +
  20.964 +    pci_register_io_region((PCIDevice *)d, 0, PNPMMIO_SIZE,
  20.965 +                           PCI_ADDRESS_SPACE_MEM, e1000_mmio_map);
  20.966 +
  20.967 +    pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE,
  20.968 +                           PCI_ADDRESS_SPACE_IO, ioport_map);
  20.969 +
  20.970 +    d->instance = instance++;
  20.971 +
  20.972 +    d->nd = nd;
  20.973 +    memmove(d->eeprom_data, e1000_eeprom_template,
  20.974 +        sizeof e1000_eeprom_template);
  20.975 +    for (i = 0; i < 3; i++)
  20.976 +        d->eeprom_data[i] = (nd->macaddr[2*i+1]<<8) | nd->macaddr[2*i];
  20.977 +    for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
  20.978 +        checksum += d->eeprom_data[i];
  20.979 +    checksum = (uint16_t) EEPROM_SUM - checksum;
  20.980 +    d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
  20.981 +
  20.982 +    memset(d->phy_reg, 0, sizeof d->phy_reg);
  20.983 +    memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
  20.984 +    memset(d->mac_reg, 0, sizeof d->mac_reg);
  20.985 +    memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
  20.986 +    d->rxbuf_min_shift = 1;
  20.987 +    memset(&d->tx, 0, sizeof d->tx);
  20.988 +
  20.989 +    d->vc = qemu_new_vlan_client(nd->vlan, e1000_receive,
  20.990 +                                 e1000_can_receive, d);
  20.991 +
  20.992 +    snprintf(d->vc->info_str, sizeof(d->vc->info_str),
  20.993 +             "%s macaddr=%02x:%02x:%02x:%02x:%02x:%02x", info_str,
  20.994 +             d->nd->macaddr[0], d->nd->macaddr[1], d->nd->macaddr[2],
  20.995 +             d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);
  20.996 +
  20.997 +    register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);
  20.998 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/ioemu/hw/e1000_hw.h	Tue Feb 26 10:12:04 2008 -0700
    21.3 @@ -0,0 +1,865 @@
    21.4 +/*******************************************************************************
    21.5 +
    21.6 +  Intel PRO/1000 Linux driver
    21.7 +  Copyright(c) 1999 - 2006 Intel Corporation.
    21.8 +
    21.9 +  This program is free software; you can redistribute it and/or modify it
   21.10 +  under the terms and conditions of the GNU General Public License,
   21.11 +  version 2, as published by the Free Software Foundation.
   21.12 +
   21.13 +  This program is distributed in the hope it will be useful, but WITHOUT
   21.14 +  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.15 +  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   21.16 +  more details.
   21.17 +
   21.18 +  You should have received a copy of the GNU General Public License along with
   21.19 +  this program; if not, write to the Free Software Foundation, Inc.,
   21.20 +  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
   21.21 +
   21.22 +  The full GNU General Public License is included in this distribution in
   21.23 +  the file called "COPYING".
   21.24 +
   21.25 +  Contact Information:
   21.26 +  Linux NICS <linux.nics@intel.com>
   21.27 +  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   21.28 +  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
   21.29 +
   21.30 +*******************************************************************************/
   21.31 +
   21.32 +/* e1000_hw.h
   21.33 + * Structures, enums, and macros for the MAC
   21.34 + */
   21.35 +
   21.36 +#ifndef _E1000_HW_H_
   21.37 +#define _E1000_HW_H_
   21.38 +
   21.39 +
   21.40 +/* PCI Device IDs */
   21.41 +#define E1000_DEV_ID_82542               0x1000
   21.42 +#define E1000_DEV_ID_82543GC_FIBER       0x1001
   21.43 +#define E1000_DEV_ID_82543GC_COPPER      0x1004
   21.44 +#define E1000_DEV_ID_82544EI_COPPER      0x1008
   21.45 +#define E1000_DEV_ID_82544EI_FIBER       0x1009
   21.46 +#define E1000_DEV_ID_82544GC_COPPER      0x100C
   21.47 +#define E1000_DEV_ID_82544GC_LOM         0x100D
   21.48 +#define E1000_DEV_ID_82540EM             0x100E
   21.49 +#define E1000_DEV_ID_82540EM_LOM         0x1015
   21.50 +#define E1000_DEV_ID_82540EP_LOM         0x1016
   21.51 +#define E1000_DEV_ID_82540EP             0x1017
   21.52 +#define E1000_DEV_ID_82540EP_LP          0x101E
   21.53 +#define E1000_DEV_ID_82545EM_COPPER      0x100F
   21.54 +#define E1000_DEV_ID_82545EM_FIBER       0x1011
   21.55 +#define E1000_DEV_ID_82545GM_COPPER      0x1026
   21.56 +#define E1000_DEV_ID_82545GM_FIBER       0x1027
   21.57 +#define E1000_DEV_ID_82545GM_SERDES      0x1028
   21.58 +#define E1000_DEV_ID_82546EB_COPPER      0x1010
   21.59 +#define E1000_DEV_ID_82546EB_FIBER       0x1012
   21.60 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
   21.61 +#define E1000_DEV_ID_82541EI             0x1013
   21.62 +#define E1000_DEV_ID_82541EI_MOBILE      0x1018
   21.63 +#define E1000_DEV_ID_82541ER_LOM         0x1014
   21.64 +#define E1000_DEV_ID_82541ER             0x1078
   21.65 +#define E1000_DEV_ID_82547GI             0x1075
   21.66 +#define E1000_DEV_ID_82541GI             0x1076
   21.67 +#define E1000_DEV_ID_82541GI_MOBILE      0x1077
   21.68 +#define E1000_DEV_ID_82541GI_LF          0x107C
   21.69 +#define E1000_DEV_ID_82546GB_COPPER      0x1079
   21.70 +#define E1000_DEV_ID_82546GB_FIBER       0x107A
   21.71 +#define E1000_DEV_ID_82546GB_SERDES      0x107B
   21.72 +#define E1000_DEV_ID_82546GB_PCIE        0x108A
   21.73 +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
   21.74 +#define E1000_DEV_ID_82547EI             0x1019
   21.75 +#define E1000_DEV_ID_82547EI_MOBILE      0x101A
   21.76 +#define E1000_DEV_ID_82571EB_COPPER      0x105E
   21.77 +#define E1000_DEV_ID_82571EB_FIBER       0x105F
   21.78 +#define E1000_DEV_ID_82571EB_SERDES      0x1060
   21.79 +#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
   21.80 +#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
   21.81 +#define E1000_DEV_ID_82571EB_QUAD_FIBER  0x10A5
   21.82 +#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE  0x10BC
   21.83 +#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
   21.84 +#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
   21.85 +#define E1000_DEV_ID_82572EI_COPPER      0x107D
   21.86 +#define E1000_DEV_ID_82572EI_FIBER       0x107E
   21.87 +#define E1000_DEV_ID_82572EI_SERDES      0x107F
   21.88 +#define E1000_DEV_ID_82572EI             0x10B9
   21.89 +#define E1000_DEV_ID_82573E              0x108B
   21.90 +#define E1000_DEV_ID_82573E_IAMT         0x108C
   21.91 +#define E1000_DEV_ID_82573L              0x109A
   21.92 +#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
   21.93 +#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT     0x1096
   21.94 +#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT     0x1098
   21.95 +#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT     0x10BA
   21.96 +#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT     0x10BB
   21.97 +
   21.98 +#define E1000_DEV_ID_ICH8_IGP_M_AMT      0x1049
   21.99 +#define E1000_DEV_ID_ICH8_IGP_AMT        0x104A
  21.100 +#define E1000_DEV_ID_ICH8_IGP_C          0x104B
  21.101 +#define E1000_DEV_ID_ICH8_IFE            0x104C
  21.102 +#define E1000_DEV_ID_ICH8_IFE_GT         0x10C4
  21.103 +#define E1000_DEV_ID_ICH8_IFE_G          0x10C5
  21.104 +#define E1000_DEV_ID_ICH8_IGP_M          0x104D
  21.105 +
  21.106 +/* Register Set. (82543, 82544)
  21.107 + *
  21.108 + * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
  21.109 + * These registers are physically located on the NIC, but are mapped into the
  21.110 + * host memory address space.
  21.111 + *
  21.112 + * RW - register is both readable and writable
  21.113 + * RO - register is read only
  21.114 + * WO - register is write only
  21.115 + * R/clr - register is read only and is cleared when read
  21.116 + * A - register array
  21.117 + */
  21.118 +#define E1000_CTRL     0x00000  /* Device Control - RW */
  21.119 +#define E1000_CTRL_DUP 0x00004  /* Device Control Duplicate (Shadow) - RW */
  21.120 +#define E1000_STATUS   0x00008  /* Device Status - RO */
  21.121 +#define E1000_EECD     0x00010  /* EEPROM/Flash Control - RW */
  21.122 +#define E1000_EERD     0x00014  /* EEPROM Read - RW */
  21.123 +#define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
  21.124 +#define E1000_FLA      0x0001C  /* Flash Access - RW */
  21.125 +#define E1000_MDIC     0x00020  /* MDI Control - RW */
  21.126 +#define E1000_SCTL     0x00024  /* SerDes Control - RW */
  21.127 +#define E1000_FEXTNVM  0x00028  /* Future Extended NVM register */
  21.128 +#define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
  21.129 +#define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
  21.130 +#define E1000_FCT      0x00030  /* Flow Control Type - RW */
  21.131 +#define E1000_VET      0x00038  /* VLAN Ether Type - RW */
  21.132 +#define E1000_ICR      0x000C0  /* Interrupt Cause Read - R/clr */
  21.133 +#define E1000_ITR      0x000C4  /* Interrupt Throttling Rate - RW */
  21.134 +#define E1000_ICS      0x000C8  /* Interrupt Cause Set - WO */
  21.135 +#define E1000_IMS      0x000D0  /* Interrupt Mask Set - RW */
  21.136 +#define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
  21.137 +#define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
  21.138 +#define E1000_RCTL     0x00100  /* RX Control - RW */
  21.139 +#define E1000_RDTR1    0x02820  /* RX Delay Timer (1) - RW */
  21.140 +#define E1000_RDBAL1   0x02900  /* RX Descriptor Base Address Low (1) - RW */
  21.141 +#define E1000_RDBAH1   0x02904  /* RX Descriptor Base Address High (1) - RW */
  21.142 +#define E1000_RDLEN1   0x02908  /* RX Descriptor Length (1) - RW */
  21.143 +#define E1000_RDH1     0x02910  /* RX Descriptor Head (1) - RW */
  21.144 +#define E1000_RDT1     0x02918  /* RX Descriptor Tail (1) - RW */
  21.145 +#define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
  21.146 +#define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
  21.147 +#define E1000_RXCW     0x00180  /* RX Configuration Word - RO */
  21.148 +#define E1000_TCTL     0x00400  /* TX Control - RW */
  21.149 +#define E1000_TCTL_EXT 0x00404  /* Extended TX Control - RW */
  21.150 +#define E1000_TIPG     0x00410  /* TX Inter-packet gap -RW */
  21.151 +#define E1000_TBT      0x00448  /* TX Burst Timer - RW */
  21.152 +#define E1000_AIT      0x00458  /* Adaptive Interframe Spacing Throttle - RW */
  21.153 +#define E1000_LEDCTL   0x00E00  /* LED Control - RW */
  21.154 +#define E1000_EXTCNF_CTRL  0x00F00  /* Extended Configuration Control */
  21.155 +#define E1000_EXTCNF_SIZE  0x00F08  /* Extended Configuration Size */
  21.156 +#define E1000_PHY_CTRL     0x00F10  /* PHY Control Register in CSR */
  21.157 +#define FEXTNVM_SW_CONFIG  0x0001
  21.158 +#define E1000_PBA      0x01000  /* Packet Buffer Allocation - RW */
  21.159 +#define E1000_PBS      0x01008  /* Packet Buffer Size */
  21.160 +#define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
  21.161 +#define E1000_FLASH_UPDATES 1000
  21.162 +#define E1000_EEARBC   0x01024  /* EEPROM Auto Read Bus Control */
  21.163 +#define E1000_FLASHT   0x01028  /* FLASH Timer Register */
  21.164 +#define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */
  21.165 +#define E1000_FLSWCTL  0x01030  /* FLASH control register */
  21.166 +#define E1000_FLSWDATA 0x01034  /* FLASH data register */
  21.167 +#define E1000_FLSWCNT  0x01038  /* FLASH Access Counter */
  21.168 +#define E1000_FLOP     0x0103C  /* FLASH Opcode Register */
  21.169 +#define E1000_ERT      0x02008  /* Early Rx Threshold - RW */
  21.170 +#define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
  21.171 +#define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
  21.172 +#define E1000_PSRCTL   0x02170  /* Packet Split Receive Control - RW */
  21.173 +#define E1000_RDBAL    0x02800  /* RX Descriptor Base Address Low - RW */
  21.174 +#define E1000_RDBAH    0x02804  /* RX Descriptor Base Address High - RW */
  21.175 +#define E1000_RDLEN    0x02808  /* RX Descriptor Length - RW */
  21.176 +#define E1000_RDH      0x02810  /* RX Descriptor Head - RW */
  21.177 +#define E1000_RDT      0x02818  /* RX Descriptor Tail - RW */
  21.178 +#define E1000_RDTR     0x02820  /* RX Delay Timer - RW */
  21.179 +#define E1000_RDBAL0   E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
  21.180 +#define E1000_RDBAH0   E1000_RDBAH /* RX Desc Base Address High (0) - RW */
  21.181 +#define E1000_RDLEN0   E1000_RDLEN /* RX Desc Length (0) - RW */
  21.182 +#define E1000_RDH0     E1000_RDH   /* RX Desc Head (0) - RW */
  21.183 +#define E1000_RDT0     E1000_RDT   /* RX Desc Tail (0) - RW */
  21.184 +#define E1000_RDTR0    E1000_RDTR  /* RX Delay Timer (0) - RW */
  21.185 +#define E1000_RXDCTL   0x02828  /* RX Descriptor Control queue 0 - RW */
  21.186 +#define E1000_RXDCTL1  0x02928  /* RX Descriptor Control queue 1 - RW */
  21.187 +#define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
  21.188 +#define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
  21.189 +#define E1000_RAID     0x02C08  /* Receive Ack Interrupt Delay - RW */
  21.190 +#define E1000_TXDMAC   0x03000  /* TX DMA Control - RW */
  21.191 +#define E1000_KABGTXD  0x03004  /* AFE Band Gap Transmit Ref Data */
  21.192 +#define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
  21.193 +#define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
  21.194 +#define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
  21.195 +#define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */
  21.196 +#define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
  21.197 +#define E1000_TDBAL    0x03800  /* TX Descriptor Base Address Low - RW */
  21.198 +#define E1000_TDBAH    0x03804  /* TX Descriptor Base Address High - RW */
  21.199 +#define E1000_TDLEN    0x03808  /* TX Descriptor Length - RW */
  21.200 +#define E1000_TDH      0x03810  /* TX Descriptor Head - RW */
  21.201 +#define E1000_TDT      0x03818  /* TX Descripotr Tail - RW */
  21.202 +#define E1000_TIDV     0x03820  /* TX Interrupt Delay Value - RW */
  21.203 +#define E1000_TXDCTL   0x03828  /* TX Descriptor Control - RW */
  21.204 +#define E1000_TADV     0x0382C  /* TX Interrupt Absolute Delay Val - RW */
  21.205 +#define E1000_TSPMT    0x03830  /* TCP Segmentation PAD & Min Threshold - RW */
  21.206 +#define E1000_TARC0    0x03840  /* TX Arbitration Count (0) */
  21.207 +#define E1000_TDBAL1   0x03900  /* TX Desc Base Address Low (1) - RW */
  21.208 +#define E1000_TDBAH1   0x03904  /* TX Desc Base Address High (1) - RW */
  21.209 +#define E1000_TDLEN1   0x03908  /* TX Desc Length (1) - RW */
  21.210 +#define E1000_TDH1     0x03910  /* TX Desc Head (1) - RW */
  21.211 +#define E1000_TDT1     0x03918  /* TX Desc Tail (1) - RW */
  21.212 +#define E1000_TXDCTL1  0x03928  /* TX Descriptor Control (1) - RW */
  21.213 +#define E1000_TARC1    0x03940  /* TX Arbitration Count (1) */
  21.214 +#define E1000_CRCERRS  0x04000  /* CRC Error Count - R/clr */
  21.215 +#define E1000_ALGNERRC 0x04004  /* Alignment Error Count - R/clr */
  21.216 +#define E1000_SYMERRS  0x04008  /* Symbol Error Count - R/clr */
  21.217 +#define E1000_RXERRC   0x0400C  /* Receive Error Count - R/clr */
  21.218 +#define E1000_MPC      0x04010  /* Missed Packet Count - R/clr */
  21.219 +#define E1000_SCC      0x04014  /* Single Collision Count - R/clr */
  21.220 +#define E1000_ECOL     0x04018  /* Excessive Collision Count - R/clr */
  21.221 +#define E1000_MCC      0x0401C  /* Multiple Collision Count - R/clr */
  21.222 +#define E1000_LATECOL  0x04020  /* Late Collision Count - R/clr */
  21.223 +#define E1000_COLC     0x04028  /* Collision Count - R/clr */
  21.224 +#define E1000_DC       0x04030  /* Defer Count - R/clr */
  21.225 +#define E1000_TNCRS    0x04034  /* TX-No CRS - R/clr */
  21.226 +#define E1000_SEC      0x04038  /* Sequence Error Count - R/clr */
  21.227 +#define E1000_CEXTERR  0x0403C  /* Carrier Extension Error Count - R/clr */
  21.228 +#define E1000_RLEC     0x04040  /* Receive Length Error Count - R/clr */
  21.229 +#define E1000_XONRXC   0x04048  /* XON RX Count - R/clr */
  21.230 +#define E1000_XONTXC   0x0404C  /* XON TX Count - R/clr */
  21.231 +#define E1000_XOFFRXC  0x04050  /* XOFF RX Count - R/clr */
  21.232 +#define E1000_XOFFTXC  0x04054  /* XOFF TX Count - R/clr */
  21.233 +#define E1000_FCRUC    0x04058  /* Flow Control RX Unsupported Count- R/clr */
  21.234 +#define E1000_PRC64    0x0405C  /* Packets RX (64 bytes) - R/clr */
  21.235 +#define E1000_PRC127   0x04060  /* Packets RX (65-127 bytes) - R/clr */
  21.236 +#define E1000_PRC255   0x04064  /* Packets RX (128-255 bytes) - R/clr */
  21.237 +#define E1000_PRC511   0x04068  /* Packets RX (255-511 bytes) - R/clr */
  21.238 +#define E1000_PRC1023  0x0406C  /* Packets RX (512-1023 bytes) - R/clr */
  21.239 +#define E1000_PRC1522  0x04070  /* Packets RX (1024-1522 bytes) - R/clr */
  21.240 +#define E1000_GPRC     0x04074  /* Good Packets RX Count - R/clr */
  21.241 +#define E1000_BPRC     0x04078  /* Broadcast Packets RX Count - R/clr */
  21.242 +#define E1000_MPRC     0x0407C  /* Multicast Packets RX Count - R/clr */
  21.243 +#define E1000_GPTC     0x04080  /* Good Packets TX Count - R/clr */
  21.244 +#define E1000_GORCL    0x04088  /* Good Octets RX Count Low - R/clr */
  21.245 +#define E1000_GORCH    0x0408C  /* Good Octets RX Count High - R/clr */
  21.246 +#define E1000_GOTCL    0x04090  /* Good Octets TX Count Low - R/clr */
  21.247 +#define E1000_GOTCH    0x04094  /* Good Octets TX Count High - R/clr */
  21.248 +#define E1000_RNBC     0x040A0  /* RX No Buffers Count - R/clr */
  21.249 +#define E1000_RUC      0x040A4  /* RX Undersize Count - R/clr */
  21.250 +#define E1000_RFC      0x040A8  /* RX Fragment Count - R/clr */
  21.251 +#define E1000_ROC      0x040AC  /* RX Oversize Count - R/clr */
  21.252 +#define E1000_RJC      0x040B0  /* RX Jabber Count - R/clr */
  21.253 +#define E1000_MGTPRC   0x040B4  /* Management Packets RX Count - R/clr */
  21.254 +#define E1000_MGTPDC   0x040B8  /* Management Packets Dropped Count - R/clr */
  21.255 +#define E1000_MGTPTC   0x040BC  /* Management Packets TX Count - R/clr */
  21.256 +#define E1000_TORL     0x040C0  /* Total Octets RX Low - R/clr */
  21.257 +#define E1000_TORH     0x040C4  /* Total Octets RX High - R/clr */
  21.258 +#define E1000_TOTL     0x040C8  /* Total Octets TX Low - R/clr */
  21.259 +#define E1000_TOTH     0x040CC  /* Total Octets TX High - R/clr */
  21.260 +#define E1000_TPR      0x040D0  /* Total Packets RX - R/clr */
  21.261 +#define E1000_TPT      0x040D4  /* Total Packets TX - R/clr */
  21.262 +#define E1000_PTC64    0x040D8  /* Packets TX (64 bytes) - R/clr */
  21.263 +#define E1000_PTC127   0x040DC  /* Packets TX (65-127 bytes) - R/clr */
  21.264 +#define E1000_PTC255   0x040E0  /* Packets TX (128-255 bytes) - R/clr */
  21.265 +#define E1000_PTC511   0x040E4  /* Packets TX (256-511 bytes) - R/clr */
  21.266 +#define E1000_PTC1023  0x040E8  /* Packets TX (512-1023 bytes) - R/clr */
  21.267 +#define E1000_PTC1522  0x040EC  /* Packets TX (1024-1522 Bytes) - R/clr */
  21.268 +#define E1000_MPTC     0x040F0  /* Multicast Packets TX Count - R/clr */
  21.269 +#define E1000_BPTC     0x040F4  /* Broadcast Packets TX Count - R/clr */
  21.270 +#define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
  21.271 +#define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
  21.272 +#define E1000_IAC      0x04100  /* Interrupt Assertion Count */
  21.273 +#define E1000_ICRXPTC  0x04104  /* Interrupt Cause Rx Packet Timer Expire Count */
  21.274 +#define E1000_ICRXATC  0x04108  /* Interrupt Cause Rx Absolute Timer Expire Count */
  21.275 +#define E1000_ICTXPTC  0x0410C  /* Interrupt Cause Tx Packet Timer Expire Count */
  21.276 +#define E1000_ICTXATC  0x04110  /* Interrupt Cause Tx Absolute Timer Expire Count */
  21.277 +#define E1000_ICTXQEC  0x04118  /* Interrupt Cause Tx Queue Empty Count */
  21.278 +#define E1000_ICTXQMTC 0x0411C  /* Interrupt Cause Tx Queue Minimum Threshold Count */
  21.279 +#define E1000_ICRXDMTC 0x04120  /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
  21.280 +#define E1000_ICRXOC   0x04124  /* Interrupt Cause Receiver Overrun Count */
  21.281 +#define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
  21.282 +#define E1000_RFCTL    0x05008  /* Receive Filter Control*/
  21.283 +#define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
  21.284 +#define E1000_RA       0x05400  /* Receive Address - RW Array */
  21.285 +#define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
  21.286 +#define E1000_WUC      0x05800  /* Wakeup Control - RW */
  21.287 +#define E1000_WUFC     0x05808  /* Wakeup Filter Control - RW */
  21.288 +#define E1000_WUS      0x05810  /* Wakeup Status - RO */
  21.289 +#define E1000_MANC     0x05820  /* Management Control - RW */
  21.290 +#define E1000_IPAV     0x05838  /* IP Address Valid - RW */
  21.291 +#define E1000_IP4AT    0x05840  /* IPv4 Address Table - RW Array */
  21.292 +#define E1000_IP6AT    0x05880  /* IPv6 Address Table - RW Array */
  21.293 +#define E1000_WUPL     0x05900  /* Wakeup Packet Length - RW */
  21.294 +#define E1000_WUPM     0x05A00  /* Wakeup Packet Memory - RO A */
  21.295 +#define E1000_FFLT     0x05F00  /* Flexible Filter Length Table - RW Array */
  21.296 +#define E1000_HOST_IF  0x08800  /* Host Interface */
  21.297 +#define E1000_FFMT     0x09000  /* Flexible Filter Mask Table - RW Array */
  21.298 +#define E1000_FFVT     0x09800  /* Flexible Filter Value Table - RW Array */
  21.299 +
  21.300 +#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
  21.301 +#define E1000_MDPHYA     0x0003C  /* PHY address - RW */
  21.302 +#define E1000_MANC2H     0x05860  /* Managment Control To Host - RW */
  21.303 +#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
  21.304 +
  21.305 +#define E1000_GCR       0x05B00 /* PCI-Ex Control */
  21.306 +#define E1000_GSCL_1    0x05B10 /* PCI-Ex Statistic Control #1 */
  21.307 +#define E1000_GSCL_2    0x05B14 /* PCI-Ex Statistic Control #2 */
  21.308 +#define E1000_GSCL_3    0x05B18 /* PCI-Ex Statistic Control #3 */
  21.309 +#define E1000_GSCL_4    0x05B1C /* PCI-Ex Statistic Control #4 */
  21.310 +#define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
  21.311 +#define E1000_SWSM      0x05B50 /* SW Semaphore */
  21.312 +#define E1000_FWSM      0x05B54 /* FW Semaphore */
  21.313 +#define E1000_FFLT_DBG  0x05F04 /* Debug Register */
  21.314 +#define E1000_HICR      0x08F00 /* Host Inteface Control */
  21.315 +
  21.316 +/* RSS registers */
  21.317 +#define E1000_CPUVEC    0x02C10 /* CPU Vector Register - RW */
  21.318 +#define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
  21.319 +#define E1000_RETA      0x05C00 /* Redirection Table - RW Array */
  21.320 +#define E1000_RSSRK     0x05C80 /* RSS Random Key - RW Array */
  21.321 +#define E1000_RSSIM     0x05864 /* RSS Interrupt Mask */
  21.322 +#define E1000_RSSIR     0x05868 /* RSS Interrupt Request */
  21.323 +
  21.324 +/* PHY 1000 MII Register/Bit Definitions */
  21.325 +/* PHY Registers defined by IEEE */
  21.326 +#define PHY_CTRL         0x00 /* Control Register */
  21.327 +#define PHY_STATUS       0x01 /* Status Regiser */
  21.328 +#define PHY_ID1          0x02 /* Phy Id Reg (word 1) */
  21.329 +#define PHY_ID2          0x03 /* Phy Id Reg (word 2) */
  21.330 +#define PHY_AUTONEG_ADV  0x04 /* Autoneg Advertisement */
  21.331 +#define PHY_LP_ABILITY   0x05 /* Link Partner Ability (Base Page) */
  21.332 +#define PHY_AUTONEG_EXP  0x06 /* Autoneg Expansion Reg */
  21.333 +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
  21.334 +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
  21.335 +#define PHY_1000T_CTRL   0x09 /* 1000Base-T Control Reg */
  21.336 +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
  21.337 +#define PHY_EXT_STATUS   0x0F /* Extended Status Reg */
  21.338 +
  21.339 +#define MAX_PHY_REG_ADDRESS        0x1F  /* 5 bit address bus (0-0x1F) */
  21.340 +#define MAX_PHY_MULTI_PAGE_REG     0xF   /* Registers equal on all pages */
  21.341 +
  21.342 +/* M88E1000 Specific Registers */
  21.343 +#define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
  21.344 +#define M88E1000_PHY_SPEC_STATUS   0x11  /* PHY Specific Status Register */
  21.345 +#define M88E1000_INT_ENABLE        0x12  /* Interrupt Enable Register */
  21.346 +#define M88E1000_INT_STATUS        0x13  /* Interrupt Status Register */
  21.347 +#define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */
  21.348 +#define M88E1000_RX_ERR_CNTR       0x15  /* Receive Error Counter */
  21.349 +
  21.350 +#define M88E1000_PHY_EXT_CTRL      0x1A  /* PHY extend control register */
  21.351 +#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
  21.352 +#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */
  21.353 +#define M88E1000_PHY_VCO_REG_BIT8  0x100 /* Bits 8 & 11 are adjusted for */
  21.354 +#define M88E1000_PHY_VCO_REG_BIT11 0x800    /* improved BER performance */
  21.355 +
  21.356 +/* Interrupt Cause Read */
  21.357 +#define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
  21.358 +#define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
  21.359 +#define E1000_ICR_LSC           0x00000004 /* Link Status Change */
  21.360 +#define E1000_ICR_RXSEQ         0x00000008 /* rx sequence error */
  21.361 +#define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
  21.362 +#define E1000_ICR_RXO           0x00000040 /* rx overrun */
  21.363 +#define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
  21.364 +#define E1000_ICR_MDAC          0x00000200 /* MDIO access complete */
  21.365 +#define E1000_ICR_RXCFG         0x00000400 /* RX /c/ ordered set */
  21.366 +#define E1000_ICR_GPI_EN0       0x00000800 /* GP Int 0 */
  21.367 +#define E1000_ICR_GPI_EN1       0x00001000 /* GP Int 1 */
  21.368 +#define E1000_ICR_GPI_EN2       0x00002000 /* GP Int 2 */
  21.369 +#define E1000_ICR_GPI_EN3       0x00004000 /* GP Int 3 */
  21.370 +#define E1000_ICR_TXD_LOW       0x00008000
  21.371 +#define E1000_ICR_SRPD          0x00010000
  21.372 +#define E1000_ICR_ACK           0x00020000 /* Receive Ack frame */
  21.373 +#define E1000_ICR_MNG           0x00040000 /* Manageability event */
  21.374 +#define E1000_ICR_DOCK          0x00080000 /* Dock/Undock */
  21.375 +#define E1000_ICR_INT_ASSERTED  0x80000000 /* If this bit asserted, the driver should claim the interrupt */
  21.376 +#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */
  21.377 +#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */
  21.378 +#define E1000_ICR_HOST_ARB_PAR  0x00400000 /* host arb read buffer parity error */
  21.379 +#define E1000_ICR_PB_PAR        0x00800000 /* packet buffer parity error */
  21.380 +#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */
  21.381 +#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */
  21.382 +#define E1000_ICR_ALL_PARITY    0x03F00000 /* all parity error bits */
  21.383 +#define E1000_ICR_DSW           0x00000020 /* FW changed the status of DISSW bit in the FWSM */
  21.384 +#define E1000_ICR_PHYINT        0x00001000 /* LAN connected device generates an interrupt */
  21.385 +#define E1000_ICR_EPRST         0x00100000 /* ME handware reset occurs */
  21.386 +
  21.387 +/* Interrupt Cause Set */
  21.388 +#define E1000_ICS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
  21.389 +#define E1000_ICS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
  21.390 +#define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
  21.391 +#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
  21.392 +#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
  21.393 +#define E1000_ICS_RXO       E1000_ICR_RXO       /* rx overrun */
  21.394 +#define E1000_ICS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
  21.395 +#define E1000_ICS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
  21.396 +#define E1000_ICS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
  21.397 +#define E1000_ICS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
  21.398 +#define E1000_ICS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
  21.399 +#define E1000_ICS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
  21.400 +#define E1000_ICS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
  21.401 +#define E1000_ICS_TXD_LOW   E1000_ICR_TXD_LOW
  21.402 +#define E1000_ICS_SRPD      E1000_ICR_SRPD
  21.403 +#define E1000_ICS_ACK       E1000_ICR_ACK       /* Receive Ack frame */
  21.404 +#define E1000_ICS_MNG       E1000_ICR_MNG       /* Manageability event */
  21.405 +#define E1000_ICS_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
  21.406 +#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
  21.407 +#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
  21.408 +#define E1000_ICS_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR  /* host arb read buffer parity error */
  21.409 +#define E1000_ICS_PB_PAR        E1000_ICR_PB_PAR        /* packet buffer parity error */
  21.410 +#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
  21.411 +#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
  21.412 +#define E1000_ICS_DSW       E1000_ICR_DSW
  21.413 +#define E1000_ICS_PHYINT    E1000_ICR_PHYINT
  21.414 +#define E1000_ICS_EPRST     E1000_ICR_EPRST
  21.415 +
  21.416 +/* Interrupt Mask Set */
  21.417 +#define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
  21.418 +#define E1000_IMS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
  21.419 +#define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
  21.420 +#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
  21.421 +#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
  21.422 +#define E1000_IMS_RXO       E1000_ICR_RXO       /* rx overrun */
  21.423 +#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
  21.424 +#define E1000_IMS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
  21.425 +#define E1000_IMS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
  21.426 +#define E1000_IMS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
  21.427 +#define E1000_IMS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
  21.428 +#define E1000_IMS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
  21.429 +#define E1000_IMS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
  21.430 +#define E1000_IMS_TXD_LOW   E1000_ICR_TXD_LOW
  21.431 +#define E1000_IMS_SRPD      E1000_ICR_SRPD
  21.432 +#define E1000_IMS_ACK       E1000_ICR_ACK       /* Receive Ack frame */
  21.433 +#define E1000_IMS_MNG       E1000_ICR_MNG       /* Manageability event */
  21.434 +#define E1000_IMS_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
  21.435 +#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
  21.436 +#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
  21.437 +#define E1000_IMS_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR  /* host arb read buffer parity error */
  21.438 +#define E1000_IMS_PB_PAR        E1000_ICR_PB_PAR        /* packet buffer parity error */
  21.439 +#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
  21.440 +#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
  21.441 +#define E1000_IMS_DSW       E1000_ICR_DSW
  21.442 +#define E1000_IMS_PHYINT    E1000_ICR_PHYINT
  21.443 +#define E1000_IMS_EPRST     E1000_ICR_EPRST
  21.444 +
  21.445 +/* Interrupt Mask Clear */
  21.446 +#define E1000_IMC_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
  21.447 +#define E1000_IMC_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
  21.448 +#define E1000_IMC_LSC       E1000_ICR_LSC       /* Link Status Change */
  21.449 +#define E1000_IMC_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
  21.450 +#define E1000_IMC_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
  21.451 +#define E1000_IMC_RXO       E1000_ICR_RXO       /* rx overrun */
  21.452 +#define E1000_IMC_RXT0      E1000_ICR_RXT0      /* rx timer intr */
  21.453 +#define E1000_IMC_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
  21.454 +#define E1000_IMC_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
  21.455 +#define E1000_IMC_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
  21.456 +#define E1000_IMC_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
  21.457 +#define E1000_IMC_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
  21.458 +#define E1000_IMC_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
  21.459 +#define E1000_IMC_TXD_LOW   E1000_ICR_TXD_LOW
  21.460 +#define E1000_IMC_SRPD      E1000_ICR_SRPD
  21.461 +#define E1000_IMC_ACK       E1000_ICR_ACK       /* Receive Ack frame */
  21.462 +#define E1000_IMC_MNG       E1000_ICR_MNG       /* Manageability event */
  21.463 +#define E1000_IMC_DOCK      E1000_ICR_DOCK      /* Dock/Undock */
  21.464 +#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
  21.465 +#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
  21.466 +#define E1000_IMC_HOST_ARB_PAR  E1000_ICR_HOST_ARB_PAR  /* host arb read buffer parity error */
  21.467 +#define E1000_IMC_PB_PAR        E1000_ICR_PB_PAR        /* packet buffer parity error */
  21.468 +#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
  21.469 +#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
  21.470 +#define E1000_IMC_DSW       E1000_ICR_DSW
  21.471 +#define E1000_IMC_PHYINT    E1000_ICR_PHYINT
  21.472 +#define E1000_IMC_EPRST     E1000_ICR_EPRST
  21.473 +
  21.474 +/* Receive Control */
  21.475 +#define E1000_RCTL_RST            0x00000001    /* Software reset */
  21.476 +#define E1000_RCTL_EN             0x00000002    /* enable */
  21.477 +#define E1000_RCTL_SBP            0x00000004    /* store bad packet */
  21.478 +#define E1000_RCTL_UPE            0x00000008    /* unicast promiscuous enable */
  21.479 +#define E1000_RCTL_MPE            0x00000010    /* multicast promiscuous enab */
  21.480 +#define E1000_RCTL_LPE            0x00000020    /* long packet enable */
  21.481 +#define E1000_RCTL_LBM_NO         0x00000000    /* no loopback mode */
  21.482 +#define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
  21.483 +#define E1000_RCTL_LBM_SLP        0x00000080    /* serial link loopback mode */
  21.484 +#define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
  21.485 +#define E1000_RCTL_DTYP_MASK      0x00000C00    /* Descriptor type mask */
  21.486 +#define E1000_RCTL_DTYP_PS        0x00000400    /* Packet Split descriptor */
  21.487 +#define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size */
  21.488 +#define E1000_RCTL_RDMTS_QUAT     0x00000100    /* rx desc min threshold size */
  21.489 +#define E1000_RCTL_RDMTS_EIGTH    0x00000200    /* rx desc min threshold size */
  21.490 +#define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
  21.491 +#define E1000_RCTL_MO_0           0x00000000    /* multicast offset 11:0 */
  21.492 +#define E1000_RCTL_MO_1           0x00001000    /* multicast offset 12:1 */
  21.493 +#define E1000_RCTL_MO_2           0x00002000    /* multicast offset 13:2 */
  21.494 +#define E1000_RCTL_MO_3           0x00003000    /* multicast offset 15:4 */
  21.495 +#define E1000_RCTL_MDR            0x00004000    /* multicast desc ring 0 */
  21.496 +#define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
  21.497 +/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
  21.498 +#define E1000_RCTL_SZ_2048        0x00000000    /* rx buffer size 2048 */
  21.499 +#define E1000_RCTL_SZ_1024        0x00010000    /* rx buffer size 1024 */
  21.500 +#define E1000_RCTL_SZ_512         0x00020000    /* rx buffer size 512 */
  21.501 +#define E1000_RCTL_SZ_256         0x00030000    /* rx buffer size 256 */
  21.502 +/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
  21.503 +#define E1000_RCTL_SZ_16384       0x00010000    /* rx buffer size 16384 */
  21.504 +#define E1000_RCTL_SZ_8192        0x00020000    /* rx buffer size 8192 */
  21.505 +#define E1000_RCTL_SZ_4096        0x00030000    /* rx buffer size 4096 */
  21.506 +#define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
  21.507 +#define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
  21.508 +#define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
  21.509 +#define E1000_RCTL_DPF            0x00400000    /* discard pause frames */
  21.510 +#define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
  21.511 +#define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
  21.512 +#define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */
  21.513 +#define E1000_RCTL_FLXBUF_MASK    0x78000000    /* Flexible buffer size */
  21.514 +#define E1000_RCTL_FLXBUF_SHIFT   27            /* Flexible buffer shift */
  21.515 +
  21.516 +
  21.517 +#define E1000_EEPROM_SWDPIN0   0x0001   /* SWDPIN 0 EEPROM Value */
  21.518 +#define E1000_EEPROM_LED_LOGIC 0x0020   /* Led Logic Word */
  21.519 +#define E1000_EEPROM_RW_REG_DATA   16   /* Offset to data in EEPROM read/write registers */
  21.520 +#define E1000_EEPROM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */
  21.521 +#define E1000_EEPROM_RW_REG_START  1    /* First bit for telling part to start operation */
  21.522 +#define E1000_EEPROM_RW_ADDR_SHIFT 2    /* Shift to the address bits */
  21.523 +#define E1000_EEPROM_POLL_WRITE    1    /* Flag for polling for write complete */
  21.524 +#define E1000_EEPROM_POLL_READ     0    /* Flag for polling for read complete */
  21.525 +/* Register Bit Masks */
  21.526 +/* Device Control */
  21.527 +#define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
  21.528 +#define E1000_CTRL_BEM      0x00000002  /* Endian Mode.0=little,1=big */
  21.529 +#define E1000_CTRL_PRIOR    0x00000004  /* Priority on PCI. 0=rx,1=fair */
  21.530 +#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
  21.531 +#define E1000_CTRL_LRST     0x00000008  /* Link reset. 0=normal,1=reset */
  21.532 +#define E1000_CTRL_TME      0x00000010  /* Test mode. 0=normal,1=test */
  21.533 +#define E1000_CTRL_SLE      0x00000020  /* Serial Link on 0=dis,1=en */
  21.534 +#define E1000_CTRL_ASDE     0x00000020  /* Auto-speed detect enable */
  21.535 +#define E1000_CTRL_SLU      0x00000040  /* Set link up (Force Link) */
  21.536 +#define E1000_CTRL_ILOS     0x00000080  /* Invert Loss-Of Signal */
  21.537 +#define E1000_CTRL_SPD_SEL  0x00000300  /* Speed Select Mask */
  21.538 +#define E1000_CTRL_SPD_10   0x00000000  /* Force 10Mb */
  21.539 +#define E1000_CTRL_SPD_100  0x00000100  /* Force 100Mb */
  21.540 +#define E1000_CTRL_SPD_1000 0x00000200  /* Force 1Gb */
  21.541 +#define E1000_CTRL_BEM32    0x00000400  /* Big Endian 32 mode */
  21.542 +#define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
  21.543 +#define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
  21.544 +#define E1000_CTRL_D_UD_EN  0x00002000  /* Dock/Undock enable */
  21.545 +#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
  21.546 +#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */
  21.547 +#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
  21.548 +#define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
  21.549 +#define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
  21.550 +#define E1000_CTRL_SWDPIN2  0x00100000  /* SWDPIN 2 value */
  21.551 +#define E1000_CTRL_SWDPIN3  0x00200000  /* SWDPIN 3 value */
  21.552 +#define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */
  21.553 +#define E1000_CTRL_SWDPIO1  0x00800000  /* SWDPIN 1 input or output */
  21.554 +#define E1000_CTRL_SWDPIO2  0x01000000  /* SWDPIN 2 input or output */
  21.555 +#define E1000_CTRL_SWDPIO3  0x02000000  /* SWDPIN 3 input or output */
  21.556 +#define E1000_CTRL_RST      0x04000000  /* Global reset */
  21.557 +#define E1000_CTRL_RFCE     0x08000000  /* Receive Flow Control enable */
  21.558 +#define E1000_CTRL_TFCE     0x10000000  /* Transmit flow control enable */
  21.559 +#define E1000_CTRL_RTE      0x20000000  /* Routing tag enable */
  21.560 +#define E1000_CTRL_VME      0x40000000  /* IEEE VLAN mode enable */
  21.561 +#define E1000_CTRL_PHY_RST  0x80000000  /* PHY Reset */
  21.562 +#define E1000_CTRL_SW2FW_INT 0x02000000  /* Initiate an interrupt to manageability engine */
  21.563 +
  21.564 +/* Device Status */
  21.565 +#define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
  21.566 +#define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
  21.567 +#define E1000_STATUS_FUNC_MASK  0x0000000C      /* PCI Function Mask */
  21.568 +#define E1000_STATUS_FUNC_SHIFT 2
  21.569 +#define E1000_STATUS_FUNC_0     0x00000000      /* Function 0 */
  21.570 +#define E1000_STATUS_FUNC_1     0x00000004      /* Function 1 */
  21.571 +#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
  21.572 +#define E1000_STATUS_TBIMODE    0x00000020      /* TBI mode */
  21.573 +#define E1000_STATUS_SPEED_MASK 0x000000C0
  21.574 +#define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */
  21.575 +#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
  21.576 +#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
  21.577 +#define E1000_STATUS_LAN_INIT_DONE 0x00000200   /* Lan Init Completion
  21.578 +                                                   by EEPROM/Flash */
  21.579 +#define E1000_STATUS_ASDV       0x00000300      /* Auto speed detect value */
  21.580 +#define E1000_STATUS_DOCK_CI    0x00000800      /* Change in Dock/Undock state. Clear on write '0'. */
  21.581 +#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
  21.582 +#define E1000_STATUS_MTXCKOK    0x00000400      /* MTX clock running OK */
  21.583 +#define E1000_STATUS_PCI66      0x00000800      /* In 66Mhz slot */
  21.584 +#define E1000_STATUS_BUS64      0x00001000      /* In 64 bit slot */
  21.585 +#define E1000_STATUS_PCIX_MODE  0x00002000      /* PCI-X mode */
  21.586 +#define E1000_STATUS_PCIX_SPEED 0x0000C000      /* PCI-X bus speed */
  21.587 +#define E1000_STATUS_BMC_SKU_0  0x00100000 /* BMC USB redirect disabled */
  21.588 +#define E1000_STATUS_BMC_SKU_1  0x00200000 /* BMC SRAM disabled */
  21.589 +#define E1000_STATUS_BMC_SKU_2  0x00400000 /* BMC SDRAM disabled */
  21.590 +#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */
  21.591 +#define E1000_STATUS_BMC_LITE   0x01000000 /* BMC external code execution disabled */
  21.592 +#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */
  21.593 +#define E1000_STATUS_FUSE_8       0x04000000
  21.594 +#define E1000_STATUS_FUSE_9       0x08000000
  21.595 +#define E1000_STATUS_SERDES0_DIS  0x10000000 /* SERDES disabled on port 0 */
  21.596 +#define E1000_STATUS_SERDES1_DIS  0x20000000 /* SERDES disabled on port 1 */
  21.597 +
  21.598 +/* EEPROM/Flash Control */
  21.599 +#define E1000_EECD_SK        0x00000001 /* EEPROM Clock */
  21.600 +#define E1000_EECD_CS        0x00000002 /* EEPROM Chip Select */
  21.601 +#define E1000_EECD_DI        0x00000004 /* EEPROM Data In */
  21.602 +#define E1000_EECD_DO        0x00000008 /* EEPROM Data Out */
  21.603 +#define E1000_EECD_FWE_MASK  0x00000030
  21.604 +#define E1000_EECD_FWE_DIS   0x00000010 /* Disable FLASH writes */
  21.605 +#define E1000_EECD_FWE_EN    0x00000020 /* Enable FLASH writes */
  21.606 +#define E1000_EECD_FWE_SHIFT 4
  21.607 +#define E1000_EECD_REQ       0x00000040 /* EEPROM Access Request */
  21.608 +#define E1000_EECD_GNT       0x00000080 /* EEPROM Access Grant */
  21.609 +#define E1000_EECD_PRES      0x00000100 /* EEPROM Present */
  21.610 +#define E1000_EECD_SIZE      0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
  21.611 +#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
  21.612 +                                         * (0-small, 1-large) */
  21.613 +#define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
  21.614 +#ifndef E1000_EEPROM_GRANT_ATTEMPTS
  21.615 +#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
  21.616 +#endif
  21.617 +#define E1000_EECD_AUTO_RD          0x00000200  /* EEPROM Auto Read done */
  21.618 +#define E1000_EECD_SIZE_EX_MASK     0x00007800  /* EEprom Size */
  21.619 +#define E1000_EECD_SIZE_EX_SHIFT    11
  21.620 +#define E1000_EECD_NVADDS    0x00018000 /* NVM Address Size */
  21.621 +#define E1000_EECD_SELSHAD   0x00020000 /* Select Shadow RAM */
  21.622 +#define E1000_EECD_INITSRAM  0x00040000 /* Initialize Shadow RAM */
  21.623 +#define E1000_EECD_FLUPD     0x00080000 /* Update FLASH */
  21.624 +#define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
  21.625 +#define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
  21.626 +#define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
  21.627 +#define E1000_EECD_SECVAL_SHIFT      22
  21.628 +#define E1000_STM_OPCODE     0xDB00
  21.629 +#define E1000_HICR_FW_RESET  0xC0
  21.630 +
  21.631 +#define E1000_SHADOW_RAM_WORDS     2048
  21.632 +#define E1000_ICH_NVM_SIG_WORD     0x13
  21.633 +#define E1000_ICH_NVM_SIG_MASK     0xC0
  21.634 +
  21.635 +/* MDI Control */
  21.636 +#define E1000_MDIC_DATA_MASK 0x0000FFFF
  21.637 +#define E1000_MDIC_REG_MASK  0x001F0000
  21.638 +#define E1000_MDIC_REG_SHIFT 16
  21.639 +#define E1000_MDIC_PHY_MASK  0x03E00000
  21.640 +#define E1000_MDIC_PHY_SHIFT 21
  21.641 +#define E1000_MDIC_OP_WRITE  0x04000000
  21.642 +#define E1000_MDIC_OP_READ   0x08000000
  21.643 +#define E1000_MDIC_READY     0x10000000
  21.644 +#define E1000_MDIC_INT_EN    0x20000000
  21.645 +#define E1000_MDIC_ERROR     0x40000000
  21.646 +
  21.647 +/* EEPROM Commands - Microwire */
  21.648 +#define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
  21.649 +#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
  21.650 +#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7  /* EEPROM erase opcode */
  21.651 +#define EEPROM_EWEN_OPCODE_MICROWIRE  0x13 /* EEPROM erase/write enable */
  21.652 +#define EEPROM_EWDS_OPCODE_MICROWIRE  0x10 /* EEPROM erast/write disable */
  21.653 +
  21.654 +/* EEPROM Word Offsets */
  21.655 +#define EEPROM_COMPAT                 0x0003
  21.656 +#define EEPROM_ID_LED_SETTINGS        0x0004
  21.657 +#define EEPROM_VERSION                0x0005
  21.658 +#define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude adjustment. */
  21.659 +#define EEPROM_PHY_CLASS_WORD         0x0007
  21.660 +#define EEPROM_INIT_CONTROL1_REG      0x000A
  21.661 +#define EEPROM_INIT_CONTROL2_REG      0x000F
  21.662 +#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
  21.663 +#define EEPROM_INIT_CONTROL3_PORT_B   0x0014
  21.664 +#define EEPROM_INIT_3GIO_3            0x001A
  21.665 +#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
  21.666 +#define EEPROM_INIT_CONTROL3_PORT_A   0x0024
  21.667 +#define EEPROM_CFG                    0x0012
  21.668 +#define EEPROM_FLASH_VERSION          0x0032
  21.669 +#define EEPROM_CHECKSUM_REG           0x003F
  21.670 +
  21.671 +#define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
  21.672 +#define E1000_EEPROM_CFG_DONE_PORT_1  0x00080000   /* ...for second port */
  21.673 +
  21.674 +/* Transmit Descriptor */
  21.675 +struct e1000_tx_desc {
  21.676 +    uint64_t buffer_addr;       /* Address of the descriptor's data buffer */
  21.677 +    union {
  21.678 +        uint32_t data;
  21.679 +        struct {
  21.680 +            uint16_t length;    /* Data buffer length */
  21.681 +            uint8_t cso;        /* Checksum offset */
  21.682 +            uint8_t cmd;        /* Descriptor control */
  21.683 +        } flags;
  21.684 +    } lower;
  21.685 +    union {
  21.686 +        uint32_t data;
  21.687 +        struct {
  21.688 +            uint8_t status;     /* Descriptor status */
  21.689 +            uint8_t css;        /* Checksum start */
  21.690 +            uint16_t special;
  21.691 +        } fields;
  21.692 +    } upper;
  21.693 +};
  21.694 +
  21.695 +/* Transmit Descriptor bit definitions */
  21.696 +#define E1000_TXD_DTYP_D     0x00100000 /* Data Descriptor */
  21.697 +#define E1000_TXD_DTYP_C     0x00000000 /* Context Descriptor */
  21.698 +#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
  21.699 +#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
  21.700 +#define E1000_TXD_CMD_EOP    0x01000000 /* End of Packet */
  21.701 +#define E1000_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */
  21.702 +#define E1000_TXD_CMD_IC     0x04000000 /* Insert Checksum */
  21.703 +#define E1000_TXD_CMD_RS     0x08000000 /* Report Status */
  21.704 +#define E1000_TXD_CMD_RPS    0x10000000 /* Report Packet Sent */
  21.705 +#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
  21.706 +#define E1000_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
  21.707 +#define E1000_TXD_CMD_IDE    0x80000000 /* Enable Tidv register */
  21.708 +#define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */
  21.709 +#define E1000_TXD_STAT_EC    0x00000002 /* Excess Collisions */
  21.710 +#define E1000_TXD_STAT_LC    0x00000004 /* Late Collisions */
  21.711 +#define E1000_TXD_STAT_TU    0x00000008 /* Transmit underrun */
  21.712 +#define E1000_TXD_CMD_TCP    0x01000000 /* TCP packet */
  21.713 +#define E1000_TXD_CMD_IP     0x02000000 /* IP packet */
  21.714 +#define E1000_TXD_CMD_TSE    0x04000000 /* TCP Seg enable */
  21.715 +#define E1000_TXD_STAT_TC    0x00000004 /* Tx Underrun */
  21.716 +
  21.717 +/* Transmit Control */
  21.718 +#define E1000_TCTL_RST    0x00000001    /* software reset */
  21.719 +#define E1000_TCTL_EN     0x00000002    /* enable tx */
  21.720 +#define E1000_TCTL_BCE    0x00000004    /* busy check enable */
  21.721 +#define E1000_TCTL_PSP    0x00000008    /* pad short packets */
  21.722 +#define E1000_TCTL_CT     0x00000ff0    /* collision threshold */
  21.723 +#define E1000_TCTL_COLD   0x003ff000    /* collision distance */
  21.724 +#define E1000_TCTL_SWXOFF 0x00400000    /* SW Xoff transmission */
  21.725 +#define E1000_TCTL_PBE    0x00800000    /* Packet Burst Enable */
  21.726 +#define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
  21.727 +#define E1000_TCTL_NRTU   0x02000000    /* No Re-transmit on underrun */
  21.728 +#define E1000_TCTL_MULR   0x10000000    /* Multiple request support */
  21.729 +
  21.730 +/* Receive Descriptor */
  21.731 +struct e1000_rx_desc {
  21.732 +    uint64_t buffer_addr; /* Address of the descriptor's data buffer */
  21.733 +    uint16_t length;     /* Length of data DMAed into data buffer */
  21.734 +    uint16_t csum;       /* Packet checksum */
  21.735 +    uint8_t status;      /* Descriptor status */
  21.736 +    uint8_t errors;      /* Descriptor Errors */
  21.737 +    uint16_t special;
  21.738 +};
  21.739 +
  21.740 +/* Receive Decriptor bit definitions */
  21.741 +#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
  21.742 +#define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
  21.743 +#define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
  21.744 +#define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
  21.745 +#define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum caculated */
  21.746 +#define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
  21.747 +#define E1000_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
  21.748 +#define E1000_RXD_STAT_PIF      0x80    /* passed in-exact filter */
  21.749 +#define E1000_RXD_STAT_IPIDV    0x200   /* IP identification valid */
  21.750 +#define E1000_RXD_STAT_UDPV     0x400   /* Valid UDP checksum */
  21.751 +#define E1000_RXD_STAT_ACK      0x8000  /* ACK Packet indication */
  21.752 +#define E1000_RXD_ERR_CE        0x01    /* CRC Error */
  21.753 +#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
  21.754 +#define E1000_RXD_ERR_SEQ       0x04    /* Sequence Error */
  21.755 +#define E1000_RXD_ERR_CXE       0x10    /* Carrier Extension Error */
  21.756 +#define E1000_RXD_ERR_TCPE      0x20    /* TCP/UDP Checksum Error */
  21.757 +#define E1000_RXD_ERR_IPE       0x40    /* IP Checksum Error */
  21.758 +#define E1000_RXD_ERR_RXE       0x80    /* Rx Data Error */
  21.759 +#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
  21.760 +#define E1000_RXD_SPC_PRI_MASK  0xE000  /* Priority is in upper 3 bits */
  21.761 +#define E1000_RXD_SPC_PRI_SHIFT 13
  21.762 +#define E1000_RXD_SPC_CFI_MASK  0x1000  /* CFI is bit 12 */
  21.763 +#define E1000_RXD_SPC_CFI_SHIFT 12
  21.764 +
  21.765 +#define E1000_RXDEXT_STATERR_CE    0x01000000
  21.766 +#define E1000_RXDEXT_STATERR_SE    0x02000000
  21.767 +#define E1000_RXDEXT_STATERR_SEQ   0x04000000
  21.768 +#define E1000_RXDEXT_STATERR_CXE   0x10000000
  21.769 +#define E1000_RXDEXT_STATERR_TCPE  0x20000000
  21.770 +#define E1000_RXDEXT_STATERR_IPE   0x40000000
  21.771 +#define E1000_RXDEXT_STATERR_RXE   0x80000000
  21.772 +
  21.773 +#define E1000_RXDPS_HDRSTAT_HDRSP        0x00008000
  21.774 +#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK  0x000003FF
  21.775 +
  21.776 +/* Receive Address */
  21.777 +#define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
  21.778 +
  21.779 +/* Offload Context Descriptor */
  21.780 +struct e1000_context_desc {
  21.781 +    union {
  21.782 +        uint32_t ip_config;
  21.783 +        struct {
  21.784 +            uint8_t ipcss;      /* IP checksum start */
  21.785 +            uint8_t ipcso;      /* IP checksum offset */
  21.786 +            uint16_t ipcse;     /* IP checksum end */
  21.787 +        } ip_fields;
  21.788 +    } lower_setup;
  21.789 +    union {
  21.790 +        uint32_t tcp_config;
  21.791 +        struct {
  21.792 +            uint8_t tucss;      /* TCP checksum start */
  21.793 +            uint8_t tucso;      /* TCP checksum offset */
  21.794 +            uint16_t tucse;     /* TCP checksum end */
  21.795 +        } tcp_fields;
  21.796 +    } upper_setup;
  21.797 +    uint32_t cmd_and_length;    /* */
  21.798 +    union {
  21.799 +        uint32_t data;
  21.800 +        struct {
  21.801 +            uint8_t status;     /* Descriptor status */
  21.802 +            uint8_t hdr_len;    /* Header length */
  21.803 +            uint16_t mss;       /* Maximum segment size */
  21.804 +        } fields;
  21.805 +    } tcp_seg_setup;
  21.806 +};
  21.807 +
  21.808 +/* Offload data descriptor */
  21.809 +struct e1000_data_desc {
  21.810 +    uint64_t buffer_addr;       /* Address of the descriptor's buffer address */
  21.811 +    union {
  21.812 +        uint32_t data;
  21.813 +        struct {
  21.814 +            uint16_t length;    /* Data buffer length */
  21.815 +            uint8_t typ_len_ext;        /* */
  21.816 +            uint8_t cmd;        /* */
  21.817 +        } flags;
  21.818 +    } lower;
  21.819 +    union {
  21.820 +        uint32_t data;
  21.821 +        struct {
  21.822 +            uint8_t status;     /* Descriptor status */
  21.823 +            uint8_t popts;      /* Packet Options */
  21.824 +            uint16_t special;   /* */
  21.825 +        } fields;
  21.826 +    } upper;
  21.827 +};
  21.828 +
  21.829 +/* Management Control */
  21.830 +#define E1000_MANC_SMBUS_EN      0x00000001 /* SMBus Enabled - RO */
  21.831 +#define E1000_MANC_ASF_EN        0x00000002 /* ASF Enabled - RO */
  21.832 +#define E1000_MANC_R_ON_FORCE    0x00000004 /* Reset on Force TCO - RO */
  21.833 +#define E1000_MANC_RMCP_EN       0x00000100 /* Enable RCMP 026Fh Filtering */
  21.834 +#define E1000_MANC_0298_EN       0x00000200 /* Enable RCMP 0298h Filtering */
  21.835 +#define E1000_MANC_IPV4_EN       0x00000400 /* Enable IPv4 */
  21.836 +#define E1000_MANC_IPV6_EN       0x00000800 /* Enable IPv6 */
  21.837 +#define E1000_MANC_SNAP_EN       0x00001000 /* Accept LLC/SNAP */
  21.838 +#define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
  21.839 +#define E1000_MANC_NEIGHBOR_EN   0x00004000 /* Enable Neighbor Discovery
  21.840 +                                             * Filtering */
  21.841 +#define E1000_MANC_ARP_RES_EN    0x00008000 /* Enable ARP response Filtering */
  21.842 +#define E1000_MANC_TCO_RESET     0x00010000 /* TCO Reset Occurred */
  21.843 +#define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
  21.844 +#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
  21.845 +#define E1000_MANC_RCV_ALL       0x00080000 /* Receive All Enabled */
  21.846 +#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
  21.847 +#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000 /* Enable MAC address
  21.848 +                                                    * filtering */
  21.849 +#define E1000_MANC_EN_MNG2HOST   0x00200000 /* Enable MNG packets to host
  21.850 +                                             * memory */
  21.851 +#define E1000_MANC_EN_IP_ADDR_FILTER    0x00400000 /* Enable IP address
  21.852 +                                                    * filtering */
  21.853 +#define E1000_MANC_EN_XSUM_FILTER   0x00800000 /* Enable checksum filtering */
  21.854 +#define E1000_MANC_BR_EN         0x01000000 /* Enable broadcast filtering */
  21.855 +#define E1000_MANC_SMB_REQ       0x01000000 /* SMBus Request */
  21.856 +#define E1000_MANC_SMB_GNT       0x02000000 /* SMBus Grant */
  21.857 +#define E1000_MANC_SMB_CLK_IN    0x04000000 /* SMBus Clock In */
  21.858 +#define E1000_MANC_SMB_DATA_IN   0x08000000 /* SMBus Data In */
  21.859 +#define E1000_MANC_SMB_DATA_OUT  0x10000000 /* SMBus Data Out */
  21.860 +#define E1000_MANC_SMB_CLK_OUT   0x20000000 /* SMBus Clock Out */
  21.861 +
  21.862 +#define E1000_MANC_SMB_DATA_OUT_SHIFT  28 /* SMBus Data Out Shift */
  21.863 +#define E1000_MANC_SMB_CLK_OUT_SHIFT   29 /* SMBus Clock Out Shift */
  21.864 +
  21.865 +/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
  21.866 +#define EEPROM_SUM 0xBABA
  21.867 +
  21.868 +#endif /* _E1000_HW_H_ */
    22.1 --- a/tools/ioemu/hw/pci.c	Mon Feb 25 06:29:01 2008 -0700
    22.2 +++ b/tools/ioemu/hw/pci.c	Tue Feb 26 10:12:04 2008 -0700
    22.3 @@ -574,6 +574,8 @@ void pci_nic_init(PCIBus *bus, NICInfo *
    22.4          pci_pcnet_init(bus, nd, devfn);
    22.5      } else if (strcmp(nd->model, "e100") == 0) {
    22.6          pci_e100_init(bus, nd);
    22.7 +    } else if (strcmp(nd->model, "e1000") == 0) {
    22.8 +        pci_e1000_init(bus, nd, devfn);
    22.9      } else {
   22.10          fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model);
   22.11          exit (1);
    23.1 --- a/tools/ioemu/hw/xen_console.c	Mon Feb 25 06:29:01 2008 -0700
    23.2 +++ b/tools/ioemu/hw/xen_console.c	Tue Feb 26 10:12:04 2008 -0700
    23.3 @@ -381,7 +381,7 @@ static void xencons_startup(void *opaque
    23.4  	qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, NULL, NULL, NULL);
    23.5  
    23.6  	fprintf(stderr, "Console: connected to guest frontend\n");
    23.7 -	if (qemu_set_fd_handler2(dom->xce_handle, NULL, xencons_ring_read, NULL, dom) < 0)
    23.8 +	if (qemu_set_fd_handler2(xc_evtchn_fd(dom->xce_handle), NULL, xencons_ring_read, NULL, dom) < 0)
    23.9  		return;
   23.10  
   23.11  	qemu_chr_add_handlers(dom->chr, xencons_can_receive, xencons_receive,
    24.1 --- a/tools/ioemu/hw/xenfb.c	Mon Feb 25 06:29:01 2008 -0700
    24.2 +++ b/tools/ioemu/hw/xenfb.c	Tue Feb 26 10:12:04 2008 -0700
    24.3 @@ -1160,7 +1160,7 @@ static int xenfb_register_console(struct
    24.4  			     xenfb);
    24.5  	dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
    24.6  
    24.7 -	if (qemu_set_fd_handler2(xenfb->evt_xch, NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
    24.8 +	if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
    24.9  	        return -1;
   24.10  	if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0)
   24.11  		return -1;
    25.1 --- a/tools/ioemu/osdep.c	Mon Feb 25 06:29:01 2008 -0700
    25.2 +++ b/tools/ioemu/osdep.c	Tue Feb 26 10:12:04 2008 -0700
    25.3 @@ -178,7 +178,7 @@ void kqemu_vfree(void *ptr)
    25.4  
    25.5  void *qemu_memalign(size_t alignment, size_t size)
    25.6  {
    25.7 -#if defined(_POSIX_C_SOURCE)
    25.8 +#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
    25.9      int ret;
   25.10      void *ptr;
   25.11      ret = posix_memalign(&ptr, alignment, size);
    26.1 --- a/tools/ioemu/vl.h	Mon Feb 25 06:29:01 2008 -0700
    26.2 +++ b/tools/ioemu/vl.h	Tue Feb 26 10:12:04 2008 -0700
    26.3 @@ -1055,6 +1055,11 @@ void pci_pcnet_init(PCIBus *bus, NICInfo
    26.4  void pcnet_h_reset(void *opaque);
    26.5  void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque);
    26.6  
    26.7 +/* e100.c */
    26.8 +void pci_e100_init(PCIBus *bus, NICInfo *nd);
    26.9 +
   26.10 +/* e1000.c */
   26.11 +void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn);
   26.12  
   26.13  /* pckbd.c */
   26.14  
    27.1 --- a/tools/ioemu/vnc.c	Mon Feb 25 06:29:01 2008 -0700
    27.2 +++ b/tools/ioemu/vnc.c	Tue Feb 26 10:12:04 2008 -0700
    27.3 @@ -137,6 +137,23 @@ enum {
    27.4  
    27.5  #endif /* CONFIG_VNC_TLS */
    27.6  
    27.7 +#define QUEUE_ALLOC_UNIT 10
    27.8 +
    27.9 +typedef struct _QueueItem
   27.10 +{
   27.11 +    int x, y, w, h;
   27.12 +    int32_t enc;
   27.13 +    struct _QueueItem *next;
   27.14 +} QueueItem;
   27.15 +
   27.16 +typedef struct _Queue
   27.17 +{
   27.18 +    QueueItem *queue_start;
   27.19 +    int start_count;
   27.20 +    QueueItem *queue_end;
   27.21 +    int end_count;
   27.22 +} Queue;
   27.23 +
   27.24  struct VncState
   27.25  {
   27.26      QEMUTimer *timer;
   27.27 @@ -152,6 +169,9 @@ struct VncState
   27.28      uint64_t *update_row;	/* outstanding updates */
   27.29      int has_update;		/* there's outstanding updates in the
   27.30  				 * visible area */
   27.31 +
   27.32 +    int update_requested;       /* the client requested an update */
   27.33 +
   27.34      uint8_t *old_data;
   27.35      int depth; /* internal VNC frame buffer byte per pixel */
   27.36      int has_resize;
   27.37 @@ -186,6 +206,9 @@ struct VncState
   27.38  
   27.39      Buffer output;
   27.40      Buffer input;
   27.41 +    
   27.42 +    Queue upqueue;
   27.43 +
   27.44      kbd_layout_t *kbd_layout;
   27.45      /* current output mode information */
   27.46      VncWritePixels *write_pixels;
   27.47 @@ -248,6 +271,11 @@ static void _vnc_update_client(void *opa
   27.48  static void vnc_update_client(void *opaque);
   27.49  static void vnc_client_read(void *opaque);
   27.50  static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h);
   27.51 +static void pixel_format_message (VncState *vs);
   27.52 +static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h, int32_t encoding);
   27.53 +static void dequeue_framebuffer_update(VncState *vs);
   27.54 +static int is_empty_queue(VncState *vs);
   27.55 +static void free_queue(VncState *vs);
   27.56  
   27.57  #if 0
   27.58  static inline void vnc_set_bit(uint32_t *d, int k)
   27.59 @@ -370,13 +398,18 @@ static void vnc_dpy_resize(DisplayState 
   27.60      ds->height = h;
   27.61      ds->linesize = w * vs->depth;
   27.62      if (vs->csock != -1 && vs->has_resize && size_changed) {
   27.63 -	vnc_write_u8(vs, 0);  /* msg id */
   27.64 -	vnc_write_u8(vs, 0);
   27.65 -	vnc_write_u16(vs, 1); /* number of rects */
   27.66 -	vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
   27.67 -	vnc_flush(vs);
   27.68 -	vs->width = ds->width;
   27.69 -	vs->height = ds->height;
   27.70 +        vs->width = ds->width;
   27.71 +        vs->height = ds->height;
   27.72 +        if (vs->update_requested) {
   27.73 +	    vnc_write_u8(vs, 0);  /* msg id */
   27.74 +	    vnc_write_u8(vs, 0);
   27.75 +	    vnc_write_u16(vs, 1); /* number of rects */
   27.76 +	    vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
   27.77 +	    vnc_flush(vs);
   27.78 +            vs->update_requested--;
   27.79 +        } else {
   27.80 +            enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223);
   27.81 +        }
   27.82      }
   27.83      vs->dirty_pixel_shift = 0;
   27.84      for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
   27.85 @@ -553,7 +586,8 @@ static void vnc_copy(DisplayState *ds, i
   27.86          return;
   27.87      }
   27.88  
   27.89 -    if (src_x < vs->visible_x || src_y < vs->visible_y ||
   27.90 +    if (!vs->update_requested ||
   27.91 +        src_x < vs->visible_x || src_y < vs->visible_y ||
   27.92  	dst_x < vs->visible_x || dst_y < vs->visible_y ||
   27.93  	(src_x + w) > (vs->visible_x + vs->visible_w) ||
   27.94  	(src_y + h) > (vs->visible_y + vs->visible_h) ||
   27.95 @@ -592,6 +626,7 @@ static void vnc_copy(DisplayState *ds, i
   27.96  	vnc_write_u16(vs, src_x);
   27.97  	vnc_write_u16(vs, src_y);
   27.98  	vnc_flush(vs);
   27.99 +        vs->update_requested--;
  27.100      } else
  27.101  	framebuffer_set_updated(vs, dst_x, dst_y, w, h);
  27.102  }
  27.103 @@ -624,8 +659,21 @@ static void _vnc_update_client(void *opa
  27.104      int maxx, maxy;
  27.105      int tile_bytes = vs->depth * DP2X(vs, 1);
  27.106  
  27.107 -    if (vs->csock == -1)
  27.108 +    if (!vs->update_requested || vs->csock == -1)
  27.109  	return;
  27.110 +    while (!is_empty_queue(vs) && vs->update_requested) {
  27.111 +        int enc = vs->upqueue.queue_end->enc; 
  27.112 +        dequeue_framebuffer_update(vs);
  27.113 +        switch (enc) {
  27.114 +            case 0x574D5669:
  27.115 +                pixel_format_message(vs);
  27.116 +                break;
  27.117 +            default:
  27.118 +                break;
  27.119 +        }
  27.120 +        vs->update_requested--;
  27.121 +    }
  27.122 +    if (!vs->update_requested) return;
  27.123  
  27.124      now = qemu_get_clock(rt_clock);
  27.125  
  27.126 @@ -717,8 +765,11 @@ static void _vnc_update_client(void *opa
  27.127      vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
  27.128      vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
  27.129  
  27.130 -    if (n_rectangles == 0)
  27.131 +    if (n_rectangles == 0) {
  27.132 +        vs->output.offset = saved_offset - 2;
  27.133  	goto backoff;
  27.134 +    } else
  27.135 +        vs->update_requested--;
  27.136  
  27.137      vs->has_update = 0;
  27.138      vnc_flush(vs);
  27.139 @@ -735,7 +786,8 @@ static void _vnc_update_client(void *opa
  27.140      vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
  27.141      if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
  27.142  	vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
  27.143 -	if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
  27.144 +	if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL &&
  27.145 +            vs->update_requested) {
  27.146  	    /* Send a null update.  If the client is no longer
  27.147  	       interested (e.g. minimised) it'll ignore this, and we
  27.148  	       can stop scanning the buffer until it sends another
  27.149 @@ -752,6 +804,7 @@ static void _vnc_update_client(void *opa
  27.150  	    send_framebuffer_update(vs, 0, 0, 1, 1);
  27.151  	    vnc_flush(vs);
  27.152  	    vs->last_update_time = now;
  27.153 +            vs->update_requested--;
  27.154  	    return;
  27.155  	}
  27.156      }
  27.157 @@ -821,6 +874,88 @@ static void buffer_append(Buffer *buffer
  27.158      buffer->offset += len;
  27.159  }
  27.160  
  27.161 +static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h,
  27.162 +                                   int32_t encoding)
  27.163 +{
  27.164 +    Queue *q = &vs->upqueue; 
  27.165 +    if (q->queue_end != NULL) {
  27.166 +        if (q->queue_end != q->queue_start || q->start_count != q->end_count) {
  27.167 +            if (q->queue_end->next == NULL) {
  27.168 +                q->queue_end->next = (QueueItem *) qemu_mallocz (sizeof(QueueItem) * QUEUE_ALLOC_UNIT);
  27.169 +                q->end_count = QUEUE_ALLOC_UNIT;
  27.170 +            }
  27.171 +            q->queue_end = q->queue_end->next;
  27.172 +        }
  27.173 +    } else {
  27.174 +        q->queue_end = (QueueItem *) qemu_mallocz (sizeof(QueueItem) * QUEUE_ALLOC_UNIT);
  27.175 +        q->queue_start = q->queue_end;
  27.176 +        q->start_count = QUEUE_ALLOC_UNIT;
  27.177 +        q->end_count = QUEUE_ALLOC_UNIT;
  27.178 +    }
  27.179 +    q->end_count--;
  27.180 +
  27.181 +    q->queue_end->x = x;
  27.182 +    q->queue_end->y = y;
  27.183 +    q->queue_end->w = w;
  27.184 +    q->queue_end->h = h;
  27.185 +    q->queue_end->enc = encoding;
  27.186 +    q->queue_end->next = (q->end_count > 0) ? (q->queue_end + 1) : NULL;
  27.187 +}
  27.188 +
  27.189 +static void dequeue_framebuffer_update(VncState *vs)
  27.190 +{
  27.191 +    Queue *q = &vs->upqueue;
  27.192 +    if (q->queue_start == NULL || 
  27.193 +            (q->queue_end == q->queue_start && q->start_count == q->end_count))
  27.194 +        return;
  27.195 +
  27.196 +    vnc_write_u8(vs, 0);
  27.197 +    vnc_write_u8(vs, 0);
  27.198 +    vnc_write_u16(vs, 1);
  27.199 +    vnc_framebuffer_update(vs, q->queue_start->x, q->queue_start->y,
  27.200 +            q->queue_start->w, q->queue_start->h, q->queue_start->enc);
  27.201 +
  27.202 +    q->start_count--;
  27.203 +    if (q->queue_end != q->queue_start) {
  27.204 +        if (!q->start_count) {
  27.205 +            QueueItem *i = q->queue_start;
  27.206 +            q->queue_start = q->queue_start->next;
  27.207 +            q->start_count = QUEUE_ALLOC_UNIT;
  27.208 +            free (i - QUEUE_ALLOC_UNIT + 1);
  27.209 +        } else
  27.210 +            q->queue_start = q->queue_start->next;
  27.211 +    } else {
  27.212 +        q->queue_end = q->queue_end - QUEUE_ALLOC_UNIT + q->end_count + 1;
  27.213 +        q->queue_start = q->queue_end;
  27.214 +        q->end_count = QUEUE_ALLOC_UNIT;
  27.215 +        q->start_count = QUEUE_ALLOC_UNIT;
  27.216 +    }
  27.217 +}
  27.218 +
  27.219 +static int is_empty_queue(VncState *vs)
  27.220 +{
  27.221 +    Queue *q = &vs->upqueue;
  27.222 +    if (q->queue_end == NULL) return 1;
  27.223 +    if (q->queue_end == q->queue_start && q->start_count == q->end_count) return 1;
  27.224 +    return 0;
  27.225 +}
  27.226 +
  27.227 +static void free_queue(VncState *vs)
  27.228 +{
  27.229 +    Queue *q = &vs->upqueue;
  27.230 +    while (q->queue_start != NULL) {
  27.231 +        QueueItem *i;
  27.232 +        q->queue_start = q->queue_start + q->start_count - 1;
  27.233 +        i = q->queue_start;
  27.234 +        q->queue_start = q->queue_start->next;
  27.235 +        free(i - QUEUE_ALLOC_UNIT + 1);
  27.236 +        q->start_count = QUEUE_ALLOC_UNIT;
  27.237 +    }
  27.238 +    q->queue_end = NULL;
  27.239 +    q->start_count = 0;
  27.240 +    q->end_count = 0;
  27.241 +}
  27.242 +
  27.243  static int vnc_client_io_error(VncState *vs, int ret, int last_errno)
  27.244  {
  27.245      if (ret == 0 || ret == -1) {
  27.246 @@ -833,6 +968,8 @@ static int vnc_client_io_error(VncState 
  27.247  	vs->csock = -1;
  27.248  	buffer_reset(&vs->input);
  27.249  	buffer_reset(&vs->output);
  27.250 +        free_queue(vs);
  27.251 +        vs->update_requested = 0;
  27.252  #if CONFIG_VNC_TLS
  27.253  	if (vs->tls_session) {
  27.254  	    gnutls_deinit(vs->tls_session);
  27.255 @@ -1044,12 +1181,18 @@ static void client_cut_text(VncState *vs
  27.256  static void check_pointer_type_change(VncState *vs, int absolute)
  27.257  {
  27.258      if (vs->has_pointer_type_change && vs->absolute != absolute) {
  27.259 -	vnc_write_u8(vs, 0);
  27.260 -	vnc_write_u8(vs, 0);
  27.261 -	vnc_write_u16(vs, 1);
  27.262 -	vnc_framebuffer_update(vs, absolute, 0,
  27.263 +        if (vs->update_requested) {
  27.264 +	    vnc_write_u8(vs, 0);
  27.265 +	    vnc_write_u8(vs, 0);
  27.266 +	    vnc_write_u16(vs, 1);
  27.267 +	    vnc_framebuffer_update(vs, absolute, 0,
  27.268  			       vs->ds->width, vs->ds->height, -257);
  27.269 -	vnc_flush(vs);
  27.270 +	    vnc_flush(vs);
  27.271 +            vs->update_requested--;
  27.272 +        } else {
  27.273 +            enqueue_framebuffer_update(vs, absolute, 0,
  27.274 +                               vs->ds->width, vs->ds->height, -257);
  27.275 +        }
  27.276      }
  27.277      vs->absolute = absolute;
  27.278  }
  27.279 @@ -1316,6 +1459,7 @@ static void framebuffer_update_request(V
  27.280      vs->visible_w = w;
  27.281      vs->visible_h = h;
  27.282  
  27.283 +    vs->update_requested++;
  27.284      qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
  27.285  }
  27.286  
  27.287 @@ -1536,12 +1680,17 @@ static void vnc_dpy_colourdepth(DisplayS
  27.288          vnc_client_error(vs);
  27.289      } else if (vs->csock != -1 && vs->has_WMVi) {
  27.290          /* Sending a WMVi message to notify the client*/
  27.291 -        vnc_write_u8(vs, 0);  /* msg id */
  27.292 -        vnc_write_u8(vs, 0);
  27.293 -        vnc_write_u16(vs, 1); /* number of rects */
  27.294 -        vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
  27.295 -        pixel_format_message(vs);
  27.296 -        vnc_flush(vs);
  27.297 +        if (vs->update_requested) {
  27.298 +            vnc_write_u8(vs, 0);  /* msg id */
  27.299 +            vnc_write_u8(vs, 0);
  27.300 +            vnc_write_u16(vs, 1); /* number of rects */
  27.301 +            vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
  27.302 +            pixel_format_message(vs);
  27.303 +            vnc_flush(vs);
  27.304 +            vs->update_requested--;
  27.305 +        } else {
  27.306 +            enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669);
  27.307 +        }
  27.308      } else {
  27.309          if (vs->pix_bpp == 4 && vs->depth == 4 &&
  27.310              host_big_endian_flag == vs->pix_big_endian &&
  27.311 @@ -2291,6 +2440,7 @@ static void vnc_listen_read(void *opaque
  27.312  	framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height);
  27.313  	vs->has_resize = 0;
  27.314  	vs->has_hextile = 0;
  27.315 +        vs->update_requested = 0;
  27.316  	vs->ds->dpy_copy = NULL;
  27.317  	vnc_timer_init(vs);
  27.318      }
  27.319 @@ -2413,6 +2563,8 @@ void vnc_display_close(DisplayState *ds)
  27.320  	vs->csock = -1;
  27.321  	buffer_reset(&vs->input);
  27.322  	buffer_reset(&vs->output);
  27.323 +        free_queue(vs);
  27.324 +        vs->update_requested = 0;
  27.325  #if CONFIG_VNC_TLS
  27.326  	if (vs->tls_session) {
  27.327  	    gnutls_deinit(vs->tls_session);
    28.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Mon Feb 25 06:29:01 2008 -0700
    28.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Tue Feb 26 10:12:04 2008 -0700
    28.3 @@ -764,7 +764,8 @@ static PyObject *pyxc_physinfo(XcObject 
    28.4      xc_physinfo_t info;
    28.5      char cpu_cap[128], *p=cpu_cap, *q=cpu_cap;
    28.6      int i, j, max_cpu_id;
    28.7 -    PyObject *ret_obj, *node_to_cpu_obj;
    28.8 +    uint64_t free_heap;
    28.9 +    PyObject *ret_obj, *node_to_cpu_obj, *node_to_memory_obj;
   28.10      xc_cpu_to_node_t map[MAX_CPU_ID + 1];
   28.11  
   28.12      set_xen_guest_handle(info.cpu_to_node, map);
   28.13 @@ -812,7 +813,17 @@ static PyObject *pyxc_physinfo(XcObject 
   28.14          PyList_Append(node_to_cpu_obj, cpus); 
   28.15      }
   28.16  
   28.17 +    node_to_memory_obj = PyList_New(0);
   28.18 +
   28.19 +    for ( i = 0; i < info.nr_nodes; i++ )
   28.20 +    {
   28.21 +	xc_availheap(self->xc_handle, 0, 0, i, &free_heap);
   28.22 +	PyList_Append(node_to_memory_obj,
   28.23 +	    PyInt_FromLong(free_heap / 1024));
   28.24 +    }
   28.25 +	
   28.26      PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
   28.27 +    PyDict_SetItemString(ret_obj, "node_to_memory", node_to_memory_obj);
   28.28   
   28.29      return ret_obj;
   28.30  #undef MAX_CPU_ID
    29.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Mon Feb 25 06:29:01 2008 -0700
    29.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Tue Feb 26 10:12:04 2008 -0700
    29.3 @@ -906,6 +906,7 @@ class XendDomainInfo:
    29.4          log.debug("Setting memory maximum of domain %s (%s) to %d MiB.",
    29.5                    self.info['name_label'], str(self.domid), limit)
    29.6  
    29.7 +        maxmem_cur = self.get_memory_static_max()
    29.8          MiB = 1024 * 1024
    29.9          self._safe_set_memory('memory_static_max', limit * MiB)
   29.10  
   29.11 @@ -914,6 +915,7 @@ class XendDomainInfo:
   29.12              try:
   29.13                  return xc.domain_setmaxmem(self.domid, maxmem)
   29.14              except Exception, ex:
   29.15 +                self._safe_set_memory('memory_static_max', maxmem_cur)
   29.16                  raise XendError(str(ex))
   29.17          xen.xend.XendDomain.instance().managed_config_save(self)
   29.18  
    30.1 --- a/tools/python/xen/xend/XendNode.py	Mon Feb 25 06:29:01 2008 -0700
    30.2 +++ b/tools/python/xen/xend/XendNode.py	Tue Feb 26 10:12:04 2008 -0700
    30.3 @@ -573,6 +573,20 @@ class XendNode:
    30.4          except:
    30.5              str='none\n'
    30.6          return str[:-1];
    30.7 +    def format_node_to_memory(self, pinfo):
    30.8 +        str=''
    30.9 +        whitespace=''
   30.10 +        try:
   30.11 +            node_to_memory=pinfo['node_to_memory']
   30.12 +            for i in range(0, pinfo['nr_nodes']):
   30.13 +                str+='%snode%d:%d\n' % (whitespace,
   30.14 +                                        i,
   30.15 +                                        node_to_memory[i] / 1024)
   30.16 +                whitespace='%25s' % ''
   30.17 +        except:
   30.18 +            str='none\n'
   30.19 +        return str[:-1];
   30.20 +
   30.21  
   30.22      def physinfo(self):
   30.23          info = self.xc.physinfo()
   30.24 @@ -583,6 +597,7 @@ class XendNode:
   30.25          info['total_memory'] = info['total_memory'] / 1024
   30.26          info['free_memory']  = info['free_memory'] / 1024
   30.27          info['node_to_cpu']  = self.format_node_to_cpu(info)
   30.28 +        info['node_to_memory'] = self.format_node_to_memory(info)
   30.29  
   30.30          ITEM_ORDER = ['nr_cpus',
   30.31                        'nr_nodes',
   30.32 @@ -592,7 +607,8 @@ class XendNode:
   30.33                        'hw_caps',
   30.34                        'total_memory',
   30.35                        'free_memory',
   30.36 -                      'node_to_cpu'
   30.37 +                      'node_to_cpu',
   30.38 +                      'node_to_memory'
   30.39                        ]
   30.40  
   30.41          return [[k, info[k]] for k in ITEM_ORDER]
    31.1 --- a/tools/python/xen/xend/image.py	Mon Feb 25 06:29:01 2008 -0700
    31.2 +++ b/tools/python/xen/xend/image.py	Tue Feb 26 10:12:04 2008 -0700
    31.3 @@ -390,7 +390,7 @@ class LinuxImageHandler(ImageHandler):
    31.4          ImageHandler.configure(self, vmConfig)
    31.5          rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
    31.6          if rtc_timeoffset is not None:
    31.7 -            xc.domain_set_time_offset(self.vm.getDomid(), rtc_timeoffset)
    31.8 +            xc.domain_set_time_offset(self.vm.getDomid(), int(rtc_timeoffset))
    31.9  
   31.10      def buildDomain(self):
   31.11          store_evtchn = self.vm.getStorePort()
    32.1 --- a/tools/xentrace/xentrace.c	Mon Feb 25 06:29:01 2008 -0700
    32.2 +++ b/tools/xentrace/xentrace.c	Tue Feb 26 10:12:04 2008 -0700
    32.3 @@ -15,6 +15,7 @@
    32.4  #include <sys/mman.h>
    32.5  #include <sys/stat.h>
    32.6  #include <sys/types.h>
    32.7 +#include <sys/vfs.h>
    32.8  #include <fcntl.h>
    32.9  #include <unistd.h>
   32.10  #include <errno.h>
   32.11 @@ -53,7 +54,10 @@ typedef struct settings_st {
   32.12      uint32_t evt_mask;
   32.13      uint32_t cpu_mask;
   32.14      unsigned long tbuf_size;
   32.15 -    uint8_t discard:1;
   32.16 +    unsigned long disk_rsvd;
   32.17 +    unsigned long timeout;
   32.18 +    uint8_t discard:1,
   32.19 +        disable_tracing:1;
   32.20  } settings_t;
   32.21  
   32.22  settings_t opts;
   32.23 @@ -83,8 +87,36 @@ void close_handler(int signal)
   32.24  void write_buffer(unsigned int cpu, unsigned char *start, int size,
   32.25                 int total_size, int outfd)
   32.26  {
   32.27 +    struct statfs stat;
   32.28      size_t written = 0;
   32.29      
   32.30 +    if ( opts.disk_rsvd != 0 )
   32.31 +    {
   32.32 +        unsigned long long freespace;
   32.33 +
   32.34 +        /* Check that filesystem has enough space. */
   32.35 +        if ( fstatfs (outfd, &stat) )
   32.36 +        {
   32.37 +                fprintf(stderr, "Statfs failed!\n");
   32.38 +                goto fail;
   32.39 +        }
   32.40 +
   32.41 +        freespace = stat.f_bsize * (unsigned long long)stat.f_bfree;
   32.42 +
   32.43 +        if ( total_size )
   32.44 +            freespace -= total_size;
   32.45 +        else
   32.46 +            freespace -= size;
   32.47 +
   32.48 +        freespace >>= 20; /* Convert to MB */
   32.49 +
   32.50 +        if ( freespace <= opts.disk_rsvd )
   32.51 +        {
   32.52 +                fprintf(stderr, "Disk space limit reached (free space: %lluMB, limit: %luMB).\n", freespace, opts.disk_rsvd);
   32.53 +                exit (EXIT_FAILURE);
   32.54 +        }
   32.55 +    }
   32.56 +
   32.57      /* Write a CPU_BUF record on each buffer "window" written.  Wrapped
   32.58       * windows may involve two writes, so only write the record on the
   32.59       * first write. */
   32.60 @@ -128,6 +160,28 @@ void write_buffer(unsigned int cpu, unsi
   32.61      exit(EXIT_FAILURE);
   32.62  }
   32.63  
   32.64 +static void disable_tbufs(void)
   32.65 +{
   32.66 +    int xc_handle = xc_interface_open();
   32.67 +    int ret;
   32.68 +
   32.69 +    if ( xc_handle < 0 ) 
   32.70 +    {
   32.71 +        perror("Couldn't open xc handle to disable tbufs.");
   32.72 +        goto out;
   32.73 +    }
   32.74 +
   32.75 +    ret = xc_tbuf_disable(xc_handle);
   32.76 +
   32.77 +    if ( ret != 0 )
   32.78 +    {
   32.79 +        perror("Couldn't disable trace buffers");
   32.80 +    }
   32.81 +
   32.82 +out:
   32.83 +    xc_interface_close(xc_handle);
   32.84 +}
   32.85 +
   32.86  static void get_tbufs(unsigned long *mfn, unsigned long *size)
   32.87  {
   32.88      int ret;
   32.89 @@ -435,6 +489,9 @@ int monitor_tbufs(int outfd)
   32.90          wait_for_event_or_timeout(opts.poll_sleep);
   32.91      }
   32.92  
   32.93 +    if(opts.disable_tracing)
   32.94 +        disable_tbufs();
   32.95 +
   32.96      /* cleanup */
   32.97      free(meta);
   32.98      free(data);
   32.99 @@ -471,6 +528,14 @@ void usage(void)
  32.100  "                          N.B. that the trace buffer cannot be resized.\n" \
  32.101  "                          if it has already been set this boot cycle,\n" \
  32.102  "                          this argument will be ignored.\n" \
  32.103 +"  -D  --discard-buffers   Discard all records currently in the trace\n" \
  32.104 +"                          buffers before beginning.\n" \
  32.105 +"  -x  --dont-disable-tracing\n" \
  32.106 +"                          By default, xentrace will disable tracing when\n" \
  32.107 +"                          it exits. Selecting this option will tell it to\n" \
  32.108 +"                          keep tracing on.  Traces will be collected in\n" \
  32.109 +"                          Xen's trace buffers until they become full.\n" \
  32.110 +"  -T  --time-interval=s   Run xentrace for s seconds and quit.\n" \
  32.111  "  -?, --help              Show this message\n" \
  32.112  "  -V, --version           Print program version\n" \
  32.113  "\n" \
  32.114 @@ -539,6 +604,10 @@ void parse_args(int argc, char **argv)
  32.115          { "cpu-mask",       required_argument, 0, 'c' },
  32.116          { "evt-mask",       required_argument, 0, 'e' },
  32.117          { "trace-buf-size", required_argument, 0, 'S' },
  32.118 +        { "reserve-disk-space", required_argument, 0, 'r' },
  32.119 +        { "time-interval",  required_argument, 0, 'T' },
  32.120 +        { "discard-buffers", no_argument,      0, 'D' },
  32.121 +        { "dont-disable-tracing", no_argument, 0, 'x' },
  32.122          { "help",           no_argument,       0, '?' },
  32.123          { "version",        no_argument,       0, 'V' },
  32.124          { 0, 0, 0, 0 }
  32.125 @@ -569,7 +638,23 @@ void parse_args(int argc, char **argv)
  32.126              printf("%s\n", program_version);
  32.127              exit(EXIT_SUCCESS);
  32.128              break;
  32.129 -            
  32.130 +
  32.131 +        case 'D': /* Discard traces currently in buffer */
  32.132 +            opts.discard = 1;
  32.133 +            break;
  32.134 +
  32.135 +        case 'r': /* Disk-space reservation */
  32.136 +            opts.disk_rsvd = argtol(optarg, 0);
  32.137 +            break;
  32.138 +
  32.139 +        case 'x': /* Don't disable tracing */
  32.140 +            opts.disable_tracing = 0;
  32.141 +            break;
  32.142 +
  32.143 +        case 'T':
  32.144 +            opts.timeout = argtol(optarg, 0);
  32.145 +            break;
  32.146 +
  32.147          default:
  32.148              usage();
  32.149          }
  32.150 @@ -582,7 +667,6 @@ void parse_args(int argc, char **argv)
  32.151      opts.outfile = argv[optind];
  32.152  }
  32.153  
  32.154 -
  32.155  /* *BSD has no O_LARGEFILE */
  32.156  #ifndef O_LARGEFILE
  32.157  #define O_LARGEFILE	0
  32.158 @@ -597,6 +681,9 @@ int main(int argc, char **argv)
  32.159      opts.poll_sleep = POLL_SLEEP_MILLIS;
  32.160      opts.evt_mask = 0;
  32.161      opts.cpu_mask = 0;
  32.162 +    opts.disk_rsvd = 0;
  32.163 +    opts.disable_tracing = 1;
  32.164 +    opts.timeout = 0;
  32.165  
  32.166      parse_args(argc, argv);
  32.167  
  32.168 @@ -613,6 +700,9 @@ int main(int argc, char **argv)
  32.169      if ( opts.cpu_mask != 0 )
  32.170          set_mask(opts.cpu_mask, 1);
  32.171  
  32.172 +    if ( opts.timeout != 0 ) 
  32.173 +        alarm(opts.timeout);
  32.174 +
  32.175      if ( opts.outfile )
  32.176          outfd = open(opts.outfile,
  32.177                       O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE,
  32.178 @@ -637,6 +727,7 @@ int main(int argc, char **argv)
  32.179      sigaction(SIGHUP,  &act, NULL);
  32.180      sigaction(SIGTERM, &act, NULL);
  32.181      sigaction(SIGINT,  &act, NULL);
  32.182 +    sigaction(SIGALRM, &act, NULL);
  32.183  
  32.184      ret = monitor_tbufs(outfd);
  32.185  
    33.1 --- a/xen/arch/x86/hvm/emulate.c	Mon Feb 25 06:29:01 2008 -0700
    33.2 +++ b/xen/arch/x86/hvm/emulate.c	Tue Feb 26 10:12:04 2008 -0700
    33.3 @@ -124,8 +124,9 @@ static int hvmemul_virtual_to_linear(
    33.4  
    33.5      if ( !okay )
    33.6      {
    33.7 -        hvmemul_ctxt->flags.exn_pending = 1;
    33.8 +        hvmemul_ctxt->exn_pending = 1;
    33.9          hvmemul_ctxt->exn_vector = TRAP_gp_fault;
   33.10 +        hvmemul_ctxt->exn_error_code = 0;
   33.11          hvmemul_ctxt->exn_insn_len = 0;
   33.12          return X86EMUL_EXCEPTION;
   33.13      }
   33.14 @@ -439,9 +440,6 @@ static int hvmemul_write_segment(
   33.15          container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
   33.16      struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
   33.17  
   33.18 -    if ( seg == x86_seg_ss )
   33.19 -        hvmemul_ctxt->flags.mov_ss = 1;
   33.20 -
   33.21      memcpy(sreg, reg, sizeof(struct segment_register));
   33.22      __set_bit(seg, &hvmemul_ctxt->seg_reg_dirty);
   33.23  
   33.24 @@ -571,17 +569,6 @@ static int hvmemul_write_msr(
   33.25      return hvm_funcs.msr_write_intercept(&_regs);
   33.26  }
   33.27  
   33.28 -static int hvmemul_write_rflags(
   33.29 -    unsigned long val,
   33.30 -    struct x86_emulate_ctxt *ctxt)
   33.31 -{
   33.32 -    struct hvm_emulate_ctxt *hvmemul_ctxt =
   33.33 -        container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
   33.34 -    if ( (val & X86_EFLAGS_IF) && !(ctxt->regs->eflags & X86_EFLAGS_IF) )
   33.35 -        hvmemul_ctxt->flags.sti = 1;
   33.36 -    return X86EMUL_OKAY;
   33.37 -}
   33.38 -
   33.39  static int hvmemul_wbinvd(
   33.40      struct x86_emulate_ctxt *ctxt)
   33.41  {
   33.42 @@ -600,28 +587,17 @@ static int hvmemul_cpuid(
   33.43      return X86EMUL_OKAY;
   33.44  }
   33.45  
   33.46 -static int hvmemul_hlt(
   33.47 -    struct x86_emulate_ctxt *ctxt)
   33.48 -{
   33.49 -    struct hvm_emulate_ctxt *hvmemul_ctxt =
   33.50 -        container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
   33.51 -    hvmemul_ctxt->flags.hlt = 1;
   33.52 -    return X86EMUL_OKAY;
   33.53 -}
   33.54 -
   33.55  static int hvmemul_inject_hw_exception(
   33.56      uint8_t vector,
   33.57 -    uint16_t error_code,
   33.58 +    int32_t error_code,
   33.59      struct x86_emulate_ctxt *ctxt)
   33.60  {
   33.61      struct hvm_emulate_ctxt *hvmemul_ctxt =
   33.62          container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
   33.63  
   33.64 -    if ( error_code != 0 )
   33.65 -        return X86EMUL_UNHANDLEABLE;
   33.66 -
   33.67 -    hvmemul_ctxt->flags.exn_pending = 1;
   33.68 +    hvmemul_ctxt->exn_pending = 1;
   33.69      hvmemul_ctxt->exn_vector = vector;
   33.70 +    hvmemul_ctxt->exn_error_code = error_code;
   33.71      hvmemul_ctxt->exn_insn_len = 0;
   33.72  
   33.73      return X86EMUL_OKAY;
   33.74 @@ -635,8 +611,9 @@ static int hvmemul_inject_sw_interrupt(
   33.75      struct hvm_emulate_ctxt *hvmemul_ctxt =
   33.76          container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
   33.77  
   33.78 -    hvmemul_ctxt->flags.exn_pending = 1;
   33.79 +    hvmemul_ctxt->exn_pending = 1;
   33.80      hvmemul_ctxt->exn_vector = vector;
   33.81 +    hvmemul_ctxt->exn_error_code = -1;
   33.82      hvmemul_ctxt->exn_insn_len = insn_len;
   33.83  
   33.84      return X86EMUL_OKAY;
   33.85 @@ -684,10 +661,8 @@ static struct x86_emulate_ops hvm_emulat
   33.86      .write_cr      = hvmemul_write_cr,
   33.87      .read_msr      = hvmemul_read_msr,
   33.88      .write_msr     = hvmemul_write_msr,
   33.89 -    .write_rflags  = hvmemul_write_rflags,
   33.90      .wbinvd        = hvmemul_wbinvd,
   33.91      .cpuid         = hvmemul_cpuid,
   33.92 -    .hlt           = hvmemul_hlt,
   33.93      .inject_hw_exception = hvmemul_inject_hw_exception,
   33.94      .inject_sw_interrupt = hvmemul_inject_sw_interrupt,
   33.95      .load_fpu_ctxt = hvmemul_load_fpu_ctxt,
   33.96 @@ -698,7 +673,9 @@ int hvm_emulate_one(
   33.97      struct hvm_emulate_ctxt *hvmemul_ctxt)
   33.98  {
   33.99      struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs;
  33.100 +    uint32_t new_intr_shadow;
  33.101      unsigned long addr;
  33.102 +    int rc;
  33.103  
  33.104      hvmemul_ctxt->ctxt.addr_size =
  33.105          hvmemul_ctxt->seg_reg[x86_seg_cs].attr.fields.db ? 32 : 16;
  33.106 @@ -715,15 +692,46 @@ int hvm_emulate_one(
  33.107               hvmemul_ctxt->insn_buf, addr, sizeof(hvmemul_ctxt->insn_buf)))
  33.108          ? sizeof(hvmemul_ctxt->insn_buf) : 0;
  33.109  
  33.110 -    hvmemul_ctxt->flag_word = 0;
  33.111 +    hvmemul_ctxt->exn_pending = 0;
  33.112  
  33.113 -    return x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops);
  33.114 +    rc = x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops);
  33.115 +    if ( rc != X86EMUL_OKAY )
  33.116 +        return rc;
  33.117 +
  33.118 +    new_intr_shadow = hvmemul_ctxt->intr_shadow;
  33.119 +
  33.120 +    /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */
  33.121 +    if ( hvmemul_ctxt->ctxt.retire.flags.mov_ss )
  33.122 +        new_intr_shadow ^= HVM_INTR_SHADOW_MOV_SS;
  33.123 +    else
  33.124 +        new_intr_shadow &= ~HVM_INTR_SHADOW_MOV_SS;
  33.125 +
  33.126 +    /* STI instruction toggles STI shadow, else we just clear it. */
  33.127 +    if ( hvmemul_ctxt->ctxt.retire.flags.sti )
  33.128 +        new_intr_shadow ^= HVM_INTR_SHADOW_STI;
  33.129 +    else
  33.130 +        new_intr_shadow &= ~HVM_INTR_SHADOW_STI;
  33.131 +
  33.132 +    if ( hvmemul_ctxt->intr_shadow != new_intr_shadow )
  33.133 +    {
  33.134 +        hvmemul_ctxt->intr_shadow = new_intr_shadow;
  33.135 +        hvm_funcs.set_interrupt_shadow(current, new_intr_shadow);
  33.136 +    }
  33.137 +
  33.138 +    if ( hvmemul_ctxt->ctxt.retire.flags.hlt &&
  33.139 +         !hvm_local_events_need_delivery(current) )
  33.140 +    {
  33.141 +        hvm_hlt(regs->eflags);
  33.142 +    }
  33.143 +
  33.144 +    return X86EMUL_OKAY;
  33.145  }
  33.146  
  33.147  void hvm_emulate_prepare(
  33.148      struct hvm_emulate_ctxt *hvmemul_ctxt,
  33.149      struct cpu_user_regs *regs)
  33.150  {
  33.151 +    hvmemul_ctxt->intr_shadow = hvm_funcs.get_interrupt_shadow(current);
  33.152      hvmemul_ctxt->ctxt.regs = regs;
  33.153      hvmemul_ctxt->ctxt.force_writeback = 1;
  33.154      hvmemul_ctxt->seg_reg_accessed = 0;
    34.1 --- a/xen/arch/x86/hvm/hvm.c	Mon Feb 25 06:29:01 2008 -0700
    34.2 +++ b/xen/arch/x86/hvm/hvm.c	Tue Feb 26 10:12:04 2008 -0700
    34.3 @@ -1640,12 +1640,22 @@ void hvm_cpuid(unsigned int input, unsig
    34.4  
    34.5  enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack)
    34.6  {
    34.7 -    enum hvm_intblk r;
    34.8 +    unsigned long intr_shadow;
    34.9 +
   34.10      ASSERT(v == current);
   34.11  
   34.12 -    r = hvm_funcs.interrupt_blocked(v, intack);
   34.13 -    if ( r != hvm_intblk_none )
   34.14 -        return r;
   34.15 +    if ( (intack.source != hvm_intsrc_nmi) &&
   34.16 +         !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
   34.17 +        return hvm_intblk_rflags_ie;
   34.18 +
   34.19 +    intr_shadow = hvm_funcs.get_interrupt_shadow(v);
   34.20 +
   34.21 +    if ( intr_shadow & (HVM_INTR_SHADOW_STI|HVM_INTR_SHADOW_MOV_SS) )
   34.22 +        return hvm_intblk_shadow;
   34.23 +
   34.24 +    if ( intack.source == hvm_intsrc_nmi )
   34.25 +        return ((intr_shadow & HVM_INTR_SHADOW_NMI) ?
   34.26 +                hvm_intblk_nmi_iret : hvm_intblk_none);
   34.27  
   34.28      if ( intack.source == hvm_intsrc_lapic )
   34.29      {
   34.30 @@ -1654,7 +1664,7 @@ enum hvm_intblk hvm_interrupt_blocked(st
   34.31              return hvm_intblk_tpr;
   34.32      }
   34.33  
   34.34 -    return r;
   34.35 +    return hvm_intblk_none;
   34.36  }
   34.37  
   34.38  static long hvm_grant_table_op(
    35.1 --- a/xen/arch/x86/hvm/io.c	Mon Feb 25 06:29:01 2008 -0700
    35.2 +++ b/xen/arch/x86/hvm/io.c	Tue Feb 26 10:12:04 2008 -0700
    35.3 @@ -262,8 +262,8 @@ int handle_mmio(void)
    35.4                   ctxt.insn_buf[4], ctxt.insn_buf[5]);
    35.5          return 0;
    35.6      case X86EMUL_EXCEPTION:
    35.7 -        if ( ctxt.flags.exn_pending )
    35.8 -            hvm_inject_exception(ctxt.exn_vector, 0, 0);
    35.9 +        if ( ctxt.exn_pending )
   35.10 +            hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0);
   35.11          break;
   35.12      default:
   35.13          break;
    36.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Feb 25 06:29:01 2008 -0700
    36.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Tue Feb 26 10:12:04 2008 -0700
    36.3 @@ -366,24 +366,18 @@ static void svm_fpu_leave(struct vcpu *v
    36.4      }
    36.5  }
    36.6  
    36.7 -static enum hvm_intblk svm_interrupt_blocked(
    36.8 -    struct vcpu *v, struct hvm_intack intack)
    36.9 +static unsigned int svm_get_interrupt_shadow(struct vcpu *v)
   36.10  {
   36.11      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   36.12 -
   36.13 -    if ( vmcb->interrupt_shadow )
   36.14 -        return hvm_intblk_shadow;
   36.15 -
   36.16 -    if ( intack.source == hvm_intsrc_nmi )
   36.17 -        return hvm_intblk_none;
   36.18 +    return (vmcb->interrupt_shadow ?
   36.19 +            (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI) : 0);
   36.20 +}
   36.21  
   36.22 -    ASSERT((intack.source == hvm_intsrc_pic) ||
   36.23 -           (intack.source == hvm_intsrc_lapic));
   36.24 -
   36.25 -    if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
   36.26 -        return hvm_intblk_rflags_ie;
   36.27 -
   36.28 -    return hvm_intblk_none;
   36.29 +static void svm_set_interrupt_shadow(struct vcpu *v, unsigned int intr_shadow)
   36.30 +{
   36.31 +    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   36.32 +    vmcb->interrupt_shadow =
   36.33 +        !!(intr_shadow & (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI));
   36.34  }
   36.35  
   36.36  static int svm_guest_x86_mode(struct vcpu *v)
   36.37 @@ -779,7 +773,8 @@ static struct hvm_function_table svm_fun
   36.38      .vcpu_destroy         = svm_vcpu_destroy,
   36.39      .save_cpu_ctxt        = svm_save_vmcb_ctxt,
   36.40      .load_cpu_ctxt        = svm_load_vmcb_ctxt,
   36.41 -    .interrupt_blocked    = svm_interrupt_blocked,
   36.42 +    .get_interrupt_shadow = svm_get_interrupt_shadow,
   36.43 +    .set_interrupt_shadow = svm_set_interrupt_shadow,
   36.44      .guest_x86_mode       = svm_guest_x86_mode,
   36.45      .get_segment_register = svm_get_segment_register,
   36.46      .set_segment_register = svm_set_segment_register,
   36.47 @@ -1176,7 +1171,7 @@ static void svm_vmexit_do_hlt(struct vmc
   36.48      /* Check for pending exception or new interrupt. */
   36.49      if ( vmcb->eventinj.fields.v ||
   36.50           ((intack.source != hvm_intsrc_none) &&
   36.51 -          !svm_interrupt_blocked(current, intack)) )
   36.52 +          !hvm_interrupt_blocked(current, intack)) )
   36.53      {
   36.54          HVMTRACE_1D(HLT, curr, /*int pending=*/ 1);
   36.55          return;
    37.1 --- a/xen/arch/x86/hvm/vmx/intr.c	Mon Feb 25 06:29:01 2008 -0700
    37.2 +++ b/xen/arch/x86/hvm/vmx/intr.c	Tue Feb 26 10:12:04 2008 -0700
    37.3 @@ -65,10 +65,6 @@
    37.4   * Injecting a virtual NMI sets the NMI-blocking interruptibility flag only
    37.5   * if the 'virtual NMIs' control is set. Injecting *any* kind of event clears
    37.6   * the STI- and MOV-SS-blocking interruptibility-state flags.
    37.7 - * 
    37.8 - * If MOV/POP SS is executed while MOV-SS-blocking is in effect, the effect
    37.9 - * is cleared. If STI is executed while MOV-SS- or STI-blocking is in effect,
   37.10 - * the effect is cleared. (i.e., MOV-SS-blocking 'dominates' STI-blocking).
   37.11   */
   37.12  
   37.13  static void enable_intr_window(struct vcpu *v, struct hvm_intack intack)
    38.1 --- a/xen/arch/x86/hvm/vmx/realmode.c	Mon Feb 25 06:29:01 2008 -0700
    38.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c	Tue Feb 26 10:12:04 2008 -0700
    38.3 @@ -21,25 +21,20 @@
    38.4  #include <asm/hvm/vmx/vmx.h>
    38.5  #include <asm/hvm/vmx/vmcs.h>
    38.6  
    38.7 -struct realmode_emulate_ctxt {
    38.8 -    struct hvm_emulate_ctxt hvm;
    38.9 -    uint32_t intr_shadow;
   38.10 -};
   38.11 -
   38.12  static void realmode_deliver_exception(
   38.13      unsigned int vector,
   38.14      unsigned int insn_len,
   38.15 -    struct realmode_emulate_ctxt *rm_ctxt)
   38.16 +    struct hvm_emulate_ctxt *hvmemul_ctxt)
   38.17  {
   38.18      struct segment_register *idtr, *csr;
   38.19 -    struct cpu_user_regs *regs = rm_ctxt->hvm.ctxt.regs;
   38.20 +    struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs;
   38.21      uint32_t cs_eip, pstk;
   38.22      uint16_t frame[3];
   38.23      unsigned int last_byte;
   38.24  
   38.25 -    idtr = hvmemul_get_seg_reg(x86_seg_idtr, &rm_ctxt->hvm);
   38.26 -    csr  = hvmemul_get_seg_reg(x86_seg_cs,   &rm_ctxt->hvm);
   38.27 -    __set_bit(x86_seg_cs, &rm_ctxt->hvm.seg_reg_dirty);
   38.28 +    idtr = hvmemul_get_seg_reg(x86_seg_idtr, hvmemul_ctxt);
   38.29 +    csr  = hvmemul_get_seg_reg(x86_seg_cs,   hvmemul_ctxt);
   38.30 +    __set_bit(x86_seg_cs, &hvmemul_ctxt->seg_reg_dirty);
   38.31  
   38.32   again:
   38.33      last_byte = (vector * 4) + 3;
   38.34 @@ -74,7 +69,7 @@ static void realmode_deliver_exception(
   38.35      frame[1] = csr->sel;
   38.36      frame[2] = regs->eflags & ~X86_EFLAGS_RF;
   38.37  
   38.38 -    if ( rm_ctxt->hvm.ctxt.addr_size == 32 )
   38.39 +    if ( hvmemul_ctxt->ctxt.addr_size == 32 )
   38.40      {
   38.41          regs->esp -= 6;
   38.42          pstk = regs->esp;
   38.43 @@ -86,7 +81,7 @@ static void realmode_deliver_exception(
   38.44          regs->esp |= pstk;
   38.45      }
   38.46  
   38.47 -    pstk += hvmemul_get_seg_reg(x86_seg_ss, &rm_ctxt->hvm)->base;
   38.48 +    pstk += hvmemul_get_seg_reg(x86_seg_ss, hvmemul_ctxt)->base;
   38.49      (void)hvm_copy_to_guest_phys(pstk, frame, sizeof(frame));
   38.50  
   38.51      csr->sel  = cs_eip >> 16;
   38.52 @@ -95,41 +90,42 @@ static void realmode_deliver_exception(
   38.53      regs->eflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF | X86_EFLAGS_RF);
   38.54  
   38.55      /* Exception delivery clears STI and MOV-SS blocking. */
   38.56 -    if ( rm_ctxt->intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
   38.57 +    if ( hvmemul_ctxt->intr_shadow &
   38.58 +         (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
   38.59      {
   38.60 -        rm_ctxt->intr_shadow &= ~(VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS);
   38.61 -        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, rm_ctxt->intr_shadow);
   38.62 +        hvmemul_ctxt->intr_shadow &=
   38.63 +            ~(VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS);
   38.64 +        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, hvmemul_ctxt->intr_shadow);
   38.65      }
   38.66  }
   38.67  
   38.68 -static void realmode_emulate_one(struct realmode_emulate_ctxt *rm_ctxt)
   38.69 +static void realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt)
   38.70  {
   38.71 -    struct cpu_user_regs *regs = rm_ctxt->hvm.ctxt.regs;
   38.72      struct vcpu *curr = current;
   38.73      unsigned long seg_reg_dirty;
   38.74 -    uint32_t new_intr_shadow, intr_info;
   38.75 +    uint32_t intr_info;
   38.76      int rc;
   38.77  
   38.78 -    seg_reg_dirty = rm_ctxt->hvm.seg_reg_dirty;
   38.79 -    rm_ctxt->hvm.seg_reg_dirty = 0;
   38.80 +    seg_reg_dirty = hvmemul_ctxt->seg_reg_dirty;
   38.81 +    hvmemul_ctxt->seg_reg_dirty = 0;
   38.82  
   38.83 -    rc = hvm_emulate_one(&rm_ctxt->hvm);
   38.84 +    rc = hvm_emulate_one(hvmemul_ctxt);
   38.85  
   38.86 -    if ( test_bit(x86_seg_cs, &rm_ctxt->hvm.seg_reg_dirty) )
   38.87 +    if ( test_bit(x86_seg_cs, &hvmemul_ctxt->seg_reg_dirty) )
   38.88      {
   38.89          curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_CS;
   38.90 -        if ( hvmemul_get_seg_reg(x86_seg_cs, &rm_ctxt->hvm)->sel & 3 )
   38.91 +        if ( hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt)->sel & 3 )
   38.92              curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_CS;
   38.93      }
   38.94  
   38.95 -    if ( test_bit(x86_seg_ss, &rm_ctxt->hvm.seg_reg_dirty) )
   38.96 +    if ( test_bit(x86_seg_ss, &hvmemul_ctxt->seg_reg_dirty) )
   38.97      {
   38.98          curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_SS;
   38.99 -        if ( hvmemul_get_seg_reg(x86_seg_ss, &rm_ctxt->hvm)->sel & 3 )
  38.100 +        if ( hvmemul_get_seg_reg(x86_seg_ss, hvmemul_ctxt)->sel & 3 )
  38.101              curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_SS;
  38.102      }
  38.103  
  38.104 -    rm_ctxt->hvm.seg_reg_dirty |= seg_reg_dirty;
  38.105 +    hvmemul_ctxt->seg_reg_dirty |= seg_reg_dirty;
  38.106  
  38.107      if ( rc == X86EMUL_UNHANDLEABLE )
  38.108      {
  38.109 @@ -137,33 +133,9 @@ static void realmode_emulate_one(struct 
  38.110          goto fail;
  38.111      }
  38.112  
  38.113 -    if ( rc == X86EMUL_RETRY )
  38.114 -        return;
  38.115 -
  38.116 -    new_intr_shadow = rm_ctxt->intr_shadow;
  38.117 -
  38.118 -    /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */
  38.119 -    if ( rm_ctxt->hvm.flags.mov_ss )
  38.120 -        new_intr_shadow ^= VMX_INTR_SHADOW_MOV_SS;
  38.121 -    else
  38.122 -        new_intr_shadow &= ~VMX_INTR_SHADOW_MOV_SS;
  38.123 -
  38.124 -    /* STI instruction toggles STI shadow, else we just clear it. */
  38.125 -    if ( rm_ctxt->hvm.flags.sti )
  38.126 -        new_intr_shadow ^= VMX_INTR_SHADOW_STI;
  38.127 -    else
  38.128 -        new_intr_shadow &= ~VMX_INTR_SHADOW_STI;
  38.129 -
  38.130 -    /* Update interrupt shadow information in VMCS only if it changes. */
  38.131 -    if ( rm_ctxt->intr_shadow != new_intr_shadow )
  38.132 -    {
  38.133 -        rm_ctxt->intr_shadow = new_intr_shadow;
  38.134 -        __vmwrite(GUEST_INTERRUPTIBILITY_INFO, rm_ctxt->intr_shadow);
  38.135 -    }
  38.136 -
  38.137      if ( rc == X86EMUL_EXCEPTION )
  38.138      {
  38.139 -        if ( !rm_ctxt->hvm.flags.exn_pending )
  38.140 +        if ( !hvmemul_ctxt->exn_pending )
  38.141          {
  38.142              intr_info = __vmread(VM_ENTRY_INTR_INFO);
  38.143              __vmwrite(VM_ENTRY_INTR_INFO, 0);
  38.144 @@ -172,23 +144,21 @@ static void realmode_emulate_one(struct 
  38.145                  gdprintk(XENLOG_ERR, "Exception pending but no info.\n");
  38.146                  goto fail;
  38.147              }
  38.148 -            rm_ctxt->hvm.exn_vector = (uint8_t)intr_info;
  38.149 -            rm_ctxt->hvm.exn_insn_len = 0;
  38.150 +            hvmemul_ctxt->exn_vector = (uint8_t)intr_info;
  38.151 +            hvmemul_ctxt->exn_insn_len = 0;
  38.152          }
  38.153  
  38.154          if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE )
  38.155          {
  38.156              gdprintk(XENLOG_ERR, "Exception %02x in protected mode.\n",
  38.157 -                     rm_ctxt->hvm.exn_vector);
  38.158 +                     hvmemul_ctxt->exn_vector);
  38.159              goto fail;
  38.160          }
  38.161  
  38.162          realmode_deliver_exception(
  38.163 -            rm_ctxt->hvm.exn_vector, rm_ctxt->hvm.exn_insn_len, rm_ctxt);
  38.164 -    }
  38.165 -    else if ( rm_ctxt->hvm.flags.hlt && !hvm_local_events_need_delivery(curr) )
  38.166 -    {
  38.167 -        hvm_hlt(regs->eflags);
  38.168 +            hvmemul_ctxt->exn_vector,
  38.169 +            hvmemul_ctxt->exn_insn_len,
  38.170 +            hvmemul_ctxt);
  38.171      }
  38.172  
  38.173      return;
  38.174 @@ -197,18 +167,18 @@ static void realmode_emulate_one(struct 
  38.175      gdprintk(XENLOG_ERR,
  38.176               "Real-mode emulation failed @ %04x:%08lx: "
  38.177               "%02x %02x %02x %02x %02x %02x\n",
  38.178 -             hvmemul_get_seg_reg(x86_seg_cs, &rm_ctxt->hvm)->sel,
  38.179 -             rm_ctxt->hvm.insn_buf_eip,
  38.180 -             rm_ctxt->hvm.insn_buf[0], rm_ctxt->hvm.insn_buf[1],
  38.181 -             rm_ctxt->hvm.insn_buf[2], rm_ctxt->hvm.insn_buf[3],
  38.182 -             rm_ctxt->hvm.insn_buf[4], rm_ctxt->hvm.insn_buf[5]);
  38.183 +             hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt)->sel,
  38.184 +             hvmemul_ctxt->insn_buf_eip,
  38.185 +             hvmemul_ctxt->insn_buf[0], hvmemul_ctxt->insn_buf[1],
  38.186 +             hvmemul_ctxt->insn_buf[2], hvmemul_ctxt->insn_buf[3],
  38.187 +             hvmemul_ctxt->insn_buf[4], hvmemul_ctxt->insn_buf[5]);
  38.188      domain_crash_synchronous();
  38.189  }
  38.190  
  38.191  void vmx_realmode(struct cpu_user_regs *regs)
  38.192  {
  38.193      struct vcpu *curr = current;
  38.194 -    struct realmode_emulate_ctxt rm_ctxt;
  38.195 +    struct hvm_emulate_ctxt hvmemul_ctxt;
  38.196      struct segment_register *sreg;
  38.197      unsigned long intr_info;
  38.198      unsigned int emulations = 0;
  38.199 @@ -218,17 +188,16 @@ void vmx_realmode(struct cpu_user_regs *
  38.200      if ( intr_info & INTR_INFO_VALID_MASK )
  38.201          __vmwrite(VM_ENTRY_INTR_INFO, 0);
  38.202  
  38.203 -    hvm_emulate_prepare(&rm_ctxt.hvm, regs);
  38.204 -    rm_ctxt.intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
  38.205 +    hvm_emulate_prepare(&hvmemul_ctxt, regs);
  38.206  
  38.207      if ( curr->arch.hvm_vcpu.io_completed )
  38.208 -        realmode_emulate_one(&rm_ctxt);
  38.209 +        realmode_emulate_one(&hvmemul_ctxt);
  38.210  
  38.211      /* Only deliver interrupts into emulated real mode. */
  38.212      if ( !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) &&
  38.213           (intr_info & INTR_INFO_VALID_MASK) )
  38.214      {
  38.215 -        realmode_deliver_exception((uint8_t)intr_info, 0, &rm_ctxt);
  38.216 +        realmode_deliver_exception((uint8_t)intr_info, 0, &hvmemul_ctxt);
  38.217          intr_info = 0;
  38.218      }
  38.219  
  38.220 @@ -245,7 +214,7 @@ void vmx_realmode(struct cpu_user_regs *
  38.221               !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) &&
  38.222               hvm_local_events_need_delivery(curr) )
  38.223              break;
  38.224 -        realmode_emulate_one(&rm_ctxt);
  38.225 +        realmode_emulate_one(&hvmemul_ctxt);
  38.226      }
  38.227  
  38.228      if ( !curr->arch.hvm_vmx.vmxemul )
  38.229 @@ -255,20 +224,20 @@ void vmx_realmode(struct cpu_user_regs *
  38.230           * At this point CS.RPL == SS.RPL == CS.DPL == SS.DPL == 0. For
  38.231           * DS, ES, FS and GS the most uninvasive trick is to set DPL == RPL.
  38.232           */
  38.233 -        sreg = hvmemul_get_seg_reg(x86_seg_ds, &rm_ctxt.hvm);
  38.234 -        sreg->attr.fields.dpl = sreg->sel & 3;
  38.235 -        sreg = hvmemul_get_seg_reg(x86_seg_es, &rm_ctxt.hvm);
  38.236 +        sreg = hvmemul_get_seg_reg(x86_seg_ds, &hvmemul_ctxt);
  38.237          sreg->attr.fields.dpl = sreg->sel & 3;
  38.238 -        sreg = hvmemul_get_seg_reg(x86_seg_fs, &rm_ctxt.hvm);
  38.239 +        sreg = hvmemul_get_seg_reg(x86_seg_es, &hvmemul_ctxt);
  38.240          sreg->attr.fields.dpl = sreg->sel & 3;
  38.241 -        sreg = hvmemul_get_seg_reg(x86_seg_gs, &rm_ctxt.hvm);
  38.242 +        sreg = hvmemul_get_seg_reg(x86_seg_fs, &hvmemul_ctxt);
  38.243          sreg->attr.fields.dpl = sreg->sel & 3;
  38.244 -        rm_ctxt.hvm.seg_reg_dirty |=
  38.245 +        sreg = hvmemul_get_seg_reg(x86_seg_gs, &hvmemul_ctxt);
  38.246 +        sreg->attr.fields.dpl = sreg->sel & 3;
  38.247 +        hvmemul_ctxt.seg_reg_dirty |=
  38.248              (1ul << x86_seg_ds) | (1ul << x86_seg_es) |
  38.249              (1ul << x86_seg_fs) | (1ul << x86_seg_gs);
  38.250      }
  38.251  
  38.252 -    hvm_emulate_writeback(&rm_ctxt.hvm);
  38.253 +    hvm_emulate_writeback(&hvmemul_ctxt);
  38.254  
  38.255      /* Re-instate VM_ENTRY_INTR_INFO if we did not discharge it. */
  38.256      if ( intr_info & INTR_INFO_VALID_MASK )
    39.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Feb 25 06:29:01 2008 -0700
    39.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Tue Feb 26 10:12:04 2008 -0700
    39.3 @@ -890,32 +890,14 @@ static void vmx_init_hypercall_page(stru
    39.4      *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
    39.5  }
    39.6  
    39.7 -static enum hvm_intblk vmx_interrupt_blocked(
    39.8 -    struct vcpu *v, struct hvm_intack intack)
    39.9 +static unsigned int vmx_get_interrupt_shadow(struct vcpu *v)
   39.10  {
   39.11 -    unsigned long intr_shadow;
   39.12 -
   39.13 -    /*
   39.14 -     * Test EFLAGS.IF first. It is often the most likely reason for interrupt
   39.15 -     * blockage, and is the cheapest to test (because no VMREAD is required).
   39.16 -     */
   39.17 -    if ( (intack.source != hvm_intsrc_nmi) &&
   39.18 -         !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
   39.19 -        return hvm_intblk_rflags_ie;
   39.20 +    return __vmread(GUEST_INTERRUPTIBILITY_INFO);
   39.21 +}
   39.22  
   39.23 -    intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO);
   39.24 -
   39.25 -    if ( intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) )
   39.26 -        return hvm_intblk_shadow;
   39.27 -
   39.28 -    if ( intack.source == hvm_intsrc_nmi )
   39.29 -        return ((intr_shadow & VMX_INTR_SHADOW_NMI) ?
   39.30 -                hvm_intblk_nmi_iret : hvm_intblk_none);
   39.31 -
   39.32 -    ASSERT((intack.source == hvm_intsrc_pic) ||
   39.33 -           (intack.source == hvm_intsrc_lapic));
   39.34 -
   39.35 -    return hvm_intblk_none;
   39.36 +static void vmx_set_interrupt_shadow(struct vcpu *v, unsigned int intr_shadow)
   39.37 +{
   39.38 +    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow);
   39.39  }
   39.40  
   39.41  static void vmx_update_host_cr3(struct vcpu *v)
   39.42 @@ -1038,7 +1020,8 @@ static struct hvm_function_table vmx_fun
   39.43      .vcpu_destroy         = vmx_vcpu_destroy,
   39.44      .save_cpu_ctxt        = vmx_save_vmcs_ctxt,
   39.45      .load_cpu_ctxt        = vmx_load_vmcs_ctxt,
   39.46 -    .interrupt_blocked    = vmx_interrupt_blocked,
   39.47 +    .get_interrupt_shadow = vmx_get_interrupt_shadow,
   39.48 +    .set_interrupt_shadow = vmx_set_interrupt_shadow,
   39.49      .guest_x86_mode       = vmx_guest_x86_mode,
   39.50      .get_segment_register = vmx_get_segment_register,
   39.51      .set_segment_register = vmx_set_segment_register,
    40.1 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S	Mon Feb 25 06:29:01 2008 -0700
    40.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S	Tue Feb 26 10:12:04 2008 -0700
    40.3 @@ -89,7 +89,7 @@ ENTRY(vmx_asm_vmexit_handler)
    40.4  
    40.5          ALIGN
    40.6  vmx_process_softirqs:
    40.7 -        sti       
    40.8 +        sti
    40.9          call do_softirq
   40.10          jmp vmx_asm_do_vmentry
   40.11  
   40.12 @@ -104,6 +104,10 @@ ENTRY(vmx_asm_do_vmentry)
   40.13          jnz  vmx_process_softirqs
   40.14  
   40.15          call vmx_intr_assist
   40.16 +
   40.17 +        testb $0xff,VCPU_vmx_emul(%ebx)
   40.18 +        jnz  vmx_goto_realmode
   40.19 +
   40.20          movl VCPU_hvm_guest_cr2(%ebx),%eax
   40.21          movl %eax,%cr2
   40.22          call vmx_trace_vmentry
   40.23 @@ -115,9 +119,6 @@ ENTRY(vmx_asm_do_vmentry)
   40.24          movl $GUEST_RFLAGS,%eax
   40.25          VMWRITE(UREGS_eflags)
   40.26  
   40.27 -        testb $0xff,VCPU_vmx_emul(%ebx)
   40.28 -        jnz  vmx_goto_realmode
   40.29 -
   40.30          cmpb $0,VCPU_vmx_launched(%ebx)
   40.31          je   vmx_launch
   40.32  
    41.1 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S	Mon Feb 25 06:29:01 2008 -0700
    41.2 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S	Tue Feb 26 10:12:04 2008 -0700
    41.3 @@ -105,7 +105,7 @@ ENTRY(vmx_asm_vmexit_handler)
    41.4  
    41.5          ALIGN
    41.6  vmx_process_softirqs:
    41.7 -        sti       
    41.8 +        sti
    41.9          call do_softirq
   41.10          jmp vmx_asm_do_vmentry
   41.11  
   41.12 @@ -121,6 +121,10 @@ ENTRY(vmx_asm_do_vmentry)
   41.13          jnz   vmx_process_softirqs
   41.14  
   41.15          call vmx_intr_assist
   41.16 +
   41.17 +        testb $0xff,VCPU_vmx_emul(%rbx)
   41.18 +        jnz  vmx_goto_realmode
   41.19 +
   41.20          movq VCPU_hvm_guest_cr2(%rbx),%rax
   41.21          movq %rax,%cr2
   41.22          call vmx_trace_vmentry
   41.23 @@ -134,9 +138,6 @@ ENTRY(vmx_asm_do_vmentry)
   41.24          movl $GUEST_RFLAGS,%eax
   41.25          VMWRITE(UREGS_eflags)
   41.26  
   41.27 -        testb $0xff,VCPU_vmx_emul(%rbx)
   41.28 -        jnz  vmx_goto_realmode
   41.29 -
   41.30          cmpb $0,VCPU_vmx_launched(%rbx)
   41.31          je   vmx_launch
   41.32  
    42.1 --- a/xen/arch/x86/mm/shadow/multi.c	Mon Feb 25 06:29:01 2008 -0700
    42.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Tue Feb 26 10:12:04 2008 -0700
    42.3 @@ -761,7 +761,7 @@ static always_inline void
    42.4              sflags |= get_pat_flags(v,
    42.5                                      gflags,
    42.6                                      gfn_to_paddr(target_gfn),
    42.7 -                                    mfn_x(target_mfn) << PAGE_SHIFT);
    42.8 +                                    ((paddr_t)mfn_x(target_mfn)) << PAGE_SHIFT);
    42.9      }
   42.10  
   42.11      // Set the A&D bits for higher level shadows.
    43.1 --- a/xen/arch/x86/oprofile/xenoprof.c	Mon Feb 25 06:29:01 2008 -0700
    43.2 +++ b/xen/arch/x86/oprofile/xenoprof.c	Tue Feb 26 10:12:04 2008 -0700
    43.3 @@ -11,6 +11,9 @@
    43.4  #include <xen/guest_access.h>
    43.5  #include <xen/sched.h>
    43.6  #include <public/xenoprof.h>
    43.7 +#ifdef CONFIG_COMPAT
    43.8 +#include <compat/xenoprof.h>
    43.9 +#endif
   43.10  #include <asm/hvm/support.h>
   43.11  
   43.12  #include "op_counter.h"
   43.13 @@ -35,6 +38,28 @@ int xenoprof_arch_counter(XEN_GUEST_HAND
   43.14      return 0;
   43.15  }
   43.16  
   43.17 +#ifdef CONFIG_COMPAT
   43.18 +int compat_oprof_arch_counter(XEN_GUEST_HANDLE(void) arg)
   43.19 +{
   43.20 +    struct compat_oprof_counter counter;
   43.21 +
   43.22 +    if ( copy_from_guest(&counter, arg, 1) )
   43.23 +        return -EFAULT;
   43.24 +
   43.25 +    if ( counter.ind > OP_MAX_COUNTER )
   43.26 +        return -E2BIG;
   43.27 +
   43.28 +    counter_config[counter.ind].count     = counter.count;
   43.29 +    counter_config[counter.ind].enabled   = counter.enabled;
   43.30 +    counter_config[counter.ind].event     = counter.event;
   43.31 +    counter_config[counter.ind].kernel    = counter.kernel;
   43.32 +    counter_config[counter.ind].user      = counter.user;
   43.33 +    counter_config[counter.ind].unit_mask = counter.unit_mask;
   43.34 +
   43.35 +    return 0;
   43.36 +}
   43.37 +#endif
   43.38 +
   43.39  int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs)
   43.40  {
   43.41      if ( !guest_mode(regs) )
    44.1 --- a/xen/arch/x86/x86_emulate.c	Mon Feb 25 06:29:01 2008 -0700
    44.2 +++ b/xen/arch/x86/x86_emulate.c	Tue Feb 26 10:12:04 2008 -0700
    44.3 @@ -482,7 +482,7 @@ do{ asm volatile (                      
    44.4     if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \
    44.5     _regs.eip += (_size); /* real hardware doesn't truncate */           \
    44.6     generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15,   \
    44.7 -                         EXC_GP);                                       \
    44.8 +                         EXC_GP, 0);                                    \
    44.9     rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt);          \
   44.10     if ( rc ) goto done;                                                 \
   44.11     _x;                                                                  \
   44.12 @@ -505,12 +505,12 @@ do {                                    
   44.13      if ( rc ) goto done;                                \
   44.14  } while (0)
   44.15  
   44.16 -#define generate_exception_if(p, e)                                      \
   44.17 -({  if ( (p) ) {                                                         \
   44.18 -        fail_if(ops->inject_hw_exception == NULL);                       \
   44.19 -        rc = ops->inject_hw_exception(e, 0, ctxt) ? : X86EMUL_EXCEPTION; \
   44.20 -        goto done;                                                       \
   44.21 -    }                                                                    \
   44.22 +#define generate_exception_if(p, e, ec)                                   \
   44.23 +({  if ( (p) ) {                                                          \
   44.24 +        fail_if(ops->inject_hw_exception == NULL);                        \
   44.25 +        rc = ops->inject_hw_exception(e, ec, ctxt) ? : X86EMUL_EXCEPTION; \
   44.26 +        goto done;                                                        \
   44.27 +    }                                                                     \
   44.28  })
   44.29  
   44.30  /*
   44.31 @@ -1023,6 +1023,8 @@ x86_emulate(
   44.32      ea.mem.seg = x86_seg_ds;
   44.33      ea.mem.off = 0;
   44.34  
   44.35 +    ctxt->retire.byte = 0;
   44.36 +
   44.37      op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8;
   44.38      if ( op_bytes == 8 )
   44.39      {
   44.40 @@ -1105,7 +1107,7 @@ x86_emulate(
   44.41      }
   44.42  
   44.43      /* Lock prefix is allowed only on RMW instructions. */
   44.44 -    generate_exception_if((d & Mov) && lock_prefix, EXC_GP);
   44.45 +    generate_exception_if((d & Mov) && lock_prefix, EXC_GP, 0);
   44.46  
   44.47      /* ModRM and SIB bytes. */
   44.48      if ( d & ModRM )
   44.49 @@ -1393,7 +1395,7 @@ x86_emulate(
   44.50      }
   44.51  
   44.52      /* LOCK prefix allowed only on instructions with memory destination. */
   44.53 -    generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP);
   44.54 +    generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP, 0);
   44.55  
   44.56      if ( twobyte )
   44.57          goto twobyte_insn;
   44.58 @@ -1459,14 +1461,15 @@ x86_emulate(
   44.59      case 0x62: /* bound */ {
   44.60          unsigned long src_val2;
   44.61          int lb, ub, idx;
   44.62 -        generate_exception_if(mode_64bit() || (src.type != OP_MEM), EXC_UD);
   44.63 +        generate_exception_if(mode_64bit() || (src.type != OP_MEM),
   44.64 +                              EXC_UD, -1);
   44.65          if ( (rc = ops->read(src.mem.seg, src.mem.off + op_bytes,
   44.66                               &src_val2, op_bytes, ctxt)) )
   44.67              goto done;
   44.68          ub  = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2;
   44.69          lb  = (op_bytes == 2) ? (int16_t)src.val  : (int32_t)src.val;
   44.70          idx = (op_bytes == 2) ? (int16_t)dst.val  : (int32_t)dst.val;
   44.71 -        generate_exception_if((idx < lb) || (idx > ub), EXC_BR);
   44.72 +        generate_exception_if((idx < lb) || (idx > ub), EXC_BR, -1);
   44.73          dst.type = OP_NONE;
   44.74          break;
   44.75      }
   44.76 @@ -1493,7 +1496,7 @@ x86_emulate(
   44.77                  dst.val  = (dst.val & ~3) | (src_val & 3);
   44.78              else
   44.79                  dst.type = OP_NONE;
   44.80 -            generate_exception_if(in_realmode(ctxt, ops), EXC_UD);
   44.81 +            generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1);
   44.82          }
   44.83          break;
   44.84  
   44.85 @@ -1534,7 +1537,7 @@ x86_emulate(
   44.86      }
   44.87  
   44.88      case 0x82: /* Grp1 (x86/32 only) */
   44.89 -        generate_exception_if(mode_64bit(), EXC_UD);
   44.90 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
   44.91      case 0x80: case 0x81: case 0x83: /* Grp1 */
   44.92          switch ( modrm_reg & 7 )
   44.93          {
   44.94 @@ -1571,7 +1574,7 @@ x86_emulate(
   44.95          break;
   44.96  
   44.97      case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
   44.98 -        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
   44.99 +        generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1);
  44.100      case 0x88 ... 0x8b: /* mov */
  44.101          dst.val = src.val;
  44.102          break;
  44.103 @@ -1579,7 +1582,7 @@ x86_emulate(
  44.104      case 0x8c: /* mov Sreg,r/m */ {
  44.105          struct segment_register reg;
  44.106          enum x86_segment seg = decode_segment(modrm_reg);
  44.107 -        generate_exception_if(seg == decode_segment_failed, EXC_UD);
  44.108 +        generate_exception_if(seg == decode_segment_failed, EXC_UD, -1);
  44.109          fail_if(ops->read_segment == NULL);
  44.110          if ( (rc = ops->read_segment(seg, &reg, ctxt)) != 0 )
  44.111              goto done;
  44.112 @@ -1591,9 +1594,11 @@ x86_emulate(
  44.113  
  44.114      case 0x8e: /* mov r/m,Sreg */ {
  44.115          enum x86_segment seg = decode_segment(modrm_reg);
  44.116 -        generate_exception_if(seg == decode_segment_failed, EXC_UD);
  44.117 +        generate_exception_if(seg == decode_segment_failed, EXC_UD, -1);
  44.118          if ( (rc = load_seg(seg, (uint16_t)src.val, ctxt, ops)) != 0 )
  44.119              goto done;
  44.120 +        if ( seg == x86_seg_ss )
  44.121 +            ctxt->retire.flags.mov_ss = 1;
  44.122          dst.type = OP_NONE;
  44.123          break;
  44.124      }
  44.125 @@ -1603,7 +1608,7 @@ x86_emulate(
  44.126          break;
  44.127  
  44.128      case 0x8f: /* pop (sole member of Grp1a) */
  44.129 -        generate_exception_if((modrm_reg & 7) != 0, EXC_UD);
  44.130 +        generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1);
  44.131          /* 64-bit mode: POP defaults to a 64-bit operand. */
  44.132          if ( mode_64bit() && (dst.bytes == 4) )
  44.133              dst.bytes = 8;
  44.134 @@ -1659,7 +1664,7 @@ x86_emulate(
  44.135          unsigned long sel;
  44.136          dst.val = x86_seg_es;
  44.137      les: /* dst.val identifies the segment */
  44.138 -        generate_exception_if(src.type != OP_MEM, EXC_UD);
  44.139 +        generate_exception_if(src.type != OP_MEM, EXC_UD, -1);
  44.140          if ( (rc = ops->read(src.mem.seg, src.mem.off + src.bytes,
  44.141                               &sel, 2, ctxt)) != 0 )
  44.142              goto done;
  44.143 @@ -1797,7 +1802,7 @@ x86_emulate(
  44.144                  v    = (uint8_t)src.val;
  44.145                  generate_exception_if(
  44.146                      div_dbl(u, v) || ((uint8_t)u[0] != (uint16_t)u[0]),
  44.147 -                    EXC_DE);
  44.148 +                    EXC_DE, -1);
  44.149                  dst.val = (uint8_t)u[0];
  44.150                  ((uint8_t *)&_regs.eax)[1] = u[1];
  44.151                  break;
  44.152 @@ -1807,7 +1812,7 @@ x86_emulate(
  44.153                  v    = (uint16_t)src.val;
  44.154                  generate_exception_if(
  44.155                      div_dbl(u, v) || ((uint16_t)u[0] != (uint32_t)u[0]),
  44.156 -                    EXC_DE);
  44.157 +                    EXC_DE, -1);
  44.158                  dst.val = (uint16_t)u[0];
  44.159                  *(uint16_t *)&_regs.edx = u[1];
  44.160                  break;
  44.161 @@ -1818,7 +1823,7 @@ x86_emulate(
  44.162                  v    = (uint32_t)src.val;
  44.163                  generate_exception_if(
  44.164                      div_dbl(u, v) || ((uint32_t)u[0] != u[0]),
  44.165 -                    EXC_DE);
  44.166 +                    EXC_DE, -1);
  44.167                  dst.val   = (uint32_t)u[0];
  44.168                  _regs.edx = (uint32_t)u[1];
  44.169                  break;
  44.170 @@ -1827,7 +1832,7 @@ x86_emulate(
  44.171                  u[0] = _regs.eax;
  44.172                  u[1] = _regs.edx;
  44.173                  v    = src.val;
  44.174 -                generate_exception_if(div_dbl(u, v), EXC_DE);
  44.175 +                generate_exception_if(div_dbl(u, v), EXC_DE, -1);
  44.176                  dst.val   = u[0];
  44.177                  _regs.edx = u[1];
  44.178                  break;
  44.179 @@ -1847,7 +1852,7 @@ x86_emulate(
  44.180                  v    = (int8_t)src.val;
  44.181                  generate_exception_if(
  44.182                      idiv_dbl(u, v) || ((int8_t)u[0] != (int16_t)u[0]),
  44.183 -                    EXC_DE);
  44.184 +                    EXC_DE, -1);
  44.185                  dst.val = (int8_t)u[0];
  44.186                  ((int8_t *)&_regs.eax)[1] = u[1];
  44.187                  break;
  44.188 @@ -1857,7 +1862,7 @@ x86_emulate(
  44.189                  v    = (int16_t)src.val;
  44.190                  generate_exception_if(
  44.191                      idiv_dbl(u, v) || ((int16_t)u[0] != (int32_t)u[0]),
  44.192 -                    EXC_DE);
  44.193 +                    EXC_DE, -1);
  44.194                  dst.val = (int16_t)u[0];
  44.195                  *(int16_t *)&_regs.edx = u[1];
  44.196                  break;
  44.197 @@ -1868,7 +1873,7 @@ x86_emulate(
  44.198                  v    = (int32_t)src.val;
  44.199                  generate_exception_if(
  44.200                      idiv_dbl(u, v) || ((int32_t)u[0] != u[0]),
  44.201 -                    EXC_DE);
  44.202 +                    EXC_DE, -1);
  44.203                  dst.val   = (int32_t)u[0];
  44.204                  _regs.edx = (uint32_t)u[1];
  44.205                  break;
  44.206 @@ -1877,7 +1882,7 @@ x86_emulate(
  44.207                  u[0] = _regs.eax;
  44.208                  u[1] = _regs.edx;
  44.209                  v    = src.val;
  44.210 -                generate_exception_if(idiv_dbl(u, v), EXC_DE);
  44.211 +                generate_exception_if(idiv_dbl(u, v), EXC_DE, -1);
  44.212                  dst.val   = u[0];
  44.213                  _regs.edx = u[1];
  44.214                  break;
  44.215 @@ -1890,7 +1895,7 @@ x86_emulate(
  44.216          break;
  44.217  
  44.218      case 0xfe: /* Grp4 */
  44.219 -        generate_exception_if((modrm_reg & 7) >= 2, EXC_UD);
  44.220 +        generate_exception_if((modrm_reg & 7) >= 2, EXC_UD, -1);
  44.221      case 0xff: /* Grp5 */
  44.222          switch ( modrm_reg & 7 )
  44.223          {
  44.224 @@ -1921,7 +1926,7 @@ x86_emulate(
  44.225          case 5: /* jmp (far, absolute indirect) */ {
  44.226              unsigned long sel;
  44.227  
  44.228 -            generate_exception_if(dst.type != OP_MEM, EXC_UD);
  44.229 +            generate_exception_if(dst.type != OP_MEM, EXC_UD, -1);
  44.230  
  44.231              if ( (rc = ops->read(dst.mem.seg, dst.mem.off+dst.bytes,
  44.232                                   &sel, 2, ctxt)) )
  44.233 @@ -1963,7 +1968,7 @@ x86_emulate(
  44.234              dst.type = OP_NONE;
  44.235              break;
  44.236          case 7:
  44.237 -            generate_exception_if(1, EXC_UD);
  44.238 +            generate_exception_if(1, EXC_UD, -1);
  44.239          default:
  44.240              goto cannot_emulate;
  44.241          }
  44.242 @@ -2003,11 +2008,9 @@ x86_emulate(
  44.243      /* Commit shadow register state. */
  44.244      _regs.eflags &= ~EFLG_RF;
  44.245      *ctxt->regs = _regs;
  44.246 -
  44.247 -    if ( (_regs.eflags & EFLG_TF) &&
  44.248 -         (rc == X86EMUL_OKAY) &&
  44.249 +    if ( (_regs.eflags & EFLG_TF) && (rc == X86EMUL_OKAY) &&
  44.250           (ops->inject_hw_exception != NULL) )
  44.251 -        rc = ops->inject_hw_exception(EXC_DB, 0, ctxt) ? : X86EMUL_EXCEPTION;
  44.252 +        rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION;
  44.253  
  44.254   done:
  44.255      return rc;
  44.256 @@ -2022,7 +2025,7 @@ x86_emulate(
  44.257      generate_exception_if(lock_prefix &&
  44.258                            ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */
  44.259                            (b != 0xc7),                  /* CMPXCHG{8,16}B */
  44.260 -                          EXC_GP);
  44.261 +                          EXC_GP, 0);
  44.262  
  44.263      if ( twobyte )
  44.264          goto twobyte_special_insn;
  44.265 @@ -2069,6 +2072,7 @@ x86_emulate(
  44.266  
  44.267      case 0x17: /* pop %%ss */
  44.268          src.val = x86_seg_ss;
  44.269 +        ctxt->retire.flags.mov_ss = 1;
  44.270          goto pop_seg;
  44.271  
  44.272      case 0x1e: /* push %%ds */
  44.273 @@ -2082,7 +2086,7 @@ x86_emulate(
  44.274      case 0x27: /* daa */ {
  44.275          uint8_t al = _regs.eax;
  44.276          unsigned long eflags = _regs.eflags;
  44.277 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.278 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.279          _regs.eflags &= ~(EFLG_CF|EFLG_AF);
  44.280          if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
  44.281          {
  44.282 @@ -2104,7 +2108,7 @@ x86_emulate(
  44.283      case 0x2f: /* das */ {
  44.284          uint8_t al = _regs.eax;
  44.285          unsigned long eflags = _regs.eflags;
  44.286 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.287 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.288          _regs.eflags &= ~(EFLG_CF|EFLG_AF);
  44.289          if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
  44.290          {
  44.291 @@ -2127,7 +2131,7 @@ x86_emulate(
  44.292  
  44.293      case 0x37: /* aaa */
  44.294      case 0x3f: /* aas */
  44.295 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.296 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.297          _regs.eflags &= ~EFLG_CF;
  44.298          if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) )
  44.299          {
  44.300 @@ -2171,7 +2175,7 @@ x86_emulate(
  44.301          unsigned long regs[] = {
  44.302              _regs.eax, _regs.ecx, _regs.edx, _regs.ebx,
  44.303              _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
  44.304 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.305 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.306          for ( i = 0; i < 8; i++ )
  44.307              if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
  44.308                                    regs[i], op_bytes, ctxt)) != 0 )
  44.309 @@ -2186,7 +2190,7 @@ x86_emulate(
  44.310              (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp,
  44.311              (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx,
  44.312              (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
  44.313 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.314 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.315          for ( i = 0; i < 8; i++ )
  44.316          {
  44.317              if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
  44.318 @@ -2224,7 +2228,7 @@ x86_emulate(
  44.319  
  44.320      case 0x6c ... 0x6d: /* ins %dx,%es:%edi */ {
  44.321          unsigned long nr_reps = get_rep_prefix();
  44.322 -        generate_exception_if(!mode_iopl(), EXC_GP);
  44.323 +        generate_exception_if(!mode_iopl(), EXC_GP, 0);
  44.324          dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
  44.325          dst.mem.seg = x86_seg_es;
  44.326          dst.mem.off = truncate_ea(_regs.edi);
  44.327 @@ -2254,7 +2258,7 @@ x86_emulate(
  44.328  
  44.329      case 0x6e ... 0x6f: /* outs %esi,%dx */ {
  44.330          unsigned long nr_reps = get_rep_prefix();
  44.331 -        generate_exception_if(!mode_iopl(), EXC_GP);
  44.332 +        generate_exception_if(!mode_iopl(), EXC_GP, 0);
  44.333          dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
  44.334          if ( (nr_reps > 1) && (ops->rep_outs != NULL) &&
  44.335               ((rc = ops->rep_outs(ea.mem.seg, truncate_ea(_regs.esi),
  44.336 @@ -2333,7 +2337,7 @@ x86_emulate(
  44.337          uint32_t eip;
  44.338  
  44.339          fail_if(ops->read_segment == NULL);
  44.340 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.341 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.342  
  44.343          eip = insn_fetch_bytes(op_bytes);
  44.344          sel = insn_fetch_type(uint16_t);
  44.345 @@ -2359,7 +2363,6 @@ x86_emulate(
  44.346          uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM;
  44.347          if ( !mode_iopl() )
  44.348              mask |= EFLG_IOPL;
  44.349 -        fail_if(ops->write_rflags == NULL);
  44.350          /* 64-bit mode: POP defaults to a 64-bit operand. */
  44.351          if ( mode_64bit() && (op_bytes == 4) )
  44.352              op_bytes = 8;
  44.353 @@ -2371,8 +2374,6 @@ x86_emulate(
  44.354          dst.val &= 0x257fd5;
  44.355          _regs.eflags &= mask;
  44.356          _regs.eflags |= (uint32_t)(dst.val & ~mask) | 0x02;
  44.357 -        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
  44.358 -            goto done;
  44.359          break;
  44.360      }
  44.361  
  44.362 @@ -2597,7 +2598,7 @@ x86_emulate(
  44.363          goto done;
  44.364  
  44.365      case 0xce: /* into */
  44.366 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.367 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.368          if ( !(_regs.eflags & EFLG_OF) )
  44.369              break;
  44.370          src.val = EXC_OF;
  44.371 @@ -2609,7 +2610,6 @@ x86_emulate(
  44.372          if ( !mode_iopl() )
  44.373              mask |= EFLG_IOPL;
  44.374          fail_if(!in_realmode(ctxt, ops));
  44.375 -        fail_if(ops->write_rflags == NULL);
  44.376          if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
  44.377                               &eip, op_bytes, ctxt)) ||
  44.378               (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
  44.379 @@ -2622,8 +2622,6 @@ x86_emulate(
  44.380          eflags &= 0x257fd5;
  44.381          _regs.eflags &= mask;
  44.382          _regs.eflags |= (uint32_t)(eflags & ~mask) | 0x02;
  44.383 -        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
  44.384 -            goto done;
  44.385          _regs.eip = eip;
  44.386          if ( (rc = load_seg(x86_seg_cs, (uint16_t)cs, ctxt, ops)) != 0 )
  44.387              goto done;
  44.388 @@ -2633,8 +2631,8 @@ x86_emulate(
  44.389      case 0xd4: /* aam */ {
  44.390          unsigned int base = insn_fetch_type(uint8_t);
  44.391          uint8_t al = _regs.eax;
  44.392 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.393 -        generate_exception_if(base == 0, EXC_DE);
  44.394 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.395 +        generate_exception_if(base == 0, EXC_DE, -1);
  44.396          *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base);
  44.397          _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
  44.398          _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
  44.399 @@ -2646,7 +2644,7 @@ x86_emulate(
  44.400      case 0xd5: /* aad */ {
  44.401          unsigned int base = insn_fetch_type(uint8_t);
  44.402          uint16_t ax = _regs.eax;
  44.403 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.404 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.405          *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base));
  44.406          _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF);
  44.407          _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0;
  44.408 @@ -2656,7 +2654,7 @@ x86_emulate(
  44.409      }
  44.410  
  44.411      case 0xd6: /* salc */
  44.412 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.413 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.414          *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00;
  44.415          break;
  44.416  
  44.417 @@ -2673,7 +2671,7 @@ x86_emulate(
  44.418          fail_if(ops->load_fpu_ctxt == NULL);
  44.419          ops->load_fpu_ctxt(ctxt);
  44.420          fail_if((modrm_reg & 7) != 7);
  44.421 -        fail_if(modrm_reg >= 0xc0);
  44.422 +        fail_if(modrm >= 0xc0);
  44.423          /* fnstcw m2byte */
  44.424          ea.bytes = 2;
  44.425          dst = ea;
  44.426 @@ -2692,7 +2690,7 @@ x86_emulate(
  44.427          fail_if(ops->load_fpu_ctxt == NULL);
  44.428          ops->load_fpu_ctxt(ctxt);
  44.429          fail_if((modrm_reg & 7) != 7);
  44.430 -        fail_if(modrm_reg >= 0xc0);
  44.431 +        fail_if(modrm >= 0xc0);
  44.432          /* fnstsw m2byte */
  44.433          ea.bytes = 2;
  44.434          dst = ea;
  44.435 @@ -2743,7 +2741,7 @@ x86_emulate(
  44.436          unsigned int port = ((b < 0xe8)
  44.437                               ? insn_fetch_type(uint8_t)
  44.438                               : (uint16_t)_regs.edx);
  44.439 -        generate_exception_if(!mode_iopl(), EXC_GP);
  44.440 +        generate_exception_if(!mode_iopl(), EXC_GP, 0);
  44.441          op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes;
  44.442          if ( b & 2 )
  44.443          {
  44.444 @@ -2787,7 +2785,7 @@ x86_emulate(
  44.445      case 0xea: /* jmp (far, absolute) */ {
  44.446          uint16_t sel;
  44.447          uint32_t eip;
  44.448 -        generate_exception_if(mode_64bit(), EXC_UD);
  44.449 +        generate_exception_if(mode_64bit(), EXC_UD, -1);
  44.450          eip = insn_fetch_bytes(op_bytes);
  44.451          sel = insn_fetch_type(uint16_t);
  44.452          if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 )
  44.453 @@ -2807,9 +2805,7 @@ x86_emulate(
  44.454          goto swint;
  44.455  
  44.456      case 0xf4: /* hlt */
  44.457 -        fail_if(ops->hlt == NULL);
  44.458 -        if ( (rc = ops->hlt(ctxt)) != 0 )
  44.459 -            goto done;
  44.460 +        ctxt->retire.flags.hlt = 1;
  44.461          break;
  44.462  
  44.463      case 0xf5: /* cmc */
  44.464 @@ -2825,14 +2821,17 @@ x86_emulate(
  44.465          break;
  44.466  
  44.467      case 0xfa: /* cli */
  44.468 -    case 0xfb: /* sti */
  44.469 -        generate_exception_if(!mode_iopl(), EXC_GP);
  44.470 -        fail_if(ops->write_rflags == NULL);
  44.471 +        generate_exception_if(!mode_iopl(), EXC_GP, 0);
  44.472          _regs.eflags &= ~EFLG_IF;
  44.473 -        if ( b == 0xfb ) /* sti */
  44.474 +        break;
  44.475 +
  44.476 +    case 0xfb: /* sti */
  44.477 +        generate_exception_if(!mode_iopl(), EXC_GP, 0);
  44.478 +        if ( !(_regs.eflags & EFLG_IF) )
  44.479 +        {
  44.480              _regs.eflags |= EFLG_IF;
  44.481 -        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
  44.482 -            goto done;
  44.483 +            ctxt->retire.flags.sti = 1;
  44.484 +        }
  44.485          break;
  44.486  
  44.487      case 0xfc: /* cld */
  44.488 @@ -3001,7 +3000,7 @@ x86_emulate(
  44.489          case 5: goto bts;
  44.490          case 6: goto btr;
  44.491          case 7: goto btc;
  44.492 -        default: generate_exception_if(1, EXC_UD);
  44.493 +        default: generate_exception_if(1, EXC_UD, -1);
  44.494          }
  44.495          break;
  44.496  
  44.497 @@ -3038,8 +3037,8 @@ x86_emulate(
  44.498  
  44.499          if ( modrm == 0xdf ) /* invlpga */
  44.500          {
  44.501 -            generate_exception_if(in_realmode(ctxt, ops), EXC_UD);
  44.502 -            generate_exception_if(!mode_ring0(), EXC_GP);
  44.503 +            generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1);
  44.504 +            generate_exception_if(!mode_ring0(), EXC_GP, 0);
  44.505              fail_if(ops->invlpg == NULL);
  44.506              if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax),
  44.507                                     ctxt)) )
  44.508 @@ -3051,7 +3050,7 @@ x86_emulate(
  44.509          {
  44.510          case 0: /* sgdt */
  44.511          case 1: /* sidt */
  44.512 -            generate_exception_if(ea.type != OP_MEM, EXC_UD);
  44.513 +            generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
  44.514              fail_if(ops->read_segment == NULL);
  44.515              if ( (rc = ops->read_segment((modrm_reg & 1) ?
  44.516                                           x86_seg_idtr : x86_seg_gdtr,
  44.517 @@ -3067,7 +3066,7 @@ x86_emulate(
  44.518              break;
  44.519          case 2: /* lgdt */
  44.520          case 3: /* lidt */
  44.521 -            generate_exception_if(ea.type != OP_MEM, EXC_UD);
  44.522 +            generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
  44.523              fail_if(ops->write_segment == NULL);
  44.524              memset(&reg, 0, sizeof(reg));
  44.525              if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0,
  44.526 @@ -3108,8 +3107,8 @@ x86_emulate(
  44.527                  goto done;
  44.528              break;
  44.529          case 7: /* invlpg */
  44.530 -            generate_exception_if(!mode_ring0(), EXC_GP);
  44.531 -            generate_exception_if(ea.type != OP_MEM, EXC_UD);
  44.532 +            generate_exception_if(!mode_ring0(), EXC_GP, 0);
  44.533 +            generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
  44.534              fail_if(ops->invlpg == NULL);
  44.535              if ( (rc = ops->invlpg(ea.mem.seg, ea.mem.off, ctxt)) )
  44.536                  goto done;
  44.537 @@ -3121,7 +3120,7 @@ x86_emulate(
  44.538      }
  44.539  
  44.540      case 0x06: /* clts */
  44.541 -        generate_exception_if(!mode_ring0(), EXC_GP);
  44.542 +        generate_exception_if(!mode_ring0(), EXC_GP, 0);
  44.543          fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL));
  44.544          if ( (rc = ops->read_cr(0, &dst.val, ctxt)) ||
  44.545               (rc = ops->write_cr(0, dst.val&~8, ctxt)) )
  44.546 @@ -3130,7 +3129,7 @@ x86_emulate(
  44.547  
  44.548      case 0x08: /* invd */
  44.549      case 0x09: /* wbinvd */
  44.550 -        generate_exception_if(!mode_ring0(), EXC_GP);
  44.551 +        generate_exception_if(!mode_ring0(), EXC_GP, 0);
  44.552          fail_if(ops->wbinvd == NULL);
  44.553          if ( (rc = ops->wbinvd(ctxt)) != 0 )
  44.554              goto done;
  44.555 @@ -3145,7 +3144,7 @@ x86_emulate(
  44.556      case 0x21: /* mov dr,reg */
  44.557      case 0x22: /* mov reg,cr */
  44.558      case 0x23: /* mov reg,dr */
  44.559 -        generate_exception_if(!mode_ring0(), EXC_GP);
  44.560 +        generate_exception_if(!mode_ring0(), EXC_GP, 0);
  44.561          modrm_rm  |= (rex_prefix & 1) << 3;
  44.562          modrm_reg |= lock_prefix << 3;
  44.563          if ( b & 2 )
  44.564 @@ -3182,7 +3181,7 @@ x86_emulate(
  44.565  
  44.566      case 0x30: /* wrmsr */ {
  44.567          uint64_t val = ((uint64_t)_regs.edx << 32) | (uint32_t)_regs.eax;
  44.568 -        generate_exception_if(!mode_ring0(), EXC_GP);
  44.569 +        generate_exception_if(!mode_ring0(), EXC_GP, 0);
  44.570          fail_if(ops->write_msr == NULL);
  44.571          if ( (rc = ops->write_msr((uint32_t)_regs.ecx, val, ctxt)) != 0 )
  44.572              goto done;
  44.573 @@ -3195,7 +3194,7 @@ x86_emulate(
  44.574          fail_if(ops->read_cr == NULL);
  44.575          if ( (rc = ops->read_cr(4, &cr4, ctxt)) )
  44.576              goto done;
  44.577 -        generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP);
  44.578 +        generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP, 0);
  44.579          fail_if(ops->read_msr == NULL);
  44.580          if ( (rc = ops->read_msr(MSR_TSC, &val, ctxt)) != 0 )
  44.581              goto done;
  44.582 @@ -3206,7 +3205,7 @@ x86_emulate(
  44.583  
  44.584      case 0x32: /* rdmsr */ {
  44.585          uint64_t val;
  44.586 -        generate_exception_if(!mode_ring0(), EXC_GP);
  44.587 +        generate_exception_if(!mode_ring0(), EXC_GP, 0);
  44.588          fail_if(ops->read_msr == NULL);
  44.589          if ( (rc = ops->read_msr((uint32_t)_regs.ecx, &val, ctxt)) != 0 )
  44.590              goto done;
  44.591 @@ -3255,8 +3254,8 @@ x86_emulate(
  44.592  #if defined(__i386__)
  44.593      {
  44.594          unsigned long old_lo, old_hi;
  44.595 -        generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
  44.596 -        generate_exception_if(ea.type != OP_MEM, EXC_UD);
  44.597 +        generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1);
  44.598 +        generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
  44.599          if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &old_lo, 4, ctxt)) ||
  44.600               (rc = ops->read(ea.mem.seg, ea.mem.off+4, &old_hi, 4, ctxt)) )
  44.601              goto done;
  44.602 @@ -3283,8 +3282,8 @@ x86_emulate(
  44.603  #elif defined(__x86_64__)
  44.604      {
  44.605          unsigned long old, new;
  44.606 -        generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
  44.607 -        generate_exception_if(ea.type != OP_MEM, EXC_UD);
  44.608 +        generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1);
  44.609 +        generate_exception_if(ea.type != OP_MEM, EXC_UD, -1);
  44.610          if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 )
  44.611              goto done;
  44.612          if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
    45.1 --- a/xen/common/compat/xenoprof.c	Mon Feb 25 06:29:01 2008 -0700
    45.2 +++ b/xen/common/compat/xenoprof.c	Tue Feb 26 10:12:04 2008 -0700
    45.3 @@ -14,6 +14,7 @@ CHECK_oprof_init;
    45.4  
    45.5  #define xenoprof_get_buffer compat_oprof_get_buffer
    45.6  #define xenoprof_op_get_buffer compat_oprof_op_get_buffer
    45.7 +#define xenoprof_arch_counter compat_oprof_arch_counter
    45.8  
    45.9  #define xen_domid_t domid_t
   45.10  #define compat_domid_t domid_compat_t
    46.1 --- a/xen/common/grant_table.c	Mon Feb 25 06:29:01 2008 -0700
    46.2 +++ b/xen/common/grant_table.c	Tue Feb 26 10:12:04 2008 -0700
    46.3 @@ -350,10 +350,10 @@ static void
    46.4      else
    46.5      {
    46.6          if ( unlikely(!mfn_valid(frame)) ||
    46.7 -             unlikely(!((op->flags & GNTMAP_readonly) ?
    46.8 -                        get_page(mfn_to_page(frame), rd) :
    46.9 +             unlikely(!(gnttab_host_mapping_get_page_type(op, ld, rd) ?
   46.10                          get_page_and_type(mfn_to_page(frame), rd,
   46.11 -                                          PGT_writable_page))) )
   46.12 +                                          PGT_writable_page) :
   46.13 +                        get_page(mfn_to_page(frame), rd))) )
   46.14          {
   46.15              if ( !rd->is_dying )
   46.16                  gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n",
   46.17 @@ -367,7 +367,7 @@ static void
   46.18              rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0);
   46.19              if ( rc != GNTST_okay )
   46.20              {
   46.21 -                if ( !(op->flags & GNTMAP_readonly) )
   46.22 +                if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
   46.23                      put_page_type(mfn_to_page(frame));
   46.24                  put_page(mfn_to_page(frame));
   46.25                  goto undo_out;
   46.26 @@ -604,7 +604,7 @@ static void
   46.27  
   46.28          if ( !is_iomem_page(op->frame) ) 
   46.29          {
   46.30 -            if ( !(op->flags & GNTMAP_readonly) )
   46.31 +            if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
   46.32                  put_page_type(mfn_to_page(op->frame));
   46.33              put_page(mfn_to_page(op->frame));
   46.34          }
   46.35 @@ -1662,8 +1662,9 @@ gnttab_release_mappings(
   46.36              {
   46.37                  BUG_ON(!(act->pin & GNTPIN_hstr_mask));
   46.38                  act->pin -= GNTPIN_hstr_inc;
   46.39 -                if ( !is_iomem_page(act->frame) )
   46.40 -                    gnttab_release_put_page(mfn_to_page(act->frame));
   46.41 +                if ( gnttab_release_host_mappings &&
   46.42 +                     !is_iomem_page(act->frame) )
   46.43 +                    put_page(mfn_to_page(act->frame));
   46.44              }
   46.45          }
   46.46          else
   46.47 @@ -1680,8 +1681,13 @@ gnttab_release_mappings(
   46.48              {
   46.49                  BUG_ON(!(act->pin & GNTPIN_hstw_mask));
   46.50                  act->pin -= GNTPIN_hstw_inc;
   46.51 -                if ( !is_iomem_page(act->frame) )
   46.52 -                    gnttab_release_put_page_and_type(mfn_to_page(act->frame));
   46.53 +                if ( gnttab_release_host_mappings &&
   46.54 +                     !is_iomem_page(act->frame) )
   46.55 +                {
   46.56 +                    if ( gnttab_host_mapping_get_page_type(map, d, rd) )
   46.57 +                        put_page_type(mfn_to_page(act->frame));
   46.58 +                    put_page(mfn_to_page(act->frame));
   46.59 +                }
   46.60              }
   46.61  
   46.62              if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
    47.1 --- a/xen/include/asm-ia64/grant_table.h	Mon Feb 25 06:29:01 2008 -0700
    47.2 +++ b/xen/include/asm-ia64/grant_table.h	Tue Feb 26 10:12:04 2008 -0700
    47.3 @@ -65,8 +65,10 @@ static inline void gnttab_clear_flag(uns
    47.4  	clear_bit(nr, addr);
    47.5  }
    47.6  
    47.7 -#define gnttab_release_put_page(page)           put_page((page))
    47.8 -#define gnttab_release_put_page_and_type(page)  put_page_and_type((page))
    47.9 +#define gnttab_host_mapping_get_page_type(op, ld, rd)   \
   47.10 +    (!((op)->flags & GNTMAP_readonly))
   47.11 +
   47.12 +#define gnttab_release_host_mappings 1
   47.13  
   47.14  static inline int replace_grant_supported(void)
   47.15  {
    48.1 --- a/xen/include/asm-powerpc/grant_table.h	Mon Feb 25 06:29:01 2008 -0700
    48.2 +++ b/xen/include/asm-powerpc/grant_table.h	Tue Feb 26 10:12:04 2008 -0700
    48.3 @@ -76,17 +76,14 @@ static inline uint cpu_foreign_map_order
    48.4      return 34 - PAGE_SHIFT;
    48.5  }
    48.6  
    48.7 -#if 0
    48.8 +#define gnttab_host_mapping_get_page_type(op, ld, rd)   \
    48.9 +    (!((op)->flags & GNTMAP_readonly))
   48.10 +
   48.11  /*
   48.12   * without put_page()/put_page_and_type() page might be leaked.
   48.13   * with put_page()/put_page_and_type() freed page might be accessed.
   48.14   */
   48.15 -#define gnttab_release_put_page(page)           put_page((page))
   48.16 -#define gnttab_release_put_page_and_type(page)  put_page_and_type((page))
   48.17 -#else
   48.18 -#define gnttab_release_put_page(page)           do { } while (0)
   48.19 -#define gnttab_release_put_page_and_type(page)  do { } while (0)
   48.20 -#endif
   48.21 +#define gnttab_release_host_mappings 0
   48.22  
   48.23  static inline int replace_grant_supported(void)
   48.24  {
    49.1 --- a/xen/include/asm-x86/grant_table.h	Mon Feb 25 06:29:01 2008 -0700
    49.2 +++ b/xen/include/asm-x86/grant_table.h	Tue Feb 26 10:12:04 2008 -0700
    49.3 @@ -38,15 +38,13 @@ static inline void gnttab_clear_flag(uns
    49.4      clear_bit(nr, addr);
    49.5  }
    49.6  
    49.7 -#define gnttab_release_put_page(page)                           \
    49.8 -    do {                                                        \
    49.9 -        /* Done implicitly when page tables are destroyed. */   \
   49.10 -    } while (0)
   49.11 +/* Foreign mappings of HHVM-guest pages do not modify the type count. */
   49.12 +#define gnttab_host_mapping_get_page_type(op, ld, rd)   \
   49.13 +    (!((op)->flags & GNTMAP_readonly) &&                \
   49.14 +     (((ld) == (rd)) || !paging_mode_external(rd)))
   49.15  
   49.16 -#define gnttab_release_put_page_and_type(page)                  \
   49.17 -    do {                                                        \
   49.18 -        /* Done implicitly when page tables are destroyed. */   \
   49.19 -    } while (0)
   49.20 +/* Done implicitly when page tables are destroyed. */
   49.21 +#define gnttab_release_host_mappings 0
   49.22  
   49.23  static inline int replace_grant_supported(void)
   49.24  {
    50.1 --- a/xen/include/asm-x86/hvm/emulate.h	Mon Feb 25 06:29:01 2008 -0700
    50.2 +++ b/xen/include/asm-x86/hvm/emulate.h	Tue Feb 26 10:12:04 2008 -0700
    50.3 @@ -27,18 +27,12 @@ struct hvm_emulate_ctxt {
    50.4      unsigned long seg_reg_accessed;
    50.5      unsigned long seg_reg_dirty;
    50.6  
    50.7 -    union {
    50.8 -        struct {
    50.9 -            unsigned int hlt:1;
   50.10 -            unsigned int mov_ss:1;
   50.11 -            unsigned int sti:1;
   50.12 -            unsigned int exn_pending:1;
   50.13 -        } flags;
   50.14 -        unsigned int flag_word;
   50.15 -    };
   50.16 -
   50.17 +    bool_t exn_pending;
   50.18      uint8_t exn_vector;
   50.19      uint8_t exn_insn_len;
   50.20 +    int32_t exn_error_code;
   50.21 +
   50.22 +    uint32_t intr_shadow;
   50.23  };
   50.24  
   50.25  int hvm_emulate_one(
    51.1 --- a/xen/include/asm-x86/hvm/hvm.h	Mon Feb 25 06:29:01 2008 -0700
    51.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Tue Feb 26 10:12:04 2008 -0700
    51.3 @@ -49,6 +49,12 @@ enum hvm_intblk {
    51.4      hvm_intblk_nmi_iret   /* NMI blocked until IRET */
    51.5  };
    51.6  
    51.7 +/* These happen to be the same as the VMX interrupt shadow definitions. */
    51.8 +#define HVM_INTR_SHADOW_STI    0x00000001
    51.9 +#define HVM_INTR_SHADOW_MOV_SS 0x00000002
   51.10 +#define HVM_INTR_SHADOW_SMI    0x00000004
   51.11 +#define HVM_INTR_SHADOW_NMI    0x00000008
   51.12 +
   51.13  /*
   51.14   * The hardware virtual machine (HVM) interface abstracts away from the
   51.15   * x86/x86_64 CPU virtualization assist specifics. Currently this interface
   51.16 @@ -72,14 +78,9 @@ struct hvm_function_table {
   51.17      void (*save_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
   51.18      int (*load_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt);
   51.19  
   51.20 -    /*
   51.21 -     * Examine specifics of the guest state:
   51.22 -     * 1) determine whether interrupts are enabled or not
   51.23 -     * 2) determine the mode the guest is running in
   51.24 -     * 3) return the current guest segment descriptor base
   51.25 -     * 4) return the current guest segment descriptor
   51.26 -     */
   51.27 -    enum hvm_intblk (*interrupt_blocked)(struct vcpu *v, struct hvm_intack);
   51.28 +    /* Examine specifics of the guest state. */
   51.29 +    unsigned int (*get_interrupt_shadow)(struct vcpu *v);
   51.30 +    void (*set_interrupt_shadow)(struct vcpu *v, unsigned int intr_shadow);
   51.31      int (*guest_x86_mode)(struct vcpu *v);
   51.32      void (*get_segment_register)(struct vcpu *v, enum x86_segment seg,
   51.33                                   struct segment_register *reg);
    52.1 --- a/xen/include/asm-x86/x86_emulate.h	Mon Feb 25 06:29:01 2008 -0700
    52.2 +++ b/xen/include/asm-x86/x86_emulate.h	Tue Feb 26 10:12:04 2008 -0700
    52.3 @@ -318,11 +318,6 @@ struct x86_emulate_ops
    52.4          uint64_t val,
    52.5          struct x86_emulate_ctxt *ctxt);
    52.6  
    52.7 -    /* write_rflags: Modify privileged bits in RFLAGS. */
    52.8 -    int (*write_rflags)(
    52.9 -        unsigned long val,
   52.10 -        struct x86_emulate_ctxt *ctxt);
   52.11 -
   52.12      /* wbinvd: Write-back and invalidate cache contents. */
   52.13      int (*wbinvd)(
   52.14          struct x86_emulate_ctxt *ctxt);
   52.15 @@ -335,14 +330,10 @@ struct x86_emulate_ops
   52.16          unsigned int *edx,
   52.17          struct x86_emulate_ctxt *ctxt);
   52.18  
   52.19 -    /* hlt: Emulate HLT. */
   52.20 -    int (*hlt)(
   52.21 -        struct x86_emulate_ctxt *ctxt);
   52.22 -
   52.23      /* inject_hw_exception */
   52.24      int (*inject_hw_exception)(
   52.25          uint8_t vector,
   52.26 -        uint16_t error_code,
   52.27 +        int32_t error_code,
   52.28          struct x86_emulate_ctxt *ctxt);
   52.29  
   52.30      /* inject_sw_interrupt */
   52.31 @@ -376,7 +367,17 @@ struct x86_emulate_ctxt
   52.32      unsigned int sp_size;
   52.33  
   52.34      /* Set this if writes may have side effects. */
   52.35 -    int force_writeback;
   52.36 +    uint8_t force_writeback;
   52.37 +
   52.38 +    /* Retirement state, set by the emulator (valid only on X86EMUL_OKAY). */
   52.39 +    union {
   52.40 +        struct {
   52.41 +            uint8_t hlt:1;          /* Instruction HLTed. */
   52.42 +            uint8_t mov_ss:1;       /* Instruction sets MOV-SS irq shadow. */
   52.43 +            uint8_t sti:1;          /* Instruction sets STI irq shadow. */
   52.44 +        } flags;
   52.45 +        uint8_t byte;
   52.46 +    } retire;
   52.47  };
   52.48  
   52.49  /*
    53.1 --- a/xen/include/asm-x86/xenoprof.h	Mon Feb 25 06:29:01 2008 -0700
    53.2 +++ b/xen/include/asm-x86/xenoprof.h	Tue Feb 26 10:12:04 2008 -0700
    53.3 @@ -41,6 +41,7 @@ int xenoprof_arch_init(int *num_events, 
    53.4  #define xenoprof_arch_release_counters()        nmi_release_counters()
    53.5  
    53.6  int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
    53.7 +int compat_oprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
    53.8  
    53.9  struct vcpu;
   53.10  struct cpu_user_regs;
    54.1 --- a/xen/include/public/io/protocols.h	Mon Feb 25 06:29:01 2008 -0700
    54.2 +++ b/xen/include/public/io/protocols.h	Tue Feb 26 10:12:04 2008 -0700
    54.3 @@ -1,3 +1,25 @@
    54.4 +/******************************************************************************
    54.5 + * protocols.h
    54.6 + * 
    54.7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    54.8 + * of this software and associated documentation files (the "Software"), to
    54.9 + * deal in the Software without restriction, including without limitation the
   54.10 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   54.11 + * sell copies of the Software, and to permit persons to whom the Software is
   54.12 + * furnished to do so, subject to the following conditions:
   54.13 + *
   54.14 + * The above copyright notice and this permission notice shall be included in
   54.15 + * all copies or substantial portions of the Software.
   54.16 + *
   54.17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   54.18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   54.19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   54.20 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   54.21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   54.22 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   54.23 + * DEALINGS IN THE SOFTWARE.
   54.24 + */
   54.25 +
   54.26  #ifndef __XEN_PROTOCOLS_H__
   54.27  #define __XEN_PROTOCOLS_H__
   54.28  
    55.1 --- a/xen/include/public/kexec.h	Mon Feb 25 06:29:01 2008 -0700
    55.2 +++ b/xen/include/public/kexec.h	Tue Feb 26 10:12:04 2008 -0700
    55.3 @@ -1,6 +1,24 @@
    55.4  /******************************************************************************
    55.5   * kexec.h - Public portion
    55.6   * 
    55.7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    55.8 + * of this software and associated documentation files (the "Software"), to
    55.9 + * deal in the Software without restriction, including without limitation the
   55.10 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   55.11 + * sell copies of the Software, and to permit persons to whom the Software is
   55.12 + * furnished to do so, subject to the following conditions:
   55.13 + *
   55.14 + * The above copyright notice and this permission notice shall be included in
   55.15 + * all copies or substantial portions of the Software.
   55.16 + *
   55.17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   55.18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   55.19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   55.20 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   55.21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   55.22 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   55.23 + * DEALINGS IN THE SOFTWARE.
   55.24 + * 
   55.25   * Xen port written by:
   55.26   * - Simon 'Horms' Horman <horms@verge.net.au>
   55.27   * - Magnus Damm <magnus@valinux.co.jp>
    56.1 --- a/xen/include/public/libelf.h	Mon Feb 25 06:29:01 2008 -0700
    56.2 +++ b/xen/include/public/libelf.h	Tue Feb 26 10:12:04 2008 -0700
    56.3 @@ -1,3 +1,25 @@
    56.4 +/******************************************************************************
    56.5 + * libelf.h
    56.6 + * 
    56.7 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    56.8 + * of this software and associated documentation files (the "Software"), to
    56.9 + * deal in the Software without restriction, including without limitation the
   56.10 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   56.11 + * sell copies of the Software, and to permit persons to whom the Software is
   56.12 + * furnished to do so, subject to the following conditions:
   56.13 + *
   56.14 + * The above copyright notice and this permission notice shall be included in
   56.15 + * all copies or substantial portions of the Software.
   56.16 + *
   56.17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   56.18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   56.19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   56.20 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   56.21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   56.22 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   56.23 + * DEALINGS IN THE SOFTWARE.
   56.24 + */
   56.25 +
   56.26  #ifndef __XC_LIBELF__
   56.27  #define __XC_LIBELF__ 1
   56.28