[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User Alex Williamson <alex.williamson@xxxxxx> # Date 1204045924 25200 # Node ID f97a0b6152c3ce0c5a0428d729be27d02e4eabe1 # Parent 7e8334e651c479fc1277db84d49a97b73b86d27e # Parent 2a8eaba24bf0482db8d44aa1c638ffa7e3894f43 merge with xen-unstable.hg --- extras/mini-os/fbfront.c | 468 ++++++++++++++ extras/mini-os/include/fbfront.h | 38 + extras/mini-os/include/lib.h | 4 extras/mini-os/kernel.c | 149 ++++ extras/mini-os/lib/math.c | 23 extras/mini-os/lib/sys.c | 24 stubdom/README | 17 stubdom/stubdom-dm | 3 tools/blktap/drivers/block-aio.c | 144 ---- tools/blktap/drivers/block-qcow.c | 249 +------ tools/blktap/drivers/block-qcow2.c | 275 -------- tools/blktap/drivers/tapaio.c | 190 +++++ tools/blktap/drivers/tapaio.h | 64 + tools/examples/vtpm-common.sh | 25 tools/examples/vtpm-delete | 13 tools/firmware/hvmloader/acpi/build.c | 78 -- tools/firmware/hvmloader/acpi/dsdt.asl | 20 tools/firmware/hvmloader/acpi/dsdt.c | 1059 ++++++++++++++++---------------- tools/ioemu/Makefile.target | 4 tools/ioemu/hw/e1000.c | 995 ++++++++++++++++++++++++++++++ tools/ioemu/hw/e1000_hw.h | 865 ++++++++++++++++++++++++++ tools/ioemu/hw/pci.c | 2 tools/ioemu/hw/xen_console.c | 2 tools/ioemu/hw/xenfb.c | 2 tools/ioemu/osdep.c | 2 tools/ioemu/vl.h | 5 tools/ioemu/vnc.c | 196 +++++ tools/python/xen/lowlevel/xc/xc.c | 13 tools/python/xen/xend/XendDomainInfo.py | 2 tools/python/xen/xend/XendNode.py | 18 tools/python/xen/xend/image.py | 2 tools/xentrace/xentrace.c | 97 ++ xen/arch/x86/hvm/emulate.c | 88 +- xen/arch/x86/hvm/hvm.c | 20 xen/arch/x86/hvm/io.c | 4 xen/arch/x86/hvm/svm/svm.c | 35 - xen/arch/x86/hvm/vmx/intr.c | 4 xen/arch/x86/hvm/vmx/realmode.c | 143 +--- xen/arch/x86/hvm/vmx/vmx.c | 37 - xen/arch/x86/hvm/vmx/x86_32/exits.S | 9 xen/arch/x86/hvm/vmx/x86_64/exits.S | 9 xen/arch/x86/mm/shadow/multi.c | 2 xen/arch/x86/oprofile/xenoprof.c | 25 xen/arch/x86/x86_emulate.c | 165 ++-- xen/common/compat/xenoprof.c | 1 xen/common/grant_table.c | 24 xen/include/asm-ia64/grant_table.h | 6 xen/include/asm-powerpc/grant_table.h | 11 xen/include/asm-x86/grant_table.h | 14 xen/include/asm-x86/hvm/emulate.h | 14 xen/include/asm-x86/hvm/hvm.h | 17 xen/include/asm-x86/x86_emulate.h | 23 xen/include/asm-x86/xenoprof.h | 1 xen/include/public/io/protocols.h | 22 xen/include/public/kexec.h | 18 xen/include/public/libelf.h | 22 56 files changed, 4207 insertions(+), 1555 deletions(-) diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/fbfront.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/fbfront.c Tue Feb 26 10:12:04 2008 -0700 @@ -0,0 +1,468 @@ +/* + * Frame Buffer + Keyboard driver for Mini-OS. + * Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>, 2008 + * Based on blkfront.c. + */ + +#include <os.h> +#include <xenbus.h> +#include <events.h> +#include <xen/io/kbdif.h> +#include <xen/io/fbif.h> +#include <xen/io/protocols.h> +#include <gnttab.h> +#include <xmalloc.h> +#include <fbfront.h> +#include <lib.h> + +DECLARE_WAIT_QUEUE_HEAD(kbdfront_queue); + + + + + + +struct kbdfront_dev { + domid_t dom; + + struct xenkbd_page *page; + evtchn_port_t evtchn, local_port; + + char *nodename; + char *backend; + + char *data; + int width; + int height; + int depth; + int line_length; + int mem_length; + +#ifdef HAVE_LIBC + int fd; +#endif +}; + +void kbdfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) +{ +#ifdef HAVE_LIBC + struct kbdfront_dev *dev = data; + int fd = dev->fd; + + files[fd].read = 1; +#endif + wake_up(&kbdfront_queue); +} + +struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer) +{ + xenbus_transaction_t xbt; + char* err; + char* message=NULL; + struct xenkbd_page *s; + int retry=0; + char* msg; + + struct kbdfront_dev *dev; + + if (!nodename) + nodename = "device/vkbd/0"; + + char path[strlen(nodename) + 1 + 10 + 1]; + + printk("******************* KBDFRONT for %s **********\n\n\n", nodename); + + dev = malloc(sizeof(*dev)); + dev->nodename = strdup(nodename); + + evtchn_alloc_unbound_t op; + op.dom = DOMID_SELF; + snprintf(path, sizeof(path), "%s/backend-id", nodename); + dev->dom = op.remote_dom = xenbus_read_integer(path); + HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); + clear_evtchn(op.port); /* Without, handler gets invoked now! */ + dev->local_port = bind_evtchn(op.port, kbdfront_handler, dev); + dev->evtchn=op.port; + + dev->page = s = (struct xenkbd_page*) alloc_page(); + memset(s,0,PAGE_SIZE); + + s->in_cons = s->in_prod = 0; + s->out_cons = s->out_prod = 0; + + // FIXME: proper frees on failures +again: + err = xenbus_transaction_start(&xbt); + if (err) { + printk("starting transaction\n"); + } + + err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s)); + if (err) { + message = "writing page-ref"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + if (abs_pointer) { + err = xenbus_printf(xbt, nodename, "request-abs-pointer", "1"); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + } + + err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */ + if (err) + printk("error writing initialized: %s\n", err); + + + err = xenbus_transaction_end(xbt, 0, &retry); + if (retry) { + goto again; + printk("completing transaction\n"); + } + + goto done; + +abort_transaction: + xenbus_transaction_end(xbt, 1, &retry); + return NULL; + +done: + + snprintf(path, sizeof(path), "%s/backend", nodename); + msg = xenbus_read(XBT_NIL, path, &dev->backend); + if (msg) { + printk("Error %s when reading the backend path %s\n", msg, path); + return NULL; + } + + printk("backend at %s\n", dev->backend); + + { + char path[strlen(dev->backend) + 1 + 6 + 1]; + + snprintf(path, sizeof(path), "%s/state", dev->backend); + + xenbus_watch_path(XBT_NIL, path); + + xenbus_wait_for_value(path,"4"); + + xenbus_unwatch_path(XBT_NIL, path); + + printk("%s connected\n", dev->backend); + + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */ + } + + printk("************************** KBDFRONT\n"); + + return dev; +} + +int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n) +{ + struct xenkbd_page *page = dev->page; + uint32_t prod, cons; + int i; + +#ifdef HAVE_LIBC + files[dev->fd].read = 0; + mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ +#endif + + prod = page->in_prod; + + if (prod == page->in_cons) + return 0; + + rmb(); /* ensure we see ring contents up to prod */ + + for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++) + memcpy(buf + i, &XENKBD_IN_RING_REF(page, cons), sizeof(*buf)); + + mb(); /* ensure we got ring contents */ + page->in_cons = cons; + notify_remote_via_evtchn(dev->evtchn); + +#ifdef HAVE_LIBC + if (cons != prod) + /* still some events to read */ + files[dev->fd].read = 1; +#endif + + return i; +} + + +void shutdown_kbdfront(struct kbdfront_dev *dev) +{ + char* err; + char *nodename = dev->nodename; + + char path[strlen(dev->backend) + 1 + 5 + 1]; + + printk("close kbd: backend at %s\n",dev->backend); + + snprintf(path, sizeof(path), "%s/state", dev->backend); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */ + xenbus_wait_for_value(path,"5"); + + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); + xenbus_wait_for_value(path,"6"); + + unbind_evtchn(dev->local_port); + + free_pages(dev->page,0); + free(nodename); + free(dev->backend); + free(dev); +} + +#ifdef HAVE_LIBC +int kbdfront_open(struct kbdfront_dev *dev) +{ + dev->fd = alloc_fd(FTYPE_KBD); + printk("kbd_open(%s) -> %d\n", dev->nodename, dev->fd); + files[dev->fd].kbd.dev = dev; + return dev->fd; +} +#endif + + + + + +DECLARE_WAIT_QUEUE_HEAD(fbfront_queue); + + + + + + +struct fbfront_dev { + domid_t dom; + + struct xenfb_page *page; + evtchn_port_t evtchn, local_port; + + char *nodename; + char *backend; + + char *data; + int width; + int height; + int depth; + int line_length; + int mem_length; +}; + +void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) +{ + wake_up(&fbfront_queue); +} + +struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int height, int depth, int line_length, int mem_length) +{ + xenbus_transaction_t xbt; + char* err; + char* message=NULL; + struct xenfb_page *s; + int retry=0; + char* msg; + int i, j; + struct fbfront_dev *dev; + + if (!nodename) + nodename = "device/vfb/0"; + + char path[strlen(nodename) + 1 + 10 + 1]; + + printk("******************* FBFRONT for %s **********\n\n\n", nodename); + + dev = malloc(sizeof(*dev)); + dev->nodename = strdup(nodename); + + evtchn_alloc_unbound_t op; + op.dom = DOMID_SELF; + snprintf(path, sizeof(path), "%s/backend-id", nodename); + dev->dom = op.remote_dom = xenbus_read_integer(path); + HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op); + clear_evtchn(op.port); /* Without, handler gets invoked now! */ + dev->local_port = bind_evtchn(op.port, fbfront_handler, dev); + dev->evtchn=op.port; + + dev->page = s = (struct xenfb_page*) alloc_page(); + memset(s,0,PAGE_SIZE); + + s->in_cons = s->in_prod = 0; + s->out_cons = s->out_prod = 0; + dev->width = s->width = width; + dev->height = s->height = height; + dev->depth = s->depth = depth; + dev->line_length = s->line_length = line_length; + dev->mem_length = s->mem_length = mem_length; + + ASSERT(!((unsigned long)data & ~PAGE_MASK)); + dev->data = data; + + const int max_pd = sizeof(s->pd) / sizeof(s->pd[0]); + unsigned long mapped = 0; + + for (i = 0; mapped < mem_length && i < max_pd; i++) { + unsigned long *pd = (unsigned long *) alloc_page(); + for (j = 0; mapped < mem_length && j < PAGE_SIZE / sizeof(unsigned long); j++) { + pd[j] = virt_to_mfn((unsigned long) data + mapped); + mapped += PAGE_SIZE; + } + for ( ; j < PAGE_SIZE / sizeof(unsigned long); j++) + pd[j] = 0; + s->pd[i] = virt_to_mfn(pd); + } + for ( ; i < max_pd; i++) + s->pd[i] = 0; + + + // FIXME: proper frees on failures +again: + err = xenbus_transaction_start(&xbt); + if (err) { + printk("starting transaction\n"); + } + + err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s)); + if (err) { + message = "writing page-ref"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, "protocol", "%s", + XEN_IO_PROTO_ABI_NATIVE); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + err = xenbus_printf(xbt, nodename, "feature-update", "1"); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */ + + + err = xenbus_transaction_end(xbt, 0, &retry); + if (retry) { + goto again; + printk("completing transaction\n"); + } + + goto done; + +abort_transaction: + xenbus_transaction_end(xbt, 1, &retry); + return NULL; + +done: + + snprintf(path, sizeof(path), "%s/backend", nodename); + msg = xenbus_read(XBT_NIL, path, &dev->backend); + if (msg) { + printk("Error %s when reading the backend path %s\n", msg, path); + return NULL; + } + + printk("backend at %s\n", dev->backend); + + { + char path[strlen(dev->backend) + 1 + 6 + 1]; + + snprintf(path, sizeof(path), "%s/state", dev->backend); + + xenbus_watch_path(XBT_NIL, path); + + xenbus_wait_for_value(path,"4"); + + printk("%s connected\n", dev->backend); + + xenbus_unwatch_path(XBT_NIL, path); + + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */ + } + + printk("************************** FBFRONT\n"); + + return dev; +} + +void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height) +{ + struct xenfb_page *page = dev->page; + uint32_t prod; + DEFINE_WAIT(w); + + if (x < 0) { + width += x; + x = 0; + } + if (x + width > dev->width) + width = dev->width - x; + + if (y < 0) { + height += y; + y = 0; + } + if (y + height > dev->height) + height = dev->height - y; + + if (width <= 0 || height <= 0) + return; + + add_waiter(w, fbfront_queue); + while (page->out_prod - page->out_cons == XENFB_OUT_RING_LEN) + schedule(); + remove_waiter(w); + + prod = page->out_prod; + mb(); /* ensure ring space available */ + XENFB_OUT_RING_REF(page, prod).type = XENFB_TYPE_UPDATE; + XENFB_OUT_RING_REF(page, prod).update.x = x; + XENFB_OUT_RING_REF(page, prod).update.y = y; + XENFB_OUT_RING_REF(page, prod).update.width = width; + XENFB_OUT_RING_REF(page, prod).update.height = height; + wmb(); /* ensure ring contents visible */ + page->out_prod = prod + 1; + notify_remote_via_evtchn(dev->evtchn); +} + +void shutdown_fbfront(struct fbfront_dev *dev) +{ + char* err; + char *nodename = dev->nodename; + + char path[strlen(dev->backend) + 1 + 5 + 1]; + + printk("close fb: backend at %s\n",dev->backend); + + snprintf(path, sizeof(path), "%s/state", dev->backend); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */ + xenbus_wait_for_value(path,"5"); + + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); + xenbus_wait_for_value(path,"6"); + + unbind_evtchn(dev->local_port); + + free_pages(dev->page,0); + free(nodename); + free(dev->backend); + free(dev); +} diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/include/fbfront.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/fbfront.h Tue Feb 26 10:12:04 2008 -0700 @@ -0,0 +1,38 @@ +#include <xen/io/kbdif.h> +#include <wait.h> + +/* from <linux/input.h> */ +#ifndef BTN_LEFT +#define BTN_LEFT 0x110 +#endif +#ifndef BTN_RIGHT +#define BTN_RIGHT 0x111 +#endif +#ifndef BTN_MIDDLE +#define BTN_MIDDLE 0x112 +#endif +#ifndef KEY_Q +#define KEY_Q 16 +#endif + + +struct kbdfront_dev; +struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer); +#ifdef HAVE_LIBC +int kbdfront_open(struct kbdfront_dev *dev); +#endif + +int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n); +extern struct wait_queue_head kbdfront_queue; + +void shutdown_kbdfront(struct kbdfront_dev *dev); + + +struct fbfront_dev *init_fbfront(char *nodename, void *data, int width, int height, int depth, int line_length, int mem_length); +#ifdef HAVE_LIBC +int fbfront_open(struct fbfront_dev *dev); +#endif + +void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height); + +void shutdown_fbfront(struct fbfront_dev *dev); diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/include/lib.h --- a/extras/mini-os/include/lib.h Mon Feb 25 06:29:01 2008 -0700 +++ b/extras/mini-os/include/lib.h Tue Feb 26 10:12:04 2008 -0700 @@ -140,6 +140,7 @@ enum fd_type { FTYPE_SOCKET, FTYPE_TAP, FTYPE_BLK, + FTYPE_KBD, }; #define MAX_EVTCHN_PORTS 16 @@ -171,6 +172,9 @@ extern struct file { struct { struct blkfront_dev *dev; } blk; + struct { + struct kbdfront_dev *dev; + } kbd; struct { /* To each xenbus FD is associated a queue of watch events for this * FD. */ diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Mon Feb 25 06:29:01 2008 -0700 +++ b/extras/mini-os/kernel.c Tue Feb 26 10:12:04 2008 -0700 @@ -39,6 +39,7 @@ #include <gnttab.h> #include <netfront.h> #include <blkfront.h> +#include <fbfront.h> #include <fs.h> #include <xmalloc.h> #include <fcntl.h> @@ -248,6 +249,152 @@ static void blkfront_thread(void *p) } } +#define WIDTH 800 +#define HEIGHT 600 +#define DEPTH 32 + +static uint32_t *fb; +static struct fbfront_dev *fb_dev; +static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0); + +static void fbfront_drawvert(int x, int y1, int y2, uint32_t color) +{ + int y; + if (x < 0) + return; + if (x >= WIDTH) + return; + if (y1 < 0) + y1 = 0; + if (y2 >= HEIGHT) + y2 = HEIGHT-1; + for (y = y1; y <= y2; y++) + fb[x + y*WIDTH] ^= color; +} + +static void fbfront_drawhoriz(int x1, int x2, int y, uint32_t color) +{ + int x; + if (y < 0) + return; + if (y >= HEIGHT) + return; + if (x1 < 0) + x1 = 0; + if (x2 >= WIDTH) + x2 = WIDTH-1; + for (x = x1; x <= x2; x++) + fb[x + y*WIDTH] ^= color; +} + +static void fbfront_thread(void *p) +{ + size_t line_length = WIDTH * (DEPTH / 8); + size_t memsize = HEIGHT * line_length; + + fb = _xmalloc(memsize, PAGE_SIZE); + fb_dev = init_fbfront(NULL, fb, WIDTH, HEIGHT, DEPTH, line_length, memsize); + if (!fb_dev) { + xfree(fb); + return; + } + up(&fbfront_sem); +} + +static void clip_cursor(int *x, int *y) +{ + if (*x < 0) + *x = 0; + if (*x >= WIDTH) + *x = WIDTH - 1; + if (*y < 0) + *y = 0; + if (*y >= HEIGHT) + *y = HEIGHT - 1; +} + +static void refresh_cursor(int new_x, int new_y) +{ + static int old_x = -1, old_y = -1; + if (old_x != -1 && old_y != -1) { + fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff); + fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff); + fbfront_update(fb_dev, old_x, old_y, 9, 9); + } + old_x = new_x; + old_y = new_y; + fbfront_drawvert(new_x, new_y + 1, new_y + 8, 0xffffffff); + fbfront_drawhoriz(new_x + 1, new_x + 8, new_y, 0xffffffff); + fbfront_update(fb_dev, new_x, new_y, 9, 9); +} + +static void kbdfront_thread(void *p) +{ + struct kbdfront_dev *kbd_dev; + DEFINE_WAIT(w); + int x = WIDTH / 2, y = HEIGHT / 2, z; + + kbd_dev = init_kbdfront(NULL, 1); + if (!kbd_dev) + return; + + down(&fbfront_sem); + refresh_cursor(x, y); + while (1) { + union xenkbd_in_event event; + + add_waiter(w, kbdfront_queue); + + if (kbdfront_receive(kbd_dev, &event, 1) == 0) + schedule(); + else switch(event.type) { + case XENKBD_TYPE_MOTION: + printk("motion x:%d y:%d z:%d\n", + event.motion.rel_x, + event.motion.rel_y, + event.motion.rel_z); + x += event.motion.rel_x; + y += event.motion.rel_y; + z += event.motion.rel_z; + clip_cursor(&x, &y); + refresh_cursor(x, y); + break; + case XENKBD_TYPE_POS: + printk("pos x:%d y:%d z:%d\n", + event.pos.abs_x, + event.pos.abs_y, + event.pos.abs_z); + x = event.pos.abs_x; + y = event.pos.abs_y; + z = event.pos.abs_z; + clip_cursor(&x, &y); + refresh_cursor(x, y); + break; + case XENKBD_TYPE_KEY: + printk("key %d %s\n", + event.key.keycode, + event.key.pressed ? "pressed" : "released"); + if (event.key.keycode == BTN_LEFT) { + printk("mouse %s at (%d,%d,%d)\n", + event.key.pressed ? "clic" : "release", x, y, z); + if (event.key.pressed) { + uint32_t color = rand(); + fbfront_drawvert(x - 16, y - 16, y + 15, color); + fbfront_drawhoriz(x - 16, x + 15, y + 16, color); + fbfront_drawvert(x + 16, y - 15, y + 16, color); + fbfront_drawhoriz(x - 15, x + 16, y - 16, color); + fbfront_update(fb_dev, x - 16, y - 16, 33, 33); + } + } else if (event.key.keycode == KEY_Q) { + struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff }; + HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); + do_exit(); + } + break; + } + } +} + static void fs_thread(void *p) { init_fs_frontend(); @@ -261,6 +408,8 @@ __attribute__((weak)) int app_main(start create_thread("periodic_thread", periodic_thread, si); create_thread("netfront", netfront_thread, si); create_thread("blkfront", blkfront_thread, si); + create_thread("fbfront", fbfront_thread, si); + create_thread("kbdfront", kbdfront_thread, si); create_thread("fs-frontend", fs_thread, si); return 0; } diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/lib/math.c --- a/extras/mini-os/lib/math.c Mon Feb 25 06:29:01 2008 -0700 +++ b/extras/mini-os/lib/math.c Tue Feb 26 10:12:04 2008 -0700 @@ -388,6 +388,29 @@ __umoddi3(u_quad_t a, u_quad_t b) return (r); } +/* + * Return remainder after dividing two signed quads. + * + * XXX + * If -1/2 should produce -1 on this machine, this code is wrong. + */ +quad_t +__moddi3(quad_t a, quad_t b) +{ + u_quad_t ua, ub, ur; + int neg; + + if (a < 0) + ua = -(u_quad_t)a, neg = 1; + else + ua = a, neg = 0; + if (b < 0) + ub = -(u_quad_t)b; + else + ub = b; + (void)__qdivrem(ua, ub, &ur); + return (neg ? -ur : ur); +} #endif /* !defined(__ia64__) */ #ifndef HAVE_LIBC diff -r 7e8334e651c4 -r f97a0b6152c3 extras/mini-os/lib/sys.c --- a/extras/mini-os/lib/sys.c Mon Feb 25 06:29:01 2008 -0700 +++ b/extras/mini-os/lib/sys.c Tue Feb 26 10:12:04 2008 -0700 @@ -26,6 +26,7 @@ #include <wait.h> #include <netfront.h> #include <blkfront.h> +#include <fbfront.h> #include <xenbus.h> #include <xs.h> @@ -221,6 +222,16 @@ int read(int fd, void *buf, size_t nbyte } return ret; } + case FTYPE_KBD: { + int ret, n; + n = nbytes / sizeof(union xenkbd_in_event); + ret = kbdfront_receive(files[fd].kbd.dev, buf, n); + if (ret <= 0) { + errno = EAGAIN; + return -1; + } + return ret * sizeof(union xenkbd_in_event); + } case FTYPE_NONE: case FTYPE_XENBUS: case FTYPE_EVTCHN: @@ -261,6 +272,7 @@ int write(int fd, const void *buf, size_ case FTYPE_XENBUS: case FTYPE_EVTCHN: case FTYPE_BLK: + case FTYPE_KBD: break; } printk("write(%d): Bad descriptor\n", fd); @@ -318,6 +330,7 @@ int fsync(int fd) { case FTYPE_EVTCHN: case FTYPE_TAP: case FTYPE_BLK: + case FTYPE_KBD: break; } printk("fsync(%d): Bad descriptor\n", fd); @@ -360,6 +373,10 @@ int close(int fd) shutdown_blkfront(files[fd].blk.dev); files[fd].type = FTYPE_NONE; return 0; + case FTYPE_KBD: + shutdown_kbdfront(files[fd].kbd.dev); + files[fd].type = FTYPE_NONE; + return 0; case FTYPE_NONE: break; } @@ -450,6 +467,7 @@ int fstat(int fd, struct stat *buf) case FTYPE_EVTCHN: case FTYPE_TAP: case FTYPE_BLK: + case FTYPE_KBD: break; } @@ -477,6 +495,7 @@ int ftruncate(int fd, off_t length) case FTYPE_EVTCHN: case FTYPE_TAP: case FTYPE_BLK: + case FTYPE_KBD: break; } @@ -587,6 +606,7 @@ static const char file_types[] = { [FTYPE_SOCKET] = 'S', [FTYPE_TAP] = 'T', [FTYPE_BLK] = 'B', + [FTYPE_KBD] = 'K', }; #ifdef LIBC_DEBUG static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) @@ -694,6 +714,7 @@ static int select_poll(int nfds, fd_set case FTYPE_EVTCHN: case FTYPE_TAP: case FTYPE_BLK: + case FTYPE_KBD: if (FD_ISSET(i, readfds)) { if (files[i].read) n++; @@ -775,6 +796,7 @@ int select(int nfds, fd_set *readfds, fd DEFINE_WAIT(w2); DEFINE_WAIT(w3); DEFINE_WAIT(w4); + DEFINE_WAIT(w5); assert(thread == main_thread); @@ -795,6 +817,7 @@ int select(int nfds, fd_set *readfds, fd add_waiter(w2, event_queue); add_waiter(w3, blkfront_queue); add_waiter(w4, xenbus_watch_queue); + add_waiter(w5, kbdfront_queue); myread = *readfds; mywrite = *writefds; @@ -860,6 +883,7 @@ out: remove_waiter(w2); remove_waiter(w3); remove_waiter(w4); + remove_waiter(w5); return ret; } diff -r 7e8334e651c4 -r f97a0b6152c3 stubdom/README --- a/stubdom/README Mon Feb 25 06:29:01 2008 -0700 +++ b/stubdom/README Tue Feb 26 10:12:04 2008 -0700 @@ -16,10 +16,12 @@ ln -s /usr/share/qemu/keymaps /exports/u In your HVM config "hvmconfig", -- use VNC, set vnclisten to "172.30.206.1" for instance: +- use VNC, set vnclisten to "172.30.206.1" for instance. Do not use a host name +as Mini-OS does not have a name resolver. Do not use 127.0.0.1 since then you +will not be able to connect to it. -vnc=1 -vnclisten="172.30.206.1" +vnc = 1 +vnclisten = "172.30.206.1" - use /usr/lib/xen/bin/stubdom-dm as dm script @@ -28,14 +30,15 @@ device_model = '/usr/lib/xen/bin/stubdom - comment the disk statement: #disk = [ 'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ] -Create /etc/xen/stubdom-hvmconfig ("hvmconfig" must match your main config file) -with +Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is your HVM guest domain +name) with -kernel="/usr/lib/xen/boot/stubdom.gz" -vif=[ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34'] +kernel = "/usr/lib/xen/boot/stubdom.gz" +vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34'] disk = [ 'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ] where - 172.30.206.1 is the IP for vnc, -- 'ip=10.0.1.1,mac=' is the same net configuration as in the hvmconfig script, +- 'ip=10.0.1.1,mac= etc...' is the same net configuration as in the hvmconfig +script, - and disk = is the same block configuration as in the hvmconfig script. diff -r 7e8334e651c4 -r f97a0b6152c3 stubdom/stubdom-dm --- a/stubdom/stubdom-dm Mon Feb 25 06:29:01 2008 -0700 +++ b/stubdom/stubdom-dm Tue Feb 26 10:12:04 2008 -0700 @@ -62,11 +62,12 @@ done creation="xm create -c stubdom-$domname target=$domid memory=32" -(while true ; do sleep 60 ; done) | $creation & +(while true ; do sleep 60 ; done) | $creation > /var/log/xen/qemu-dm-$domid.log & #xterm -geometry +0+0 -e /bin/sh -c "$creation ; echo ; echo press ENTER to shut down ; read" & consolepid=$! +# Wait for vnc server to appear while ! vnc_port=`xenstore-read /local/domain/$domid/console/vnc-port` do # Check that the stubdom job is still alive diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/block-aio.c --- a/tools/blktap/drivers/block-aio.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/blktap/drivers/block-aio.c Tue Feb 26 10:12:04 2008 -0700 @@ -52,28 +52,11 @@ #define O_LARGEFILE 0 #endif -struct pending_aio { - td_callback_t cb; - int id; - void *private; - uint64_t lsec; -}; - struct tdaio_state { int fd; - - /* libaio state */ - tap_aio_context_t aio_ctx; - struct iocb iocb_list [MAX_AIO_REQS]; - struct iocb *iocb_free [MAX_AIO_REQS]; - struct pending_aio pending_aio[MAX_AIO_REQS]; - int iocb_free_count; - struct iocb *iocb_queue[MAX_AIO_REQS]; - int iocb_queued; - struct io_event aio_events[MAX_AIO_REQS]; + tap_aio_context_t aio; }; -#define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list) /*Get Image size, secsize*/ static int get_image_info(struct td_state *s, int fd) @@ -131,7 +114,7 @@ static inline void init_fds(struct disk_ for(i = 0; i < MAX_IOFD; i++) dd->io_fd[i] = 0; - dd->io_fd[0] = prv->aio_ctx.pollfd; + dd->io_fd[0] = prv->aio.aio_ctx.pollfd; } /* Open the disk file and initialize aio state. */ @@ -142,27 +125,11 @@ int tdaio_open (struct disk_driver *dd, struct tdaio_state *prv = (struct tdaio_state *)dd->private; DPRINTF("block-aio open('%s')", name); + /* Initialize AIO */ - prv->iocb_free_count = MAX_AIO_REQS; - prv->iocb_queued = 0; - - ret = tap_aio_setup(&prv->aio_ctx, prv->aio_events, MAX_AIO_REQS); - if (ret < 0) { - if (ret == -EAGAIN) { - DPRINTF("Couldn't setup AIO context. If you are " - "trying to concurrently use a large number " - "of blktap-based disks, you may need to " - "increase the system-wide aio request limit. " - "(e.g. 'echo echo 1048576 > /proc/sys/fs/" - "aio-max-nr')\n"); - } else { - DPRINTF("Couldn't setup AIO context.\n"); - } - goto done; - } - - for (i=0;i<MAX_AIO_REQS;i++) - prv->iocb_free[i] = &prv->iocb_list[i]; + ret = tap_aio_init(&prv->aio, 0, MAX_AIO_REQS); + if (ret != 0) + return ret; /* Open the file */ o_flags = O_DIRECT | O_LARGEFILE | @@ -198,87 +165,40 @@ int tdaio_queue_read(struct disk_driver int nb_sectors, char *buf, td_callback_t cb, int id, void *private) { - struct iocb *io; - struct pending_aio *pio; struct td_state *s = dd->td_state; struct tdaio_state *prv = (struct tdaio_state *)dd->private; int size = nb_sectors * s->sector_size; uint64_t offset = sector * (uint64_t)s->sector_size; - long ioidx; - - if (prv->iocb_free_count == 0) - return -ENOMEM; - io = prv->iocb_free[--prv->iocb_free_count]; - - ioidx = IOCB_IDX(prv, io); - pio = &prv->pending_aio[ioidx]; - pio->cb = cb; - pio->id = id; - pio->private = private; - pio->lsec = sector; - - io_prep_pread(io, prv->fd, buf, size, offset); - io->data = (void *)ioidx; - - prv->iocb_queue[prv->iocb_queued++] = io; - - return 0; + + return tap_aio_read(&prv->aio, prv->fd, size, offset, buf, + cb, id, sector, private); } int tdaio_queue_write(struct disk_driver *dd, uint64_t sector, int nb_sectors, char *buf, td_callback_t cb, int id, void *private) { - struct iocb *io; - struct pending_aio *pio; struct td_state *s = dd->td_state; struct tdaio_state *prv = (struct tdaio_state *)dd->private; int size = nb_sectors * s->sector_size; uint64_t offset = sector * (uint64_t)s->sector_size; - long ioidx; + + return tap_aio_write(&prv->aio, prv->fd, size, offset, buf, + cb, id, sector, private); +} + +int tdaio_submit(struct disk_driver *dd) +{ + struct tdaio_state *prv = (struct tdaio_state *)dd->private; + + return tap_aio_submit(&prv->aio); +} + +int tdaio_close(struct disk_driver *dd) +{ + struct tdaio_state *prv = (struct tdaio_state *)dd->private; - if (prv->iocb_free_count == 0) - return -ENOMEM; - io = prv->iocb_free[--prv->iocb_free_count]; - - ioidx = IOCB_IDX(prv, io); - pio = &prv->pending_aio[ioidx]; - pio->cb = cb; - pio->id = id; - pio->private = private; - pio->lsec = sector; - - io_prep_pwrite(io, prv->fd, buf, size, offset); - io->data = (void *)ioidx; - - prv->iocb_queue[prv->iocb_queued++] = io; - - return 0; -} - -int tdaio_submit(struct disk_driver *dd) -{ - int ret; - struct tdaio_state *prv = (struct tdaio_state *)dd->private; - - if (!prv->iocb_queued) - return 0; - - ret = io_submit(prv->aio_ctx.aio_ctx, prv->iocb_queued, prv->iocb_queue); - - /* XXX: TODO: Handle error conditions here. */ - - /* Success case: */ - prv->iocb_queued = 0; - - return 0; -} - -int tdaio_close(struct disk_driver *dd) -{ - struct tdaio_state *prv = (struct tdaio_state *)dd->private; - - io_destroy(prv->aio_ctx.aio_ctx); + io_destroy(prv->aio.aio_ctx.aio_ctx); close(prv->fd); return 0; @@ -290,26 +210,26 @@ int tdaio_do_callbacks(struct disk_drive struct io_event *ep; struct tdaio_state *prv = (struct tdaio_state *)dd->private; - nr_events = tap_aio_get_events(&prv->aio_ctx); + nr_events = tap_aio_get_events(&prv->aio.aio_ctx); repeat: - for (ep = prv->aio_events, i = nr_events; i-- > 0; ep++) { + for (ep = prv->aio.aio_events, i = nr_events; i-- > 0; ep++) { struct iocb *io = ep->obj; struct pending_aio *pio; - pio = &prv->pending_aio[(long)io->data]; + pio = &prv->aio.pending_aio[(long)io->data]; rsp += pio->cb(dd, ep->res == io->u.c.nbytes ? 0 : 1, - pio->lsec, io->u.c.nbytes >> 9, + pio->sector, io->u.c.nbytes >> 9, pio->id, pio->private); - prv->iocb_free[prv->iocb_free_count++] = io; + prv->aio.iocb_free[prv->aio.iocb_free_count++] = io; } if (nr_events) { - nr_events = tap_aio_more_events(&prv->aio_ctx); + nr_events = tap_aio_more_events(&prv->aio.aio_ctx); goto repeat; } - tap_aio_continue(&prv->aio_ctx); + tap_aio_continue(&prv->aio.aio_ctx); return rsp; } diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/block-qcow.c --- a/tools/blktap/drivers/block-qcow.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/blktap/drivers/block-qcow.c Tue Feb 26 10:12:04 2008 -0700 @@ -59,15 +59,7 @@ (l + (s - 1)) - ((l + (s - 1)) % s)); \ }) -struct pending_aio { - td_callback_t cb; - int id; - void *private; - int nb_sectors; - char *buf; - uint64_t sector; -}; - +#undef IOCB_IDX #define IOCB_IDX(_s, _io) ((_io) - (_s)->iocb_list) #define ZERO_TEST(_b) (_b | 0x00) @@ -140,109 +132,18 @@ struct tdqcow_state { uint32_t l2_cache_counts[L2_CACHE_SIZE]; /*Cache access record*/ uint8_t *cluster_cache; uint8_t *cluster_data; - uint8_t *sector_lock; /*Locking bitmap for AIO reads/writes*/ uint64_t cluster_cache_offset; /**/ uint32_t crypt_method; /*current crypt method, 0 if no *key yet */ uint32_t crypt_method_header; /**/ AES_KEY aes_encrypt_key; /*AES key*/ AES_KEY aes_decrypt_key; /*AES key*/ - /* libaio state */ - tap_aio_context_t aio_ctx; - int max_aio_reqs; - struct iocb *iocb_list; - struct iocb **iocb_free; - struct pending_aio *pending_aio; - int iocb_free_count; - struct iocb **iocb_queue; - int iocb_queued; - struct io_event *aio_events; + + /* libaio state */ + tap_aio_context_t aio; }; static int decompress_cluster(struct tdqcow_state *s, uint64_t cluster_offset); - -static void free_aio_state(struct disk_driver *dd) -{ - struct tdqcow_state *s = (struct tdqcow_state *)dd->private; - - if (s->sector_lock) - free(s->sector_lock); - if (s->iocb_list) - free(s->iocb_list); - if (s->pending_aio) - free(s->pending_aio); - if (s->aio_events) - free(s->aio_events); - if (s->iocb_free) - free(s->iocb_free); - if (s->iocb_queue) - free(s->iocb_queue); -} - -static int init_aio_state(struct disk_driver *dd) -{ - int i, ret; - struct td_state *bs = dd->td_state; - struct tdqcow_state *s = (struct tdqcow_state *)dd->private; - long ioidx; - - s->iocb_list = NULL; - s->pending_aio = NULL; - s->aio_events = NULL; - s->iocb_free = NULL; - s->iocb_queue = NULL; - - /*Initialize Locking bitmap*/ - s->sector_lock = calloc(1, bs->size); - - if (!s->sector_lock) { - DPRINTF("Failed to allocate sector lock\n"); - goto fail; - } - - /* A segment (i.e. a page) can span multiple clusters */ - s->max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) * - MAX_SEGMENTS_PER_REQ * MAX_REQUESTS; - - /* Initialize AIO */ - s->iocb_free_count = s->max_aio_reqs; - s->iocb_queued = 0; - - if (!(s->iocb_list = malloc(sizeof(struct iocb) * s->max_aio_reqs)) || - !(s->pending_aio = malloc(sizeof(struct pending_aio) * s->max_aio_reqs)) || - !(s->aio_events = malloc(sizeof(struct io_event) * s->max_aio_reqs)) || - !(s->iocb_free = malloc(sizeof(struct iocb *) * s->max_aio_reqs)) || - !(s->iocb_queue = malloc(sizeof(struct iocb *) * s->max_aio_reqs))) { - DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n", - s->max_aio_reqs); - goto fail; - } - - ret = tap_aio_setup(&s->aio_ctx, s->aio_events, s->max_aio_reqs); - if (ret < 0) { - if (ret == -EAGAIN) { - DPRINTF("Couldn't setup AIO context. If you are " - "trying to concurrently use a large number " - "of blktap-based disks, you may need to " - "increase the system-wide aio request limit. " - "(e.g. 'echo echo 1048576 > /proc/sys/fs/" - "aio-max-nr')\n"); - } else { - DPRINTF("Couldn't setup AIO context.\n"); - } - goto fail; - } - - for (i=0;i<s->max_aio_reqs;i++) - s->iocb_free[i] = &s->iocb_list[i]; - - DPRINTF("AIO state initialised\n"); - - return 0; - - fail: - return -1; -} static uint32_t gen_cksum(char *ptr, int len) { @@ -337,79 +238,6 @@ static int qcow_set_key(struct tdqcow_st } #endif return 0; -} - -static int async_read(struct tdqcow_state *s, int size, - uint64_t offset, char *buf, td_callback_t cb, - int id, uint64_t sector, void *private) -{ - struct iocb *io; - struct pending_aio *pio; - long ioidx; - - io = s->iocb_free[--s->iocb_free_count]; - - ioidx = IOCB_IDX(s, io); - pio = &s->pending_aio[ioidx]; - pio->cb = cb; - pio->id = id; - pio->private = private; - pio->nb_sectors = size/512; - pio->buf = buf; - pio->sector = sector; - - io_prep_pread(io, s->fd, buf, size, offset); - io->data = (void *)ioidx; - - s->iocb_queue[s->iocb_queued++] = io; - - return 1; -} - -static int async_write(struct tdqcow_state *s, int size, - uint64_t offset, char *buf, td_callback_t cb, - int id, uint64_t sector, void *private) -{ - struct iocb *io; - struct pending_aio *pio; - long ioidx; - - io = s->iocb_free[--s->iocb_free_count]; - - ioidx = IOCB_IDX(s, io); - pio = &s->pending_aio[ioidx]; - pio->cb = cb; - pio->id = id; - pio->private = private; - pio->nb_sectors = size/512; - pio->buf = buf; - pio->sector = sector; - - io_prep_pwrite(io, s->fd, buf, size, offset); - io->data = (void *)ioidx; - - s->iocb_queue[s->iocb_queued++] = io; - - return 1; -} - -/*TODO: Fix sector span!*/ -static int aio_can_lock(struct tdqcow_state *s, uint64_t sector) -{ - return (s->sector_lock[sector] ? 0 : 1); -} - -static int aio_lock(struct tdqcow_state *s, uint64_t sector) -{ - return ++s->sector_lock[sector]; -} - -static void aio_unlock(struct tdqcow_state *s, uint64_t sector) -{ - if (!s->sector_lock[sector]) return; - - --s->sector_lock[sector]; - return; } /* @@ -841,13 +669,14 @@ static inline void init_fds(struct disk_ for(i = 0; i < MAX_IOFD; i++) dd->io_fd[i] = 0; - dd->io_fd[0] = s->aio_ctx.pollfd; + dd->io_fd[0] = s->aio.aio_ctx.pollfd; } /* Open the disk file and initialize qcow state. */ int tdqcow_open (struct disk_driver *dd, const char *name, td_flag_t flags) { int fd, len, i, shift, ret, size, l1_table_size, o_flags; + int max_aio_reqs; struct td_state *bs = dd->td_state; struct tdqcow_state *s = (struct tdqcow_state *)dd->private; char *buf; @@ -996,9 +825,14 @@ int tdqcow_open (struct disk_driver *dd, } end_xenhdr: - if (init_aio_state(dd)!=0) { + + /* A segment (i.e. a page) can span multiple clusters */ + max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) * + MAX_SEGMENTS_PER_REQ * MAX_REQUESTS; + + if (tap_aio_init(&s->aio, bs->size, max_aio_reqs)!=0) { DPRINTF("Unable to initialise AIO state\n"); - free_aio_state(dd); + tap_aio_free(&s->aio); goto fail; } init_fds(dd); @@ -1015,7 +849,7 @@ int tdqcow_open (struct disk_driver *dd, fail: DPRINTF("QCOW Open failed\n"); - free_aio_state(dd); + tap_aio_free(&s->aio); free(s->l1_table); free(s->l2_cache); free(s->cluster_cache); @@ -1037,7 +871,7 @@ int tdqcow_queue_read(struct disk_driver /*Check we can get a lock*/ for (i = 0; i < nb_sectors; i++) - if (!aio_can_lock(s, sector + i)) + if (!tap_aio_can_lock(&s->aio, sector + i)) return cb(dd, -EBUSY, sector, nb_sectors, id, private); /*We store a local record of the request*/ @@ -1049,11 +883,11 @@ int tdqcow_queue_read(struct disk_driver if (n > nb_sectors) n = nb_sectors; - if (s->iocb_free_count == 0 || !aio_lock(s, sector)) + if (s->aio.iocb_free_count == 0 || !tap_aio_lock(&s->aio, sector)) return cb(dd, -EBUSY, sector, nb_sectors, id, private); if(!cluster_offset) { - aio_unlock(s, sector); + tap_aio_unlock(&s->aio, sector); ret = cb(dd, BLK_NOT_ALLOCATED, sector, n, id, private); if (ret == -EBUSY) { @@ -1064,7 +898,7 @@ int tdqcow_queue_read(struct disk_driver } else rsp += ret; } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { - aio_unlock(s, sector); + tap_aio_unlock(&s->aio, sector); if (decompress_cluster(s, cluster_offset) < 0) { rsp += cb(dd, -EIO, sector, nb_sectors, id, private); @@ -1074,7 +908,7 @@ int tdqcow_queue_read(struct disk_driver 512 * n); rsp += cb(dd, 0, sector, n, id, private); } else { - async_read(s, n * 512, + tap_aio_read(&s->aio, s->fd, n * 512, (cluster_offset + index_in_cluster * 512), buf, cb, id, sector, private); } @@ -1099,7 +933,7 @@ int tdqcow_queue_write(struct disk_drive /*Check we can get a lock*/ for (i = 0; i < nb_sectors; i++) - if (!aio_can_lock(s, sector + i)) + if (!tap_aio_can_lock(&s->aio, sector + i)) return cb(dd, -EBUSY, sector, nb_sectors, id, private); /*We store a local record of the request*/ @@ -1109,7 +943,7 @@ int tdqcow_queue_write(struct disk_drive if (n > nb_sectors) n = nb_sectors; - if (s->iocb_free_count == 0 || !aio_lock(s, sector)) + if (s->aio.iocb_free_count == 0 || !tap_aio_lock(&s->aio, sector)) return cb(dd, -EBUSY, sector, nb_sectors, id, private); cluster_offset = get_cluster_offset(s, sector << 9, 1, 0, @@ -1117,7 +951,7 @@ int tdqcow_queue_write(struct disk_drive index_in_cluster+n); if (!cluster_offset) { DPRINTF("Ooops, no write cluster offset!\n"); - aio_unlock(s, sector); + tap_aio_unlock(&s->aio, sector); return cb(dd, -EIO, sector, nb_sectors, id, private); } @@ -1125,12 +959,12 @@ int tdqcow_queue_write(struct disk_drive encrypt_sectors(s, sector, s->cluster_data, (unsigned char *)buf, n, 1, &s->aes_encrypt_key); - async_write(s, n * 512, + tap_aio_write(&s->aio, s->fd, n * 512, (cluster_offset + index_in_cluster*512), (char *)s->cluster_data, cb, id, sector, private); } else { - async_write(s, n * 512, + tap_aio_write(&s->aio, s->fd, n * 512, (cluster_offset + index_in_cluster*512), buf, cb, id, sector, private); } @@ -1146,20 +980,9 @@ int tdqcow_queue_write(struct disk_drive int tdqcow_submit(struct disk_driver *dd) { - int ret; - struct tdqcow_state *prv = (struct tdqcow_state *)dd->private; - - if (!prv->iocb_queued) - return 0; - - ret = io_submit(prv->aio_ctx.aio_ctx, prv->iocb_queued, prv->iocb_queue); - - /* XXX: TODO: Handle error conditions here. */ - - /* Success case: */ - prv->iocb_queued = 0; - - return 0; + struct tdqcow_state *prv = (struct tdqcow_state *)dd->private; + + return tap_aio_submit(&prv->aio); } int tdqcow_close(struct disk_driver *dd) @@ -1180,7 +1003,7 @@ int tdqcow_close(struct disk_driver *dd) close(fd); } - io_destroy(s->aio_ctx.aio_ctx); + io_destroy(s->aio.aio_ctx.aio_ctx); free(s->name); free(s->l1_table); free(s->l2_cache); @@ -1198,15 +1021,15 @@ int tdqcow_do_callbacks(struct disk_driv if (sid > MAX_IOFD) return 1; - nr_events = tap_aio_get_events(&prv->aio_ctx); + nr_events = tap_aio_get_events(&prv->aio.aio_ctx); repeat: - for (ep = prv->aio_events, i = nr_events; i-- > 0; ep++) { + for (ep = prv->aio.aio_events, i = nr_events; i-- > 0; ep++) { struct iocb *io = ep->obj; struct pending_aio *pio; - pio = &prv->pending_aio[(long)io->data]; - - aio_unlock(prv, pio->sector); + pio = &prv->aio.pending_aio[(long)io->data]; + + tap_aio_unlock(&prv->aio, pio->sector); if (prv->crypt_method) encrypt_sectors(prv, pio->sector, @@ -1219,15 +1042,15 @@ repeat: pio->sector, pio->nb_sectors, pio->id, pio->private); - prv->iocb_free[prv->iocb_free_count++] = io; + prv->aio.iocb_free[prv->aio.iocb_free_count++] = io; } if (nr_events) { - nr_events = tap_aio_more_events(&prv->aio_ctx); + nr_events = tap_aio_more_events(&prv->aio.aio_ctx); goto repeat; } - tap_aio_continue(&prv->aio_ctx); + tap_aio_continue(&prv->aio.aio_ctx); return rsp; } diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/block-qcow2.c --- a/tools/blktap/drivers/block-qcow2.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/blktap/drivers/block-qcow2.c Tue Feb 26 10:12:04 2008 -0700 @@ -145,20 +145,7 @@ typedef struct BDRVQcowState { int64_t total_sectors; - - struct { - tap_aio_context_t aio_ctx; - int max_aio_reqs; - struct iocb *iocb_list; - struct iocb **iocb_free; - struct pending_aio *pending_aio; - int iocb_free_count; - struct iocb **iocb_queue; - int iocb_queued; - struct io_event *aio_events; - - uint8_t *sector_lock; /*Locking bitmap for AIO reads/writes*/ - } async; + tap_aio_context_t async; /* Original qemu variables */ int cluster_bits; @@ -222,9 +209,6 @@ static void check_refcounts(struct disk_ static void check_refcounts(struct disk_driver *bs); #endif -static int init_aio_state(struct disk_driver *bs); -static void free_aio_state(struct disk_driver *bs); - static int qcow_sync_read(struct disk_driver *dd, uint64_t sector, int nb_sectors, char *buf, td_callback_t cb, int id, void *prv); @@ -309,7 +293,7 @@ static int qcow_open(struct disk_driver static int qcow_open(struct disk_driver *bs, const char *filename, td_flag_t flags) { BDRVQcowState *s = bs->private; - int len, i, shift, ret; + int len, i, shift, ret, max_aio_reqs; QCowHeader header; int fd, o_flags; @@ -475,9 +459,14 @@ static int qcow_open(struct disk_driver #ifdef USE_AIO /* Initialize AIO */ - if (init_aio_state(bs)!=0) { + + /* A segment (i.e. a page) can span multiple clusters */ + max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) * + MAX_SEGMENTS_PER_REQ * MAX_REQUESTS; + + if (tap_aio_init(&s->async, bs->td_state->size, max_aio_reqs)) { DPRINTF("Unable to initialise AIO state\n"); - free_aio_state(bs); + tap_aio_free(&s->async); goto fail; } @@ -496,7 +485,7 @@ static int qcow_open(struct disk_driver DPRINTF("qcow_open failed\n"); #ifdef USE_AIO - free_aio_state(bs); + tap_aio_free(&s->async); #endif qcow_free_snapshots(bs); @@ -1070,200 +1059,6 @@ static int qcow_write(struct disk_driver #ifdef USE_AIO /* - * General AIO helper functions - */ - -#define IOCB_IDX(_s, _io) ((_io) - (_s)->async.iocb_list) - -struct pending_aio { - td_callback_t cb; - int id; - void *private; - int nb_sectors; - char *buf; - uint64_t sector; -}; - - -static int init_aio_state(struct disk_driver *dd) -{ - int i, ret; - struct td_state *bs = dd->td_state; - struct BDRVQcowState *s = (struct BDRVQcowState*) dd->private; - long ioidx; - - s->async.iocb_list = NULL; - s->async.pending_aio = NULL; - s->async.aio_events = NULL; - s->async.iocb_free = NULL; - s->async.iocb_queue = NULL; - - /*Initialize Locking bitmap*/ - s->async.sector_lock = calloc(1, bs->size); - - if (!s->async.sector_lock) { - DPRINTF("Failed to allocate sector lock\n"); - goto fail; - } - - /* A segment (i.e. a page) can span multiple clusters */ - s->async.max_aio_reqs = ((getpagesize() / s->cluster_size) + 1) * - MAX_SEGMENTS_PER_REQ * MAX_REQUESTS; - - /* Initialize AIO */ - s->async.iocb_free_count = s->async.max_aio_reqs; - s->async.iocb_queued = 0; - - if (!(s->async.iocb_list = malloc(sizeof(struct iocb) * s->async.max_aio_reqs)) || - !(s->async.pending_aio = malloc(sizeof(struct pending_aio) * s->async.max_aio_reqs)) || - !(s->async.aio_events = malloc(sizeof(struct io_event) * s->async.max_aio_reqs)) || - !(s->async.iocb_free = malloc(sizeof(struct iocb *) * s->async.max_aio_reqs)) || - !(s->async.iocb_queue = malloc(sizeof(struct iocb *) * s->async.max_aio_reqs))) - { - DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n", - s->async.max_aio_reqs); - goto fail; - } - - ret = tap_aio_setup(&s->async.aio_ctx, s->async.aio_events, s->async.max_aio_reqs); - if (ret < 0) { - if (ret == -EAGAIN) { - DPRINTF("Couldn't setup AIO context. If you are " - "trying to concurrently use a large number " - "of blktap-based disks, you may need to " - "increase the system-wide aio request limit. " - "(e.g. 'echo echo 1048576 > /proc/sys/fs/" - "aio-max-nr')\n"); - } else { - DPRINTF("Couldn't setup AIO context.\n"); - } - goto fail; - } - - for (i=0;i<s->async.max_aio_reqs;i++) - s->async.iocb_free[i] = &s->async.iocb_list[i]; - - DPRINTF("AIO state initialised\n"); - - return 0; - -fail: - return -1; -} - -static void free_aio_state(struct disk_driver *dd) -{ - struct BDRVQcowState *s = (struct BDRVQcowState*) dd->private; - - if (s->async.sector_lock) - free(s->async.sector_lock); - if (s->async.iocb_list) - free(s->async.iocb_list); - if (s->async.pending_aio) - free(s->async.pending_aio); - if (s->async.aio_events) - free(s->async.aio_events); - if (s->async.iocb_free) - free(s->async.iocb_free); - if (s->async.iocb_queue) - free(s->async.iocb_queue); -} - -static int async_read(struct BDRVQcowState *s, int size, - uint64_t offset, char *buf, td_callback_t cb, - int id, uint64_t sector, void *private) -{ - struct iocb *io; - struct pending_aio *pio; - long ioidx; - - io = s->async.iocb_free[--s->async.iocb_free_count]; - - ioidx = IOCB_IDX(s, io); - pio = &s->async.pending_aio[ioidx]; - pio->cb = cb; - pio->id = id; - pio->private = private; - pio->nb_sectors = size/512; - pio->buf = buf; - pio->sector = sector; - - io_prep_pread(io, s->fd, buf, size, offset); - io->data = (void *)ioidx; - - s->async.iocb_queue[s->async.iocb_queued++] = io; - - return 1; -} - -static int async_write(struct BDRVQcowState *s, int size, - uint64_t offset, char *buf, td_callback_t cb, - int id, uint64_t sector, void *private) -{ - struct iocb *io; - struct pending_aio *pio; - long ioidx; - - io = s->async.iocb_free[--s->async.iocb_free_count]; - - ioidx = IOCB_IDX(s, io); - pio = &s->async.pending_aio[ioidx]; - pio->cb = cb; - pio->id = id; - pio->private = private; - pio->nb_sectors = size/512; - pio->buf = buf; - pio->sector = sector; - - io_prep_pwrite(io, s->fd, buf, size, offset); - io->data = (void *)ioidx; - - s->async.iocb_queue[s->async.iocb_queued++] = io; - - return 1; -} - -static int async_submit(struct disk_driver *dd) -{ - int ret; - struct BDRVQcowState *prv = (struct BDRVQcowState*) dd->private; - - if (!prv->async.iocb_queued) - return 0; - - ret = io_submit(prv->async.aio_ctx.aio_ctx, prv->async.iocb_queued, prv->async.iocb_queue); - - /* XXX: TODO: Handle error conditions here. */ - - /* Success case: */ - prv->async.iocb_queued = 0; - - return 0; -} - -/*TODO: Fix sector span!*/ -static int aio_can_lock(struct BDRVQcowState *s, uint64_t sector) -{ - return (s->async.sector_lock[sector] ? 0 : 1); -} - -static int aio_lock(struct BDRVQcowState *s, uint64_t sector) -{ - return ++s->async.sector_lock[sector]; -} - -static void aio_unlock(struct BDRVQcowState *s, uint64_t sector) -{ - if (!s->async.sector_lock[sector]) return; - - --s->async.sector_lock[sector]; - return; -} - - - - -/* * QCOW2 specific AIO functions */ @@ -1278,7 +1073,7 @@ static int qcow_queue_read(struct disk_d /*Check we can get a lock*/ for (i = 0; i < nb_sectors; i++) - if (!aio_can_lock(s, sector + i)) + if (!tap_aio_can_lock(&s->async, sector + i)) return cb(bs, -EBUSY, sector, nb_sectors, id, private); while (nb_sectors > 0) { @@ -1290,13 +1085,13 @@ static int qcow_queue_read(struct disk_d if (n > nb_sectors) n = nb_sectors; - if (s->async.iocb_free_count == 0 || !aio_lock(s, sector)) + if (s->async.iocb_free_count == 0 || !tap_aio_lock(&s->async, sector)) return cb(bs, -EBUSY, sector, nb_sectors, id, private); if (!cluster_offset) { /* The requested sector is not allocated */ - aio_unlock(s, sector); + tap_aio_unlock(&s->async, sector); ret = cb(bs, BLK_NOT_ALLOCATED, sector, n, id, private); if (ret == -EBUSY) { @@ -1311,7 +1106,7 @@ static int qcow_queue_read(struct disk_d } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { /* sync read for compressed clusters */ - aio_unlock(s, sector); + tap_aio_unlock(&s->async, sector); if (decompress_cluster(s, cluster_offset) < 0) { rsp += cb(bs, -EIO, sector, nb_sectors, id, private); goto done; @@ -1323,7 +1118,7 @@ static int qcow_queue_read(struct disk_d } else { /* async read */ - async_read(s, n * 512, + tap_aio_read(&s->async, s->fd, n * 512, (cluster_offset + index_in_cluster * 512), buf, cb, id, sector, private); } @@ -1351,7 +1146,7 @@ static int qcow_queue_write(struct disk_ /*Check we can get a lock*/ for (i = 0; i < nb_sectors; i++) - if (!aio_can_lock(s, sector + i)) + if (!tap_aio_can_lock(&s->async, sector + i)) return cb(bs, -EBUSY, sector, nb_sectors, id, private); @@ -1362,7 +1157,7 @@ static int qcow_queue_write(struct disk_ if (n > nb_sectors) n = nb_sectors; - if (s->async.iocb_free_count == 0 || !aio_lock(s, sector)) + if (s->async.iocb_free_count == 0 || !tap_aio_lock(&s->async, sector)) return cb(bs, -EBUSY, sector, nb_sectors, id, private); @@ -1372,14 +1167,14 @@ static int qcow_queue_write(struct disk_ if (!cluster_offset) { DPRINTF("Ooops, no write cluster offset!\n"); - aio_unlock(s, sector); + tap_aio_unlock(&s->async, sector); return cb(bs, -EIO, sector, nb_sectors, id, private); } // TODO Encryption - async_write(s, n * 512, + tap_aio_write(&s->async, s->fd, n * 512, (cluster_offset + index_in_cluster*512), buf, cb, id, sector, private); @@ -1402,9 +1197,14 @@ static int qcow_close(struct disk_driver static int qcow_close(struct disk_driver *bs) { BDRVQcowState *s = bs->private; - + +#ifdef USE_AIO + io_destroy(s->async.aio_ctx.aio_ctx); + tap_aio_free(&s->async); +#else close(s->poll_pipe[0]); - close(s->poll_pipe[1]); + close(s->poll_pipe[1]); +#endif qemu_free(s->l1_table); qemu_free(s->l2_cache); @@ -1606,23 +1406,10 @@ static int qcow_write_compressed(struct static int qcow_submit(struct disk_driver *bs) { - int ret; - struct BDRVQcowState *prv = (struct BDRVQcowState*)bs->private; - - - fsync(prv->fd); - - if (!prv->async.iocb_queued) - return 0; - - ret = io_submit(prv->async.aio_ctx.aio_ctx, prv->async.iocb_queued, prv->async.iocb_queue); - - /* XXX: TODO: Handle error conditions here. */ - - /* Success case: */ - prv->async.iocb_queued = 0; - - return 0; + struct BDRVQcowState *s = (struct BDRVQcowState*) bs->private; + + fsync(s->fd); + return tap_aio_submit(&s->async); } @@ -2246,7 +2033,7 @@ repeat: pio = &prv->async.pending_aio[(long)io->data]; - aio_unlock(prv, pio->sector); + tap_aio_unlock(&prv->async, pio->sector); if (prv->crypt_method) encrypt_sectors(prv, pio->sector, diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/tapaio.c --- a/tools/blktap/drivers/tapaio.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/blktap/drivers/tapaio.c Tue Feb 26 10:12:04 2008 -0700 @@ -32,6 +32,7 @@ #include <unistd.h> #include <errno.h> #include <string.h> +#include <stdlib.h> /** * We used a kernel patch to return an fd associated with the AIO context @@ -62,7 +63,7 @@ static void * static void * tap_aio_completion_thread(void *arg) { - tap_aio_context_t *ctx = (tap_aio_context_t *) arg; + tap_aio_internal_context_t *ctx = (tap_aio_internal_context_t *) arg; int command; int nr_events; int rc; @@ -84,7 +85,7 @@ tap_aio_completion_thread(void *arg) } void -tap_aio_continue(tap_aio_context_t *ctx) +tap_aio_continue(tap_aio_internal_context_t *ctx) { int cmd = 0; @@ -95,8 +96,8 @@ tap_aio_continue(tap_aio_context_t *ctx) DPRINTF("Cannot write to command pipe\n"); } -int -tap_aio_setup(tap_aio_context_t *ctx, +static int +tap_aio_setup(tap_aio_internal_context_t *ctx, struct io_event *aio_events, int max_aio_events) { @@ -144,7 +145,7 @@ tap_aio_setup(tap_aio_context_t *ctx, } int -tap_aio_get_events(tap_aio_context_t *ctx) +tap_aio_get_events(tap_aio_internal_context_t *ctx) { int nr_events = 0; @@ -171,10 +172,185 @@ tap_aio_get_events(tap_aio_context_t *ct return nr_events; } -int tap_aio_more_events(tap_aio_context_t *ctx) +int tap_aio_more_events(tap_aio_internal_context_t *ctx) { return io_getevents(ctx->aio_ctx, 0, ctx->max_aio_events, ctx->aio_events, NULL); } - +int tap_aio_init(tap_aio_context_t *ctx, uint64_t sectors, + int max_aio_reqs) +{ + int i, ret; + long ioidx; + + ctx->iocb_list = NULL; + ctx->pending_aio = NULL; + ctx->aio_events = NULL; + ctx->iocb_free = NULL; + ctx->iocb_queue = NULL; + + /*Initialize Locking bitmap*/ + ctx->sector_lock = calloc(1, sectors); + + if (!ctx->sector_lock) { + DPRINTF("Failed to allocate sector lock\n"); + goto fail; + } + + + /* Initialize AIO */ + ctx->max_aio_reqs = max_aio_reqs; + ctx->iocb_free_count = ctx->max_aio_reqs; + ctx->iocb_queued = 0; + + if (!(ctx->iocb_list = malloc(sizeof(struct iocb) * ctx->max_aio_reqs)) || + !(ctx->pending_aio = malloc(sizeof(struct pending_aio) * ctx->max_aio_reqs)) || + !(ctx->aio_events = malloc(sizeof(struct io_event) * ctx->max_aio_reqs)) || + !(ctx->iocb_free = malloc(sizeof(struct iocb *) * ctx->max_aio_reqs)) || + !(ctx->iocb_queue = malloc(sizeof(struct iocb *) * ctx->max_aio_reqs))) + { + DPRINTF("Failed to allocate AIO structs (max_aio_reqs = %d)\n", + ctx->max_aio_reqs); + goto fail; + } + + ret = tap_aio_setup(&ctx->aio_ctx, ctx->aio_events, ctx->max_aio_reqs); + if (ret < 0) { + if (ret == -EAGAIN) { + DPRINTF("Couldn't setup AIO context. If you are " + "trying to concurrently use a large number " + "of blktap-based disks, you may need to " + "increase the system-wide aio request limit. " + "(e.g. 'echo echo 1048576 > /proc/sys/fs/" + "aio-max-nr')\n"); + } else { + DPRINTF("Couldn't setup AIO context.\n"); + } + goto fail; + } + + for (i=0;i<ctx->max_aio_reqs;i++) + ctx->iocb_free[i] = &ctx->iocb_list[i]; + + DPRINTF("AIO state initialised\n"); + + return 0; + +fail: + return -1; +} + +void tap_aio_free(tap_aio_context_t *ctx) +{ + if (ctx->sector_lock) + free(ctx->sector_lock); + if (ctx->iocb_list) + free(ctx->iocb_list); + if (ctx->pending_aio) + free(ctx->pending_aio); + if (ctx->aio_events) + free(ctx->aio_events); + if (ctx->iocb_free) + free(ctx->iocb_free); + if (ctx->iocb_queue) + free(ctx->iocb_queue); +} + +/*TODO: Fix sector span!*/ +int tap_aio_can_lock(tap_aio_context_t *ctx, uint64_t sector) +{ + return (ctx->sector_lock[sector] ? 0 : 1); +} + +int tap_aio_lock(tap_aio_context_t *ctx, uint64_t sector) +{ + return ++ctx->sector_lock[sector]; +} + +void tap_aio_unlock(tap_aio_context_t *ctx, uint64_t sector) +{ + if (!ctx->sector_lock[sector]) return; + + --ctx->sector_lock[sector]; + return; +} + + +int tap_aio_read(tap_aio_context_t *ctx, int fd, int size, + uint64_t offset, char *buf, td_callback_t cb, + int id, uint64_t sector, void *private) +{ + struct iocb *io; + struct pending_aio *pio; + long ioidx; + + if (ctx->iocb_free_count == 0) + return -ENOMEM; + + io = ctx->iocb_free[--ctx->iocb_free_count]; + + ioidx = IOCB_IDX(ctx, io); + pio = &ctx->pending_aio[ioidx]; + pio->cb = cb; + pio->id = id; + pio->private = private; + pio->nb_sectors = size/512; + pio->buf = buf; + pio->sector = sector; + + io_prep_pread(io, fd, buf, size, offset); + io->data = (void *)ioidx; + + ctx->iocb_queue[ctx->iocb_queued++] = io; + + return 0; +} + +int tap_aio_write(tap_aio_context_t *ctx, int fd, int size, + uint64_t offset, char *buf, td_callback_t cb, + int id, uint64_t sector, void *private) +{ + struct iocb *io; + struct pending_aio *pio; + long ioidx; + + if (ctx->iocb_free_count == 0) + return -ENOMEM; + + io = ctx->iocb_free[--ctx->iocb_free_count]; + + ioidx = IOCB_IDX(ctx, io); + pio = &ctx->pending_aio[ioidx]; + pio->cb = cb; + pio->id = id; + pio->private = private; + pio->nb_sectors = size/512; + pio->buf = buf; + pio->sector = sector; + + io_prep_pwrite(io, fd, buf, size, offset); + io->data = (void *)ioidx; + + ctx->iocb_queue[ctx->iocb_queued++] = io; + + return 0; +} + +int tap_aio_submit(tap_aio_context_t *ctx) +{ + int ret; + + if (!ctx->iocb_queued) + return 0; + + ret = io_submit(ctx->aio_ctx.aio_ctx, ctx->iocb_queued, ctx->iocb_queue); + + /* XXX: TODO: Handle error conditions here. */ + + /* Success case: */ + ctx->iocb_queued = 0; + + return 0; +} + diff -r 7e8334e651c4 -r f97a0b6152c3 tools/blktap/drivers/tapaio.h --- a/tools/blktap/drivers/tapaio.h Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/blktap/drivers/tapaio.h Tue Feb 26 10:12:04 2008 -0700 @@ -32,8 +32,13 @@ #include <pthread.h> #include <libaio.h> +#include <stdint.h> -struct tap_aio_context { +#include "tapdisk.h" + +#define IOCB_IDX(_ctx, _io) ((_io) - (_ctx)->iocb_list) + +struct tap_aio_internal_context { io_context_t aio_ctx; struct io_event *aio_events; @@ -45,14 +50,59 @@ struct tap_aio_context { int pollfd; unsigned int poll_in_thread : 1; }; + + +typedef struct tap_aio_internal_context tap_aio_internal_context_t; + + +struct pending_aio { + td_callback_t cb; + int id; + void *private; + int nb_sectors; + char *buf; + uint64_t sector; +}; + + +struct tap_aio_context { + tap_aio_internal_context_t aio_ctx; + + int max_aio_reqs; + struct iocb *iocb_list; + struct iocb **iocb_free; + struct pending_aio *pending_aio; + int iocb_free_count; + struct iocb **iocb_queue; + int iocb_queued; + struct io_event *aio_events; + + /* Locking bitmap for AIO reads/writes */ + uint8_t *sector_lock; +}; typedef struct tap_aio_context tap_aio_context_t; -int tap_aio_setup (tap_aio_context_t *ctx, - struct io_event *aio_events, - int max_aio_events); -void tap_aio_continue (tap_aio_context_t *ctx); -int tap_aio_get_events (tap_aio_context_t *ctx); -int tap_aio_more_events(tap_aio_context_t *ctx); +void tap_aio_continue (tap_aio_internal_context_t *ctx); +int tap_aio_get_events (tap_aio_internal_context_t *ctx); +int tap_aio_more_events(tap_aio_internal_context_t *ctx); + + +int tap_aio_init(tap_aio_context_t *ctx, uint64_t sectors, + int max_aio_reqs); +void tap_aio_free(tap_aio_context_t *ctx); + +int tap_aio_can_lock(tap_aio_context_t *ctx, uint64_t sector); +int tap_aio_lock(tap_aio_context_t *ctx, uint64_t sector); +void tap_aio_unlock(tap_aio_context_t *ctx, uint64_t sector); + + +int tap_aio_read(tap_aio_context_t *ctx, int fd, int size, + uint64_t offset, char *buf, td_callback_t cb, + int id, uint64_t sector, void *private); +int tap_aio_write(tap_aio_context_t *ctx, int fd, int size, + uint64_t offset, char *buf, td_callback_t cb, + int id, uint64_t sector, void *private); +int tap_aio_submit(tap_aio_context_t *ctx); #endif /* __TAPAIO_H__ */ diff -r 7e8334e651c4 -r f97a0b6152c3 tools/examples/vtpm-common.sh --- a/tools/examples/vtpm-common.sh Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/examples/vtpm-common.sh Tue Feb 26 10:12:04 2008 -0700 @@ -407,7 +407,7 @@ function vtpm_domid_from_name () { local id name ids ids=$(xenstore-list /local/domain) for id in $ids; do - name=$(xenstore_read /local/domain/$id/name) + name=$(xenstore-read /local/domain/$id/name) if [ "$name" == "$1" ]; then echo "$id" return @@ -416,16 +416,33 @@ function vtpm_domid_from_name () { echo "-1" } +#Determine the virtual TPM's instance number using the domain ID. +#1st parm: domain ID +function vtpm_uuid_by_domid() { + echo $(xenstore-read /local/domain/0/backend/vtpm/$1/0/uuid) +} + + +# Determine the vTPM's UUID by the name of the VM +function vtpm_uuid_from_vmname() { + local domid=$(vtpm_domid_from_name $1) + if [ "$domid" != "-1" ]; then + echo $(vtpm_uuid_by_domid $domid) + return + fi + echo "" +} #Add a virtual TPM instance number and its associated domain name #to the VTPMDB file and activate usage of this virtual TPM instance #by writing the instance number into the xenstore #1st parm: name of virtual machine -#2nd parm: instance of assoicate virtual TPM +#2nd parm: instance of associated virtual TPM function vtpm_add_and_activate() { local domid=$(vtpm_domid_from_name $1) - if [ "$domid" != "-1" ]; then - vtpmdb_add_instance $1 $2 + local vtpm_uuid=$(vtpm_uuid_from_vmname $1) + if [ "$vtpm_uuid" != "" -a "$domid" != "-1" ]; then + vtpmdb_add_instance $vtpm_uuid $2 xenstore-write backend/vtpm/$domid/0/instance $2 fi } diff -r 7e8334e651c4 -r f97a0b6152c3 tools/examples/vtpm-delete --- a/tools/examples/vtpm-delete Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/examples/vtpm-delete Tue Feb 26 10:12:04 2008 -0700 @@ -1,9 +1,18 @@ #!/bin/bash # This scripts must be called the following way: -# vtpm-delete <domain name> +# vtpm-delete <vtpm uuid> +# or +# vtpm-delete --vmname <vm name> dir=$(dirname "$0") . "$dir/vtpm-common.sh" -vtpm_delete_instance $1 +if [ "$1" == "--vmname" ]; then + vtpm_uuid=$(vtpm_uuid_from_vmname $2) + if [ "$vtpm_uuid" != "" ];then + vtpm_delete_instance $vtpm_uuid + fi +else + vtpm_delete_instance $1 +fi diff -r 7e8334e651c4 -r f97a0b6152c3 tools/firmware/hvmloader/acpi/build.c --- a/tools/firmware/hvmloader/acpi/build.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/firmware/hvmloader/acpi/build.c Tue Feb 26 10:12:04 2008 -0700 @@ -189,80 +189,6 @@ static int construct_hpet(struct acpi_20 return offset; } -static int construct_processor_objects(uint8_t *buf) -{ - static const char pdat[13] = { 0x5b, 0x83, 0x0b, 0x50, 0x52 }; - static const char hex[] = "0123456789ABCDEF"; - static const char pr_scope[] = "\\_PR_"; - unsigned int i, length, nr_cpus = get_vcpu_nr(); - struct acpi_header *hdr; - uint8_t *p = buf; - - /* - * 1. Table Header. - */ - - hdr = (struct acpi_header *)p; - hdr->signature = ASCII32('S','S','D','T'); - hdr->revision = 2; - fixed_strcpy(hdr->oem_id, ACPI_OEM_ID); - fixed_strcpy(hdr->oem_table_id, ACPI_OEM_TABLE_ID); - hdr->oem_revision = ACPI_OEM_REVISION; - hdr->creator_id = ACPI_CREATOR_ID; - hdr->creator_revision = ACPI_CREATOR_REVISION; - p += sizeof(*hdr); - - /* - * 2. Scope Definition. - */ - - /* ScopeOp */ - *p++ = 0x10; - - /* PkgLength (includes length bytes!). */ - length = 1 + strlen(pr_scope) + (nr_cpus * sizeof(pdat)); - if ( length <= 0x3f ) - { - *p++ = length; - } - else if ( ++length <= 0xfff ) - { - *p++ = 0x40 | (length & 0xf); - *p++ = length >> 4; - } - else - { - length++; - *p++ = 0x80 | (length & 0xf); - *p++ = (length >> 4) & 0xff; - *p++ = (length >> 12) & 0xff; - } - - /* NameString */ - strncpy((char *)p, pr_scope, strlen(pr_scope)); - p += strlen(pr_scope); - - /* - * 3. Processor Objects. - */ - - for ( i = 0; i < nr_cpus; i++ ) - { - memcpy(p, pdat, sizeof(pdat)); - /* ProcessorName */ - p[5] = hex[(i>>4)&15]; - p[6] = hex[(i>>0)&15]; - /* ProcessorID */ - p[7] = i; - p += sizeof(pdat); - } - - hdr->length = p - buf; - set_checksum(hdr, offsetof(struct acpi_header, checksum), hdr->length); - - return hdr->length; -} - static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs) { int offset = 0, nr_tables = 0; @@ -287,10 +213,6 @@ static int construct_secondary_tables(ui offset += construct_hpet(hpet); table_ptrs[nr_tables++] = (unsigned long)hpet; } - - /* Processor Object SSDT. */ - table_ptrs[nr_tables++] = (unsigned long)&buf[offset]; - offset += construct_processor_objects(&buf[offset]); /* TPM TCPA and SSDT. */ tis_hdr = (uint16_t *)0xFED40F00; diff -r 7e8334e651c4 -r f97a0b6152c3 tools/firmware/hvmloader/acpi/dsdt.asl --- a/tools/firmware/hvmloader/acpi/dsdt.asl Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl Tue Feb 26 10:12:04 2008 -0700 @@ -26,6 +26,26 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, Name (\APCB, 0xFEC00000) Name (\APCL, 0x00010000) Name (\PUID, 0x00) + + Scope (\_PR) + { + Processor (PR00, 0x00, 0x0000, 0x00) {} + Processor (PR01, 0x01, 0x0000, 0x00) {} + Processor (PR02, 0x02, 0x0000, 0x00) {} + Processor (PR03, 0x03, 0x0000, 0x00) {} + Processor (PR04, 0x00, 0x0000, 0x00) {} + Processor (PR05, 0x01, 0x0000, 0x00) {} + Processor (PR06, 0x02, 0x0000, 0x00) {} + Processor (PR07, 0x03, 0x0000, 0x00) {} + Processor (PR08, 0x00, 0x0000, 0x00) {} + Processor (PR09, 0x01, 0x0000, 0x00) {} + Processor (PR0A, 0x02, 0x0000, 0x00) {} + Processor (PR0B, 0x03, 0x0000, 0x00) {} + Processor (PR0C, 0x00, 0x0000, 0x00) {} + Processor (PR0D, 0x01, 0x0000, 0x00) {} + Processor (PR0E, 0x02, 0x0000, 0x00) {} + Processor (PR0F, 0x03, 0x0000, 0x00) {} + } /* S4 (STD) and S5 (power-off) type codes: must match piix4 emulation. */ Name (\_S4, Package (0x04) diff -r 7e8334e651c4 -r f97a0b6152c3 tools/firmware/hvmloader/acpi/dsdt.c --- a/tools/firmware/hvmloader/acpi/dsdt.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/firmware/hvmloader/acpi/dsdt.c Tue Feb 26 10:12:04 2008 -0700 @@ -5,15 +5,15 @@ * Copyright (C) 2000 - 2006 Intel Corporation * Supports ACPI Specification Revision 3.0a * - * Compilation of "dsdt.asl" - Fri Feb 15 14:07:57 2008 + * Compilation of "dsdt.asl" - Mon Feb 25 10:54:06 2008 * * C source code output * */ unsigned char AmlCode[] = { - 0x44,0x53,0x44,0x54,0x5A,0x10,0x00,0x00, /* 00000000 "DSDTZ..." */ - 0x02,0xCC,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ + 0x44,0x53,0x44,0x54,0x31,0x11,0x00,0x00, /* 00000000 "DSDT1..." */ + 0x02,0xC7,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ 0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ @@ -23,518 +23,545 @@ unsigned char AmlCode[] = 0x41,0x50,0x43,0x42,0x0C,0x00,0x00,0xC0, /* 00000040 "APCB...." */ 0xFE,0x08,0x41,0x50,0x43,0x4C,0x0C,0x00, /* 00000048 "..APCL.." */ 0x00,0x01,0x00,0x08,0x50,0x55,0x49,0x44, /* 00000050 "....PUID" */ - 0x00,0x08,0x5F,0x53,0x34,0x5F,0x12,0x08, /* 00000058 ".._S4_.." */ - 0x04,0x0A,0x06,0x0A,0x06,0x00,0x00,0x08, /* 00000060 "........" */ - 0x5F,0x53,0x35,0x5F,0x12,0x08,0x04,0x0A, /* 00000068 "_S5_...." */ - 0x07,0x0A,0x07,0x00,0x00,0x08,0x50,0x49, /* 00000070 "......PI" */ - 0x43,0x44,0x00,0x14,0x0C,0x5F,0x50,0x49, /* 00000078 "CD..._PI" */ - 0x43,0x01,0x70,0x68,0x50,0x49,0x43,0x44, /* 00000080 "C.phPICD" */ - 0x10,0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B, /* 00000088 ".B._SB_[" */ - 0x80,0x42,0x49,0x4F,0x53,0x00,0x0C,0x00, /* 00000090 ".BIOS..." */ - 0xA0,0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21, /* 00000098 ".....[.!" */ - 0x42,0x49,0x4F,0x53,0x01,0x55,0x41,0x52, /* 000000A0 "BIOS.UAR" */ - 0x31,0x01,0x55,0x41,0x52,0x32,0x01,0x48, /* 000000A8 "1.UAR2.H" */ - 0x50,0x45,0x54,0x01,0x00,0x1D,0x50,0x4D, /* 000000B0 "PET...PM" */ - 0x49,0x4E,0x20,0x50,0x4C,0x45,0x4E,0x20, /* 000000B8 "IN PLEN " */ - 0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D,0x30, /* 000000C0 "[.I.MEM0" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 000000C8 "._HID.A." */ - 0x0C,0x02,0x08,0x5F,0x43,0x52,0x53,0x11, /* 000000D0 "..._CRS." */ - 0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00,0x0D, /* 000000D8 "3.0.+..." */ - 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */ - 0x00,0xFF,0xFF,0x09,0x00,0x00,0x00,0x00, /* 000000F0 "........" */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F8 "........" */ - 0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00, /* 00000100 "........" */ - 0x00,0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50, /* 00000108 ".y.[.N.P" */ - 0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44, /* 00000110 "CI0._HID" */ - 0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55, /* 00000118 ".A...._U" */ - 0x49,0x44,0x00,0x08,0x5F,0x41,0x44,0x52, /* 00000120 "ID.._ADR" */ - 0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x14, /* 00000128 ".._BBN.." */ - 0x4E,0x0C,0x5F,0x43,0x52,0x53,0x00,0x08, /* 00000130 "N._CRS.." */ - 0x50,0x52,0x54,0x30,0x11,0x42,0x07,0x0A, /* 00000138 "PRT0.B.." */ - 0x6E,0x88,0x0D,0x00,0x02,0x0E,0x00,0x00, /* 00000140 "n......." */ - 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, /* 00000148 "........" */ - 0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01, /* 00000150 ".G......" */ - 0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00, /* 00000158 "........" */ - 0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8, /* 00000160 "........" */ - 0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,0x00, /* 00000168 "........" */ - 0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00, /* 00000170 "........" */ - 0xF3,0x87,0x17,0x00,0x00,0x0C,0x03,0x00, /* 00000178 "........" */ - 0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0xFF, /* 00000180 "........" */ - 0xFF,0x0B,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000188 "........" */ - 0x00,0x02,0x00,0x87,0x17,0x00,0x00,0x0C, /* 00000190 "........" */ - 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000198 "........" */ - 0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00, /* 000001A0 "........" */ - 0x00,0x00,0x00,0x00,0x05,0x79,0x00,0x8A, /* 000001A8 ".....y.." */ - 0x50,0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D, /* 000001B0 "PRT0.\MM" */ - 0x49,0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A, /* 000001B8 "IN.PRT0." */ - 0x60,0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52, /* 000001C0 "`MMAX.PR" */ - 0x54,0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E, /* 000001C8 "T0.hMLEN" */ - 0x70,0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49, /* 000001D0 "pPMINMMI" */ - 0x4E,0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C, /* 000001D8 "NpPLENML" */ - 0x45,0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D, /* 000001E0 "ENrMMINM" */ - 0x4C,0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74, /* 000001E8 "LENMMAXt" */ - 0x4D,0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41, /* 000001F0 "MMAX.MMA" */ - 0x58,0xA4,0x50,0x52,0x54,0x30,0x08,0x42, /* 000001F8 "X.PRT0.B" */ - 0x55,0x46,0x41,0x11,0x09,0x0A,0x06,0x23, /* 00000200 "UFA....#" */ - 0x20,0x0C,0x18,0x79,0x00,0x08,0x42,0x55, /* 00000208 " ..y..BU" */ - 0x46,0x42,0x11,0x09,0x0A,0x06,0x23,0x00, /* 00000210 "FB....#." */ - 0x00,0x18,0x79,0x00,0x8B,0x42,0x55,0x46, /* 00000218 "..y..BUF" */ - 0x42,0x01,0x49,0x52,0x51,0x56,0x5B,0x82, /* 00000220 "B.IRQV[." */ - 0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F, /* 00000228 "H.LNKA._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 00000230 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x1C, /* 00000238 "._UID..." */ - 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 00000240 "_STA.{PI" */ - 0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 00000248 "RA..`..." */ - 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 00000250 "`......." */ - 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 00000258 "....._PR" */ - 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 00000260 "S..BUFA." */ - 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 00000268 "._DIS.}P" */ - 0x49,0x52,0x41,0x0A,0x80,0x50,0x49,0x52, /* 00000270 "IRA..PIR" */ - 0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 00000278 "A.._CRS." */ - 0x7B,0x50,0x49,0x52,0x41,0x0A,0x0F,0x60, /* 00000280 "{PIRA..`" */ - 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000288 "y.`IRQV." */ - 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000290 "BUFB.._S" */ - 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000298 "RS..h.IR" */ - 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 000002A0 "Q1.IRQ1`" */ - 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x41, /* 000002A8 "v`p`PIRA" */ - 0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42, /* 000002B0 "[.I.LNKB" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 000002B8 "._HID.A." */ - 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 000002C0 "..._UID." */ - 0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00, /* 000002C8 "..._STA." */ - 0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,0x60, /* 000002D0 "{PIRB..`" */ - 0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A, /* 000002D8 "...`...." */ - 0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B, /* 000002E0 "........" */ - 0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55, /* 000002E8 "_PRS..BU" */ - 0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53, /* 000002F0 "FA.._DIS" */ - 0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80, /* 000002F8 ".}PIRB.." */ - 0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,0x43, /* 00000300 "PIRB.._C" */ - 0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x42, /* 00000308 "RS.{PIRB" */ - 0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52, /* 00000310 "..`y.`IR" */ - 0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14, /* 00000318 "QV.BUFB." */ - 0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68, /* 00000320 "._SRS..h" */ - 0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52, /* 00000328 ".IRQ1.IR" */ - 0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50, /* 00000330 "Q1`v`p`P" */ - 0x49,0x52,0x42,0x5B,0x82,0x49,0x08,0x4C, /* 00000338 "IRB[.I.L" */ - 0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,0x44, /* 00000340 "NKC._HID" */ - 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 00000348 ".A...._U" */ - 0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53, /* 00000350 "ID...._S" */ - 0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x43, /* 00000358 "TA.{PIRC" */ - 0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A, /* 00000360 "..`...`." */ - 0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A, /* 00000368 "........" */ - 0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00, /* 00000370 "..._PRS." */ - 0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F, /* 00000378 ".BUFA.._" */ - 0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52, /* 00000380 "DIS.}PIR" */ - 0x43,0x0A,0x80,0x50,0x49,0x52,0x43,0x14, /* 00000388 "C..PIRC." */ - 0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50, /* 00000390 "._CRS.{P" */ - 0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,0x01, /* 00000398 "IRC..`y." */ - 0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55, /* 000003A0 "`IRQV.BU" */ - 0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53, /* 000003A8 "FB.._SRS" */ - 0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31, /* 000003B0 "..h.IRQ1" */ - 0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60, /* 000003B8 ".IRQ1`v`" */ - 0x70,0x60,0x50,0x49,0x52,0x43,0x5B,0x82, /* 000003C0 "p`PIRC[." */ - 0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F, /* 000003C8 "I.LNKD._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F, /* 000003D0 "HID.A..." */ - 0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,0x14, /* 000003D8 "._UID..." */ - 0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50, /* 000003E0 "._STA.{P" */ - 0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,0x08, /* 000003E8 "IRD..`.." */ - 0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1, /* 000003F0 ".`......" */ - 0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50, /* 000003F8 "......_P" */ - 0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41, /* 00000400 "RS..BUFA" */ - 0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D, /* 00000408 ".._DIS.}" */ - 0x50,0x49,0x52,0x44,0x0A,0x80,0x50,0x49, /* 00000410 "PIRD..PI" */ - 0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,0x53, /* 00000418 "RD.._CRS" */ - 0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F, /* 00000420 ".{PIRD.." */ - 0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56, /* 00000428 "`y.`IRQV" */ - 0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F, /* 00000430 ".BUFB.._" */ - 0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49, /* 00000438 "SRS..h.I" */ - 0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31, /* 00000440 "RQ1.IRQ1" */ - 0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52, /* 00000448 "`v`p`PIR" */ - 0x44,0x5B,0x82,0x44,0x05,0x48,0x50,0x45, /* 00000450 "D[.D.HPE" */ - 0x54,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000458 "T._HID.A" */ - 0xD0,0x01,0x03,0x08,0x5F,0x55,0x49,0x44, /* 00000460 "...._UID" */ - 0x00,0x14,0x18,0x5F,0x53,0x54,0x41,0x00, /* 00000468 "..._STA." */ - 0xA0,0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50, /* 00000470 "...^^^HP" */ - 0x45,0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4, /* 00000478 "ET......" */ - 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000480 "..._CRS." */ - 0x1F,0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D, /* 00000488 "........" */ - 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xD0, /* 00000490 "........" */ - 0xFE,0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00, /* 00000498 "........" */ - 0x00,0x00,0x04,0x00,0x00,0x79,0x00,0x14, /* 000004A0 ".....y.." */ - 0x16,0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A, /* 000004A8 "._PRT..." */ - 0x50,0x49,0x43,0x44,0xA4,0x50,0x52,0x54, /* 000004B0 "PICD.PRT" */ - 0x41,0xA4,0x50,0x52,0x54,0x50,0x08,0x50, /* 000004B8 "A.PRTP.P" */ - 0x52,0x54,0x50,0x12,0x49,0x36,0x3C,0x12, /* 000004C0 "RTP.I6<." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00, /* 000004C8 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 000004D0 "LNKB...." */ - 0x0C,0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E, /* 000004D8 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000004E0 "KC......" */ - 0xFF,0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000004E8 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000004F0 "D......." */ - 0x01,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 000004F8 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02, /* 00000500 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000508 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01, /* 00000510 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000518 "LNKD...." */ - 0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C, /* 00000520 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 00000528 "NKA....." */ - 0xFF,0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E, /* 00000530 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000538 "KB......" */ - 0xFF,0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 00000540 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03, /* 00000548 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000550 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A, /* 00000558 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000560 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03, /* 00000568 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04, /* 00000570 "LNKC...." */ - 0x0C,0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E, /* 00000578 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000580 "KA......" */ - 0xFF,0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42, /* 00000588 "....LNKB" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04, /* 00000590 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00, /* 00000598 "...LNKC." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000005A0 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 000005A8 "..LNKD.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00, /* 000005B0 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 000005B8 "LNKB...." */ - 0x0C,0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E, /* 000005C0 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000005C8 "KC......" */ - 0xFF,0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000005D0 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000005D8 "D......." */ - 0x05,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 000005E0 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06, /* 000005E8 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000005F0 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01, /* 000005F8 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000600 "LNKD...." */ - 0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C, /* 00000608 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 00000610 "NKA....." */ - 0xFF,0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E, /* 00000618 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000620 "KB......" */ - 0xFF,0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 00000628 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07, /* 00000630 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000638 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A, /* 00000640 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000648 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03, /* 00000650 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04, /* 00000658 "LNKC...." */ - 0x0C,0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E, /* 00000660 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000668 "KA......" */ - 0xFF,0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42, /* 00000670 "....LNKB" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08, /* 00000678 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00, /* 00000680 "...LNKC." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000688 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000690 "..LNKD.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00, /* 00000698 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 000006A0 "LNKB...." */ - 0x0C,0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E, /* 000006A8 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000006B0 "KC......" */ - 0xFF,0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000006B8 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000006C0 "D......." */ - 0x09,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 000006C8 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A, /* 000006D0 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000006D8 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01, /* 000006E0 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000006E8 "LNKD...." */ - 0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C, /* 000006F0 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000006F8 "NKA....." */ - 0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E, /* 00000700 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000708 "KB......" */ - 0xFF,0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 00000710 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000718 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000720 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A, /* 00000728 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000730 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03, /* 00000738 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04, /* 00000740 "LNKC...." */ - 0x0C,0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E, /* 00000748 "......LN" */ - 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000750 "KA......" */ - 0xFF,0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42, /* 00000758 "....LNKB" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C, /* 00000760 "........" */ - 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00, /* 00000768 "...LNKC." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000770 "........" */ - 0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000778 "..LNKD.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00, /* 00000780 "........" */ - 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 00000788 "LNKB...." */ - 0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E, /* 00000790 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000798 "KC......" */ - 0xFF,0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 000007A0 ".....LNK" */ - 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000007A8 "D......." */ - 0x0D,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41, /* 000007B0 "....LNKA" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E, /* 000007B8 "........" */ - 0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 000007C0 "..LNKC.." */ - 0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01, /* 000007C8 "........" */ - 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000007D0 "LNKD...." */ - 0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C, /* 000007D8 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000007E0 "NKA....." */ - 0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E, /* 000007E8 "......LN" */ - 0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000007F0 "KB......" */ - 0xFF,0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44, /* 000007F8 "....LNKD" */ - 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000800 "........" */ - 0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000808 "..LNKA.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 00000810 "........" */ - 0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000818 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03, /* 00000820 "........" */ - 0x4C,0x4E,0x4B,0x43,0x00,0x08,0x50,0x52, /* 00000828 "LNKC..PR" */ - 0x54,0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B, /* 00000830 "TA.A/<.." */ - 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00, /* 00000838 "........" */ - 0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000840 "........" */ - 0x01,0x00,0x01,0x00,0x0A,0x15,0x12,0x0C, /* 00000848 "........" */ - 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02, /* 00000850 "........" */ - 0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF, /* 00000858 "........" */ - 0xFF,0x01,0x00,0x0A,0x03,0x00,0x0A,0x17, /* 00000860 "........" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000868 "........" */ - 0x00,0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C, /* 00000870 "........" */ - 0xFF,0xFF,0x02,0x00,0x01,0x00,0x0A,0x19, /* 00000878 "........" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000880 "........" */ - 0x0A,0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04, /* 00000888 "........" */ - 0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00, /* 00000890 "........" */ - 0x0A,0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000898 "........" */ - 0x03,0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B, /* 000008A0 "........" */ - 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00, /* 000008A8 "........" */ - 0x0A,0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000008B0 "........" */ - 0x03,0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12, /* 000008B8 "........" */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A, /* 000008C0 "........" */ - 0x03,0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C, /* 000008C8 "........" */ - 0xFF,0xFF,0x04,0x00,0x00,0x00,0x0A,0x20, /* 000008D0 "....... " */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000008D8 "........" */ - 0x01,0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C, /* 000008E0 "...!...." */ - 0xFF,0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A, /* 000008E8 "........" */ - 0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04, /* 000008F0 ""......." */ - 0x00,0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B, /* 000008F8 ".....#.." */ - 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00, /* 00000900 "........" */ - 0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000908 ".$......" */ - 0x05,0x00,0x01,0x00,0x0A,0x25,0x12,0x0C, /* 00000910 ".....%.." */ - 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02, /* 00000918 "........" */ - 0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF, /* 00000920 "..&....." */ - 0xFF,0x05,0x00,0x0A,0x03,0x00,0x0A,0x27, /* 00000928 ".......'" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000930 "........" */ - 0x00,0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C, /* 00000938 "...(...." */ - 0xFF,0xFF,0x06,0x00,0x01,0x00,0x0A,0x29, /* 00000940 ".......)" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000948 "........" */ - 0x0A,0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04, /* 00000950 "....*..." */ - 0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00, /* 00000958 "........" */ - 0x0A,0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000960 ".+......" */ - 0x07,0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B, /* 00000968 ".....,.." */ - 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00, /* 00000970 "........" */ - 0x0A,0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000978 ".-......" */ - 0x07,0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12, /* 00000980 "........" */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A, /* 00000988 "........" */ - 0x03,0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C, /* 00000990 ".../...." */ - 0xFF,0xFF,0x08,0x00,0x00,0x00,0x0A,0x11, /* 00000998 "........" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 000009A0 "........" */ - 0x01,0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C, /* 000009A8 "........" */ - 0xFF,0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A, /* 000009B0 "........" */ - 0x13,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08, /* 000009B8 "........" */ - 0x00,0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B, /* 000009C0 "........" */ - 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00, /* 000009C8 "........" */ - 0x0A,0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000009D0 "........" */ - 0x09,0x00,0x01,0x00,0x0A,0x16,0x12,0x0C, /* 000009D8 "........" */ - 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02, /* 000009E0 "........" */ - 0x00,0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF, /* 000009E8 "........" */ - 0xFF,0x09,0x00,0x0A,0x03,0x00,0x0A,0x18, /* 000009F0 "........" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 000009F8 "........" */ - 0x00,0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C, /* 00000A00 "........" */ - 0xFF,0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A, /* 00000A08 "........" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 00000A10 "........" */ - 0x0A,0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04, /* 00000A18 "........" */ - 0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00, /* 00000A20 "........" */ - 0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000A28 "........" */ - 0x0B,0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B, /* 00000A30 "........" */ - 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00, /* 00000A38 "........" */ - 0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A40 "........" */ - 0x0B,0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12, /* 00000A48 "........" */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A, /* 00000A50 "........" */ - 0x03,0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C, /* 00000A58 "... ...." */ - 0xFF,0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21, /* 00000A60 ".......!" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000A68 "........" */ - 0x01,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C, /* 00000A70 "..."...." */ - 0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A, /* 00000A78 "........" */ - 0x23,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C, /* 00000A80 "#......." */ - 0x00,0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B, /* 00000A88 ".....$.." */ - 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00, /* 00000A90 "........" */ - 0x0A,0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000A98 ".%......" */ - 0x0D,0x00,0x01,0x00,0x0A,0x26,0x12,0x0C, /* 00000AA0 ".....&.." */ - 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02, /* 00000AA8 "........" */ - 0x00,0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF, /* 00000AB0 "..'....." */ - 0xFF,0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28, /* 00000AB8 ".......(" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000AC0 "........" */ - 0x00,0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C, /* 00000AC8 "...)...." */ - 0xFF,0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A, /* 00000AD0 ".......*" */ - 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000AD8 "........" */ - 0x0A,0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04, /* 00000AE0 "....+..." */ - 0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00, /* 00000AE8 "........" */ - 0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000AF0 ".,......" */ - 0x0F,0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B, /* 00000AF8 ".....-.." */ - 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00, /* 00000B00 "........" */ - 0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000B08 "........" */ - 0x0F,0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12, /* 00000B10 "....../." */ - 0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 00000B18 "........" */ - 0x03,0x00,0x0A,0x10,0x5B,0x82,0x46,0x37, /* 00000B20 "....[.F7" */ - 0x49,0x53,0x41,0x5F,0x08,0x5F,0x41,0x44, /* 00000B28 "ISA_._AD" */ - 0x52,0x0C,0x00,0x00,0x01,0x00,0x5B,0x80, /* 00000B30 "R.....[." */ - 0x50,0x49,0x52,0x51,0x02,0x0A,0x60,0x0A, /* 00000B38 "PIRQ..`." */ - 0x04,0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29, /* 00000B40 "...\.[.)" */ - 0x5C,0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50, /* 00000B48 "\/._SB_P" */ - 0x43,0x49,0x30,0x49,0x53,0x41,0x5F,0x50, /* 00000B50 "CI0ISA_P" */ - 0x49,0x52,0x51,0x01,0x50,0x49,0x52,0x41, /* 00000B58 "IRQ.PIRA" */ - 0x08,0x50,0x49,0x52,0x42,0x08,0x50,0x49, /* 00000B60 ".PIRB.PI" */ - 0x52,0x43,0x08,0x50,0x49,0x52,0x44,0x08, /* 00000B68 "RC.PIRD." */ - 0x5B,0x82,0x46,0x0B,0x53,0x59,0x53,0x52, /* 00000B70 "[.F.SYSR" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000B78 "._HID.A." */ - 0x0C,0x02,0x08,0x5F,0x55,0x49,0x44,0x01, /* 00000B80 "..._UID." */ - 0x08,0x43,0x52,0x53,0x5F,0x11,0x4E,0x08, /* 00000B88 ".CRS_.N." */ - 0x0A,0x8A,0x47,0x01,0x10,0x00,0x10,0x00, /* 00000B90 "..G....." */ - 0x00,0x10,0x47,0x01,0x22,0x00,0x22,0x00, /* 00000B98 "..G."."." */ - 0x00,0x0C,0x47,0x01,0x30,0x00,0x30,0x00, /* 00000BA0 "..G.0.0." */ - 0x00,0x10,0x47,0x01,0x44,0x00,0x44,0x00, /* 00000BA8 "..G.D.D." */ - 0x00,0x1C,0x47,0x01,0x62,0x00,0x62,0x00, /* 00000BB0 "..G.b.b." */ - 0x00,0x02,0x47,0x01,0x65,0x00,0x65,0x00, /* 00000BB8 "..G.e.e." */ - 0x00,0x0B,0x47,0x01,0x72,0x00,0x72,0x00, /* 00000BC0 "..G.r.r." */ - 0x00,0x0E,0x47,0x01,0x80,0x00,0x80,0x00, /* 00000BC8 "..G....." */ - 0x00,0x01,0x47,0x01,0x84,0x00,0x84,0x00, /* 00000BD0 "..G....." */ - 0x00,0x03,0x47,0x01,0x88,0x00,0x88,0x00, /* 00000BD8 "..G....." */ - 0x00,0x01,0x47,0x01,0x8C,0x00,0x8C,0x00, /* 00000BE0 "..G....." */ - 0x00,0x03,0x47,0x01,0x90,0x00,0x90,0x00, /* 00000BE8 "..G....." */ - 0x00,0x10,0x47,0x01,0xA2,0x00,0xA2,0x00, /* 00000BF0 "..G....." */ - 0x00,0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00, /* 00000BF8 "..G....." */ - 0x00,0x10,0x47,0x01,0xA0,0x08,0xA0,0x08, /* 00000C00 "..G....." */ - 0x00,0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C, /* 00000C08 "..G....." */ - 0x00,0x10,0x47,0x01,0xD0,0x04,0xD0,0x04, /* 00000C10 "..G....." */ - 0x00,0x02,0x79,0x00,0x14,0x0B,0x5F,0x43, /* 00000C18 "..y..._C" */ - 0x52,0x53,0x00,0xA4,0x43,0x52,0x53,0x5F, /* 00000C20 "RS..CRS_" */ - 0x5B,0x82,0x2B,0x50,0x49,0x43,0x5F,0x08, /* 00000C28 "[.+PIC_." */ - 0x5F,0x48,0x49,0x44,0x0B,0x41,0xD0,0x08, /* 00000C30 "_HID.A.." */ - 0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,0x15, /* 00000C38 "_CRS...." */ - 0x47,0x01,0x20,0x00,0x20,0x00,0x01,0x02, /* 00000C40 "G. . ..." */ - 0x47,0x01,0xA0,0x00,0xA0,0x00,0x01,0x02, /* 00000C48 "G......." */ - 0x22,0x04,0x00,0x79,0x00,0x5B,0x82,0x47, /* 00000C50 ""..y.[.G" */ - 0x05,0x44,0x4D,0x41,0x30,0x08,0x5F,0x48, /* 00000C58 ".DMA0._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x02,0x00,0x08, /* 00000C60 "ID.A...." */ - 0x5F,0x43,0x52,0x53,0x11,0x41,0x04,0x0A, /* 00000C68 "_CRS.A.." */ - 0x3D,0x2A,0x10,0x04,0x47,0x01,0x00,0x00, /* 00000C70 "=*..G..." */ - 0x00,0x00,0x00,0x10,0x47,0x01,0x81,0x00, /* 00000C78 "....G..." */ - 0x81,0x00,0x00,0x03,0x47,0x01,0x87,0x00, /* 00000C80 "....G..." */ - 0x87,0x00,0x00,0x01,0x47,0x01,0x89,0x00, /* 00000C88 "....G..." */ - 0x89,0x00,0x00,0x03,0x47,0x01,0x8F,0x00, /* 00000C90 "....G..." */ - 0x8F,0x00,0x00,0x01,0x47,0x01,0xC0,0x00, /* 00000C98 "....G..." */ - 0xC0,0x00,0x00,0x20,0x47,0x01,0x80,0x04, /* 00000CA0 "... G..." */ - 0x80,0x04,0x00,0x10,0x79,0x00,0x5B,0x82, /* 00000CA8 "....y.[." */ - 0x25,0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48, /* 00000CB0 "%TMR_._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x01,0x00,0x08, /* 00000CB8 "ID.A...." */ - 0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D, /* 00000CC0 "_CRS...." */ - 0x47,0x01,0x40,0x00,0x40,0x00,0x00,0x04, /* 00000CC8 "G.@.@..." */ - 0x22,0x01,0x00,0x79,0x00,0x5B,0x82,0x25, /* 00000CD0 ""..y.[.%" */ - 0x52,0x54,0x43,0x5F,0x08,0x5F,0x48,0x49, /* 00000CD8 "RTC_._HI" */ - 0x44,0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F, /* 00000CE0 "D.A...._" */ - 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000CE8 "CRS....G" */ - 0x01,0x70,0x00,0x70,0x00,0x00,0x02,0x22, /* 00000CF0 ".p.p..."" */ - 0x00,0x01,0x79,0x00,0x5B,0x82,0x22,0x53, /* 00000CF8 "..y.[."S" */ - 0x50,0x4B,0x52,0x08,0x5F,0x48,0x49,0x44, /* 00000D00 "PKR._HID" */ - 0x0C,0x41,0xD0,0x08,0x00,0x08,0x5F,0x43, /* 00000D08 ".A...._C" */ - 0x52,0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01, /* 00000D10 "RS....G." */ - 0x61,0x00,0x61,0x00,0x00,0x01,0x79,0x00, /* 00000D18 "a.a...y." */ - 0x5B,0x82,0x31,0x50,0x53,0x32,0x4D,0x08, /* 00000D20 "[.1PS2M." */ - 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F, /* 00000D28 "_HID.A.." */ - 0x13,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41, /* 00000D30 ".._CID.A" */ - 0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54, /* 00000D38 "....._ST" */ - 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000D40 "A....._C" */ - 0x52,0x53,0x11,0x08,0x0A,0x05,0x22,0x00, /* 00000D48 "RS...."." */ - 0x10,0x79,0x00,0x5B,0x82,0x42,0x04,0x50, /* 00000D50 ".y.[.B.P" */ - 0x53,0x32,0x4B,0x08,0x5F,0x48,0x49,0x44, /* 00000D58 "S2K._HID" */ - 0x0C,0x41,0xD0,0x03,0x03,0x08,0x5F,0x43, /* 00000D60 ".A...._C" */ - 0x49,0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14, /* 00000D68 "ID.A...." */ - 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000D70 "._STA..." */ - 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 00000D78 ".._CRS.." */ - 0x0A,0x15,0x47,0x01,0x60,0x00,0x60,0x00, /* 00000D80 "..G.`.`." */ - 0x00,0x01,0x47,0x01,0x64,0x00,0x64,0x00, /* 00000D88 "..G.d.d." */ - 0x00,0x01,0x22,0x02,0x00,0x79,0x00,0x5B, /* 00000D90 ".."..y.[" */ - 0x82,0x3A,0x46,0x44,0x43,0x30,0x08,0x5F, /* 00000D98 ".:FDC0._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,0x00, /* 00000DA0 "HID.A..." */ - 0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4, /* 00000DA8 ".._STA.." */ - 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000DB0 "..._CRS." */ - 0x1B,0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0, /* 00000DB8 "...G...." */ - 0x03,0x01,0x06,0x47,0x01,0xF7,0x03,0xF7, /* 00000DC0 "...G...." */ - 0x03,0x01,0x01,0x22,0x40,0x00,0x2A,0x04, /* 00000DC8 "..."@.*." */ - 0x00,0x79,0x00,0x5B,0x82,0x46,0x04,0x55, /* 00000DD0 ".y.[.F.U" */ - 0x41,0x52,0x31,0x08,0x5F,0x48,0x49,0x44, /* 00000DD8 "AR1._HID" */ - 0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55, /* 00000DE0 ".A...._U" */ - 0x49,0x44,0x01,0x14,0x19,0x5F,0x53,0x54, /* 00000DE8 "ID..._ST" */ - 0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E, /* 00000DF0 "A....^^^" */ - 0x5E,0x55,0x41,0x52,0x31,0x00,0xA4,0x00, /* 00000DF8 "^UAR1..." */ - 0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000E00 "......_C" */ - 0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00000E08 "RS....G." */ - 0xF8,0x03,0xF8,0x03,0x08,0x08,0x22,0x10, /* 00000E10 "......"." */ - 0x00,0x79,0x00,0x5B,0x82,0x47,0x04,0x55, /* 00000E18 ".y.[.G.U" */ - 0x41,0x52,0x32,0x08,0x5F,0x48,0x49,0x44, /* 00000E20 "AR2._HID" */ - 0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55, /* 00000E28 ".A...._U" */ - 0x49,0x44,0x0A,0x02,0x14,0x19,0x5F,0x53, /* 00000E30 "ID...._S" */ - 0x54,0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E, /* 00000E38 "TA....^^" */ - 0x5E,0x5E,0x55,0x41,0x52,0x32,0x00,0xA4, /* 00000E40 "^^UAR2.." */ - 0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000E48 "......._" */ - 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000E50 "CRS....G" */ - 0x01,0xF8,0x02,0xF8,0x02,0x08,0x08,0x22, /* 00000E58 "......."" */ - 0x08,0x00,0x79,0x00,0x5B,0x82,0x36,0x4C, /* 00000E60 "..y.[.6L" */ - 0x54,0x50,0x31,0x08,0x5F,0x48,0x49,0x44, /* 00000E68 "TP1._HID" */ - 0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F,0x55, /* 00000E70 ".A...._U" */ - 0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53, /* 00000E78 "ID...._S" */ - 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000E80 "TA....._" */ - 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000E88 "CRS....G" */ - 0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22, /* 00000E90 ".x.x..."" */ - 0x80,0x00,0x79,0x00,0x5B,0x82,0x4D,0x07, /* 00000E98 "..y.[.M." */ - 0x53,0x31,0x46,0x30,0x08,0x5F,0x41,0x44, /* 00000EA0 "S1F0._AD" */ - 0x52,0x0C,0x00,0x00,0x06,0x00,0x08,0x5F, /* 00000EA8 "R......_" */ - 0x53,0x55,0x4E,0x01,0x14,0x13,0x5F,0x50, /* 00000EB0 "SUN..._P" */ - 0x53,0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E, /* 00000EB8 "S0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000EC0 "_GPEDPT2" */ - 0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70, /* 00000EC8 ".._PS3.p" */ - 0x0A,0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000ED0 "..\._GPE" */ - 0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45, /* 00000ED8 "DPT2.._E" */ - 0x4A,0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E, /* 00000EE0 "J0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000EE8 "_GPEDPT2" */ - 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000EF0 "p.\._GPE" */ - 0x50,0x48,0x50,0x31,0x14,0x1E,0x5F,0x53, /* 00000EF8 "PHP1.._S" */ - 0x54,0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E, /* 00000F00 "TA.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000F08 "_GPEDPT2" */ - 0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50, /* 00000F10 ".\._GPEP" */ - 0x48,0x50,0x31,0x5B,0x82,0x4E,0x07,0x53, /* 00000F18 "HP1[.N.S" */ - 0x32,0x46,0x30,0x08,0x5F,0x41,0x44,0x52, /* 00000F20 "2F0._ADR" */ - 0x0C,0x00,0x00,0x07,0x00,0x08,0x5F,0x53, /* 00000F28 "......_S" */ - 0x55,0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50, /* 00000F30 "UN...._P" */ - 0x53,0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E, /* 00000F38 "S0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000F40 "_GPEDPT2" */ - 0x14,0x13,0x5F,0x50,0x53,0x33,0x00,0x70, /* 00000F48 ".._PS3.p" */ - 0x0A,0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000F50 "..\._GPE" */ - 0x44,0x50,0x54,0x32,0x14,0x1F,0x5F,0x45, /* 00000F58 "DPT2.._E" */ - 0x4A,0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E, /* 00000F60 "J0.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000F68 "_GPEDPT2" */ - 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00000F70 "p.\._GPE" */ - 0x50,0x48,0x50,0x32,0x14,0x1E,0x5F,0x53, /* 00000F78 "PHP2.._S" */ - 0x54,0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E, /* 00000F80 "TA.p..\." */ - 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00000F88 "_GPEDPT2" */ - 0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50, /* 00000F90 ".\._GPEP" */ - 0x48,0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47, /* 00000F98 "HP2.N._G" */ - 0x50,0x45,0x5B,0x80,0x50,0x48,0x50,0x5F, /* 00000FA0 "PE[.PHP_" */ - 0x01,0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81, /* 00000FA8 "......[." */ - 0x15,0x50,0x48,0x50,0x5F,0x01,0x50,0x53, /* 00000FB0 ".PHP_.PS" */ - 0x54,0x41,0x08,0x50,0x48,0x50,0x31,0x08, /* 00000FB8 "TA.PHP1." */ - 0x50,0x48,0x50,0x32,0x08,0x5B,0x80,0x44, /* 00000FC0 "PHP2.[.D" */ - 0x47,0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A, /* 00000FC8 "G1_..D.." */ - 0x04,0x5B,0x81,0x10,0x44,0x47,0x31,0x5F, /* 00000FD0 ".[..DG1_" */ - 0x01,0x44,0x50,0x54,0x31,0x08,0x44,0x50, /* 00000FD8 ".DPT1.DP" */ - 0x54,0x32,0x08,0x14,0x46,0x07,0x5F,0x4C, /* 00000FE0 "T2..F._L" */ - 0x30,0x33,0x00,0x08,0x53,0x4C,0x54,0x5F, /* 00000FE8 "03..SLT_" */ - 0x00,0x08,0x45,0x56,0x54,0x5F,0x00,0x70, /* 00000FF0 "..EVT_.p" */ - 0x50,0x53,0x54,0x41,0x61,0x7A,0x61,0x0A, /* 00000FF8 "PSTAaza." */ - 0x04,0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A, /* 00001000 ".SLT_{a." */ - 0x0F,0x45,0x56,0x54,0x5F,0x70,0x53,0x4C, /* 00001008 ".EVT_pSL" */ - 0x54,0x5F,0x44,0x50,0x54,0x31,0x70,0x45, /* 00001010 "T_DPT1pE" */ - 0x56,0x54,0x5F,0x44,0x50,0x54,0x32,0xA0, /* 00001018 "VT_DPT2." */ - 0x1B,0x93,0x53,0x4C,0x54,0x5F,0x01,0x86, /* 00001020 "..SLT_.." */ - 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 00001028 "\/._SB_P" */ - 0x43,0x49,0x30,0x53,0x31,0x46,0x30,0x45, /* 00001030 "CI0S1F0E" */ - 0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93, /* 00001038 "VT_....." */ - 0x53,0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C, /* 00001040 "SLT_...\" */ - 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001048 "/._SB_PC" */ - 0x49,0x30,0x53,0x32,0x46,0x30,0x45,0x56, /* 00001050 "I0S2F0EV" */ - 0x54,0x5F, + 0x00,0x10,0x46,0x0D,0x5F,0x50,0x52,0x5F, /* 00000058 "..F._PR_" */ + 0x5B,0x83,0x0B,0x50,0x52,0x30,0x30,0x00, /* 00000060 "[..PR00." */ + 0x00,0x00,0x00,0x00,0x00,0x5B,0x83,0x0B, /* 00000068 ".....[.." */ + 0x50,0x52,0x30,0x31,0x01,0x00,0x00,0x00, /* 00000070 "PR01...." */ + 0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,0x30, /* 00000078 "..[..PR0" */ + 0x32,0x02,0x00,0x00,0x00,0x00,0x00,0x5B, /* 00000080 "2......[" */ + 0x83,0x0B,0x50,0x52,0x30,0x33,0x03,0x00, /* 00000088 "..PR03.." */ + 0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x50, /* 00000090 "....[..P" */ + 0x52,0x30,0x34,0x00,0x00,0x00,0x00,0x00, /* 00000098 "R04....." */ + 0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,0x35, /* 000000A0 ".[..PR05" */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x5B,0x83, /* 000000A8 "......[." */ + 0x0B,0x50,0x52,0x30,0x36,0x02,0x00,0x00, /* 000000B0 ".PR06..." */ + 0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,0x52, /* 000000B8 "...[..PR" */ + 0x30,0x37,0x03,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "07......" */ + 0x5B,0x83,0x0B,0x50,0x52,0x30,0x38,0x00, /* 000000C8 "[..PR08." */ + 0x00,0x00,0x00,0x00,0x00,0x5B,0x83,0x0B, /* 000000D0 ".....[.." */ + 0x50,0x52,0x30,0x39,0x01,0x00,0x00,0x00, /* 000000D8 "PR09...." */ + 0x00,0x00,0x5B,0x83,0x0B,0x50,0x52,0x30, /* 000000E0 "..[..PR0" */ + 0x41,0x02,0x00,0x00,0x00,0x00,0x00,0x5B, /* 000000E8 "A......[" */ + 0x83,0x0B,0x50,0x52,0x30,0x42,0x03,0x00, /* 000000F0 "..PR0B.." */ + 0x00,0x00,0x00,0x00,0x5B,0x83,0x0B,0x50, /* 000000F8 "....[..P" */ + 0x52,0x30,0x43,0x00,0x00,0x00,0x00,0x00, /* 00000100 "R0C....." */ + 0x00,0x5B,0x83,0x0B,0x50,0x52,0x30,0x44, /* 00000108 ".[..PR0D" */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x5B,0x83, /* 00000110 "......[." */ + 0x0B,0x50,0x52,0x30,0x45,0x02,0x00,0x00, /* 00000118 ".PR0E..." */ + 0x00,0x00,0x00,0x5B,0x83,0x0B,0x50,0x52, /* 00000120 "...[..PR" */ + 0x30,0x46,0x03,0x00,0x00,0x00,0x00,0x00, /* 00000128 "0F......" */ + 0x08,0x5F,0x53,0x34,0x5F,0x12,0x08,0x04, /* 00000130 "._S4_..." */ + 0x0A,0x06,0x0A,0x06,0x00,0x00,0x08,0x5F, /* 00000138 "......._" */ + 0x53,0x35,0x5F,0x12,0x08,0x04,0x0A,0x07, /* 00000140 "S5_....." */ + 0x0A,0x07,0x00,0x00,0x08,0x50,0x49,0x43, /* 00000148 ".....PIC" */ + 0x44,0x00,0x14,0x0C,0x5F,0x50,0x49,0x43, /* 00000150 "D..._PIC" */ + 0x01,0x70,0x68,0x50,0x49,0x43,0x44,0x10, /* 00000158 ".phPICD." */ + 0x42,0xF1,0x5F,0x53,0x42,0x5F,0x5B,0x80, /* 00000160 "B._SB_[." */ + 0x42,0x49,0x4F,0x53,0x00,0x0C,0x00,0xA0, /* 00000168 "BIOS...." */ + 0x0E,0x00,0x0A,0x10,0x5B,0x81,0x21,0x42, /* 00000170 "....[.!B" */ + 0x49,0x4F,0x53,0x01,0x55,0x41,0x52,0x31, /* 00000178 "IOS.UAR1" */ + 0x01,0x55,0x41,0x52,0x32,0x01,0x48,0x50, /* 00000180 ".UAR2.HP" */ + 0x45,0x54,0x01,0x00,0x1D,0x50,0x4D,0x49, /* 00000188 "ET...PMI" */ + 0x4E,0x20,0x50,0x4C,0x45,0x4E,0x20,0x5B, /* 00000190 "N PLEN [" */ + 0x82,0x49,0x04,0x4D,0x45,0x4D,0x30,0x08, /* 00000198 ".I.MEM0." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 000001A0 "_HID.A.." */ + 0x02,0x08,0x5F,0x43,0x52,0x53,0x11,0x33, /* 000001A8 ".._CRS.3" */ + 0x0A,0x30,0x8A,0x2B,0x00,0x00,0x0D,0x03, /* 000001B0 ".0.+...." */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001B8 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001C0 "........" */ + 0xFF,0xFF,0x09,0x00,0x00,0x00,0x00,0x00, /* 000001C8 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001D0 "........" */ + 0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x00, /* 000001D8 "........" */ + 0x79,0x00,0x5B,0x82,0x4E,0xE8,0x50,0x43, /* 000001E0 "y.[.N.PC" */ + 0x49,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000001E8 "I0._HID." */ + 0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55,0x49, /* 000001F0 "A...._UI" */ + 0x44,0x00,0x08,0x5F,0x41,0x44,0x52,0x00, /* 000001F8 "D.._ADR." */ + 0x08,0x5F,0x42,0x42,0x4E,0x00,0x14,0x4E, /* 00000200 "._BBN..N" */ + 0x0C,0x5F,0x43,0x52,0x53,0x00,0x08,0x50, /* 00000208 "._CRS..P" */ + 0x52,0x54,0x30,0x11,0x42,0x07,0x0A,0x6E, /* 00000210 "RT0.B..n" */ + 0x88,0x0D,0x00,0x02,0x0E,0x00,0x00,0x00, /* 00000218 "........" */ + 0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01, /* 00000220 "........" */ + 0x47,0x01,0xF8,0x0C,0xF8,0x0C,0x01,0x08, /* 00000228 "G......." */ + 0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00, /* 00000230 "........" */ + 0x00,0x00,0xF7,0x0C,0x00,0x00,0xF8,0x0C, /* 00000238 "........" */ + 0x88,0x0D,0x00,0x01,0x0C,0x03,0x00,0x00, /* 00000240 "........" */ + 0x00,0x0D,0xFF,0xFF,0x00,0x00,0x00,0xF3, /* 00000248 "........" */ + 0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00, /* 00000250 "........" */ + 0x00,0x00,0x00,0x00,0x0A,0x00,0xFF,0xFF, /* 00000258 "........" */ + 0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000260 "........" */ + 0x02,0x00,0x87,0x17,0x00,0x00,0x0C,0x03, /* 00000268 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0, /* 00000270 "........" */ + 0xFF,0xFF,0xFF,0xF4,0x00,0x00,0x00,0x00, /* 00000278 "........" */ + 0x00,0x00,0x00,0x05,0x79,0x00,0x8A,0x50, /* 00000280 "....y..P" */ + 0x52,0x54,0x30,0x0A,0x5C,0x4D,0x4D,0x49, /* 00000288 "RT0.\MMI" */ + 0x4E,0x8A,0x50,0x52,0x54,0x30,0x0A,0x60, /* 00000290 "N.PRT0.`" */ + 0x4D,0x4D,0x41,0x58,0x8A,0x50,0x52,0x54, /* 00000298 "MMAX.PRT" */ + 0x30,0x0A,0x68,0x4D,0x4C,0x45,0x4E,0x70, /* 000002A0 "0.hMLENp" */ + 0x50,0x4D,0x49,0x4E,0x4D,0x4D,0x49,0x4E, /* 000002A8 "PMINMMIN" */ + 0x70,0x50,0x4C,0x45,0x4E,0x4D,0x4C,0x45, /* 000002B0 "pPLENMLE" */ + 0x4E,0x72,0x4D,0x4D,0x49,0x4E,0x4D,0x4C, /* 000002B8 "NrMMINML" */ + 0x45,0x4E,0x4D,0x4D,0x41,0x58,0x74,0x4D, /* 000002C0 "ENMMAXtM" */ + 0x4D,0x41,0x58,0x01,0x4D,0x4D,0x41,0x58, /* 000002C8 "MAX.MMAX" */ + 0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55, /* 000002D0 ".PRT0.BU" */ + 0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x20, /* 000002D8 "FA....# " */ + 0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46, /* 000002E0 "..y..BUF" */ + 0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00, /* 000002E8 "B....#.." */ + 0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42, /* 000002F0 ".y..BUFB" */ + 0x01,0x49,0x52,0x51,0x56,0x5B,0x82,0x48, /* 000002F8 ".IRQV[.H" */ + 0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48, /* 00000300 ".LNKA._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 00000308 "ID.A...." */ + 0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F, /* 00000310 "_UID..._" */ + 0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 00000318 "STA.{PIR" */ + 0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 00000320 "A..`...`" */ + 0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 00000328 "........" */ + 0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 00000330 "...._PRS" */ + 0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 00000338 "..BUFA.." */ + 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 00000340 "_DIS.}PI" */ + 0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41, /* 00000348 "RA..PIRA" */ + 0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 00000350 ".._CRS.{" */ + 0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,0x79, /* 00000358 "PIRA..`y" */ + 0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 00000360 ".`IRQV.B" */ + 0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 00000368 "UFB.._SR" */ + 0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 00000370 "S..h.IRQ" */ + 0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 00000378 "1.IRQ1`v" */ + 0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B, /* 00000380 "`p`PIRA[" */ + 0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08, /* 00000388 ".I.LNKB." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000390 "_HID.A.." */ + 0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02, /* 00000398 ".._UID.." */ + 0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 000003A0 ".._STA.{" */ + 0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0, /* 000003A8 "PIRB..`." */ + 0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 000003B0 "..`....." */ + 0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 000003B8 "......._" */ + 0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 000003C0 "PRS..BUF" */ + 0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 000003C8 "A.._DIS." */ + 0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50, /* 000003D0 "}PIRB..P" */ + 0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52, /* 000003D8 "IRB.._CR" */ + 0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A, /* 000003E0 "S.{PIRB." */ + 0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 000003E8 ".`y.`IRQ" */ + 0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 000003F0 "V.BUFB.." */ + 0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 000003F8 "_SRS..h." */ + 0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 00000400 "IRQ1.IRQ" */ + 0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 00000408 "1`v`p`PI" */ + 0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E, /* 00000410 "RB[.I.LN" */ + 0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000418 "KC._HID." */ + 0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 00000420 "A...._UI" */ + 0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54, /* 00000428 "D...._ST" */ + 0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A, /* 00000430 "A.{PIRC." */ + 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 00000438 ".`...`.." */ + 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 00000440 "........" */ + 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000448 ".._PRS.." */ + 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000450 "BUFA.._D" */ + 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43, /* 00000458 "IS.}PIRC" */ + 0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A, /* 00000460 "..PIRC.." */ + 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 00000468 "_CRS.{PI" */ + 0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000470 "RC..`y.`" */ + 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000478 "IRQV.BUF" */ + 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000480 "B.._SRS." */ + 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000488 ".h.IRQ1." */ + 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 00000490 "IRQ1`v`p" */ + 0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49, /* 00000498 "`PIRC[.I" */ + 0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48, /* 000004A0 ".LNKD._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000004A8 "ID.A...." */ + 0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C, /* 000004B0 "_UID...." */ + 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 000004B8 "_STA.{PI" */ + 0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 000004C0 "RD..`..." */ + 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 000004C8 "`......." */ + 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 000004D0 "....._PR" */ + 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 000004D8 "S..BUFA." */ + 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 000004E0 "._DIS.}P" */ + 0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52, /* 000004E8 "IRD..PIR" */ + 0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 000004F0 "D.._CRS." */ + 0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60, /* 000004F8 "{PIRD..`" */ + 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000500 "y.`IRQV." */ + 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000508 "BUFB.._S" */ + 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000510 "RS..h.IR" */ + 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 00000518 "Q1.IRQ1`" */ + 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44, /* 00000520 "v`p`PIRD" */ + 0x5B,0x82,0x44,0x05,0x48,0x50,0x45,0x54, /* 00000528 "[.D.HPET" */ + 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000530 "._HID.A." */ + 0x01,0x03,0x08,0x5F,0x55,0x49,0x44,0x00, /* 00000538 "..._UID." */ + 0x14,0x18,0x5F,0x53,0x54,0x41,0x00,0xA0, /* 00000540 ".._STA.." */ + 0x0C,0x93,0x5E,0x5E,0x5E,0x48,0x50,0x45, /* 00000548 "..^^^HPE" */ + 0x54,0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A, /* 00000550 "T......." */ + 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1F, /* 00000558 ".._CRS.." */ + 0x0A,0x1C,0x87,0x17,0x00,0x00,0x0D,0x01, /* 00000560 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0xFE, /* 00000568 "........" */ + 0xFF,0x03,0xD0,0xFE,0x00,0x00,0x00,0x00, /* 00000570 "........" */ + 0x00,0x04,0x00,0x00,0x79,0x00,0x14,0x16, /* 00000578 "....y..." */ + 0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,0x50, /* 00000580 "_PRT...P" */ + 0x49,0x43,0x44,0xA4,0x50,0x52,0x54,0x41, /* 00000588 "ICD.PRTA" */ + 0xA4,0x50,0x52,0x54,0x50,0x08,0x50,0x52, /* 00000590 ".PRTP.PR" */ + 0x54,0x50,0x12,0x49,0x36,0x3C,0x12,0x0D, /* 00000598 "TP.I6<.." */ + 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C, /* 000005A0 ".......L" */ + 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 000005A8 "NKB....." */ + 0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B, /* 000005B0 ".....LNK" */ + 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000005B8 "C......." */ + 0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 000005C0 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01, /* 000005C8 "........" */ + 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 000005D0 "...LNKA." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 000005D8 "........" */ + 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 000005E0 ".LNKC..." */ + 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x4C, /* 000005E8 ".......L" */ + 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000005F0 "NKD....." */ + 0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,0x4E, /* 000005F8 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000600 "KA......" */ + 0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000608 ".....LNK" */ + 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000610 "B......." */ + 0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 00000618 "...LNKD." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000620 "........" */ + 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 00000628 ".LNKA..." */ + 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02, /* 00000630 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000638 "LNKB...." */ + 0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,0x4C, /* 00000640 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000648 "NKC....." */ + 0xFF,0xFF,0x04,0x00,0x00,0x4C,0x4E,0x4B, /* 00000650 ".....LNK" */ + 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000658 "A......." */ + 0x04,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 00000660 "...LNKB." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000668 "........" */ + 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000670 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A, /* 00000678 "........" */ + 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000680 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x00,0x4C, /* 00000688 ".......L" */ + 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000690 "NKB....." */ + 0xFF,0xFF,0x05,0x00,0x01,0x4C,0x4E,0x4B, /* 00000698 ".....LNK" */ + 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000006A0 "C......." */ + 0x05,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 000006A8 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05, /* 000006B0 "........" */ + 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 000006B8 "...LNKA." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 000006C0 "........" */ + 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 000006C8 ".LNKC..." */ + 0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x4C, /* 000006D0 ".......L" */ + 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000006D8 "NKD....." */ + 0xFF,0xFF,0x06,0x00,0x0A,0x02,0x4C,0x4E, /* 000006E0 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000006E8 "KA......" */ + 0xFF,0x06,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000006F0 ".....LNK" */ + 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006F8 "B......." */ + 0x07,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 00000700 "...LNKD." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00, /* 00000708 "........" */ + 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 00000710 ".LNKA..." */ + 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02, /* 00000718 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000720 "LNKB...." */ + 0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03,0x4C, /* 00000728 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000730 "NKC....." */ + 0xFF,0xFF,0x08,0x00,0x00,0x4C,0x4E,0x4B, /* 00000738 ".....LNK" */ + 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000740 "A......." */ + 0x08,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 00000748 "...LNKB." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000750 "........" */ + 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000758 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A, /* 00000760 "........" */ + 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000768 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x00,0x4C, /* 00000770 ".......L" */ + 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000778 "NKB....." */ + 0xFF,0xFF,0x09,0x00,0x01,0x4C,0x4E,0x4B, /* 00000780 ".....LNK" */ + 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000788 "C......." */ + 0x09,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 00000790 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09, /* 00000798 "........" */ + 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 000007A0 "...LNKA." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 000007A8 "........" */ + 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 000007B0 ".LNKC..." */ + 0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C, /* 000007B8 ".......L" */ + 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000007C0 "NKD....." */ + 0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E, /* 000007C8 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000007D0 "KA......" */ + 0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000007D8 ".....LNK" */ + 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000007E0 "B......." */ + 0x0B,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 000007E8 "...LNKD." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00, /* 000007F0 "........" */ + 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000007F8 ".LNKA..." */ + 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02, /* 00000800 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 00000808 "LNKB...." */ + 0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x4C, /* 00000810 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000818 "NKC....." */ + 0xFF,0xFF,0x0C,0x00,0x00,0x4C,0x4E,0x4B, /* 00000820 ".....LNK" */ + 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000828 "A......." */ + 0x0C,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 00000830 "...LNKB." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000838 "........" */ + 0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000840 "..LNKC.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A, /* 00000848 "........" */ + 0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000850 ".LNKD..." */ + 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x4C, /* 00000858 ".......L" */ + 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000860 "NKB....." */ + 0xFF,0xFF,0x0D,0x00,0x01,0x4C,0x4E,0x4B, /* 00000868 ".....LNK" */ + 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000870 "C......." */ + 0x0D,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44, /* 00000878 "....LNKD" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000880 "........" */ + 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00, /* 00000888 "...LNKA." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000890 "........" */ + 0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 00000898 ".LNKC..." */ + 0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x4C, /* 000008A0 ".......L" */ + 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000008A8 "NKD....." */ + 0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x4C,0x4E, /* 000008B0 "......LN" */ + 0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000008B8 "KA......" */ + 0xFF,0x0E,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000008C0 ".....LNK" */ + 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000008C8 "B......." */ + 0x0F,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00, /* 000008D0 "...LNKD." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00, /* 000008D8 "........" */ + 0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000008E0 ".LNKA..." */ + 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02, /* 000008E8 "........" */ + 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04, /* 000008F0 "LNKB...." */ + 0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x4C, /* 000008F8 ".......L" */ + 0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,0x54, /* 00000900 "NKC..PRT" */ + 0x41,0x12,0x41,0x2F,0x3C,0x12,0x0B,0x04, /* 00000908 "A.A/<..." */ + 0x0C,0xFF,0xFF,0x01,0x00,0x00,0x00,0x0A, /* 00000910 "........" */ + 0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01, /* 00000918 "........" */ + 0x00,0x01,0x00,0x0A,0x15,0x12,0x0C,0x04, /* 00000920 "........" */ + 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x00, /* 00000928 "........" */ + 0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000930 "........" */ + 0x01,0x00,0x0A,0x03,0x00,0x0A,0x17,0x12, /* 00000938 "........" */ + 0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00, /* 00000940 "........" */ + 0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF, /* 00000948 "........" */ + 0xFF,0x02,0x00,0x01,0x00,0x0A,0x19,0x12, /* 00000950 "........" */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000958 "........" */ + 0x02,0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C, /* 00000960 "........" */ + 0xFF,0xFF,0x02,0x00,0x0A,0x03,0x00,0x0A, /* 00000968 "........" */ + 0x1B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03, /* 00000970 "........" */ + 0x00,0x00,0x00,0x0A,0x1C,0x12,0x0B,0x04, /* 00000978 "........" */ + 0x0C,0xFF,0xFF,0x03,0x00,0x01,0x00,0x0A, /* 00000980 "........" */ + 0x1D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03, /* 00000988 "........" */ + 0x00,0x0A,0x02,0x00,0x0A,0x1E,0x12,0x0C, /* 00000990 "........" */ + 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03, /* 00000998 "........" */ + 0x00,0x0A,0x1F,0x12,0x0B,0x04,0x0C,0xFF, /* 000009A0 "........" */ + 0xFF,0x04,0x00,0x00,0x00,0x0A,0x20,0x12, /* 000009A8 "...... ." */ + 0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01, /* 000009B0 "........" */ + 0x00,0x0A,0x21,0x12,0x0C,0x04,0x0C,0xFF, /* 000009B8 "..!....." */ + 0xFF,0x04,0x00,0x0A,0x02,0x00,0x0A,0x22, /* 000009C0 "......."" */ + 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 000009C8 "........" */ + 0x0A,0x03,0x00,0x0A,0x23,0x12,0x0B,0x04, /* 000009D0 "....#..." */ + 0x0C,0xFF,0xFF,0x05,0x00,0x00,0x00,0x0A, /* 000009D8 "........" */ + 0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05, /* 000009E0 "$......." */ + 0x00,0x01,0x00,0x0A,0x25,0x12,0x0C,0x04, /* 000009E8 "....%..." */ + 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x00, /* 000009F0 "........" */ + 0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000009F8 ".&......" */ + 0x05,0x00,0x0A,0x03,0x00,0x0A,0x27,0x12, /* 00000A00 "......'." */ + 0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00, /* 00000A08 "........" */ + 0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A10 "..(....." */ + 0xFF,0x06,0x00,0x01,0x00,0x0A,0x29,0x12, /* 00000A18 "......)." */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 00000A20 "........" */ + 0x02,0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C, /* 00000A28 "...*...." */ + 0xFF,0xFF,0x06,0x00,0x0A,0x03,0x00,0x0A, /* 00000A30 "........" */ + 0x2B,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07, /* 00000A38 "+......." */ + 0x00,0x00,0x00,0x0A,0x2C,0x12,0x0B,0x04, /* 00000A40 "....,..." */ + 0x0C,0xFF,0xFF,0x07,0x00,0x01,0x00,0x0A, /* 00000A48 "........" */ + 0x2D,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07, /* 00000A50 "-......." */ + 0x00,0x0A,0x02,0x00,0x0A,0x2E,0x12,0x0C, /* 00000A58 "........" */ + 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x03, /* 00000A60 "........" */ + 0x00,0x0A,0x2F,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A68 "../....." */ + 0xFF,0x08,0x00,0x00,0x00,0x0A,0x11,0x12, /* 00000A70 "........" */ + 0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01, /* 00000A78 "........" */ + 0x00,0x0A,0x12,0x12,0x0C,0x04,0x0C,0xFF, /* 00000A80 "........" */ + 0xFF,0x08,0x00,0x0A,0x02,0x00,0x0A,0x13, /* 00000A88 "........" */ + 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000A90 "........" */ + 0x0A,0x03,0x00,0x0A,0x14,0x12,0x0B,0x04, /* 00000A98 "........" */ + 0x0C,0xFF,0xFF,0x09,0x00,0x00,0x00,0x0A, /* 00000AA0 "........" */ + 0x15,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09, /* 00000AA8 "........" */ + 0x00,0x01,0x00,0x0A,0x16,0x12,0x0C,0x04, /* 00000AB0 "........" */ + 0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x00, /* 00000AB8 "........" */ + 0x0A,0x17,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000AC0 "........" */ + 0x09,0x00,0x0A,0x03,0x00,0x0A,0x18,0x12, /* 00000AC8 "........" */ + 0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00, /* 00000AD0 "........" */ + 0x00,0x0A,0x19,0x12,0x0B,0x04,0x0C,0xFF, /* 00000AD8 "........" */ + 0xFF,0x0A,0x00,0x01,0x00,0x0A,0x1A,0x12, /* 00000AE0 "........" */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 00000AE8 "........" */ + 0x02,0x00,0x0A,0x1B,0x12,0x0C,0x04,0x0C, /* 00000AF0 "........" */ + 0xFF,0xFF,0x0A,0x00,0x0A,0x03,0x00,0x0A, /* 00000AF8 "........" */ + 0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000B00 "........" */ + 0x00,0x00,0x00,0x0A,0x1D,0x12,0x0B,0x04, /* 00000B08 "........" */ + 0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x00,0x0A, /* 00000B10 "........" */ + 0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000B18 "........" */ + 0x00,0x0A,0x02,0x00,0x0A,0x1F,0x12,0x0C, /* 00000B20 "........" */ + 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x03, /* 00000B28 "........" */ + 0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF, /* 00000B30 ".. ....." */ + 0xFF,0x0C,0x00,0x00,0x00,0x0A,0x21,0x12, /* 00000B38 "......!." */ + 0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01, /* 00000B40 "........" */ + 0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF, /* 00000B48 ".."....." */ + 0xFF,0x0C,0x00,0x0A,0x02,0x00,0x0A,0x23, /* 00000B50 ".......#" */ + 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000B58 "........" */ + 0x0A,0x03,0x00,0x0A,0x24,0x12,0x0B,0x04, /* 00000B60 "....$..." */ + 0x0C,0xFF,0xFF,0x0D,0x00,0x00,0x00,0x0A, /* 00000B68 "........" */ + 0x25,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000B70 "%......." */ + 0x00,0x01,0x00,0x0A,0x26,0x12,0x0C,0x04, /* 00000B78 "....&..." */ + 0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x00, /* 00000B80 "........" */ + 0x0A,0x27,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000B88 ".'......" */ + 0x0D,0x00,0x0A,0x03,0x00,0x0A,0x28,0x12, /* 00000B90 "......(." */ + 0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00, /* 00000B98 "........" */ + 0x00,0x0A,0x29,0x12,0x0B,0x04,0x0C,0xFF, /* 00000BA0 "..)....." */ + 0xFF,0x0E,0x00,0x01,0x00,0x0A,0x2A,0x12, /* 00000BA8 "......*." */ + 0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 00000BB0 "........" */ + 0x02,0x00,0x0A,0x2B,0x12,0x0C,0x04,0x0C, /* 00000BB8 "...+...." */ + 0xFF,0xFF,0x0E,0x00,0x0A,0x03,0x00,0x0A, /* 00000BC0 "........" */ + 0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000BC8 ",......." */ + 0x00,0x00,0x00,0x0A,0x2D,0x12,0x0B,0x04, /* 00000BD0 "....-..." */ + 0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x00,0x0A, /* 00000BD8 "........" */ + 0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000BE0 "........" */ + 0x00,0x0A,0x02,0x00,0x0A,0x2F,0x12,0x0C, /* 00000BE8 "...../.." */ + 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x03, /* 00000BF0 "........" */ + 0x00,0x0A,0x10,0x5B,0x82,0x46,0x37,0x49, /* 00000BF8 "...[.F7I" */ + 0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,0x52, /* 00000C00 "SA_._ADR" */ + 0x0C,0x00,0x00,0x01,0x00,0x5B,0x80,0x50, /* 00000C08 ".....[.P" */ + 0x49,0x52,0x51,0x02,0x0A,0x60,0x0A,0x04, /* 00000C10 "IRQ..`.." */ + 0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29,0x5C, /* 00000C18 "..\.[.)\" */ + 0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00000C20 "/._SB_PC" */ + 0x49,0x30,0x49,0x53,0x41,0x5F,0x50,0x49, /* 00000C28 "I0ISA_PI" */ + 0x52,0x51,0x01,0x50,0x49,0x52,0x41,0x08, /* 00000C30 "RQ.PIRA." */ + 0x50,0x49,0x52,0x42,0x08,0x50,0x49,0x52, /* 00000C38 "PIRB.PIR" */ + 0x43,0x08,0x50,0x49,0x52,0x44,0x08,0x5B, /* 00000C40 "C.PIRD.[" */ + 0x82,0x46,0x0B,0x53,0x59,0x53,0x52,0x08, /* 00000C48 ".F.SYSR." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000C50 "_HID.A.." */ + 0x02,0x08,0x5F,0x55,0x49,0x44,0x01,0x08, /* 00000C58 ".._UID.." */ + 0x43,0x52,0x53,0x5F,0x11,0x4E,0x08,0x0A, /* 00000C60 "CRS_.N.." */ + 0x8A,0x47,0x01,0x10,0x00,0x10,0x00,0x00, /* 00000C68 ".G......" */ + 0x10,0x47,0x01,0x22,0x00,0x22,0x00,0x00, /* 00000C70 ".G.".".." */ + 0x0C,0x47,0x01,0x30,0x00,0x30,0x00,0x00, /* 00000C78 ".G.0.0.." */ + 0x10,0x47,0x01,0x44,0x00,0x44,0x00,0x00, /* 00000C80 ".G.D.D.." */ + 0x1C,0x47,0x01,0x62,0x00,0x62,0x00,0x00, /* 00000C88 ".G.b.b.." */ + 0x02,0x47,0x01,0x65,0x00,0x65,0x00,0x00, /* 00000C90 ".G.e.e.." */ + 0x0B,0x47,0x01,0x72,0x00,0x72,0x00,0x00, /* 00000C98 ".G.r.r.." */ + 0x0E,0x47,0x01,0x80,0x00,0x80,0x00,0x00, /* 00000CA0 ".G......" */ + 0x01,0x47,0x01,0x84,0x00,0x84,0x00,0x00, /* 00000CA8 ".G......" */ + 0x03,0x47,0x01,0x88,0x00,0x88,0x00,0x00, /* 00000CB0 ".G......" */ + 0x01,0x47,0x01,0x8C,0x00,0x8C,0x00,0x00, /* 00000CB8 ".G......" */ + 0x03,0x47,0x01,0x90,0x00,0x90,0x00,0x00, /* 00000CC0 ".G......" */ + 0x10,0x47,0x01,0xA2,0x00,0xA2,0x00,0x00, /* 00000CC8 ".G......" */ + 0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00,0x00, /* 00000CD0 ".G......" */ + 0x10,0x47,0x01,0xA0,0x08,0xA0,0x08,0x00, /* 00000CD8 ".G......" */ + 0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C,0x00, /* 00000CE0 ".G......" */ + 0x10,0x47,0x01,0xD0,0x04,0xD0,0x04,0x00, /* 00000CE8 ".G......" */ + 0x02,0x79,0x00,0x14,0x0B,0x5F,0x43,0x52, /* 00000CF0 ".y..._CR" */ + 0x53,0x00,0xA4,0x43,0x52,0x53,0x5F,0x5B, /* 00000CF8 "S..CRS_[" */ + 0x82,0x2B,0x50,0x49,0x43,0x5F,0x08,0x5F, /* 00000D00 ".+PIC_._" */ + 0x48,0x49,0x44,0x0B,0x41,0xD0,0x08,0x5F, /* 00000D08 "HID.A.._" */ + 0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47, /* 00000D10 "CRS....G" */ + 0x01,0x20,0x00,0x20,0x00,0x01,0x02,0x47, /* 00000D18 ". . ...G" */ + 0x01,0xA0,0x00,0xA0,0x00,0x01,0x02,0x22, /* 00000D20 "......."" */ + 0x04,0x00,0x79,0x00,0x5B,0x82,0x47,0x05, /* 00000D28 "..y.[.G." */ + 0x44,0x4D,0x41,0x30,0x08,0x5F,0x48,0x49, /* 00000D30 "DMA0._HI" */ + 0x44,0x0C,0x41,0xD0,0x02,0x00,0x08,0x5F, /* 00000D38 "D.A...._" */ + 0x43,0x52,0x53,0x11,0x41,0x04,0x0A,0x3D, /* 00000D40 "CRS.A..=" */ + 0x2A,0x10,0x04,0x47,0x01,0x00,0x00,0x00, /* 00000D48 "*..G...." */ + 0x00,0x00,0x10,0x47,0x01,0x81,0x00,0x81, /* 00000D50 "...G...." */ + 0x00,0x00,0x03,0x47,0x01,0x87,0x00,0x87, /* 00000D58 "...G...." */ + 0x00,0x00,0x01,0x47,0x01,0x89,0x00,0x89, /* 00000D60 "...G...." */ + 0x00,0x00,0x03,0x47,0x01,0x8F,0x00,0x8F, /* 00000D68 "...G...." */ + 0x00,0x00,0x01,0x47,0x01,0xC0,0x00,0xC0, /* 00000D70 "...G...." */ + 0x00,0x00,0x20,0x47,0x01,0x80,0x04,0x80, /* 00000D78 ".. G...." */ + 0x04,0x00,0x10,0x79,0x00,0x5B,0x82,0x25, /* 00000D80 "...y.[.%" */ + 0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48,0x49, /* 00000D88 "TMR_._HI" */ + 0x44,0x0C,0x41,0xD0,0x01,0x00,0x08,0x5F, /* 00000D90 "D.A...._" */ + 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000D98 "CRS....G" */ + 0x01,0x40,0x00,0x40,0x00,0x00,0x04,0x22, /* 00000DA0 ".@.@..."" */ + 0x01,0x00,0x79,0x00,0x5B,0x82,0x25,0x52, /* 00000DA8 "..y.[.%R" */ + 0x54,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44, /* 00000DB0 "TC_._HID" */ + 0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F,0x43, /* 00000DB8 ".A...._C" */ + 0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00000DC0 "RS....G." */ + 0x70,0x00,0x70,0x00,0x00,0x02,0x22,0x00, /* 00000DC8 "p.p..."." */ + 0x01,0x79,0x00,0x5B,0x82,0x22,0x53,0x50, /* 00000DD0 ".y.[."SP" */ + 0x4B,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000DD8 "KR._HID." */ + 0x41,0xD0,0x08,0x00,0x08,0x5F,0x43,0x52, /* 00000DE0 "A...._CR" */ + 0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01,0x61, /* 00000DE8 "S....G.a" */ + 0x00,0x61,0x00,0x00,0x01,0x79,0x00,0x5B, /* 00000DF0 ".a...y.[" */ + 0x82,0x31,0x50,0x53,0x32,0x4D,0x08,0x5F, /* 00000DF8 ".1PS2M._" */ + 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13, /* 00000E00 "HID.A..." */ + 0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0, /* 00000E08 "._CID.A." */ + 0x0F,0x13,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000E10 "...._STA" */ + 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000E18 "....._CR" */ + 0x53,0x11,0x08,0x0A,0x05,0x22,0x00,0x10, /* 00000E20 "S....".." */ + 0x79,0x00,0x5B,0x82,0x42,0x04,0x50,0x53, /* 00000E28 "y.[.B.PS" */ + 0x32,0x4B,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000E30 "2K._HID." */ + 0x41,0xD0,0x03,0x03,0x08,0x5F,0x43,0x49, /* 00000E38 "A...._CI" */ + 0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14,0x09, /* 00000E40 "D.A....." */ + 0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000E48 "_STA...." */ + 0x08,0x5F,0x43,0x52,0x53,0x11,0x18,0x0A, /* 00000E50 "._CRS..." */ + 0x15,0x47,0x01,0x60,0x00,0x60,0x00,0x00, /* 00000E58 ".G.`.`.." */ + 0x01,0x47,0x01,0x64,0x00,0x64,0x00,0x00, /* 00000E60 ".G.d.d.." */ + 0x01,0x22,0x02,0x00,0x79,0x00,0x5B,0x82, /* 00000E68 "."..y.[." */ + 0x3A,0x46,0x44,0x43,0x30,0x08,0x5F,0x48, /* 00000E70 ":FDC0._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x07,0x00,0x14, /* 00000E78 "ID.A...." */ + 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000E80 "._STA..." */ + 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x1B, /* 00000E88 ".._CRS.." */ + 0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0,0x03, /* 00000E90 "..G....." */ + 0x01,0x06,0x47,0x01,0xF7,0x03,0xF7,0x03, /* 00000E98 "..G....." */ + 0x01,0x01,0x22,0x40,0x00,0x2A,0x04,0x00, /* 00000EA0 ".."@.*.." */ + 0x79,0x00,0x5B,0x82,0x46,0x04,0x55,0x41, /* 00000EA8 "y.[.F.UA" */ + 0x52,0x31,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000EB0 "R1._HID." */ + 0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49, /* 00000EB8 "A...._UI" */ + 0x44,0x01,0x14,0x19,0x5F,0x53,0x54,0x41, /* 00000EC0 "D..._STA" */ + 0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E,0x5E, /* 00000EC8 "....^^^^" */ + 0x55,0x41,0x52,0x31,0x00,0xA4,0x00,0xA1, /* 00000ED0 "UAR1...." */ + 0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000ED8 "....._CR" */ + 0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8, /* 00000EE0 "S....G.." */ + 0x03,0xF8,0x03,0x08,0x08,0x22,0x10,0x00, /* 00000EE8 ".....".." */ + 0x79,0x00,0x5B,0x82,0x47,0x04,0x55,0x41, /* 00000EF0 "y.[.G.UA" */ + 0x52,0x32,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000EF8 "R2._HID." */ + 0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49, /* 00000F00 "A...._UI" */ + 0x44,0x0A,0x02,0x14,0x19,0x5F,0x53,0x54, /* 00000F08 "D...._ST" */ + 0x41,0x00,0xA0,0x0D,0x93,0x5E,0x5E,0x5E, /* 00000F10 "A....^^^" */ + 0x5E,0x55,0x41,0x52,0x32,0x00,0xA4,0x00, /* 00000F18 "^UAR2..." */ + 0xA1,0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000F20 "......_C" */ + 0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00000F28 "RS....G." */ + 0xF8,0x02,0xF8,0x02,0x08,0x08,0x22,0x08, /* 00000F30 "......"." */ + 0x00,0x79,0x00,0x5B,0x82,0x36,0x4C,0x54, /* 00000F38 ".y.[.6LT" */ + 0x50,0x31,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000F40 "P1._HID." */ + 0x41,0xD0,0x04,0x00,0x08,0x5F,0x55,0x49, /* 00000F48 "A...._UI" */ + 0x44,0x0A,0x02,0x14,0x09,0x5F,0x53,0x54, /* 00000F50 "D...._ST" */ + 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000F58 "A....._C" */ + 0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01, /* 00000F60 "RS....G." */ + 0x78,0x03,0x78,0x03,0x08,0x08,0x22,0x80, /* 00000F68 "x.x..."." */ + 0x00,0x79,0x00,0x5B,0x82,0x4D,0x07,0x53, /* 00000F70 ".y.[.M.S" */ + 0x31,0x46,0x30,0x08,0x5F,0x41,0x44,0x52, /* 00000F78 "1F0._ADR" */ + 0x0C,0x00,0x00,0x06,0x00,0x08,0x5F,0x53, /* 00000F80 "......_S" */ + 0x55,0x4E,0x01,0x14,0x13,0x5F,0x50,0x53, /* 00000F88 "UN..._PS" */ + 0x30,0x00,0x70,0x0A,0x80,0x5C,0x2E,0x5F, /* 00000F90 "0.p..\._" */ + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00000F98 "GPEDPT2." */ + 0x13,0x5F,0x50,0x53,0x33,0x00,0x70,0x0A, /* 00000FA0 "._PS3.p." */ + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00000FA8 ".\._GPED" */ + 0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A, /* 00000FB0 "PT2.._EJ" */ + 0x30,0x01,0x70,0x0A,0x88,0x5C,0x2E,0x5F, /* 00000FB8 "0.p..\._" */ + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x70, /* 00000FC0 "GPEDPT2p" */ + 0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50, /* 00000FC8 ".\._GPEP" */ + 0x48,0x50,0x31,0x14,0x1E,0x5F,0x53,0x54, /* 00000FD0 "HP1.._ST" */ + 0x41,0x00,0x70,0x0A,0x89,0x5C,0x2E,0x5F, /* 00000FD8 "A.p..\._" */ + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0xA4, /* 00000FE0 "GPEDPT2." */ + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48, /* 00000FE8 "\._GPEPH" */ + 0x50,0x31,0x5B,0x82,0x4E,0x07,0x53,0x32, /* 00000FF0 "P1[.N.S2" */ + 0x46,0x30,0x08,0x5F,0x41,0x44,0x52,0x0C, /* 00000FF8 "F0._ADR." */ + 0x00,0x00,0x07,0x00,0x08,0x5F,0x53,0x55, /* 00001000 "....._SU" */ + 0x4E,0x0A,0x02,0x14,0x13,0x5F,0x50,0x53, /* 00001008 "N...._PS" */ + 0x30,0x00,0x70,0x0A,0x90,0x5C,0x2E,0x5F, /* 00001010 "0.p..\._" */ + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00001018 "GPEDPT2." */ + 0x13,0x5F,0x50,0x53,0x33,0x00,0x70,0x0A, /* 00001020 "._PS3.p." */ + 0x93,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001028 ".\._GPED" */ + 0x50,0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A, /* 00001030 "PT2.._EJ" */ + 0x30,0x01,0x70,0x0A,0x98,0x5C,0x2E,0x5F, /* 00001038 "0.p..\._" */ + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x70, /* 00001040 "GPEDPT2p" */ + 0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50, /* 00001048 ".\._GPEP" */ + 0x48,0x50,0x32,0x14,0x1E,0x5F,0x53,0x54, /* 00001050 "HP2.._ST" */ + 0x41,0x00,0x70,0x0A,0x99,0x5C,0x2E,0x5F, /* 00001058 "A.p..\._" */ + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0xA4, /* 00001060 "GPEDPT2." */ + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48, /* 00001068 "\._GPEPH" */ + 0x50,0x32,0x10,0x4E,0x0B,0x5F,0x47,0x50, /* 00001070 "P2.N._GP" */ + 0x45,0x5B,0x80,0x50,0x48,0x50,0x5F,0x01, /* 00001078 "E[.PHP_." */ + 0x0B,0xC0,0x10,0x0A,0x03,0x5B,0x81,0x15, /* 00001080 ".....[.." */ + 0x50,0x48,0x50,0x5F,0x01,0x50,0x53,0x54, /* 00001088 "PHP_.PST" */ + 0x41,0x08,0x50,0x48,0x50,0x31,0x08,0x50, /* 00001090 "A.PHP1.P" */ + 0x48,0x50,0x32,0x08,0x5B,0x80,0x44,0x47, /* 00001098 "HP2.[.DG" */ + 0x31,0x5F,0x01,0x0B,0x44,0xB0,0x0A,0x04, /* 000010A0 "1_..D..." */ + 0x5B,0x81,0x10,0x44,0x47,0x31,0x5F,0x01, /* 000010A8 "[..DG1_." */ + 0x44,0x50,0x54,0x31,0x08,0x44,0x50,0x54, /* 000010B0 "DPT1.DPT" */ + 0x32,0x08,0x14,0x46,0x07,0x5F,0x4C,0x30, /* 000010B8 "2..F._L0" */ + 0x33,0x00,0x08,0x53,0x4C,0x54,0x5F,0x00, /* 000010C0 "3..SLT_." */ + 0x08,0x45,0x56,0x54,0x5F,0x00,0x70,0x50, /* 000010C8 ".EVT_.pP" */ + 0x53,0x54,0x41,0x61,0x7A,0x61,0x0A,0x04, /* 000010D0 "STAaza.." */ + 0x53,0x4C,0x54,0x5F,0x7B,0x61,0x0A,0x0F, /* 000010D8 "SLT_{a.." */ + 0x45,0x56,0x54,0x5F,0x70,0x53,0x4C,0x54, /* 000010E0 "EVT_pSLT" */ + 0x5F,0x44,0x50,0x54,0x31,0x70,0x45,0x56, /* 000010E8 "_DPT1pEV" */ + 0x54,0x5F,0x44,0x50,0x54,0x32,0xA0,0x1B, /* 000010F0 "T_DPT2.." */ + 0x93,0x53,0x4C,0x54,0x5F,0x01,0x86,0x5C, /* 000010F8 ".SLT_..\" */ + 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 00001100 "/._SB_PC" */ + 0x49,0x30,0x53,0x31,0x46,0x30,0x45,0x56, /* 00001108 "I0S1F0EV" */ + 0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93,0x53, /* 00001110 "T_.....S" */ + 0x4C,0x54,0x5F,0x0A,0x02,0x86,0x5C,0x2F, /* 00001118 "LT_...\/" */ + 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00001120 "._SB_PCI" */ + 0x30,0x53,0x32,0x46,0x30,0x45,0x56,0x54, /* 00001128 "0S2F0EVT" */ + 0x5F, }; int DsdtLen=sizeof(AmlCode); diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/ioemu/Makefile.target Tue Feb 26 10:12:04 2008 -0700 @@ -357,7 +357,7 @@ endif endif ifdef CONFIG_STUBDOM -CONFIG_PASSTHROUGH=1 +#CONFIG_PASSTHROUGH=1 else ifeq (,$(wildcard /usr/include/pci)) $(warning *** pciutils-devl package not found - missing /usr/include/pci) @@ -415,7 +415,7 @@ VL_OBJS+= usb.o usb-hub.o usb-linux.o us VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o # PCI network cards -VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o +VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o e1000.o ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/e1000.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/e1000.c Tue Feb 26 10:12:04 2008 -0700 @@ -0,0 +1,995 @@ +/* + * QEMU e1000 emulation + * + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. + * Copyright (c) 2008 Qumranet + * Based on work done by: + * Copyright (c) 2007 Dan Aloni + * Copyright (c) 2004 Antony T Curtis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "vl.h" + +#include "e1000_hw.h" + +#define DEBUG + +#ifdef DEBUG +enum { + DEBUG_GENERAL, DEBUG_IO, DEBUG_MMIO, DEBUG_INTERRUPT, + DEBUG_RX, DEBUG_TX, DEBUG_MDIC, DEBUG_EEPROM, + DEBUG_UNKNOWN, DEBUG_TXSUM, DEBUG_TXERR, DEBUG_RXERR, + DEBUG_RXFILTER, DEBUG_NOTYET, +}; +#define DBGBIT(x) (1<<DEBUG_##x) +static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL); + +#define DBGOUT(what, fmt, params...) do { \ + if (debugflags & DBGBIT(what)) \ + fprintf(stderr, "e1000: " fmt, ##params); \ + } while (0) +#else +#define DBGOUT(what, fmt, params...) do {} while (0) +#endif + +#define IOPORT_SIZE 0x40 +#define PNPMMIO_SIZE 0x60000 + +/* + * HW models: + * E1000_DEV_ID_82540EM works with Windows and Linux + * E1000_DEV_ID_82573L OK with windoze and Linux 2.6.22, + * appears to perform better than 82540EM, but breaks with Linux 2.6.18 + * E1000_DEV_ID_82544GC_COPPER appears to work; not well tested + * Others never tested + */ +enum { E1000_DEVID = E1000_DEV_ID_82540EM }; + +/* + * May need to specify additional MAC-to-PHY entries -- + * Intel's Windows driver refuses to initialize unless they match + */ +enum { + PHY_ID2_INIT = E1000_DEVID == E1000_DEV_ID_82573L ? 0xcc2 : + E1000_DEVID == E1000_DEV_ID_82544GC_COPPER ? 0xc30 : + /* default to E1000_DEV_ID_82540EM */ 0xc20 +}; + +typedef struct E1000State_st { + PCIDevice dev; + VLANClientState *vc; + NICInfo *nd; + uint32_t instance; + uint32_t mmio_base; + int mmio_index; + + uint32_t mac_reg[0x8000]; + uint16_t phy_reg[0x20]; + uint16_t eeprom_data[64]; + + uint32_t rxbuf_size; + uint32_t rxbuf_min_shift; + int check_rxov; + struct e1000_tx { + unsigned char header[256]; + unsigned char data[0x10000]; + uint16_t size; + unsigned char sum_needed; + uint8_t ipcss; + uint8_t ipcso; + uint16_t ipcse; + uint8_t tucss; + uint8_t tucso; + uint16_t tucse; + uint8_t hdr_len; + uint16_t mss; + uint32_t paylen; + uint16_t tso_frames; + char tse; + char ip; + char tcp; + } tx; + + struct { + uint32_t val_in; // shifted in from guest driver + uint16_t bitnum_in; + uint16_t bitnum_out; + uint16_t reading; + uint32_t old_eecd; + } eecd_state; +} E1000State; + +#define defreg(x) x = (E1000_##x>>2) +enum { + defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), + defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC), + defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC), + defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH), + defreg(RDBAL), defreg(RDH), defreg(RDLEN), defreg(RDT), + defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH), + defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT), + defreg(TORH), defreg(TORL), defreg(TOTH), defreg(TOTL), + defreg(TPR), defreg(TPT), defreg(TXDCTL), defreg(WUFC), + defreg(RA), defreg(MTA), defreg(CRCERRS), +}; + +enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W }; +static char phy_regcap[0x20] = { + [PHY_STATUS] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW, + [PHY_ID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW, + [PHY_CTRL] = PHY_RW, [PHY_1000T_CTRL] = PHY_RW, + [PHY_LP_ABILITY] = PHY_R, [PHY_1000T_STATUS] = PHY_R, + [PHY_AUTONEG_ADV] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R, + [PHY_ID2] = PHY_R, +}; + +static void +ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr, + uint32_t size, int type) +{ + DBGOUT(IO, "e1000_ioport_map addr=0x%04x size=0x%08x\n", addr, size); +} + +static void +set_interrupt_cause(E1000State *s, int index, uint32_t val) +{ + if (val) + val |= E1000_ICR_INT_ASSERTED; + s->mac_reg[ICR] = val; + pci_set_irq(&s->dev, 0, (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0); +} + +static void +set_ics(E1000State *s, int index, uint32_t val) +{ + DBGOUT(INTERRUPT, "set_ics %x, ICR %x, IMR %x\n", val, s->mac_reg[ICR], + s->mac_reg[IMS]); + set_interrupt_cause(s, 0, val | s->mac_reg[ICR]); +} + +static int +rxbufsize(uint32_t v) +{ + v &= E1000_RCTL_BSEX | E1000_RCTL_SZ_16384 | E1000_RCTL_SZ_8192 | + E1000_RCTL_SZ_4096 | E1000_RCTL_SZ_2048 | E1000_RCTL_SZ_1024 | + E1000_RCTL_SZ_512 | E1000_RCTL_SZ_256; + switch (v) { + case E1000_RCTL_BSEX | E1000_RCTL_SZ_16384: + return 16384; + case E1000_RCTL_BSEX | E1000_RCTL_SZ_8192: + return 8192; + case E1000_RCTL_BSEX | E1000_RCTL_SZ_4096: + return 4096; + case E1000_RCTL_SZ_1024: + return 1024; + case E1000_RCTL_SZ_512: + return 512; + case E1000_RCTL_SZ_256: + return 256; + } + return 2048; +} + +static void +set_rx_control(E1000State *s, int index, uint32_t val) +{ + s->mac_reg[RCTL] = val; + s->rxbuf_size = rxbufsize(val); + s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1; + DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT], + s->mac_reg[RCTL]); +} + +static void +set_mdic(E1000State *s, int index, uint32_t val) +{ + uint32_t data = val & E1000_MDIC_DATA_MASK; + uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT); + + if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) // phy # + val = s->mac_reg[MDIC] | E1000_MDIC_ERROR; + else if (val & E1000_MDIC_OP_READ) { + DBGOUT(MDIC, "MDIC read reg 0x%x\n", addr); + if (!(phy_regcap[addr] & PHY_R)) { + DBGOUT(MDIC, "MDIC read reg %x unhandled\n", addr); + val |= E1000_MDIC_ERROR; + } else + val = (val ^ data) | s->phy_reg[addr]; + } else if (val & E1000_MDIC_OP_WRITE) { + DBGOUT(MDIC, "MDIC write reg 0x%x, value 0x%x\n", addr, data); + if (!(phy_regcap[addr] & PHY_W)) { + DBGOUT(MDIC, "MDIC write reg %x unhandled\n", addr); + val |= E1000_MDIC_ERROR; + } else + s->phy_reg[addr] = data; + } + s->mac_reg[MDIC] = val | E1000_MDIC_READY; + set_ics(s, 0, E1000_ICR_MDAC); +} + +static uint32_t +get_eecd(E1000State *s, int index) +{ + uint32_t ret = E1000_EECD_PRES|E1000_EECD_GNT | s->eecd_state.old_eecd; + + DBGOUT(EEPROM, "reading eeprom bit %d (reading %d)\n", + s->eecd_state.bitnum_out, s->eecd_state.reading); + if (!s->eecd_state.reading || + ((s->eeprom_data[(s->eecd_state.bitnum_out >> 4) & 0x3f] >> + ((s->eecd_state.bitnum_out & 0xf) ^ 0xf))) & 1) + ret |= E1000_EECD_DO; + return ret; +} + +static void +set_eecd(E1000State *s, int index, uint32_t val) +{ + uint32_t oldval = s->eecd_state.old_eecd; + + s->eecd_state.old_eecd = val & (E1000_EECD_SK | E1000_EECD_CS | + E1000_EECD_DI|E1000_EECD_FWE_MASK|E1000_EECD_REQ); + if (!(E1000_EECD_SK & (val ^ oldval))) // no clock edge + return; + if (!(E1000_EECD_SK & val)) { // falling edge + s->eecd_state.bitnum_out++; + return; + } + if (!(val & E1000_EECD_CS)) { // rising, no CS (EEPROM reset) + memset(&s->eecd_state, 0, sizeof s->eecd_state); + return; + } + s->eecd_state.val_in <<= 1; + if (val & E1000_EECD_DI) + s->eecd_state.val_in |= 1; + if (++s->eecd_state.bitnum_in == 9 && !s->eecd_state.reading) { + s->eecd_state.bitnum_out = ((s->eecd_state.val_in & 0x3f)<<4)-1; + s->eecd_state.reading = (((s->eecd_state.val_in >> 6) & 7) == + EEPROM_READ_OPCODE_MICROWIRE); + } + DBGOUT(EEPROM, "eeprom bitnum in %d out %d, reading %d\n", + s->eecd_state.bitnum_in, s->eecd_state.bitnum_out, + s->eecd_state.reading); +} + +static uint32_t +flash_eerd_read(E1000State *s, int x) +{ + unsigned int index, r = s->mac_reg[EERD] & ~E1000_EEPROM_RW_REG_START; + + if ((index = r >> E1000_EEPROM_RW_ADDR_SHIFT) > EEPROM_CHECKSUM_REG) + return 0; + return (s->eeprom_data[index] << E1000_EEPROM_RW_REG_DATA) | + E1000_EEPROM_RW_REG_DONE | r; +} + +static unsigned int +do_cksum(uint8_t *dp, uint8_t *de) +{ + unsigned int bsum[2] = {0, 0}, i, sum; + + for (i = 1; dp < de; bsum[i^=1] += *dp++) + ; + sum = (bsum[0] << 8) + bsum[1]; + sum = (sum >> 16) + (sum & 0xffff); + return ~(sum + (sum >> 16)); +} + +static void +putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse) +{ + if (cse && cse < n) + n = cse + 1; + if (sloc < n-1) + cpu_to_be16wu((uint16_t *)(data + sloc), + do_cksum(data + css, data + n)); +} + +static void +xmit_seg(E1000State *s) +{ + uint16_t len, *sp; + unsigned int frames = s->tx.tso_frames, css, sofar, n; + struct e1000_tx *tp = &s->tx; + + if (tp->tse) { + css = tp->ipcss; + DBGOUT(TXSUM, "frames %d size %d ipcss %d\n", + frames, tp->size, css); + if (tp->ip) { // IPv4 + cpu_to_be16wu((uint16_t *)(tp->data+css+2), + tp->size - css); + cpu_to_be16wu((uint16_t *)(tp->data+css+4), + be16_to_cpup((uint16_t *)(tp->data+css+4))+frames); + } else // IPv6 + cpu_to_be16wu((uint16_t *)(tp->data+css+4), + tp->size - css); + css = tp->tucss; + len = tp->size - css; + DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len); + if (tp->tcp) { + sofar = frames * tp->mss; + cpu_to_be32wu((uint32_t *)(tp->data+css+4), // seq + be32_to_cpup((uint32_t *)(tp->data+css+4))+sofar); + if (tp->paylen - sofar > tp->mss) + tp->data[css + 13] &= ~9; // PSH, FIN + } else // UDP + cpu_to_be16wu((uint16_t *)(tp->data+css+4), len); + if (tp->sum_needed & E1000_TXD_POPTS_TXSM) { + // add pseudo-header length before checksum calculation + sp = (uint16_t *)(tp->data + tp->tucso); + cpu_to_be16wu(sp, be16_to_cpup(sp) + len); + } + tp->tso_frames++; + } + + if (tp->sum_needed & E1000_TXD_POPTS_TXSM) + putsum(tp->data, tp->size, tp->tucso, tp->tucss, tp->tucse); + if (tp->sum_needed & E1000_TXD_POPTS_IXSM) + putsum(tp->data, tp->size, tp->ipcso, tp->ipcss, tp->ipcse); + qemu_send_packet(s->vc, tp->data, tp->size); + s->mac_reg[TPT]++; + s->mac_reg[GPTC]++; + n = s->mac_reg[TOTL]; + if ((s->mac_reg[TOTL] += s->tx.size) < n) + s->mac_reg[TOTH]++; +} + +static void +process_tx_desc(E1000State *s, struct e1000_tx_desc *dp) +{ + uint32_t txd_lower = le32_to_cpu(dp->lower.data); + uint32_t dtype = txd_lower & (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D); + unsigned int split_size = txd_lower & 0xffff, bytes, sz, op; + unsigned int msh = 0xfffff, hdr = 0; + uint64_t addr; + struct e1000_context_desc *xp = (struct e1000_context_desc *)dp; + struct e1000_tx *tp = &s->tx; + + if (dtype == E1000_TXD_CMD_DEXT) { // context descriptor + op = le32_to_cpu(xp->cmd_and_length); + tp->ipcss = xp->lower_setup.ip_fields.ipcss; + tp->ipcso = xp->lower_setup.ip_fields.ipcso; + tp->ipcse = le16_to_cpu(xp->lower_setup.ip_fields.ipcse); + tp->tucss = xp->upper_setup.tcp_fields.tucss; + tp->tucso = xp->upper_setup.tcp_fields.tucso; + tp->tucse = le16_to_cpu(xp->upper_setup.tcp_fields.tucse); + tp->paylen = op & 0xfffff; + tp->hdr_len = xp->tcp_seg_setup.fields.hdr_len; + tp->mss = le16_to_cpu(xp->tcp_seg_setup.fields.mss); + tp->ip = (op & E1000_TXD_CMD_IP) ? 1 : 0; + tp->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0; + tp->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0; + tp->tso_frames = 0; + if (tp->tucso == 0) { // this is probably wrong + DBGOUT(TXSUM, "TCP/UDP: cso 0!\n"); + tp->tucso = tp->tucss + (tp->tcp ? 16 : 6); + } + return; + } else if (dtype == (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D)) + tp->sum_needed = le32_to_cpu(dp->upper.data) >> 8; + + addr = le64_to_cpu(dp->buffer_addr); + if (tp->tse) { + hdr = tp->hdr_len; + msh = hdr + tp->mss; + } + do { + bytes = split_size; + if (tp->size + bytes > msh) + bytes = msh - tp->size; + cpu_physical_memory_read(addr, tp->data + tp->size, bytes); + if ((sz = tp->size + bytes) >= hdr && tp->size < hdr) + memmove(tp->header, tp->data, hdr); + tp->size = sz; + addr += bytes; + if (sz == msh) { + xmit_seg(s); + memmove(tp->data, tp->header, hdr); + tp->size = hdr; + } + } while (split_size -= bytes); + + if (!(txd_lower & E1000_TXD_CMD_EOP)) + return; + if (tp->size > hdr) + xmit_seg(s); + tp->tso_frames = 0; + tp->sum_needed = 0; + tp->size = 0; +} + +static uint32_t +txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp) +{ + uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data); + + if (!(txd_lower & (E1000_TXD_CMD_RS|E1000_TXD_CMD_RPS))) + return 0; + txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) & + ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU); + dp->upper.data = cpu_to_le32(txd_upper); + cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp), + (void *)&dp->upper, sizeof(dp->upper)); + return E1000_ICR_TXDW; +} + +static void +start_xmit(E1000State *s) +{ + target_phys_addr_t base; + struct e1000_tx_desc desc; + uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE; + + if (!(s->mac_reg[TCTL] & E1000_TCTL_EN)) { + DBGOUT(TX, "tx disabled\n"); + return; + } + + while (s->mac_reg[TDH] != s->mac_reg[TDT]) { + base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] + + sizeof(struct e1000_tx_desc) * s->mac_reg[TDH]; + cpu_physical_memory_read(base, (void *)&desc, sizeof(desc)); + + DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH], + (void *)desc.buffer_addr, desc.lower.data, + desc.upper.data); + + process_tx_desc(s, &desc); + cause |= txdesc_writeback(base, &desc); + + if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN]) + s->mac_reg[TDH] = 0; + /* + * the following could happen only if guest sw assigns + * bogus values to TDT/TDLEN. + * there's nothing too intelligent we could do about this. + */ + if (s->mac_reg[TDH] == tdh_start) { + DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n", + tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]); + break; + } + } + set_ics(s, 0, cause); +} + +static int +receive_filter(E1000State *s, const uint8_t *buf, int size) +{ + static uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + static int mta_shift[] = {4, 3, 2, 0}; + uint32_t f, rctl = s->mac_reg[RCTL], ra[2], *rp; + + if (rctl & E1000_RCTL_UPE) // promiscuous + return 1; + + if ((buf[0] & 1) && (rctl & E1000_RCTL_MPE)) // promiscuous mcast + return 1; + + if ((rctl & E1000_RCTL_BAM) && !memcmp(buf, bcast, sizeof bcast)) + return 1; + + for (rp = s->mac_reg + RA; rp < s->mac_reg + RA + 32; rp += 2) { + if (!(rp[1] & E1000_RAH_AV)) + continue; + ra[0] = cpu_to_le32(rp[0]); + ra[1] = cpu_to_le32(rp[1]); + if (!memcmp(buf, (uint8_t *)ra, 6)) { + DBGOUT(RXFILTER, + "unicast match[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n", + (int)(rp - s->mac_reg - RA)/2, + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + return 1; + } + } + DBGOUT(RXFILTER, "unicast mismatch: %02x:%02x:%02x:%02x:%02x:%02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + + f = mta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3]; + f = (((buf[5] << 8) | buf[4]) >> f) & 0xfff; + if (s->mac_reg[MTA + (f >> 5)] & (1 << (f & 0x1f))) + return 1; + DBGOUT(RXFILTER, + "dropping, inexact filter mismatch: %02x:%02x:%02x:%02x:%02x:%02x MO %d MTA[%d] %x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + (rctl >> E1000_RCTL_MO_SHIFT) & 3, f >> 5, + s->mac_reg[MTA + (f >> 5)]); + + return 0; +} + +static int +e1000_can_receive(void *opaque) +{ + E1000State *s = opaque; + + return (!(s->mac_reg[RCTL] & E1000_RCTL_EN) || + s->mac_reg[RDH] != s->mac_reg[RDT]); +} + +static void +e1000_receive(void *opaque, const uint8_t *buf, int size) +{ + E1000State *s = opaque; + struct e1000_rx_desc desc; + target_phys_addr_t base; + unsigned int n, rdt; + uint32_t rdh_start; + + if (!(s->mac_reg[RCTL] & E1000_RCTL_EN)) + return; + + if (size > s->rxbuf_size) { + DBGOUT(RX, "packet too large for buffers (%d > %d)\n", size, + s->rxbuf_size); + return; + } + + if (!receive_filter(s, buf, size)) + return; + + rdh_start = s->mac_reg[RDH]; + size += 4; // for the header + do { + if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) { + set_ics(s, 0, E1000_ICS_RXO); + return; + } + base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] + + sizeof(desc) * s->mac_reg[RDH]; + cpu_physical_memory_read(base, (void *)&desc, sizeof(desc)); + desc.status |= E1000_RXD_STAT_DD; + if (desc.buffer_addr) { + cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr), + (void *)buf, size); + desc.length = cpu_to_le16(size); + desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM; + } else // as per intel docs; skip descriptors with null buf addr + DBGOUT(RX, "Null RX descriptor!!\n"); + cpu_physical_memory_write(base, (void *)&desc, sizeof(desc)); + + if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) + s->mac_reg[RDH] = 0; + s->check_rxov = 1; + /* see comment in start_xmit; same here */ + if (s->mac_reg[RDH] == rdh_start) { + DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n", + rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]); + set_ics(s, 0, E1000_ICS_RXO); + return; + } + } while (desc.buffer_addr == 0); + + s->mac_reg[GPRC]++; + s->mac_reg[TPR]++; + n = s->mac_reg[TORL]; + if ((s->mac_reg[TORL] += size) < n) + s->mac_reg[TORH]++; + + n = E1000_ICS_RXT0; + if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH]) + rdt += s->mac_reg[RDLEN] / sizeof(desc); + if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >= + s->mac_reg[RDLEN]) + n |= E1000_ICS_RXDMT0; + + set_ics(s, 0, n); +} + +static uint32_t +mac_readreg(E1000State *s, int index) +{ + return s->mac_reg[index]; +} + +static uint32_t +mac_icr_read(E1000State *s, int index) +{ + uint32_t ret = s->mac_reg[ICR]; + + DBGOUT(INTERRUPT, "ICR read: %x\n", ret); + set_interrupt_cause(s, 0, 0); + return ret; +} + +static uint32_t +mac_read_clr4(E1000State *s, int index) +{ + uint32_t ret = s->mac_reg[index]; + + s->mac_reg[index] = 0; + return ret; +} + +static uint32_t +mac_read_clr8(E1000State *s, int index) +{ + uint32_t ret = s->mac_reg[index]; + + s->mac_reg[index] = 0; + s->mac_reg[index-1] = 0; + return ret; +} + +static void +mac_writereg(E1000State *s, int index, uint32_t val) +{ + s->mac_reg[index] = val; +} + +static void +set_rdt(E1000State *s, int index, uint32_t val) +{ + s->check_rxov = 0; + s->mac_reg[index] = val & 0xffff; +} + +static void +set_16bit(E1000State *s, int index, uint32_t val) +{ + s->mac_reg[index] = val & 0xffff; +} + +static void +set_dlen(E1000State *s, int index, uint32_t val) +{ + s->mac_reg[index] = val & 0xfff80; +} + +static void +set_tctl(E1000State *s, int index, uint32_t val) +{ + s->mac_reg[index] = val; + s->mac_reg[TDT] &= 0xffff; + start_xmit(s); +} + +static void +set_icr(E1000State *s, int index, uint32_t val) +{ + DBGOUT(INTERRUPT, "set_icr %x\n", val); + set_interrupt_cause(s, 0, s->mac_reg[ICR] & ~val); +} + +static void +set_imc(E1000State *s, int index, uint32_t val) +{ + s->mac_reg[IMS] &= ~val; + set_ics(s, 0, 0); +} + +static void +set_ims(E1000State *s, int index, uint32_t val) +{ + s->mac_reg[IMS] |= val; + set_ics(s, 0, 0); +} + +#define getreg(x) [x] = mac_readreg +static uint32_t (*macreg_readops[])(E1000State *, int) = { + getreg(PBA), getreg(RCTL), getreg(TDH), getreg(TXDCTL), + getreg(WUFC), getreg(TDT), getreg(CTRL), getreg(LEDCTL), + getreg(MANC), getreg(MDIC), getreg(SWSM), getreg(STATUS), + getreg(TORL), getreg(TOTL), getreg(IMS), getreg(TCTL), + getreg(RDH), getreg(RDT), + + [TOTH] = mac_read_clr8, [TORH] = mac_read_clr8, [GPRC] = mac_read_clr4, + [GPTC] = mac_read_clr4, [TPR] = mac_read_clr4, [TPT] = mac_read_clr4, + [ICR] = mac_icr_read, [EECD] = get_eecd, [EERD] = flash_eerd_read, + [CRCERRS ... MPC] = &mac_readreg, + [RA ... RA+31] = &mac_readreg, + [MTA ... MTA+127] = &mac_readreg, +}; +enum { NREADOPS = sizeof(macreg_readops) / sizeof(*macreg_readops) }; + +#define putreg(x) [x] = mac_writereg +static void (*macreg_writeops[])(E1000State *, int, uint32_t) = { + putreg(PBA), putreg(EERD), putreg(SWSM), putreg(WUFC), + putreg(TDBAL), putreg(TDBAH), putreg(TXDCTL), putreg(RDBAH), + putreg(RDBAL), putreg(LEDCTL), + [TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl, + [TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics, + [TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt, + [IMC] = set_imc, [IMS] = set_ims, [ICR] = set_icr, + [EECD] = set_eecd, [RCTL] = set_rx_control, + [RA ... RA+31] = &mac_writereg, + [MTA ... MTA+127] = &mac_writereg, +}; +enum { NWRITEOPS = sizeof(macreg_writeops) / sizeof(*macreg_writeops) }; + +static void +e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +{ + E1000State *s = opaque; + unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2; + + if (index < NWRITEOPS && macreg_writeops[index]) + macreg_writeops[index](s, index, le32_to_cpu(val)); + else if (index < NREADOPS && macreg_readops[index]) + DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val); + else + DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n", + index<<2, val); +} + +static void +e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val) +{ + // emulate hw without byte enables: no RMW + e1000_mmio_writel(opaque, addr & ~3, + cpu_to_le32(le16_to_cpu(val & 0xffff) << (8*(addr & 3)))); +} + +static void +e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +{ + // emulate hw without byte enables: no RMW + e1000_mmio_writel(opaque, addr & ~3, + cpu_to_le32((val & 0xff) << (8*(addr & 3)))); +} + +static uint32_t +e1000_mmio_readl(void *opaque, target_phys_addr_t addr) +{ + E1000State *s = opaque; + unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2; + + if (index < NREADOPS && macreg_readops[index]) + return cpu_to_le32(macreg_readops[index](s, index)); + DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2); + return 0; +} + +static uint32_t +e1000_mmio_readb(void *opaque, target_phys_addr_t addr) +{ + return (le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >> + (8 * (addr & 3))) & 0xff; +} + +static uint32_t +e1000_mmio_readw(void *opaque, target_phys_addr_t addr) +{ + return cpu_to_le16((le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >> + (8 * (addr & 3))) & 0xffff); +} + +int mac_regtosave[] = { + CTRL, EECD, EERD, GPRC, GPTC, ICR, ICS, IMC, IMS, + LEDCTL, MANC, MDIC, MPC, PBA, RCTL, RDBAH, RDBAL, RDH, + RDLEN, RDT, STATUS, SWSM, TCTL, TDBAH, TDBAL, TDH, TDLEN, + TDT, TORH, TORL, TOTH, TOTL, TPR, TPT, TXDCTL, WUFC, +}; +enum { MAC_NSAVE = sizeof mac_regtosave/sizeof *mac_regtosave }; + +struct { + int size; + int array0; +} mac_regarraystosave[] = { {32, RA}, {128, MTA} }; +enum { MAC_NARRAYS = sizeof mac_regarraystosave/sizeof *mac_regarraystosave }; + +static void +nic_save(QEMUFile *f, void *opaque) +{ + E1000State *s = (E1000State *)opaque; + int i, j; + + pci_device_save(&s->dev, f); + qemu_put_be32s(f, &s->instance); + qemu_put_be32s(f, &s->mmio_base); + qemu_put_be32s(f, &s->rxbuf_size); + qemu_put_be32s(f, &s->rxbuf_min_shift); + qemu_put_be32s(f, &s->eecd_state.val_in); + qemu_put_be16s(f, &s->eecd_state.bitnum_in); + qemu_put_be16s(f, &s->eecd_state.bitnum_out); + qemu_put_be16s(f, &s->eecd_state.reading); + qemu_put_be32s(f, &s->eecd_state.old_eecd); + qemu_put_8s(f, &s->tx.ipcss); + qemu_put_8s(f, &s->tx.ipcso); + qemu_put_be16s(f, &s->tx.ipcse); + qemu_put_8s(f, &s->tx.tucss); + qemu_put_8s(f, &s->tx.tucso); + qemu_put_be16s(f, &s->tx.tucse); + qemu_put_be32s(f, &s->tx.paylen); + qemu_put_8s(f, &s->tx.hdr_len); + qemu_put_be16s(f, &s->tx.mss); + qemu_put_be16s(f, &s->tx.size); + qemu_put_be16s(f, &s->tx.tso_frames); + qemu_put_8s(f, &s->tx.sum_needed); + qemu_put_8s(f, &s->tx.ip); + qemu_put_8s(f, &s->tx.tcp); + qemu_put_buffer(f, s->tx.header, sizeof s->tx.header); + qemu_put_buffer(f, s->tx.data, sizeof s->tx.data); + for (i = 0; i < 64; i++) + qemu_put_be16s(f, s->eeprom_data + i); + for (i = 0; i < 0x20; i++) + qemu_put_be16s(f, s->phy_reg + i); + for (i = 0; i < MAC_NSAVE; i++) + qemu_put_be32s(f, s->mac_reg + mac_regtosave[i]); + for (i = 0; i < MAC_NARRAYS; i++) + for (j = 0; j < mac_regarraystosave[i].size; j++) + qemu_put_be32s(f, + s->mac_reg + mac_regarraystosave[i].array0 + j); +} + +static int +nic_load(QEMUFile *f, void *opaque, int version_id) +{ + E1000State *s = (E1000State *)opaque; + int i, j, ret; + + if ((ret = pci_device_load(&s->dev, f)) < 0) + return ret; + qemu_get_be32s(f, &s->instance); + qemu_get_be32s(f, &s->mmio_base); + qemu_get_be32s(f, &s->rxbuf_size); + qemu_get_be32s(f, &s->rxbuf_min_shift); + qemu_get_be32s(f, &s->eecd_state.val_in); + qemu_get_be16s(f, &s->eecd_state.bitnum_in); + qemu_get_be16s(f, &s->eecd_state.bitnum_out); + qemu_get_be16s(f, &s->eecd_state.reading); + qemu_get_be32s(f, &s->eecd_state.old_eecd); + qemu_get_8s(f, &s->tx.ipcss); + qemu_get_8s(f, &s->tx.ipcso); + qemu_get_be16s(f, &s->tx.ipcse); + qemu_get_8s(f, &s->tx.tucss); + qemu_get_8s(f, &s->tx.tucso); + qemu_get_be16s(f, &s->tx.tucse); + qemu_get_be32s(f, &s->tx.paylen); + qemu_get_8s(f, &s->tx.hdr_len); + qemu_get_be16s(f, &s->tx.mss); + qemu_get_be16s(f, &s->tx.size); + qemu_get_be16s(f, &s->tx.tso_frames); + qemu_get_8s(f, &s->tx.sum_needed); + qemu_get_8s(f, &s->tx.ip); + qemu_get_8s(f, &s->tx.tcp); + qemu_get_buffer(f, s->tx.header, sizeof s->tx.header); + qemu_get_buffer(f, s->tx.data, sizeof s->tx.data); + for (i = 0; i < 64; i++) + qemu_get_be16s(f, s->eeprom_data + i); + for (i = 0; i < 0x20; i++) + qemu_get_be16s(f, s->phy_reg + i); + for (i = 0; i < MAC_NSAVE; i++) + qemu_get_be32s(f, s->mac_reg + mac_regtosave[i]); + for (i = 0; i < MAC_NARRAYS; i++) + for (j = 0; j < mac_regarraystosave[i].size; j++) + qemu_get_be32s(f, + s->mac_reg + mac_regarraystosave[i].array0 + j); + return 0; +} + +static uint16_t e1000_eeprom_template[64] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, + 0x3000, 0x1000, 0x6403, E1000_DEVID, 0x8086, E1000_DEVID, 0x8086, 0x3040, + 0x0008, 0x2000, 0x7e14, 0x0048, 0x1000, 0x00d8, 0x0000, 0x2700, + 0x6cc9, 0x3150, 0x0722, 0x040b, 0x0984, 0x0000, 0xc000, 0x0706, + 0x1008, 0x0000, 0x0f04, 0x7fff, 0x4d01, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0x0100, 0x4000, 0x121c, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, +}; + +static uint16_t phy_reg_init[] = { + [PHY_CTRL] = 0x1140, [PHY_STATUS] = 0x796d, // link initially up + [PHY_ID1] = 0x141, [PHY_ID2] = PHY_ID2_INIT, + [PHY_1000T_CTRL] = 0x0e00, [M88E1000_PHY_SPEC_CTRL] = 0x360, + [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60, [PHY_AUTONEG_ADV] = 0xde1, + [PHY_LP_ABILITY] = 0x1e0, [PHY_1000T_STATUS] = 0x3c00, +}; + +static uint32_t mac_reg_init[] = { + [PBA] = 0x00100030, + [LEDCTL] = 0x602, + [CTRL] = E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN0 | + E1000_CTRL_SPD_1000 | E1000_CTRL_SLU, + [STATUS] = 0x80000000 | E1000_STATUS_GIO_MASTER_ENABLE | + E1000_STATUS_ASDV | E1000_STATUS_MTXCKOK | + E1000_STATUS_SPEED_1000 | E1000_STATUS_FD | + E1000_STATUS_LU, + [MANC] = E1000_MANC_EN_MNG2HOST | E1000_MANC_RCV_TCO_EN | + E1000_MANC_ARP_EN | E1000_MANC_0298_EN | + E1000_MANC_RMCP_EN, +}; + +/* PCI interface */ + +static CPUWriteMemoryFunc *e1000_mmio_write[] = { + e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel +}; + +static CPUReadMemoryFunc *e1000_mmio_read[] = { + e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl +}; + +static void +e1000_mmio_map(PCIDevice *pci_dev, int region_num, + uint32_t addr, uint32_t size, int type) +{ + E1000State *d = (E1000State *)pci_dev; + + DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size); + + d->mmio_base = addr; + cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index); +} + +void +pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn) +{ + E1000State *d; + uint8_t *pci_conf; + static int instance; + uint16_t checksum = 0; + char *info_str = "e1000"; + int i; + + d = (E1000State *)pci_register_device(bus, "e1000", + sizeof(E1000State), devfn, NULL, NULL); + + pci_conf = d->dev.config; + memset(pci_conf, 0, 256); + + *(uint16_t *)(pci_conf+0x00) = cpu_to_le16(0x8086); + *(uint16_t *)(pci_conf+0x02) = cpu_to_le16(E1000_DEVID); + *(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407); + *(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010); + pci_conf[0x08] = 0x03; + pci_conf[0x0a] = 0x00; // ethernet network controller + pci_conf[0x0b] = 0x02; + pci_conf[0x0c] = 0x10; + + pci_conf[0x3d] = 1; // interrupt pin 0 + + d->mmio_index = cpu_register_io_memory(0, e1000_mmio_read, + e1000_mmio_write, d); + + pci_register_io_region((PCIDevice *)d, 0, PNPMMIO_SIZE, + PCI_ADDRESS_SPACE_MEM, e1000_mmio_map); + + pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE, + PCI_ADDRESS_SPACE_IO, ioport_map); + + d->instance = instance++; + + d->nd = nd; + memmove(d->eeprom_data, e1000_eeprom_template, + sizeof e1000_eeprom_template); + for (i = 0; i < 3; i++) + d->eeprom_data[i] = (nd->macaddr[2*i+1]<<8) | nd->macaddr[2*i]; + for (i = 0; i < EEPROM_CHECKSUM_REG; i++) + checksum += d->eeprom_data[i]; + checksum = (uint16_t) EEPROM_SUM - checksum; + d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum; + + memset(d->phy_reg, 0, sizeof d->phy_reg); + memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init); + memset(d->mac_reg, 0, sizeof d->mac_reg); + memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init); + d->rxbuf_min_shift = 1; + memset(&d->tx, 0, sizeof d->tx); + + d->vc = qemu_new_vlan_client(nd->vlan, e1000_receive, + e1000_can_receive, d); + + snprintf(d->vc->info_str, sizeof(d->vc->info_str), + "%s macaddr=%02x:%02x:%02x:%02x:%02x:%02x", info_str, + d->nd->macaddr[0], d->nd->macaddr[1], d->nd->macaddr[2], + d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]); + + register_savevm(info_str, d->instance, 1, nic_save, nic_load, d); +} diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/e1000_hw.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/e1000_hw.h Tue Feb 26 10:12:04 2008 -0700 @@ -0,0 +1,865 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2006 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS <linux.nics@xxxxxxxxx> + e1000-devel Mailing List <e1000-devel@xxxxxxxxxxxxxxxxxxxxx> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +/* e1000_hw.h + * Structures, enums, and macros for the MAC + */ + +#ifndef _E1000_HW_H_ +#define _E1000_HW_H_ + + +/* PCI Device IDs */ +#define E1000_DEV_ID_82542 0x1000 +#define E1000_DEV_ID_82543GC_FIBER 0x1001 +#define E1000_DEV_ID_82543GC_COPPER 0x1004 +#define E1000_DEV_ID_82544EI_COPPER 0x1008 +#define E1000_DEV_ID_82544EI_FIBER 0x1009 +#define E1000_DEV_ID_82544GC_COPPER 0x100C +#define E1000_DEV_ID_82544GC_LOM 0x100D +#define E1000_DEV_ID_82540EM 0x100E +#define E1000_DEV_ID_82540EM_LOM 0x1015 +#define E1000_DEV_ID_82540EP_LOM 0x1016 +#define E1000_DEV_ID_82540EP 0x1017 +#define E1000_DEV_ID_82540EP_LP 0x101E +#define E1000_DEV_ID_82545EM_COPPER 0x100F +#define E1000_DEV_ID_82545EM_FIBER 0x1011 +#define E1000_DEV_ID_82545GM_COPPER 0x1026 +#define E1000_DEV_ID_82545GM_FIBER 0x1027 +#define E1000_DEV_ID_82545GM_SERDES 0x1028 +#define E1000_DEV_ID_82546EB_COPPER 0x1010 +#define E1000_DEV_ID_82546EB_FIBER 0x1012 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D +#define E1000_DEV_ID_82541EI 0x1013 +#define E1000_DEV_ID_82541EI_MOBILE 0x1018 +#define E1000_DEV_ID_82541ER_LOM 0x1014 +#define E1000_DEV_ID_82541ER 0x1078 +#define E1000_DEV_ID_82547GI 0x1075 +#define E1000_DEV_ID_82541GI 0x1076 +#define E1000_DEV_ID_82541GI_MOBILE 0x1077 +#define E1000_DEV_ID_82541GI_LF 0x107C +#define E1000_DEV_ID_82546GB_COPPER 0x1079 +#define E1000_DEV_ID_82546GB_FIBER 0x107A +#define E1000_DEV_ID_82546GB_SERDES 0x107B +#define E1000_DEV_ID_82546GB_PCIE 0x108A +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 +#define E1000_DEV_ID_82547EI 0x1019 +#define E1000_DEV_ID_82547EI_MOBILE 0x101A +#define E1000_DEV_ID_82571EB_COPPER 0x105E +#define E1000_DEV_ID_82571EB_FIBER 0x105F +#define E1000_DEV_ID_82571EB_SERDES 0x1060 +#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 +#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 +#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC +#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 +#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA +#define E1000_DEV_ID_82572EI_COPPER 0x107D +#define E1000_DEV_ID_82572EI_FIBER 0x107E +#define E1000_DEV_ID_82572EI_SERDES 0x107F +#define E1000_DEV_ID_82572EI 0x10B9 +#define E1000_DEV_ID_82573E 0x108B +#define E1000_DEV_ID_82573E_IAMT 0x108C +#define E1000_DEV_ID_82573L 0x109A +#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 +#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 +#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 +#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA +#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB + +#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 +#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A +#define E1000_DEV_ID_ICH8_IGP_C 0x104B +#define E1000_DEV_ID_ICH8_IFE 0x104C +#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 +#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 +#define E1000_DEV_ID_ICH8_IGP_M 0x104D + +/* Register Set. (82543, 82544) + * + * Registers are defined to be 32 bits and should be accessed as 32 bit values. + * These registers are physically located on the NIC, but are mapped into the + * host memory address space. + * + * RW - register is both readable and writable + * RO - register is read only + * WO - register is write only + * R/clr - register is read only and is cleared when read + * A - register array + */ +#define E1000_CTRL 0x00000 /* Device Control - RW */ +#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */ +#define E1000_STATUS 0x00008 /* Device Status - RO */ +#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ +#define E1000_EERD 0x00014 /* EEPROM Read - RW */ +#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */ +#define E1000_FLA 0x0001C /* Flash Access - RW */ +#define E1000_MDIC 0x00020 /* MDI Control - RW */ +#define E1000_SCTL 0x00024 /* SerDes Control - RW */ +#define E1000_FEXTNVM 0x00028 /* Future Extended NVM register */ +#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ +#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ +#define E1000_FCT 0x00030 /* Flow Control Type - RW */ +#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ +#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ +#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */ +#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ +#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ +#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ +#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ +#define E1000_RCTL 0x00100 /* RX Control - RW */ +#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */ +#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */ +#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */ +#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */ +#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */ +#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */ +#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ +#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ +#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */ +#define E1000_TCTL 0x00400 /* TX Control - RW */ +#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */ +#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */ +#define E1000_TBT 0x00448 /* TX Burst Timer - RW */ +#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ +#define E1000_LEDCTL 0x00E00 /* LED Control - RW */ +#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ +#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ +#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */ +#define FEXTNVM_SW_CONFIG 0x0001 +#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ +#define E1000_PBS 0x01008 /* Packet Buffer Size */ +#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ +#define E1000_FLASH_UPDATES 1000 +#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ +#define E1000_FLASHT 0x01028 /* FLASH Timer Register */ +#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ +#define E1000_FLSWCTL 0x01030 /* FLASH control register */ +#define E1000_FLSWDATA 0x01034 /* FLASH data register */ +#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ +#define E1000_FLOP 0x0103C /* FLASH Opcode Register */ +#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */ +#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ +#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ +#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ +#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ +#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ +#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ +#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */ +#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */ +#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */ +#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */ +#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */ +#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */ +#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */ +#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */ +#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */ +#define E1000_RXDCTL 0x02828 /* RX Descriptor Control queue 0 - RW */ +#define E1000_RXDCTL1 0x02928 /* RX Descriptor Control queue 1 - RW */ +#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ +#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ +#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ +#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ +#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */ +#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ +#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ +#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */ +#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */ +#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */ +#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */ +#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */ +#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */ +#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */ +#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */ +#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */ +#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */ +#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */ +#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */ +#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */ +#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */ +#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */ +#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */ +#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */ +#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */ +#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */ +#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */ +#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ +#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ +#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ +#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */ +#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */ +#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */ +#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */ +#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */ +#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ +#define E1000_COLC 0x04028 /* Collision Count - R/clr */ +#define E1000_DC 0x04030 /* Defer Count - R/clr */ +#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */ +#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */ +#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */ +#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ +#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */ +#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */ +#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */ +#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */ +#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */ +#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */ +#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */ +#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */ +#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */ +#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */ +#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */ +#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */ +#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */ +#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */ +#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */ +#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */ +#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */ +#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */ +#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */ +#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */ +#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */ +#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */ +#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */ +#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */ +#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */ +#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */ +#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */ +#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */ +#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */ +#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */ +#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */ +#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */ +#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */ +#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */ +#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */ +#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */ +#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */ +#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */ +#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */ +#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */ +#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ +#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ +#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */ +#define E1000_IAC 0x04100 /* Interrupt Assertion Count */ +#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */ +#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */ +#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */ +#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */ +#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */ +#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */ +#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */ +#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */ +#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ +#define E1000_RFCTL 0x05008 /* Receive Filter Control*/ +#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ +#define E1000_RA 0x05400 /* Receive Address - RW Array */ +#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ +#define E1000_WUC 0x05800 /* Wakeup Control - RW */ +#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ +#define E1000_WUS 0x05810 /* Wakeup Status - RO */ +#define E1000_MANC 0x05820 /* Management Control - RW */ +#define E1000_IPAV 0x05838 /* IP Address Valid - RW */ +#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */ +#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ +#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ +#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ +#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ +#define E1000_HOST_IF 0x08800 /* Host Interface */ +#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ +#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ + +#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */ +#define E1000_MDPHYA 0x0003C /* PHY address - RW */ +#define E1000_MANC2H 0x05860 /* Managment Control To Host - RW */ +#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ + +#define E1000_GCR 0x05B00 /* PCI-Ex Control */ +#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ +#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ +#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ +#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ +#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */ +#define E1000_SWSM 0x05B50 /* SW Semaphore */ +#define E1000_FWSM 0x05B54 /* FW Semaphore */ +#define E1000_FFLT_DBG 0x05F04 /* Debug Register */ +#define E1000_HICR 0x08F00 /* Host Inteface Control */ + +/* RSS registers */ +#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */ +#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */ +#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */ +#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */ +#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ +#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ + +/* PHY 1000 MII Register/Bit Definitions */ +/* PHY Registers defined by IEEE */ +#define PHY_CTRL 0x00 /* Control Register */ +#define PHY_STATUS 0x01 /* Status Regiser */ +#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ +#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ +#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ +#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */ +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ +#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ +#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ + +#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ +#define MAX_PHY_MULTI_PAGE_REG 0xF /* Registers equal on all pages */ + +/* M88E1000 Specific Registers */ +#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ +#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */ +#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */ +#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */ +#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ +#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */ + +#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */ +#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */ +#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */ +#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ +#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */ + +/* Interrupt Cause Read */ +#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ +#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ +#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ +#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ +#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ +#define E1000_ICR_RXO 0x00000040 /* rx overrun */ +#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ +#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ +#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */ +#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ +#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ +#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ +#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ +#define E1000_ICR_TXD_LOW 0x00008000 +#define E1000_ICR_SRPD 0x00010000 +#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ +#define E1000_ICR_MNG 0x00040000 /* Manageability event */ +#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ +#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ +#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */ +#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */ +#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity error */ +#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */ +#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */ +#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */ +#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */ +#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */ +#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */ +#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */ + +/* Interrupt Cause Set */ +#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ +#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ +#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_ICS_SRPD E1000_ICR_SRPD +#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */ +#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */ +#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */ +#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */ +#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */ +#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */ +#define E1000_ICS_DSW E1000_ICR_DSW +#define E1000_ICS_PHYINT E1000_ICR_PHYINT +#define E1000_ICS_EPRST E1000_ICR_EPRST + +/* Interrupt Mask Set */ +#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ +#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ +#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_IMS_SRPD E1000_ICR_SRPD +#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */ +#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */ +#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */ +#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */ +#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */ +#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */ +#define E1000_IMS_DSW E1000_ICR_DSW +#define E1000_IMS_PHYINT E1000_ICR_PHYINT +#define E1000_IMS_EPRST E1000_ICR_EPRST + +/* Interrupt Mask Clear */ +#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ +#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ +#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */ +#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ +#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ +#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */ +#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */ +#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */ +#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ +#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ +#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ +#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ +#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW +#define E1000_IMC_SRPD E1000_ICR_SRPD +#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */ +#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */ +#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */ +#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */ +#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */ +#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */ +#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */ +#define E1000_IMC_DSW E1000_ICR_DSW +#define E1000_IMC_PHYINT E1000_ICR_PHYINT +#define E1000_IMC_EPRST E1000_ICR_EPRST + +/* Receive Control */ +#define E1000_RCTL_RST 0x00000001 /* Software reset */ +#define E1000_RCTL_EN 0x00000002 /* enable */ +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ +#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ +#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ +#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ +#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ +#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ +#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */ +#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */ +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ +#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ +#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ +#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ +#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ +#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ +#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ +#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ +/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ +#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ +#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ +#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ +#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ +/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ +#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ +#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ +#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ +#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ +#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ +#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ +#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ +#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ +#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ + + +#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ +#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */ +#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */ +#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ +#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */ +#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ +#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */ +#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */ +/* Register Bit Masks */ +/* Device Control */ +#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ +#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ +#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ +#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */ +#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ +#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ +#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ +#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ +#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ +#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ +#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ +#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ +#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ +#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ +#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ +#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ +#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */ +#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */ +#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */ +#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */ +#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ +#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ +#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ +#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ +#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ +#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ +#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ +#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ +#define E1000_CTRL_RST 0x04000000 /* Global reset */ +#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ +#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ +#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */ +#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ +#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ +#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manageability engine */ + +/* Device Status */ +#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ +#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ +#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ +#define E1000_STATUS_FUNC_SHIFT 2 +#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ +#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ +#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ +#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ +#define E1000_STATUS_SPEED_MASK 0x000000C0 +#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */ +#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ +#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ +#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion + by EEPROM/Flash */ +#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ +#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */ +#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ +#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ +#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ +#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ +#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */ +#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */ +#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disabled */ +#define E1000_STATUS_BMC_SKU_1 0x00200000 /* BMC SRAM disabled */ +#define E1000_STATUS_BMC_SKU_2 0x00400000 /* BMC SDRAM disabled */ +#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */ +#define E1000_STATUS_BMC_LITE 0x01000000 /* BMC external code execution disabled */ +#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */ +#define E1000_STATUS_FUSE_8 0x04000000 +#define E1000_STATUS_FUSE_9 0x08000000 +#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */ +#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */ + +/* EEPROM/Flash Control */ +#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */ +#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */ +#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */ +#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */ +#define E1000_EECD_FWE_MASK 0x00000030 +#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ +#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ +#define E1000_EECD_FWE_SHIFT 4 +#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */ +#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */ +#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */ +#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */ +#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type + * (0-small, 1-large) */ +#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */ +#ifndef E1000_EEPROM_GRANT_ATTEMPTS +#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ +#endif +#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */ +#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */ +#define E1000_EECD_SIZE_EX_SHIFT 11 +#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ +#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */ +#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */ +#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ +#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ +#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ +#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ +#define E1000_EECD_SECVAL_SHIFT 22 +#define E1000_STM_OPCODE 0xDB00 +#define E1000_HICR_FW_RESET 0xC0 + +#define E1000_SHADOW_RAM_WORDS 2048 +#define E1000_ICH_NVM_SIG_WORD 0x13 +#define E1000_ICH_NVM_SIG_MASK 0xC0 + +/* MDI Control */ +#define E1000_MDIC_DATA_MASK 0x0000FFFF +#define E1000_MDIC_REG_MASK 0x001F0000 +#define E1000_MDIC_REG_SHIFT 16 +#define E1000_MDIC_PHY_MASK 0x03E00000 +#define E1000_MDIC_PHY_SHIFT 21 +#define E1000_MDIC_OP_WRITE 0x04000000 +#define E1000_MDIC_OP_READ 0x08000000 +#define E1000_MDIC_READY 0x10000000 +#define E1000_MDIC_INT_EN 0x20000000 +#define E1000_MDIC_ERROR 0x40000000 + +/* EEPROM Commands - Microwire */ +#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */ +#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */ +#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */ +#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */ +#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */ + +/* EEPROM Word Offsets */ +#define EEPROM_COMPAT 0x0003 +#define EEPROM_ID_LED_SETTINGS 0x0004 +#define EEPROM_VERSION 0x0005 +#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */ +#define EEPROM_PHY_CLASS_WORD 0x0007 +#define EEPROM_INIT_CONTROL1_REG 0x000A +#define EEPROM_INIT_CONTROL2_REG 0x000F +#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010 +#define EEPROM_INIT_CONTROL3_PORT_B 0x0014 +#define EEPROM_INIT_3GIO_3 0x001A +#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020 +#define EEPROM_INIT_CONTROL3_PORT_A 0x0024 +#define EEPROM_CFG 0x0012 +#define EEPROM_FLASH_VERSION 0x0032 +#define EEPROM_CHECKSUM_REG 0x003F + +#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */ +#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */ + +/* Transmit Descriptor */ +struct e1000_tx_desc { + uint64_t buffer_addr; /* Address of the descriptor's data buffer */ + union { + uint32_t data; + struct { + uint16_t length; /* Data buffer length */ + uint8_t cso; /* Checksum offset */ + uint8_t cmd; /* Descriptor control */ + } flags; + } lower; + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t css; /* Checksum start */ + uint16_t special; + } fields; + } upper; +}; + +/* Transmit Descriptor bit definitions */ +#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ +#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ +#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ +#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ +#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ +#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ +#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ +#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ +#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ +#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */ +#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ +#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ +#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ +#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ +#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ +#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ +#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ +#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ +#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ +#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ + +/* Transmit Control */ +#define E1000_TCTL_RST 0x00000001 /* software reset */ +#define E1000_TCTL_EN 0x00000002 /* enable tx */ +#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ +#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ +#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ +#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ +#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ + +/* Receive Descriptor */ +struct e1000_rx_desc { + uint64_t buffer_addr; /* Address of the descriptor's data buffer */ + uint16_t length; /* Length of data DMAed into data buffer */ + uint16_t csum; /* Packet checksum */ + uint8_t status; /* Descriptor status */ + uint8_t errors; /* Descriptor Errors */ + uint16_t special; +}; + +/* Receive Decriptor bit definitions */ +#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ +#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ +#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ +#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ +#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ +#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ +#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ +#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ +#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ +#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ +#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ +#define E1000_RXD_ERR_CE 0x01 /* CRC Error */ +#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ +#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ +#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ +#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ +#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ +#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ +#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ +#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ +#define E1000_RXD_SPC_PRI_SHIFT 13 +#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ +#define E1000_RXD_SPC_CFI_SHIFT 12 + +#define E1000_RXDEXT_STATERR_CE 0x01000000 +#define E1000_RXDEXT_STATERR_SE 0x02000000 +#define E1000_RXDEXT_STATERR_SEQ 0x04000000 +#define E1000_RXDEXT_STATERR_CXE 0x10000000 +#define E1000_RXDEXT_STATERR_TCPE 0x20000000 +#define E1000_RXDEXT_STATERR_IPE 0x40000000 +#define E1000_RXDEXT_STATERR_RXE 0x80000000 + +#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 +#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF + +/* Receive Address */ +#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ + +/* Offload Context Descriptor */ +struct e1000_context_desc { + union { + uint32_t ip_config; + struct { + uint8_t ipcss; /* IP checksum start */ + uint8_t ipcso; /* IP checksum offset */ + uint16_t ipcse; /* IP checksum end */ + } ip_fields; + } lower_setup; + union { + uint32_t tcp_config; + struct { + uint8_t tucss; /* TCP checksum start */ + uint8_t tucso; /* TCP checksum offset */ + uint16_t tucse; /* TCP checksum end */ + } tcp_fields; + } upper_setup; + uint32_t cmd_and_length; /* */ + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t hdr_len; /* Header length */ + uint16_t mss; /* Maximum segment size */ + } fields; + } tcp_seg_setup; +}; + +/* Offload data descriptor */ +struct e1000_data_desc { + uint64_t buffer_addr; /* Address of the descriptor's buffer address */ + union { + uint32_t data; + struct { + uint16_t length; /* Data buffer length */ + uint8_t typ_len_ext; /* */ + uint8_t cmd; /* */ + } flags; + } lower; + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t popts; /* Packet Options */ + uint16_t special; /* */ + } fields; + } upper; +}; + +/* Management Control */ +#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ +#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ +#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */ +#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */ +#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */ +#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */ +#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ +#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ +#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ +#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery + * Filtering */ +#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */ +#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ +#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ +#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ +#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */ +#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ +#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address + * filtering */ +#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host + * memory */ +#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address + * filtering */ +#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */ +#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */ +#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ +#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ +#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ +#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */ +#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */ +#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */ + +#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ +#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ + +/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */ +#define EEPROM_SUM 0xBABA + +#endif /* _E1000_HW_H_ */ diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/pci.c --- a/tools/ioemu/hw/pci.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/ioemu/hw/pci.c Tue Feb 26 10:12:04 2008 -0700 @@ -574,6 +574,8 @@ void pci_nic_init(PCIBus *bus, NICInfo * pci_pcnet_init(bus, nd, devfn); } else if (strcmp(nd->model, "e100") == 0) { pci_e100_init(bus, nd); + } else if (strcmp(nd->model, "e1000") == 0) { + pci_e1000_init(bus, nd, devfn); } else { fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd->model); exit (1); diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/xen_console.c --- a/tools/ioemu/hw/xen_console.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/ioemu/hw/xen_console.c Tue Feb 26 10:12:04 2008 -0700 @@ -381,7 +381,7 @@ static void xencons_startup(void *opaque qemu_set_fd_handler2(xs_fileno(dom->xsh), NULL, NULL, NULL, NULL); fprintf(stderr, "Console: connected to guest frontend\n"); - if (qemu_set_fd_handler2(dom->xce_handle, NULL, xencons_ring_read, NULL, dom) < 0) + if (qemu_set_fd_handler2(xc_evtchn_fd(dom->xce_handle), NULL, xencons_ring_read, NULL, dom) < 0) return; qemu_chr_add_handlers(dom->chr, xencons_can_receive, xencons_receive, diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/hw/xenfb.c --- a/tools/ioemu/hw/xenfb.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/ioemu/hw/xenfb.c Tue Feb 26 10:12:04 2008 -0700 @@ -1160,7 +1160,7 @@ static int xenfb_register_console(struct xenfb); dpy_resize(xenfb->ds, xenfb->width, xenfb->height); - if (qemu_set_fd_handler2(xenfb->evt_xch, NULL, xenfb_dispatch_channel, NULL, xenfb) < 0) + if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0) return -1; if (qemu_set_fd_handler2(xs_fileno(xenfb->xsh), NULL, xenfb_dispatch_store, NULL, xenfb) < 0) return -1; diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/osdep.c --- a/tools/ioemu/osdep.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/ioemu/osdep.c Tue Feb 26 10:12:04 2008 -0700 @@ -178,7 +178,7 @@ void kqemu_vfree(void *ptr) void *qemu_memalign(size_t alignment, size_t size) { -#if defined(_POSIX_C_SOURCE) +#if defined(_POSIX_C_SOURCE) && !defined(__sun__) int ret; void *ptr; ret = posix_memalign(&ptr, alignment, size); diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/ioemu/vl.h Tue Feb 26 10:12:04 2008 -0700 @@ -1055,6 +1055,11 @@ void pcnet_h_reset(void *opaque); void pcnet_h_reset(void *opaque); void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque); +/* e100.c */ +void pci_e100_init(PCIBus *bus, NICInfo *nd); + +/* e1000.c */ +void pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn); /* pckbd.c */ diff -r 7e8334e651c4 -r f97a0b6152c3 tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/ioemu/vnc.c Tue Feb 26 10:12:04 2008 -0700 @@ -137,6 +137,23 @@ enum { #endif /* CONFIG_VNC_TLS */ +#define QUEUE_ALLOC_UNIT 10 + +typedef struct _QueueItem +{ + int x, y, w, h; + int32_t enc; + struct _QueueItem *next; +} QueueItem; + +typedef struct _Queue +{ + QueueItem *queue_start; + int start_count; + QueueItem *queue_end; + int end_count; +} Queue; + struct VncState { QEMUTimer *timer; @@ -152,6 +169,9 @@ struct VncState uint64_t *update_row; /* outstanding updates */ int has_update; /* there's outstanding updates in the * visible area */ + + int update_requested; /* the client requested an update */ + uint8_t *old_data; int depth; /* internal VNC frame buffer byte per pixel */ int has_resize; @@ -186,6 +206,9 @@ struct VncState Buffer output; Buffer input; + + Queue upqueue; + kbd_layout_t *kbd_layout; /* current output mode information */ VncWritePixels *write_pixels; @@ -248,6 +271,11 @@ static void vnc_update_client(void *opaq static void vnc_update_client(void *opaque); static void vnc_client_read(void *opaque); static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h); +static void pixel_format_message (VncState *vs); +static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h, int32_t encoding); +static void dequeue_framebuffer_update(VncState *vs); +static int is_empty_queue(VncState *vs); +static void free_queue(VncState *vs); #if 0 static inline void vnc_set_bit(uint32_t *d, int k) @@ -370,13 +398,18 @@ static void vnc_dpy_resize(DisplayState ds->height = h; ds->linesize = w * vs->depth; if (vs->csock != -1 && vs->has_resize && size_changed) { - vnc_write_u8(vs, 0); /* msg id */ - vnc_write_u8(vs, 0); - vnc_write_u16(vs, 1); /* number of rects */ - vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223); - vnc_flush(vs); - vs->width = ds->width; - vs->height = ds->height; + vs->width = ds->width; + vs->height = ds->height; + if (vs->update_requested) { + vnc_write_u8(vs, 0); /* msg id */ + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); /* number of rects */ + vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223); + vnc_flush(vs); + vs->update_requested--; + } else { + enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, -223); + } } vs->dirty_pixel_shift = 0; for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2) @@ -553,7 +586,8 @@ static void vnc_copy(DisplayState *ds, i return; } - if (src_x < vs->visible_x || src_y < vs->visible_y || + if (!vs->update_requested || + src_x < vs->visible_x || src_y < vs->visible_y || dst_x < vs->visible_x || dst_y < vs->visible_y || (src_x + w) > (vs->visible_x + vs->visible_w) || (src_y + h) > (vs->visible_y + vs->visible_h) || @@ -592,6 +626,7 @@ static void vnc_copy(DisplayState *ds, i vnc_write_u16(vs, src_x); vnc_write_u16(vs, src_y); vnc_flush(vs); + vs->update_requested--; } else framebuffer_set_updated(vs, dst_x, dst_y, w, h); } @@ -624,8 +659,21 @@ static void _vnc_update_client(void *opa int maxx, maxy; int tile_bytes = vs->depth * DP2X(vs, 1); - if (vs->csock == -1) + if (!vs->update_requested || vs->csock == -1) return; + while (!is_empty_queue(vs) && vs->update_requested) { + int enc = vs->upqueue.queue_end->enc; + dequeue_framebuffer_update(vs); + switch (enc) { + case 0x574D5669: + pixel_format_message(vs); + break; + default: + break; + } + vs->update_requested--; + } + if (!vs->update_requested) return; now = qemu_get_clock(rt_clock); @@ -717,8 +765,11 @@ static void _vnc_update_client(void *opa vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF; - if (n_rectangles == 0) + if (n_rectangles == 0) { + vs->output.offset = saved_offset - 2; goto backoff; + } else + vs->update_requested--; vs->has_update = 0; vnc_flush(vs); @@ -735,7 +786,8 @@ static void _vnc_update_client(void *opa vs->timer_interval += VNC_REFRESH_INTERVAL_INC; if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) { vs->timer_interval = VNC_REFRESH_INTERVAL_MAX; - if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) { + if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL && + vs->update_requested) { /* Send a null update. If the client is no longer interested (e.g. minimised) it'll ignore this, and we can stop scanning the buffer until it sends another @@ -752,6 +804,7 @@ static void _vnc_update_client(void *opa send_framebuffer_update(vs, 0, 0, 1, 1); vnc_flush(vs); vs->last_update_time = now; + vs->update_requested--; return; } } @@ -821,6 +874,88 @@ static void buffer_append(Buffer *buffer buffer->offset += len; } +static void enqueue_framebuffer_update(VncState *vs, int x, int y, int w, int h, + int32_t encoding) +{ + Queue *q = &vs->upqueue; + if (q->queue_end != NULL) { + if (q->queue_end != q->queue_start || q->start_count != q->end_count) { + if (q->queue_end->next == NULL) { + q->queue_end->next = (QueueItem *) qemu_mallocz (sizeof(QueueItem) * QUEUE_ALLOC_UNIT); + q->end_count = QUEUE_ALLOC_UNIT; + } + q->queue_end = q->queue_end->next; + } + } else { + q->queue_end = (QueueItem *) qemu_mallocz (sizeof(QueueItem) * QUEUE_ALLOC_UNIT); + q->queue_start = q->queue_end; + q->start_count = QUEUE_ALLOC_UNIT; + q->end_count = QUEUE_ALLOC_UNIT; + } + q->end_count--; + + q->queue_end->x = x; + q->queue_end->y = y; + q->queue_end->w = w; + q->queue_end->h = h; + q->queue_end->enc = encoding; + q->queue_end->next = (q->end_count > 0) ? (q->queue_end + 1) : NULL; +} + +static void dequeue_framebuffer_update(VncState *vs) +{ + Queue *q = &vs->upqueue; + if (q->queue_start == NULL || + (q->queue_end == q->queue_start && q->start_count == q->end_count)) + return; + + vnc_write_u8(vs, 0); + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); + vnc_framebuffer_update(vs, q->queue_start->x, q->queue_start->y, + q->queue_start->w, q->queue_start->h, q->queue_start->enc); + + q->start_count--; + if (q->queue_end != q->queue_start) { + if (!q->start_count) { + QueueItem *i = q->queue_start; + q->queue_start = q->queue_start->next; + q->start_count = QUEUE_ALLOC_UNIT; + free (i - QUEUE_ALLOC_UNIT + 1); + } else + q->queue_start = q->queue_start->next; + } else { + q->queue_end = q->queue_end - QUEUE_ALLOC_UNIT + q->end_count + 1; + q->queue_start = q->queue_end; + q->end_count = QUEUE_ALLOC_UNIT; + q->start_count = QUEUE_ALLOC_UNIT; + } +} + +static int is_empty_queue(VncState *vs) +{ + Queue *q = &vs->upqueue; + if (q->queue_end == NULL) return 1; + if (q->queue_end == q->queue_start && q->start_count == q->end_count) return 1; + return 0; +} + +static void free_queue(VncState *vs) +{ + Queue *q = &vs->upqueue; + while (q->queue_start != NULL) { + QueueItem *i; + q->queue_start = q->queue_start + q->start_count - 1; + i = q->queue_start; + q->queue_start = q->queue_start->next; + free(i - QUEUE_ALLOC_UNIT + 1); + q->start_count = QUEUE_ALLOC_UNIT; + } + q->queue_end = NULL; + q->start_count = 0; + q->end_count = 0; +} + static int vnc_client_io_error(VncState *vs, int ret, int last_errno) { if (ret == 0 || ret == -1) { @@ -833,6 +968,8 @@ static int vnc_client_io_error(VncState vs->csock = -1; buffer_reset(&vs->input); buffer_reset(&vs->output); + free_queue(vs); + vs->update_requested = 0; #if CONFIG_VNC_TLS if (vs->tls_session) { gnutls_deinit(vs->tls_session); @@ -1044,12 +1181,18 @@ static void check_pointer_type_change(Vn static void check_pointer_type_change(VncState *vs, int absolute) { if (vs->has_pointer_type_change && vs->absolute != absolute) { - vnc_write_u8(vs, 0); - vnc_write_u8(vs, 0); - vnc_write_u16(vs, 1); - vnc_framebuffer_update(vs, absolute, 0, + if (vs->update_requested) { + vnc_write_u8(vs, 0); + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); + vnc_framebuffer_update(vs, absolute, 0, vs->ds->width, vs->ds->height, -257); - vnc_flush(vs); + vnc_flush(vs); + vs->update_requested--; + } else { + enqueue_framebuffer_update(vs, absolute, 0, + vs->ds->width, vs->ds->height, -257); + } } vs->absolute = absolute; } @@ -1316,6 +1459,7 @@ static void framebuffer_update_request(V vs->visible_w = w; vs->visible_h = h; + vs->update_requested++; qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock)); } @@ -1536,12 +1680,17 @@ static void vnc_dpy_colourdepth(DisplayS vnc_client_error(vs); } else if (vs->csock != -1 && vs->has_WMVi) { /* Sending a WMVi message to notify the client*/ - vnc_write_u8(vs, 0); /* msg id */ - vnc_write_u8(vs, 0); - vnc_write_u16(vs, 1); /* number of rects */ - vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669); - pixel_format_message(vs); - vnc_flush(vs); + if (vs->update_requested) { + vnc_write_u8(vs, 0); /* msg id */ + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); /* number of rects */ + vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669); + pixel_format_message(vs); + vnc_flush(vs); + vs->update_requested--; + } else { + enqueue_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669); + } } else { if (vs->pix_bpp == 4 && vs->depth == 4 && host_big_endian_flag == vs->pix_big_endian && @@ -2291,6 +2440,7 @@ static void vnc_listen_read(void *opaque framebuffer_set_updated(vs, 0, 0, vs->ds->width, vs->ds->height); vs->has_resize = 0; vs->has_hextile = 0; + vs->update_requested = 0; vs->ds->dpy_copy = NULL; vnc_timer_init(vs); } @@ -2413,6 +2563,8 @@ void vnc_display_close(DisplayState *ds) vs->csock = -1; buffer_reset(&vs->input); buffer_reset(&vs->output); + free_queue(vs); + vs->update_requested = 0; #if CONFIG_VNC_TLS if (vs->tls_session) { gnutls_deinit(vs->tls_session); diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/python/xen/lowlevel/xc/xc.c Tue Feb 26 10:12:04 2008 -0700 @@ -764,7 +764,8 @@ static PyObject *pyxc_physinfo(XcObject xc_physinfo_t info; char cpu_cap[128], *p=cpu_cap, *q=cpu_cap; int i, j, max_cpu_id; - PyObject *ret_obj, *node_to_cpu_obj; + uint64_t free_heap; + PyObject *ret_obj, *node_to_cpu_obj, *node_to_memory_obj; xc_cpu_to_node_t map[MAX_CPU_ID + 1]; set_xen_guest_handle(info.cpu_to_node, map); @@ -812,7 +813,17 @@ static PyObject *pyxc_physinfo(XcObject PyList_Append(node_to_cpu_obj, cpus); } + node_to_memory_obj = PyList_New(0); + + for ( i = 0; i < info.nr_nodes; i++ ) + { + xc_availheap(self->xc_handle, 0, 0, i, &free_heap); + PyList_Append(node_to_memory_obj, + PyInt_FromLong(free_heap / 1024)); + } + PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj); + PyDict_SetItemString(ret_obj, "node_to_memory", node_to_memory_obj); return ret_obj; #undef MAX_CPU_ID diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Feb 26 10:12:04 2008 -0700 @@ -906,6 +906,7 @@ class XendDomainInfo: log.debug("Setting memory maximum of domain %s (%s) to %d MiB.", self.info['name_label'], str(self.domid), limit) + maxmem_cur = self.get_memory_static_max() MiB = 1024 * 1024 self._safe_set_memory('memory_static_max', limit * MiB) @@ -914,6 +915,7 @@ class XendDomainInfo: try: return xc.domain_setmaxmem(self.domid, maxmem) except Exception, ex: + self._safe_set_memory('memory_static_max', maxmem_cur) raise XendError(str(ex)) xen.xend.XendDomain.instance().managed_config_save(self) diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/xend/XendNode.py --- a/tools/python/xen/xend/XendNode.py Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/python/xen/xend/XendNode.py Tue Feb 26 10:12:04 2008 -0700 @@ -573,6 +573,20 @@ class XendNode: except: str='none\n' return str[:-1]; + def format_node_to_memory(self, pinfo): + str='' + whitespace='' + try: + node_to_memory=pinfo['node_to_memory'] + for i in range(0, pinfo['nr_nodes']): + str+='%snode%d:%d\n' % (whitespace, + i, + node_to_memory[i] / 1024) + whitespace='%25s' % '' + except: + str='none\n' + return str[:-1]; + def physinfo(self): info = self.xc.physinfo() @@ -583,6 +597,7 @@ class XendNode: info['total_memory'] = info['total_memory'] / 1024 info['free_memory'] = info['free_memory'] / 1024 info['node_to_cpu'] = self.format_node_to_cpu(info) + info['node_to_memory'] = self.format_node_to_memory(info) ITEM_ORDER = ['nr_cpus', 'nr_nodes', @@ -592,7 +607,8 @@ class XendNode: 'hw_caps', 'total_memory', 'free_memory', - 'node_to_cpu' + 'node_to_cpu', + 'node_to_memory' ] return [[k, info[k]] for k in ITEM_ORDER] diff -r 7e8334e651c4 -r f97a0b6152c3 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/python/xen/xend/image.py Tue Feb 26 10:12:04 2008 -0700 @@ -390,7 +390,7 @@ class LinuxImageHandler(ImageHandler): ImageHandler.configure(self, vmConfig) rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset') if rtc_timeoffset is not None: - xc.domain_set_time_offset(self.vm.getDomid(), rtc_timeoffset) + xc.domain_set_time_offset(self.vm.getDomid(), int(rtc_timeoffset)) def buildDomain(self): store_evtchn = self.vm.getStorePort() diff -r 7e8334e651c4 -r f97a0b6152c3 tools/xentrace/xentrace.c --- a/tools/xentrace/xentrace.c Mon Feb 25 06:29:01 2008 -0700 +++ b/tools/xentrace/xentrace.c Tue Feb 26 10:12:04 2008 -0700 @@ -15,6 +15,7 @@ #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/vfs.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> @@ -53,7 +54,10 @@ typedef struct settings_st { uint32_t evt_mask; uint32_t cpu_mask; unsigned long tbuf_size; - uint8_t discard:1; + unsigned long disk_rsvd; + unsigned long timeout; + uint8_t discard:1, + disable_tracing:1; } settings_t; settings_t opts; @@ -83,8 +87,36 @@ void write_buffer(unsigned int cpu, unsi void write_buffer(unsigned int cpu, unsigned char *start, int size, int total_size, int outfd) { + struct statfs stat; size_t written = 0; + if ( opts.disk_rsvd != 0 ) + { + unsigned long long freespace; + + /* Check that filesystem has enough space. */ + if ( fstatfs (outfd, &stat) ) + { + fprintf(stderr, "Statfs failed!\n"); + goto fail; + } + + freespace = stat.f_bsize * (unsigned long long)stat.f_bfree; + + if ( total_size ) + freespace -= total_size; + else + freespace -= size; + + freespace >>= 20; /* Convert to MB */ + + if ( freespace <= opts.disk_rsvd ) + { + fprintf(stderr, "Disk space limit reached (free space: %lluMB, limit: %luMB).\n", freespace, opts.disk_rsvd); + exit (EXIT_FAILURE); + } + } + /* Write a CPU_BUF record on each buffer "window" written. Wrapped * windows may involve two writes, so only write the record on the * first write. */ @@ -126,6 +158,28 @@ void write_buffer(unsigned int cpu, unsi fail: PERROR("Failed to write trace data"); exit(EXIT_FAILURE); +} + +static void disable_tbufs(void) +{ + int xc_handle = xc_interface_open(); + int ret; + + if ( xc_handle < 0 ) + { + perror("Couldn't open xc handle to disable tbufs."); + goto out; + } + + ret = xc_tbuf_disable(xc_handle); + + if ( ret != 0 ) + { + perror("Couldn't disable trace buffers"); + } + +out: + xc_interface_close(xc_handle); } static void get_tbufs(unsigned long *mfn, unsigned long *size) @@ -435,6 +489,9 @@ int monitor_tbufs(int outfd) wait_for_event_or_timeout(opts.poll_sleep); } + if(opts.disable_tracing) + disable_tbufs(); + /* cleanup */ free(meta); free(data); @@ -471,6 +528,14 @@ void usage(void) " N.B. that the trace buffer cannot be resized.\n" \ " if it has already been set this boot cycle,\n" \ " this argument will be ignored.\n" \ +" -D --discard-buffers Discard all records currently in the trace\n" \ +" buffers before beginning.\n" \ +" -x --dont-disable-tracing\n" \ +" By default, xentrace will disable tracing when\n" \ +" it exits. Selecting this option will tell it to\n" \ +" keep tracing on. Traces will be collected in\n" \ +" Xen's trace buffers until they become full.\n" \ +" -T --time-interval=s Run xentrace for s seconds and quit.\n" \ " -?, --help Show this message\n" \ " -V, --version Print program version\n" \ "\n" \ @@ -539,6 +604,10 @@ void parse_args(int argc, char **argv) { "cpu-mask", required_argument, 0, 'c' }, { "evt-mask", required_argument, 0, 'e' }, { "trace-buf-size", required_argument, 0, 'S' }, + { "reserve-disk-space", required_argument, 0, 'r' }, + { "time-interval", required_argument, 0, 'T' }, + { "discard-buffers", no_argument, 0, 'D' }, + { "dont-disable-tracing", no_argument, 0, 'x' }, { "help", no_argument, 0, '?' }, { "version", no_argument, 0, 'V' }, { 0, 0, 0, 0 } @@ -569,7 +638,23 @@ void parse_args(int argc, char **argv) printf("%s\n", program_version); exit(EXIT_SUCCESS); break; - + + case 'D': /* Discard traces currently in buffer */ + opts.discard = 1; + break; + + case 'r': /* Disk-space reservation */ + opts.disk_rsvd = argtol(optarg, 0); + break; + + case 'x': /* Don't disable tracing */ + opts.disable_tracing = 0; + break; + + case 'T': + opts.timeout = argtol(optarg, 0); + break; + default: usage(); } @@ -581,7 +666,6 @@ void parse_args(int argc, char **argv) opts.outfile = argv[optind]; } - /* *BSD has no O_LARGEFILE */ #ifndef O_LARGEFILE @@ -597,6 +681,9 @@ int main(int argc, char **argv) opts.poll_sleep = POLL_SLEEP_MILLIS; opts.evt_mask = 0; opts.cpu_mask = 0; + opts.disk_rsvd = 0; + opts.disable_tracing = 1; + opts.timeout = 0; parse_args(argc, argv); @@ -612,6 +699,9 @@ int main(int argc, char **argv) if ( opts.cpu_mask != 0 ) set_mask(opts.cpu_mask, 1); + + if ( opts.timeout != 0 ) + alarm(opts.timeout); if ( opts.outfile ) outfd = open(opts.outfile, @@ -637,6 +727,7 @@ int main(int argc, char **argv) sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); + sigaction(SIGALRM, &act, NULL); ret = monitor_tbufs(outfd); diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/emulate.c --- a/xen/arch/x86/hvm/emulate.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/emulate.c Tue Feb 26 10:12:04 2008 -0700 @@ -124,8 +124,9 @@ static int hvmemul_virtual_to_linear( if ( !okay ) { - hvmemul_ctxt->flags.exn_pending = 1; + hvmemul_ctxt->exn_pending = 1; hvmemul_ctxt->exn_vector = TRAP_gp_fault; + hvmemul_ctxt->exn_error_code = 0; hvmemul_ctxt->exn_insn_len = 0; return X86EMUL_EXCEPTION; } @@ -438,9 +439,6 @@ static int hvmemul_write_segment( struct hvm_emulate_ctxt *hvmemul_ctxt = container_of(ctxt, struct hvm_emulate_ctxt, ctxt); struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt); - - if ( seg == x86_seg_ss ) - hvmemul_ctxt->flags.mov_ss = 1; memcpy(sreg, reg, sizeof(struct segment_register)); __set_bit(seg, &hvmemul_ctxt->seg_reg_dirty); @@ -571,17 +569,6 @@ static int hvmemul_write_msr( return hvm_funcs.msr_write_intercept(&_regs); } -static int hvmemul_write_rflags( - unsigned long val, - struct x86_emulate_ctxt *ctxt) -{ - struct hvm_emulate_ctxt *hvmemul_ctxt = - container_of(ctxt, struct hvm_emulate_ctxt, ctxt); - if ( (val & X86_EFLAGS_IF) && !(ctxt->regs->eflags & X86_EFLAGS_IF) ) - hvmemul_ctxt->flags.sti = 1; - return X86EMUL_OKAY; -} - static int hvmemul_wbinvd( struct x86_emulate_ctxt *ctxt) { @@ -600,28 +587,17 @@ static int hvmemul_cpuid( return X86EMUL_OKAY; } -static int hvmemul_hlt( - struct x86_emulate_ctxt *ctxt) -{ - struct hvm_emulate_ctxt *hvmemul_ctxt = - container_of(ctxt, struct hvm_emulate_ctxt, ctxt); - hvmemul_ctxt->flags.hlt = 1; - return X86EMUL_OKAY; -} - static int hvmemul_inject_hw_exception( uint8_t vector, - uint16_t error_code, - struct x86_emulate_ctxt *ctxt) -{ - struct hvm_emulate_ctxt *hvmemul_ctxt = - container_of(ctxt, struct hvm_emulate_ctxt, ctxt); - - if ( error_code != 0 ) - return X86EMUL_UNHANDLEABLE; - - hvmemul_ctxt->flags.exn_pending = 1; + int32_t error_code, + struct x86_emulate_ctxt *ctxt) +{ + struct hvm_emulate_ctxt *hvmemul_ctxt = + container_of(ctxt, struct hvm_emulate_ctxt, ctxt); + + hvmemul_ctxt->exn_pending = 1; hvmemul_ctxt->exn_vector = vector; + hvmemul_ctxt->exn_error_code = error_code; hvmemul_ctxt->exn_insn_len = 0; return X86EMUL_OKAY; @@ -635,8 +611,9 @@ static int hvmemul_inject_sw_interrupt( struct hvm_emulate_ctxt *hvmemul_ctxt = container_of(ctxt, struct hvm_emulate_ctxt, ctxt); - hvmemul_ctxt->flags.exn_pending = 1; + hvmemul_ctxt->exn_pending = 1; hvmemul_ctxt->exn_vector = vector; + hvmemul_ctxt->exn_error_code = -1; hvmemul_ctxt->exn_insn_len = insn_len; return X86EMUL_OKAY; @@ -684,10 +661,8 @@ static struct x86_emulate_ops hvm_emulat .write_cr = hvmemul_write_cr, .read_msr = hvmemul_read_msr, .write_msr = hvmemul_write_msr, - .write_rflags = hvmemul_write_rflags, .wbinvd = hvmemul_wbinvd, .cpuid = hvmemul_cpuid, - .hlt = hvmemul_hlt, .inject_hw_exception = hvmemul_inject_hw_exception, .inject_sw_interrupt = hvmemul_inject_sw_interrupt, .load_fpu_ctxt = hvmemul_load_fpu_ctxt, @@ -698,7 +673,9 @@ int hvm_emulate_one( struct hvm_emulate_ctxt *hvmemul_ctxt) { struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs; + uint32_t new_intr_shadow; unsigned long addr; + int rc; hvmemul_ctxt->ctxt.addr_size = hvmemul_ctxt->seg_reg[x86_seg_cs].attr.fields.db ? 32 : 16; @@ -715,15 +692,46 @@ int hvm_emulate_one( hvmemul_ctxt->insn_buf, addr, sizeof(hvmemul_ctxt->insn_buf))) ? sizeof(hvmemul_ctxt->insn_buf) : 0; - hvmemul_ctxt->flag_word = 0; - - return x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops); + hvmemul_ctxt->exn_pending = 0; + + rc = x86_emulate(&hvmemul_ctxt->ctxt, &hvm_emulate_ops); + if ( rc != X86EMUL_OKAY ) + return rc; + + new_intr_shadow = hvmemul_ctxt->intr_shadow; + + /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */ + if ( hvmemul_ctxt->ctxt.retire.flags.mov_ss ) + new_intr_shadow ^= HVM_INTR_SHADOW_MOV_SS; + else + new_intr_shadow &= ~HVM_INTR_SHADOW_MOV_SS; + + /* STI instruction toggles STI shadow, else we just clear it. */ + if ( hvmemul_ctxt->ctxt.retire.flags.sti ) + new_intr_shadow ^= HVM_INTR_SHADOW_STI; + else + new_intr_shadow &= ~HVM_INTR_SHADOW_STI; + + if ( hvmemul_ctxt->intr_shadow != new_intr_shadow ) + { + hvmemul_ctxt->intr_shadow = new_intr_shadow; + hvm_funcs.set_interrupt_shadow(current, new_intr_shadow); + } + + if ( hvmemul_ctxt->ctxt.retire.flags.hlt && + !hvm_local_events_need_delivery(current) ) + { + hvm_hlt(regs->eflags); + } + + return X86EMUL_OKAY; } void hvm_emulate_prepare( struct hvm_emulate_ctxt *hvmemul_ctxt, struct cpu_user_regs *regs) { + hvmemul_ctxt->intr_shadow = hvm_funcs.get_interrupt_shadow(current); hvmemul_ctxt->ctxt.regs = regs; hvmemul_ctxt->ctxt.force_writeback = 1; hvmemul_ctxt->seg_reg_accessed = 0; diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/hvm.c Tue Feb 26 10:12:04 2008 -0700 @@ -1640,12 +1640,22 @@ void hvm_cpuid(unsigned int input, unsig enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack) { - enum hvm_intblk r; + unsigned long intr_shadow; + ASSERT(v == current); - r = hvm_funcs.interrupt_blocked(v, intack); - if ( r != hvm_intblk_none ) - return r; + if ( (intack.source != hvm_intsrc_nmi) && + !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) ) + return hvm_intblk_rflags_ie; + + intr_shadow = hvm_funcs.get_interrupt_shadow(v); + + if ( intr_shadow & (HVM_INTR_SHADOW_STI|HVM_INTR_SHADOW_MOV_SS) ) + return hvm_intblk_shadow; + + if ( intack.source == hvm_intsrc_nmi ) + return ((intr_shadow & HVM_INTR_SHADOW_NMI) ? + hvm_intblk_nmi_iret : hvm_intblk_none); if ( intack.source == hvm_intsrc_lapic ) { @@ -1654,7 +1664,7 @@ enum hvm_intblk hvm_interrupt_blocked(st return hvm_intblk_tpr; } - return r; + return hvm_intblk_none; } static long hvm_grant_table_op( diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/io.c Tue Feb 26 10:12:04 2008 -0700 @@ -262,8 +262,8 @@ int handle_mmio(void) ctxt.insn_buf[4], ctxt.insn_buf[5]); return 0; case X86EMUL_EXCEPTION: - if ( ctxt.flags.exn_pending ) - hvm_inject_exception(ctxt.exn_vector, 0, 0); + if ( ctxt.exn_pending ) + hvm_inject_exception(ctxt.exn_vector, ctxt.exn_error_code, 0); break; default: break; diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/svm/svm.c Tue Feb 26 10:12:04 2008 -0700 @@ -366,24 +366,18 @@ static void svm_fpu_leave(struct vcpu *v } } -static enum hvm_intblk svm_interrupt_blocked( - struct vcpu *v, struct hvm_intack intack) -{ - struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - - if ( vmcb->interrupt_shadow ) - return hvm_intblk_shadow; - - if ( intack.source == hvm_intsrc_nmi ) - return hvm_intblk_none; - - ASSERT((intack.source == hvm_intsrc_pic) || - (intack.source == hvm_intsrc_lapic)); - - if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) ) - return hvm_intblk_rflags_ie; - - return hvm_intblk_none; +static unsigned int svm_get_interrupt_shadow(struct vcpu *v) +{ + struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + return (vmcb->interrupt_shadow ? + (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI) : 0); +} + +static void svm_set_interrupt_shadow(struct vcpu *v, unsigned int intr_shadow) +{ + struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + vmcb->interrupt_shadow = + !!(intr_shadow & (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI)); } static int svm_guest_x86_mode(struct vcpu *v) @@ -779,7 +773,8 @@ static struct hvm_function_table svm_fun .vcpu_destroy = svm_vcpu_destroy, .save_cpu_ctxt = svm_save_vmcb_ctxt, .load_cpu_ctxt = svm_load_vmcb_ctxt, - .interrupt_blocked = svm_interrupt_blocked, + .get_interrupt_shadow = svm_get_interrupt_shadow, + .set_interrupt_shadow = svm_set_interrupt_shadow, .guest_x86_mode = svm_guest_x86_mode, .get_segment_register = svm_get_segment_register, .set_segment_register = svm_set_segment_register, @@ -1176,7 +1171,7 @@ static void svm_vmexit_do_hlt(struct vmc /* Check for pending exception or new interrupt. */ if ( vmcb->eventinj.fields.v || ((intack.source != hvm_intsrc_none) && - !svm_interrupt_blocked(current, intack)) ) + !hvm_interrupt_blocked(current, intack)) ) { HVMTRACE_1D(HLT, curr, /*int pending=*/ 1); return; diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/intr.c --- a/xen/arch/x86/hvm/vmx/intr.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/vmx/intr.c Tue Feb 26 10:12:04 2008 -0700 @@ -65,10 +65,6 @@ * Injecting a virtual NMI sets the NMI-blocking interruptibility flag only * if the 'virtual NMIs' control is set. Injecting *any* kind of event clears * the STI- and MOV-SS-blocking interruptibility-state flags. - * - * If MOV/POP SS is executed while MOV-SS-blocking is in effect, the effect - * is cleared. If STI is executed while MOV-SS- or STI-blocking is in effect, - * the effect is cleared. (i.e., MOV-SS-blocking 'dominates' STI-blocking). */ static void enable_intr_window(struct vcpu *v, struct hvm_intack intack) diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/realmode.c --- a/xen/arch/x86/hvm/vmx/realmode.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/vmx/realmode.c Tue Feb 26 10:12:04 2008 -0700 @@ -21,25 +21,20 @@ #include <asm/hvm/vmx/vmx.h> #include <asm/hvm/vmx/vmcs.h> -struct realmode_emulate_ctxt { - struct hvm_emulate_ctxt hvm; - uint32_t intr_shadow; -}; - static void realmode_deliver_exception( unsigned int vector, unsigned int insn_len, - struct realmode_emulate_ctxt *rm_ctxt) + struct hvm_emulate_ctxt *hvmemul_ctxt) { struct segment_register *idtr, *csr; - struct cpu_user_regs *regs = rm_ctxt->hvm.ctxt.regs; + struct cpu_user_regs *regs = hvmemul_ctxt->ctxt.regs; uint32_t cs_eip, pstk; uint16_t frame[3]; unsigned int last_byte; - idtr = hvmemul_get_seg_reg(x86_seg_idtr, &rm_ctxt->hvm); - csr = hvmemul_get_seg_reg(x86_seg_cs, &rm_ctxt->hvm); - __set_bit(x86_seg_cs, &rm_ctxt->hvm.seg_reg_dirty); + idtr = hvmemul_get_seg_reg(x86_seg_idtr, hvmemul_ctxt); + csr = hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt); + __set_bit(x86_seg_cs, &hvmemul_ctxt->seg_reg_dirty); again: last_byte = (vector * 4) + 3; @@ -74,7 +69,7 @@ static void realmode_deliver_exception( frame[1] = csr->sel; frame[2] = regs->eflags & ~X86_EFLAGS_RF; - if ( rm_ctxt->hvm.ctxt.addr_size == 32 ) + if ( hvmemul_ctxt->ctxt.addr_size == 32 ) { regs->esp -= 6; pstk = regs->esp; @@ -86,7 +81,7 @@ static void realmode_deliver_exception( regs->esp |= pstk; } - pstk += hvmemul_get_seg_reg(x86_seg_ss, &rm_ctxt->hvm)->base; + pstk += hvmemul_get_seg_reg(x86_seg_ss, hvmemul_ctxt)->base; (void)hvm_copy_to_guest_phys(pstk, frame, sizeof(frame)); csr->sel = cs_eip >> 16; @@ -95,41 +90,42 @@ static void realmode_deliver_exception( regs->eflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF | X86_EFLAGS_RF); /* Exception delivery clears STI and MOV-SS blocking. */ - if ( rm_ctxt->intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) ) - { - rm_ctxt->intr_shadow &= ~(VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS); - __vmwrite(GUEST_INTERRUPTIBILITY_INFO, rm_ctxt->intr_shadow); - } -} - -static void realmode_emulate_one(struct realmode_emulate_ctxt *rm_ctxt) -{ - struct cpu_user_regs *regs = rm_ctxt->hvm.ctxt.regs; + if ( hvmemul_ctxt->intr_shadow & + (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) ) + { + hvmemul_ctxt->intr_shadow &= + ~(VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS); + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, hvmemul_ctxt->intr_shadow); + } +} + +static void realmode_emulate_one(struct hvm_emulate_ctxt *hvmemul_ctxt) +{ struct vcpu *curr = current; unsigned long seg_reg_dirty; - uint32_t new_intr_shadow, intr_info; + uint32_t intr_info; int rc; - seg_reg_dirty = rm_ctxt->hvm.seg_reg_dirty; - rm_ctxt->hvm.seg_reg_dirty = 0; - - rc = hvm_emulate_one(&rm_ctxt->hvm); - - if ( test_bit(x86_seg_cs, &rm_ctxt->hvm.seg_reg_dirty) ) + seg_reg_dirty = hvmemul_ctxt->seg_reg_dirty; + hvmemul_ctxt->seg_reg_dirty = 0; + + rc = hvm_emulate_one(hvmemul_ctxt); + + if ( test_bit(x86_seg_cs, &hvmemul_ctxt->seg_reg_dirty) ) { curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_CS; - if ( hvmemul_get_seg_reg(x86_seg_cs, &rm_ctxt->hvm)->sel & 3 ) + if ( hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt)->sel & 3 ) curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_CS; } - if ( test_bit(x86_seg_ss, &rm_ctxt->hvm.seg_reg_dirty) ) + if ( test_bit(x86_seg_ss, &hvmemul_ctxt->seg_reg_dirty) ) { curr->arch.hvm_vmx.vmxemul &= ~VMXEMUL_BAD_SS; - if ( hvmemul_get_seg_reg(x86_seg_ss, &rm_ctxt->hvm)->sel & 3 ) + if ( hvmemul_get_seg_reg(x86_seg_ss, hvmemul_ctxt)->sel & 3 ) curr->arch.hvm_vmx.vmxemul |= VMXEMUL_BAD_SS; } - rm_ctxt->hvm.seg_reg_dirty |= seg_reg_dirty; + hvmemul_ctxt->seg_reg_dirty |= seg_reg_dirty; if ( rc == X86EMUL_UNHANDLEABLE ) { @@ -137,33 +133,9 @@ static void realmode_emulate_one(struct goto fail; } - if ( rc == X86EMUL_RETRY ) - return; - - new_intr_shadow = rm_ctxt->intr_shadow; - - /* MOV-SS instruction toggles MOV-SS shadow, else we just clear it. */ - if ( rm_ctxt->hvm.flags.mov_ss ) - new_intr_shadow ^= VMX_INTR_SHADOW_MOV_SS; - else - new_intr_shadow &= ~VMX_INTR_SHADOW_MOV_SS; - - /* STI instruction toggles STI shadow, else we just clear it. */ - if ( rm_ctxt->hvm.flags.sti ) - new_intr_shadow ^= VMX_INTR_SHADOW_STI; - else - new_intr_shadow &= ~VMX_INTR_SHADOW_STI; - - /* Update interrupt shadow information in VMCS only if it changes. */ - if ( rm_ctxt->intr_shadow != new_intr_shadow ) - { - rm_ctxt->intr_shadow = new_intr_shadow; - __vmwrite(GUEST_INTERRUPTIBILITY_INFO, rm_ctxt->intr_shadow); - } - if ( rc == X86EMUL_EXCEPTION ) { - if ( !rm_ctxt->hvm.flags.exn_pending ) + if ( !hvmemul_ctxt->exn_pending ) { intr_info = __vmread(VM_ENTRY_INTR_INFO); __vmwrite(VM_ENTRY_INTR_INFO, 0); @@ -172,23 +144,21 @@ static void realmode_emulate_one(struct gdprintk(XENLOG_ERR, "Exception pending but no info.\n"); goto fail; } - rm_ctxt->hvm.exn_vector = (uint8_t)intr_info; - rm_ctxt->hvm.exn_insn_len = 0; + hvmemul_ctxt->exn_vector = (uint8_t)intr_info; + hvmemul_ctxt->exn_insn_len = 0; } if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE ) { gdprintk(XENLOG_ERR, "Exception %02x in protected mode.\n", - rm_ctxt->hvm.exn_vector); + hvmemul_ctxt->exn_vector); goto fail; } realmode_deliver_exception( - rm_ctxt->hvm.exn_vector, rm_ctxt->hvm.exn_insn_len, rm_ctxt); - } - else if ( rm_ctxt->hvm.flags.hlt && !hvm_local_events_need_delivery(curr) ) - { - hvm_hlt(regs->eflags); + hvmemul_ctxt->exn_vector, + hvmemul_ctxt->exn_insn_len, + hvmemul_ctxt); } return; @@ -197,18 +167,18 @@ static void realmode_emulate_one(struct gdprintk(XENLOG_ERR, "Real-mode emulation failed @ %04x:%08lx: " "%02x %02x %02x %02x %02x %02x\n", - hvmemul_get_seg_reg(x86_seg_cs, &rm_ctxt->hvm)->sel, - rm_ctxt->hvm.insn_buf_eip, - rm_ctxt->hvm.insn_buf[0], rm_ctxt->hvm.insn_buf[1], - rm_ctxt->hvm.insn_buf[2], rm_ctxt->hvm.insn_buf[3], - rm_ctxt->hvm.insn_buf[4], rm_ctxt->hvm.insn_buf[5]); + hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt)->sel, + hvmemul_ctxt->insn_buf_eip, + hvmemul_ctxt->insn_buf[0], hvmemul_ctxt->insn_buf[1], + hvmemul_ctxt->insn_buf[2], hvmemul_ctxt->insn_buf[3], + hvmemul_ctxt->insn_buf[4], hvmemul_ctxt->insn_buf[5]); domain_crash_synchronous(); } void vmx_realmode(struct cpu_user_regs *regs) { struct vcpu *curr = current; - struct realmode_emulate_ctxt rm_ctxt; + struct hvm_emulate_ctxt hvmemul_ctxt; struct segment_register *sreg; unsigned long intr_info; unsigned int emulations = 0; @@ -218,17 +188,16 @@ void vmx_realmode(struct cpu_user_regs * if ( intr_info & INTR_INFO_VALID_MASK ) __vmwrite(VM_ENTRY_INTR_INFO, 0); - hvm_emulate_prepare(&rm_ctxt.hvm, regs); - rm_ctxt.intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); + hvm_emulate_prepare(&hvmemul_ctxt, regs); if ( curr->arch.hvm_vcpu.io_completed ) - realmode_emulate_one(&rm_ctxt); + realmode_emulate_one(&hvmemul_ctxt); /* Only deliver interrupts into emulated real mode. */ if ( !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) && (intr_info & INTR_INFO_VALID_MASK) ) { - realmode_deliver_exception((uint8_t)intr_info, 0, &rm_ctxt); + realmode_deliver_exception((uint8_t)intr_info, 0, &hvmemul_ctxt); intr_info = 0; } @@ -245,7 +214,7 @@ void vmx_realmode(struct cpu_user_regs * !(curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE) && hvm_local_events_need_delivery(curr) ) break; - realmode_emulate_one(&rm_ctxt); + realmode_emulate_one(&hvmemul_ctxt); } if ( !curr->arch.hvm_vmx.vmxemul ) @@ -255,20 +224,20 @@ void vmx_realmode(struct cpu_user_regs * * At this point CS.RPL == SS.RPL == CS.DPL == SS.DPL == 0. For * DS, ES, FS and GS the most uninvasive trick is to set DPL == RPL. */ - sreg = hvmemul_get_seg_reg(x86_seg_ds, &rm_ctxt.hvm); - sreg->attr.fields.dpl = sreg->sel & 3; - sreg = hvmemul_get_seg_reg(x86_seg_es, &rm_ctxt.hvm); - sreg->attr.fields.dpl = sreg->sel & 3; - sreg = hvmemul_get_seg_reg(x86_seg_fs, &rm_ctxt.hvm); - sreg->attr.fields.dpl = sreg->sel & 3; - sreg = hvmemul_get_seg_reg(x86_seg_gs, &rm_ctxt.hvm); - sreg->attr.fields.dpl = sreg->sel & 3; - rm_ctxt.hvm.seg_reg_dirty |= + sreg = hvmemul_get_seg_reg(x86_seg_ds, &hvmemul_ctxt); + sreg->attr.fields.dpl = sreg->sel & 3; + sreg = hvmemul_get_seg_reg(x86_seg_es, &hvmemul_ctxt); + sreg->attr.fields.dpl = sreg->sel & 3; + sreg = hvmemul_get_seg_reg(x86_seg_fs, &hvmemul_ctxt); + sreg->attr.fields.dpl = sreg->sel & 3; + sreg = hvmemul_get_seg_reg(x86_seg_gs, &hvmemul_ctxt); + sreg->attr.fields.dpl = sreg->sel & 3; + hvmemul_ctxt.seg_reg_dirty |= (1ul << x86_seg_ds) | (1ul << x86_seg_es) | (1ul << x86_seg_fs) | (1ul << x86_seg_gs); } - hvm_emulate_writeback(&rm_ctxt.hvm); + hvm_emulate_writeback(&hvmemul_ctxt); /* Re-instate VM_ENTRY_INTR_INFO if we did not discharge it. */ if ( intr_info & INTR_INFO_VALID_MASK ) diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Feb 26 10:12:04 2008 -0700 @@ -890,32 +890,14 @@ static void vmx_init_hypercall_page(stru *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */ } -static enum hvm_intblk vmx_interrupt_blocked( - struct vcpu *v, struct hvm_intack intack) -{ - unsigned long intr_shadow; - - /* - * Test EFLAGS.IF first. It is often the most likely reason for interrupt - * blockage, and is the cheapest to test (because no VMREAD is required). - */ - if ( (intack.source != hvm_intsrc_nmi) && - !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) ) - return hvm_intblk_rflags_ie; - - intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); - - if ( intr_shadow & (VMX_INTR_SHADOW_STI|VMX_INTR_SHADOW_MOV_SS) ) - return hvm_intblk_shadow; - - if ( intack.source == hvm_intsrc_nmi ) - return ((intr_shadow & VMX_INTR_SHADOW_NMI) ? - hvm_intblk_nmi_iret : hvm_intblk_none); - - ASSERT((intack.source == hvm_intsrc_pic) || - (intack.source == hvm_intsrc_lapic)); - - return hvm_intblk_none; +static unsigned int vmx_get_interrupt_shadow(struct vcpu *v) +{ + return __vmread(GUEST_INTERRUPTIBILITY_INFO); +} + +static void vmx_set_interrupt_shadow(struct vcpu *v, unsigned int intr_shadow) +{ + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); } static void vmx_update_host_cr3(struct vcpu *v) @@ -1038,7 +1020,8 @@ static struct hvm_function_table vmx_fun .vcpu_destroy = vmx_vcpu_destroy, .save_cpu_ctxt = vmx_save_vmcs_ctxt, .load_cpu_ctxt = vmx_load_vmcs_ctxt, - .interrupt_blocked = vmx_interrupt_blocked, + .get_interrupt_shadow = vmx_get_interrupt_shadow, + .set_interrupt_shadow = vmx_set_interrupt_shadow, .guest_x86_mode = vmx_guest_x86_mode, .get_segment_register = vmx_get_segment_register, .set_segment_register = vmx_set_segment_register, diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/x86_32/exits.S --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S Tue Feb 26 10:12:04 2008 -0700 @@ -89,7 +89,7 @@ ENTRY(vmx_asm_vmexit_handler) ALIGN vmx_process_softirqs: - sti + sti call do_softirq jmp vmx_asm_do_vmentry @@ -104,6 +104,10 @@ ENTRY(vmx_asm_do_vmentry) jnz vmx_process_softirqs call vmx_intr_assist + + testb $0xff,VCPU_vmx_emul(%ebx) + jnz vmx_goto_realmode + movl VCPU_hvm_guest_cr2(%ebx),%eax movl %eax,%cr2 call vmx_trace_vmentry @@ -114,9 +118,6 @@ ENTRY(vmx_asm_do_vmentry) VMWRITE(UREGS_esp) movl $GUEST_RFLAGS,%eax VMWRITE(UREGS_eflags) - - testb $0xff,VCPU_vmx_emul(%ebx) - jnz vmx_goto_realmode cmpb $0,VCPU_vmx_launched(%ebx) je vmx_launch diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/hvm/vmx/x86_64/exits.S --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S Tue Feb 26 10:12:04 2008 -0700 @@ -105,7 +105,7 @@ ENTRY(vmx_asm_vmexit_handler) ALIGN vmx_process_softirqs: - sti + sti call do_softirq jmp vmx_asm_do_vmentry @@ -121,6 +121,10 @@ ENTRY(vmx_asm_do_vmentry) jnz vmx_process_softirqs call vmx_intr_assist + + testb $0xff,VCPU_vmx_emul(%rbx) + jnz vmx_goto_realmode + movq VCPU_hvm_guest_cr2(%rbx),%rax movq %rax,%cr2 call vmx_trace_vmentry @@ -133,9 +137,6 @@ ENTRY(vmx_asm_do_vmentry) VMWRITE(UREGS_rsp) movl $GUEST_RFLAGS,%eax VMWRITE(UREGS_eflags) - - testb $0xff,VCPU_vmx_emul(%rbx) - jnz vmx_goto_realmode cmpb $0,VCPU_vmx_launched(%rbx) je vmx_launch diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/mm/shadow/multi.c Tue Feb 26 10:12:04 2008 -0700 @@ -761,7 +761,7 @@ _sh_propagate(struct vcpu *v, sflags |= get_pat_flags(v, gflags, gfn_to_paddr(target_gfn), - mfn_x(target_mfn) << PAGE_SHIFT); + ((paddr_t)mfn_x(target_mfn)) << PAGE_SHIFT); } // Set the A&D bits for higher level shadows. diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/oprofile/xenoprof.c --- a/xen/arch/x86/oprofile/xenoprof.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/oprofile/xenoprof.c Tue Feb 26 10:12:04 2008 -0700 @@ -11,6 +11,9 @@ #include <xen/guest_access.h> #include <xen/sched.h> #include <public/xenoprof.h> +#ifdef CONFIG_COMPAT +#include <compat/xenoprof.h> +#endif #include <asm/hvm/support.h> #include "op_counter.h" @@ -35,6 +38,28 @@ int xenoprof_arch_counter(XEN_GUEST_HAND return 0; } +#ifdef CONFIG_COMPAT +int compat_oprof_arch_counter(XEN_GUEST_HANDLE(void) arg) +{ + struct compat_oprof_counter counter; + + if ( copy_from_guest(&counter, arg, 1) ) + return -EFAULT; + + if ( counter.ind > OP_MAX_COUNTER ) + return -E2BIG; + + counter_config[counter.ind].count = counter.count; + counter_config[counter.ind].enabled = counter.enabled; + counter_config[counter.ind].event = counter.event; + counter_config[counter.ind].kernel = counter.kernel; + counter_config[counter.ind].user = counter.user; + counter_config[counter.ind].unit_mask = counter.unit_mask; + + return 0; +} +#endif + int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs) { if ( !guest_mode(regs) ) diff -r 7e8334e651c4 -r f97a0b6152c3 xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/arch/x86/x86_emulate.c Tue Feb 26 10:12:04 2008 -0700 @@ -482,7 +482,7 @@ do{ asm volatile ( if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \ _regs.eip += (_size); /* real hardware doesn't truncate */ \ generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15, \ - EXC_GP); \ + EXC_GP, 0); \ rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt); \ if ( rc ) goto done; \ _x; \ @@ -505,12 +505,12 @@ do { if ( rc ) goto done; \ } while (0) -#define generate_exception_if(p, e) \ -({ if ( (p) ) { \ - fail_if(ops->inject_hw_exception == NULL); \ - rc = ops->inject_hw_exception(e, 0, ctxt) ? : X86EMUL_EXCEPTION; \ - goto done; \ - } \ +#define generate_exception_if(p, e, ec) \ +({ if ( (p) ) { \ + fail_if(ops->inject_hw_exception == NULL); \ + rc = ops->inject_hw_exception(e, ec, ctxt) ? : X86EMUL_EXCEPTION; \ + goto done; \ + } \ }) /* @@ -1023,6 +1023,8 @@ x86_emulate( ea.mem.seg = x86_seg_ds; ea.mem.off = 0; + ctxt->retire.byte = 0; + op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8; if ( op_bytes == 8 ) { @@ -1105,7 +1107,7 @@ x86_emulate( } /* Lock prefix is allowed only on RMW instructions. */ - generate_exception_if((d & Mov) && lock_prefix, EXC_GP); + generate_exception_if((d & Mov) && lock_prefix, EXC_GP, 0); /* ModRM and SIB bytes. */ if ( d & ModRM ) @@ -1393,7 +1395,7 @@ x86_emulate( } /* LOCK prefix allowed only on instructions with memory destination. */ - generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP); + generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP, 0); if ( twobyte ) goto twobyte_insn; @@ -1459,14 +1461,15 @@ x86_emulate( case 0x62: /* bound */ { unsigned long src_val2; int lb, ub, idx; - generate_exception_if(mode_64bit() || (src.type != OP_MEM), EXC_UD); + generate_exception_if(mode_64bit() || (src.type != OP_MEM), + EXC_UD, -1); if ( (rc = ops->read(src.mem.seg, src.mem.off + op_bytes, &src_val2, op_bytes, ctxt)) ) goto done; ub = (op_bytes == 2) ? (int16_t)src_val2 : (int32_t)src_val2; lb = (op_bytes == 2) ? (int16_t)src.val : (int32_t)src.val; idx = (op_bytes == 2) ? (int16_t)dst.val : (int32_t)dst.val; - generate_exception_if((idx < lb) || (idx > ub), EXC_BR); + generate_exception_if((idx < lb) || (idx > ub), EXC_BR, -1); dst.type = OP_NONE; break; } @@ -1493,7 +1496,7 @@ x86_emulate( dst.val = (dst.val & ~3) | (src_val & 3); else dst.type = OP_NONE; - generate_exception_if(in_realmode(ctxt, ops), EXC_UD); + generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1); } break; @@ -1534,7 +1537,7 @@ x86_emulate( } case 0x82: /* Grp1 (x86/32 only) */ - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); case 0x80: case 0x81: case 0x83: /* Grp1 */ switch ( modrm_reg & 7 ) { @@ -1571,7 +1574,7 @@ x86_emulate( break; case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ - generate_exception_if((modrm_reg & 7) != 0, EXC_UD); + generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1); case 0x88 ... 0x8b: /* mov */ dst.val = src.val; break; @@ -1579,7 +1582,7 @@ x86_emulate( case 0x8c: /* mov Sreg,r/m */ { struct segment_register reg; enum x86_segment seg = decode_segment(modrm_reg); - generate_exception_if(seg == decode_segment_failed, EXC_UD); + generate_exception_if(seg == decode_segment_failed, EXC_UD, -1); fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(seg, ®, ctxt)) != 0 ) goto done; @@ -1591,9 +1594,11 @@ x86_emulate( case 0x8e: /* mov r/m,Sreg */ { enum x86_segment seg = decode_segment(modrm_reg); - generate_exception_if(seg == decode_segment_failed, EXC_UD); + generate_exception_if(seg == decode_segment_failed, EXC_UD, -1); if ( (rc = load_seg(seg, (uint16_t)src.val, ctxt, ops)) != 0 ) goto done; + if ( seg == x86_seg_ss ) + ctxt->retire.flags.mov_ss = 1; dst.type = OP_NONE; break; } @@ -1603,7 +1608,7 @@ x86_emulate( break; case 0x8f: /* pop (sole member of Grp1a) */ - generate_exception_if((modrm_reg & 7) != 0, EXC_UD); + generate_exception_if((modrm_reg & 7) != 0, EXC_UD, -1); /* 64-bit mode: POP defaults to a 64-bit operand. */ if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; @@ -1659,7 +1664,7 @@ x86_emulate( unsigned long sel; dst.val = x86_seg_es; les: /* dst.val identifies the segment */ - generate_exception_if(src.type != OP_MEM, EXC_UD); + generate_exception_if(src.type != OP_MEM, EXC_UD, -1); if ( (rc = ops->read(src.mem.seg, src.mem.off + src.bytes, &sel, 2, ctxt)) != 0 ) goto done; @@ -1797,7 +1802,7 @@ x86_emulate( v = (uint8_t)src.val; generate_exception_if( div_dbl(u, v) || ((uint8_t)u[0] != (uint16_t)u[0]), - EXC_DE); + EXC_DE, -1); dst.val = (uint8_t)u[0]; ((uint8_t *)&_regs.eax)[1] = u[1]; break; @@ -1807,7 +1812,7 @@ x86_emulate( v = (uint16_t)src.val; generate_exception_if( div_dbl(u, v) || ((uint16_t)u[0] != (uint32_t)u[0]), - EXC_DE); + EXC_DE, -1); dst.val = (uint16_t)u[0]; *(uint16_t *)&_regs.edx = u[1]; break; @@ -1818,7 +1823,7 @@ x86_emulate( v = (uint32_t)src.val; generate_exception_if( div_dbl(u, v) || ((uint32_t)u[0] != u[0]), - EXC_DE); + EXC_DE, -1); dst.val = (uint32_t)u[0]; _regs.edx = (uint32_t)u[1]; break; @@ -1827,7 +1832,7 @@ x86_emulate( u[0] = _regs.eax; u[1] = _regs.edx; v = src.val; - generate_exception_if(div_dbl(u, v), EXC_DE); + generate_exception_if(div_dbl(u, v), EXC_DE, -1); dst.val = u[0]; _regs.edx = u[1]; break; @@ -1847,7 +1852,7 @@ x86_emulate( v = (int8_t)src.val; generate_exception_if( idiv_dbl(u, v) || ((int8_t)u[0] != (int16_t)u[0]), - EXC_DE); + EXC_DE, -1); dst.val = (int8_t)u[0]; ((int8_t *)&_regs.eax)[1] = u[1]; break; @@ -1857,7 +1862,7 @@ x86_emulate( v = (int16_t)src.val; generate_exception_if( idiv_dbl(u, v) || ((int16_t)u[0] != (int32_t)u[0]), - EXC_DE); + EXC_DE, -1); dst.val = (int16_t)u[0]; *(int16_t *)&_regs.edx = u[1]; break; @@ -1868,7 +1873,7 @@ x86_emulate( v = (int32_t)src.val; generate_exception_if( idiv_dbl(u, v) || ((int32_t)u[0] != u[0]), - EXC_DE); + EXC_DE, -1); dst.val = (int32_t)u[0]; _regs.edx = (uint32_t)u[1]; break; @@ -1877,7 +1882,7 @@ x86_emulate( u[0] = _regs.eax; u[1] = _regs.edx; v = src.val; - generate_exception_if(idiv_dbl(u, v), EXC_DE); + generate_exception_if(idiv_dbl(u, v), EXC_DE, -1); dst.val = u[0]; _regs.edx = u[1]; break; @@ -1890,7 +1895,7 @@ x86_emulate( break; case 0xfe: /* Grp4 */ - generate_exception_if((modrm_reg & 7) >= 2, EXC_UD); + generate_exception_if((modrm_reg & 7) >= 2, EXC_UD, -1); case 0xff: /* Grp5 */ switch ( modrm_reg & 7 ) { @@ -1921,7 +1926,7 @@ x86_emulate( case 5: /* jmp (far, absolute indirect) */ { unsigned long sel; - generate_exception_if(dst.type != OP_MEM, EXC_UD); + generate_exception_if(dst.type != OP_MEM, EXC_UD, -1); if ( (rc = ops->read(dst.mem.seg, dst.mem.off+dst.bytes, &sel, 2, ctxt)) ) @@ -1963,7 +1968,7 @@ x86_emulate( dst.type = OP_NONE; break; case 7: - generate_exception_if(1, EXC_UD); + generate_exception_if(1, EXC_UD, -1); default: goto cannot_emulate; } @@ -2003,11 +2008,9 @@ x86_emulate( /* Commit shadow register state. */ _regs.eflags &= ~EFLG_RF; *ctxt->regs = _regs; - - if ( (_regs.eflags & EFLG_TF) && - (rc == X86EMUL_OKAY) && + if ( (_regs.eflags & EFLG_TF) && (rc == X86EMUL_OKAY) && (ops->inject_hw_exception != NULL) ) - rc = ops->inject_hw_exception(EXC_DB, 0, ctxt) ? : X86EMUL_EXCEPTION; + rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION; done: return rc; @@ -2022,7 +2025,7 @@ x86_emulate( generate_exception_if(lock_prefix && ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */ (b != 0xc7), /* CMPXCHG{8,16}B */ - EXC_GP); + EXC_GP, 0); if ( twobyte ) goto twobyte_special_insn; @@ -2069,6 +2072,7 @@ x86_emulate( case 0x17: /* pop %%ss */ src.val = x86_seg_ss; + ctxt->retire.flags.mov_ss = 1; goto pop_seg; case 0x1e: /* push %%ds */ @@ -2082,7 +2086,7 @@ x86_emulate( case 0x27: /* daa */ { uint8_t al = _regs.eax; unsigned long eflags = _regs.eflags; - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); _regs.eflags &= ~(EFLG_CF|EFLG_AF); if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) ) { @@ -2104,7 +2108,7 @@ x86_emulate( case 0x2f: /* das */ { uint8_t al = _regs.eax; unsigned long eflags = _regs.eflags; - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); _regs.eflags &= ~(EFLG_CF|EFLG_AF); if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) ) { @@ -2127,7 +2131,7 @@ x86_emulate( case 0x37: /* aaa */ case 0x3f: /* aas */ - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); _regs.eflags &= ~EFLG_CF; if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) ) { @@ -2171,7 +2175,7 @@ x86_emulate( unsigned long regs[] = { _regs.eax, _regs.ecx, _regs.edx, _regs.ebx, _regs.esp, _regs.ebp, _regs.esi, _regs.edi }; - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); for ( i = 0; i < 8; i++ ) if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), regs[i], op_bytes, ctxt)) != 0 ) @@ -2186,7 +2190,7 @@ x86_emulate( (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp, (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx, (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax }; - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); for ( i = 0; i < 8; i++ ) { if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), @@ -2224,7 +2228,7 @@ x86_emulate( case 0x6c ... 0x6d: /* ins %dx,%es:%edi */ { unsigned long nr_reps = get_rep_prefix(); - generate_exception_if(!mode_iopl(), EXC_GP); + generate_exception_if(!mode_iopl(), EXC_GP, 0); dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; dst.mem.seg = x86_seg_es; dst.mem.off = truncate_ea(_regs.edi); @@ -2254,7 +2258,7 @@ x86_emulate( case 0x6e ... 0x6f: /* outs %esi,%dx */ { unsigned long nr_reps = get_rep_prefix(); - generate_exception_if(!mode_iopl(), EXC_GP); + generate_exception_if(!mode_iopl(), EXC_GP, 0); dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; if ( (nr_reps > 1) && (ops->rep_outs != NULL) && ((rc = ops->rep_outs(ea.mem.seg, truncate_ea(_regs.esi), @@ -2333,7 +2337,7 @@ x86_emulate( uint32_t eip; fail_if(ops->read_segment == NULL); - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); eip = insn_fetch_bytes(op_bytes); sel = insn_fetch_type(uint16_t); @@ -2359,7 +2363,6 @@ x86_emulate( uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM; if ( !mode_iopl() ) mask |= EFLG_IOPL; - fail_if(ops->write_rflags == NULL); /* 64-bit mode: POP defaults to a 64-bit operand. */ if ( mode_64bit() && (op_bytes == 4) ) op_bytes = 8; @@ -2371,8 +2374,6 @@ x86_emulate( dst.val &= 0x257fd5; _regs.eflags &= mask; _regs.eflags |= (uint32_t)(dst.val & ~mask) | 0x02; - if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 ) - goto done; break; } @@ -2597,7 +2598,7 @@ x86_emulate( goto done; case 0xce: /* into */ - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); if ( !(_regs.eflags & EFLG_OF) ) break; src.val = EXC_OF; @@ -2609,7 +2610,6 @@ x86_emulate( if ( !mode_iopl() ) mask |= EFLG_IOPL; fail_if(!in_realmode(ctxt, ops)); - fail_if(ops->write_rflags == NULL); if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), &eip, op_bytes, ctxt)) || (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), @@ -2622,8 +2622,6 @@ x86_emulate( eflags &= 0x257fd5; _regs.eflags &= mask; _regs.eflags |= (uint32_t)(eflags & ~mask) | 0x02; - if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 ) - goto done; _regs.eip = eip; if ( (rc = load_seg(x86_seg_cs, (uint16_t)cs, ctxt, ops)) != 0 ) goto done; @@ -2633,8 +2631,8 @@ x86_emulate( case 0xd4: /* aam */ { unsigned int base = insn_fetch_type(uint8_t); uint8_t al = _regs.eax; - generate_exception_if(mode_64bit(), EXC_UD); - generate_exception_if(base == 0, EXC_DE); + generate_exception_if(mode_64bit(), EXC_UD, -1); + generate_exception_if(base == 0, EXC_DE, -1); *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base); _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; @@ -2646,7 +2644,7 @@ x86_emulate( case 0xd5: /* aad */ { unsigned int base = insn_fetch_type(uint8_t); uint16_t ax = _regs.eax; - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base)); _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; @@ -2656,7 +2654,7 @@ x86_emulate( } case 0xd6: /* salc */ - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00; break; @@ -2673,7 +2671,7 @@ x86_emulate( fail_if(ops->load_fpu_ctxt == NULL); ops->load_fpu_ctxt(ctxt); fail_if((modrm_reg & 7) != 7); - fail_if(modrm_reg >= 0xc0); + fail_if(modrm >= 0xc0); /* fnstcw m2byte */ ea.bytes = 2; dst = ea; @@ -2692,7 +2690,7 @@ x86_emulate( fail_if(ops->load_fpu_ctxt == NULL); ops->load_fpu_ctxt(ctxt); fail_if((modrm_reg & 7) != 7); - fail_if(modrm_reg >= 0xc0); + fail_if(modrm >= 0xc0); /* fnstsw m2byte */ ea.bytes = 2; dst = ea; @@ -2743,7 +2741,7 @@ x86_emulate( unsigned int port = ((b < 0xe8) ? insn_fetch_type(uint8_t) : (uint16_t)_regs.edx); - generate_exception_if(!mode_iopl(), EXC_GP); + generate_exception_if(!mode_iopl(), EXC_GP, 0); op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; if ( b & 2 ) { @@ -2787,7 +2785,7 @@ x86_emulate( case 0xea: /* jmp (far, absolute) */ { uint16_t sel; uint32_t eip; - generate_exception_if(mode_64bit(), EXC_UD); + generate_exception_if(mode_64bit(), EXC_UD, -1); eip = insn_fetch_bytes(op_bytes); sel = insn_fetch_type(uint16_t); if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 ) @@ -2807,9 +2805,7 @@ x86_emulate( goto swint; case 0xf4: /* hlt */ - fail_if(ops->hlt == NULL); - if ( (rc = ops->hlt(ctxt)) != 0 ) - goto done; + ctxt->retire.flags.hlt = 1; break; case 0xf5: /* cmc */ @@ -2825,14 +2821,17 @@ x86_emulate( break; case 0xfa: /* cli */ + generate_exception_if(!mode_iopl(), EXC_GP, 0); + _regs.eflags &= ~EFLG_IF; + break; + case 0xfb: /* sti */ - generate_exception_if(!mode_iopl(), EXC_GP); - fail_if(ops->write_rflags == NULL); - _regs.eflags &= ~EFLG_IF; - if ( b == 0xfb ) /* sti */ + generate_exception_if(!mode_iopl(), EXC_GP, 0); + if ( !(_regs.eflags & EFLG_IF) ) + { _regs.eflags |= EFLG_IF; - if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 ) - goto done; + ctxt->retire.flags.sti = 1; + } break; case 0xfc: /* cld */ @@ -3001,7 +3000,7 @@ x86_emulate( case 5: goto bts; case 6: goto btr; case 7: goto btc; - default: generate_exception_if(1, EXC_UD); + default: generate_exception_if(1, EXC_UD, -1); } break; @@ -3038,8 +3037,8 @@ x86_emulate( if ( modrm == 0xdf ) /* invlpga */ { - generate_exception_if(in_realmode(ctxt, ops), EXC_UD); - generate_exception_if(!mode_ring0(), EXC_GP); + generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1); + generate_exception_if(!mode_ring0(), EXC_GP, 0); fail_if(ops->invlpg == NULL); if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax), ctxt)) ) @@ -3051,7 +3050,7 @@ x86_emulate( { case 0: /* sgdt */ case 1: /* sidt */ - generate_exception_if(ea.type != OP_MEM, EXC_UD); + generate_exception_if(ea.type != OP_MEM, EXC_UD, -1); fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment((modrm_reg & 1) ? x86_seg_idtr : x86_seg_gdtr, @@ -3067,7 +3066,7 @@ x86_emulate( break; case 2: /* lgdt */ case 3: /* lidt */ - generate_exception_if(ea.type != OP_MEM, EXC_UD); + generate_exception_if(ea.type != OP_MEM, EXC_UD, -1); fail_if(ops->write_segment == NULL); memset(®, 0, sizeof(reg)); if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, @@ -3108,8 +3107,8 @@ x86_emulate( goto done; break; case 7: /* invlpg */ - generate_exception_if(!mode_ring0(), EXC_GP); - generate_exception_if(ea.type != OP_MEM, EXC_UD); + generate_exception_if(!mode_ring0(), EXC_GP, 0); + generate_exception_if(ea.type != OP_MEM, EXC_UD, -1); fail_if(ops->invlpg == NULL); if ( (rc = ops->invlpg(ea.mem.seg, ea.mem.off, ctxt)) ) goto done; @@ -3121,7 +3120,7 @@ x86_emulate( } case 0x06: /* clts */ - generate_exception_if(!mode_ring0(), EXC_GP); + generate_exception_if(!mode_ring0(), EXC_GP, 0); fail_if((ops->read_cr == NULL) || (ops->write_cr == NULL)); if ( (rc = ops->read_cr(0, &dst.val, ctxt)) || (rc = ops->write_cr(0, dst.val&~8, ctxt)) ) @@ -3130,7 +3129,7 @@ x86_emulate( case 0x08: /* invd */ case 0x09: /* wbinvd */ - generate_exception_if(!mode_ring0(), EXC_GP); + generate_exception_if(!mode_ring0(), EXC_GP, 0); fail_if(ops->wbinvd == NULL); if ( (rc = ops->wbinvd(ctxt)) != 0 ) goto done; @@ -3145,7 +3144,7 @@ x86_emulate( case 0x21: /* mov dr,reg */ case 0x22: /* mov reg,cr */ case 0x23: /* mov reg,dr */ - generate_exception_if(!mode_ring0(), EXC_GP); + generate_exception_if(!mode_ring0(), EXC_GP, 0); modrm_rm |= (rex_prefix & 1) << 3; modrm_reg |= lock_prefix << 3; if ( b & 2 ) @@ -3182,7 +3181,7 @@ x86_emulate( case 0x30: /* wrmsr */ { uint64_t val = ((uint64_t)_regs.edx << 32) | (uint32_t)_regs.eax; - generate_exception_if(!mode_ring0(), EXC_GP); + generate_exception_if(!mode_ring0(), EXC_GP, 0); fail_if(ops->write_msr == NULL); if ( (rc = ops->write_msr((uint32_t)_regs.ecx, val, ctxt)) != 0 ) goto done; @@ -3195,7 +3194,7 @@ x86_emulate( fail_if(ops->read_cr == NULL); if ( (rc = ops->read_cr(4, &cr4, ctxt)) ) goto done; - generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP); + generate_exception_if((cr4 & CR4_TSD) && !mode_ring0(), EXC_GP, 0); fail_if(ops->read_msr == NULL); if ( (rc = ops->read_msr(MSR_TSC, &val, ctxt)) != 0 ) goto done; @@ -3206,7 +3205,7 @@ x86_emulate( case 0x32: /* rdmsr */ { uint64_t val; - generate_exception_if(!mode_ring0(), EXC_GP); + generate_exception_if(!mode_ring0(), EXC_GP, 0); fail_if(ops->read_msr == NULL); if ( (rc = ops->read_msr((uint32_t)_regs.ecx, &val, ctxt)) != 0 ) goto done; @@ -3255,8 +3254,8 @@ x86_emulate( #if defined(__i386__) { unsigned long old_lo, old_hi; - generate_exception_if((modrm_reg & 7) != 1, EXC_UD); - generate_exception_if(ea.type != OP_MEM, EXC_UD); + generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1); + generate_exception_if(ea.type != OP_MEM, EXC_UD, -1); if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &old_lo, 4, ctxt)) || (rc = ops->read(ea.mem.seg, ea.mem.off+4, &old_hi, 4, ctxt)) ) goto done; @@ -3283,8 +3282,8 @@ x86_emulate( #elif defined(__x86_64__) { unsigned long old, new; - generate_exception_if((modrm_reg & 7) != 1, EXC_UD); - generate_exception_if(ea.type != OP_MEM, EXC_UD); + generate_exception_if((modrm_reg & 7) != 1, EXC_UD, -1); + generate_exception_if(ea.type != OP_MEM, EXC_UD, -1); if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 ) goto done; if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) || diff -r 7e8334e651c4 -r f97a0b6152c3 xen/common/compat/xenoprof.c --- a/xen/common/compat/xenoprof.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/common/compat/xenoprof.c Tue Feb 26 10:12:04 2008 -0700 @@ -14,6 +14,7 @@ CHECK_oprof_init; #define xenoprof_get_buffer compat_oprof_get_buffer #define xenoprof_op_get_buffer compat_oprof_op_get_buffer +#define xenoprof_arch_counter compat_oprof_arch_counter #define xen_domid_t domid_t #define compat_domid_t domid_compat_t diff -r 7e8334e651c4 -r f97a0b6152c3 xen/common/grant_table.c --- a/xen/common/grant_table.c Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/common/grant_table.c Tue Feb 26 10:12:04 2008 -0700 @@ -350,10 +350,10 @@ __gnttab_map_grant_ref( else { if ( unlikely(!mfn_valid(frame)) || - unlikely(!((op->flags & GNTMAP_readonly) ? - get_page(mfn_to_page(frame), rd) : + unlikely(!(gnttab_host_mapping_get_page_type(op, ld, rd) ? get_page_and_type(mfn_to_page(frame), rd, - PGT_writable_page))) ) + PGT_writable_page) : + get_page(mfn_to_page(frame), rd))) ) { if ( !rd->is_dying ) gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", @@ -367,7 +367,7 @@ __gnttab_map_grant_ref( rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0); if ( rc != GNTST_okay ) { - if ( !(op->flags & GNTMAP_readonly) ) + if ( gnttab_host_mapping_get_page_type(op, ld, rd) ) put_page_type(mfn_to_page(frame)); put_page(mfn_to_page(frame)); goto undo_out; @@ -604,7 +604,7 @@ __gnttab_unmap_common_complete(struct gn if ( !is_iomem_page(op->frame) ) { - if ( !(op->flags & GNTMAP_readonly) ) + if ( gnttab_host_mapping_get_page_type(op, ld, rd) ) put_page_type(mfn_to_page(op->frame)); put_page(mfn_to_page(op->frame)); } @@ -1662,8 +1662,9 @@ gnttab_release_mappings( { BUG_ON(!(act->pin & GNTPIN_hstr_mask)); act->pin -= GNTPIN_hstr_inc; - if ( !is_iomem_page(act->frame) ) - gnttab_release_put_page(mfn_to_page(act->frame)); + if ( gnttab_release_host_mappings && + !is_iomem_page(act->frame) ) + put_page(mfn_to_page(act->frame)); } } else @@ -1680,8 +1681,13 @@ gnttab_release_mappings( { BUG_ON(!(act->pin & GNTPIN_hstw_mask)); act->pin -= GNTPIN_hstw_inc; - if ( !is_iomem_page(act->frame) ) - gnttab_release_put_page_and_type(mfn_to_page(act->frame)); + if ( gnttab_release_host_mappings && + !is_iomem_page(act->frame) ) + { + if ( gnttab_host_mapping_get_page_type(map, d, rd) ) + put_page_type(mfn_to_page(act->frame)); + put_page(mfn_to_page(act->frame)); + } } if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 ) diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-ia64/grant_table.h --- a/xen/include/asm-ia64/grant_table.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/asm-ia64/grant_table.h Tue Feb 26 10:12:04 2008 -0700 @@ -65,8 +65,10 @@ static inline void gnttab_clear_flag(uns clear_bit(nr, addr); } -#define gnttab_release_put_page(page) put_page((page)) -#define gnttab_release_put_page_and_type(page) put_page_and_type((page)) +#define gnttab_host_mapping_get_page_type(op, ld, rd) \ + (!((op)->flags & GNTMAP_readonly)) + +#define gnttab_release_host_mappings 1 static inline int replace_grant_supported(void) { diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-powerpc/grant_table.h --- a/xen/include/asm-powerpc/grant_table.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/asm-powerpc/grant_table.h Tue Feb 26 10:12:04 2008 -0700 @@ -76,17 +76,14 @@ static inline uint cpu_foreign_map_order return 34 - PAGE_SHIFT; } -#if 0 +#define gnttab_host_mapping_get_page_type(op, ld, rd) \ + (!((op)->flags & GNTMAP_readonly)) + /* * without put_page()/put_page_and_type() page might be leaked. * with put_page()/put_page_and_type() freed page might be accessed. */ -#define gnttab_release_put_page(page) put_page((page)) -#define gnttab_release_put_page_and_type(page) put_page_and_type((page)) -#else -#define gnttab_release_put_page(page) do { } while (0) -#define gnttab_release_put_page_and_type(page) do { } while (0) -#endif +#define gnttab_release_host_mappings 0 static inline int replace_grant_supported(void) { diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/grant_table.h --- a/xen/include/asm-x86/grant_table.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/asm-x86/grant_table.h Tue Feb 26 10:12:04 2008 -0700 @@ -38,15 +38,13 @@ static inline void gnttab_clear_flag(uns clear_bit(nr, addr); } -#define gnttab_release_put_page(page) \ - do { \ - /* Done implicitly when page tables are destroyed. */ \ - } while (0) +/* Foreign mappings of HHVM-guest pages do not modify the type count. */ +#define gnttab_host_mapping_get_page_type(op, ld, rd) \ + (!((op)->flags & GNTMAP_readonly) && \ + (((ld) == (rd)) || !paging_mode_external(rd))) -#define gnttab_release_put_page_and_type(page) \ - do { \ - /* Done implicitly when page tables are destroyed. */ \ - } while (0) +/* Done implicitly when page tables are destroyed. */ +#define gnttab_release_host_mappings 0 static inline int replace_grant_supported(void) { diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/hvm/emulate.h --- a/xen/include/asm-x86/hvm/emulate.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/asm-x86/hvm/emulate.h Tue Feb 26 10:12:04 2008 -0700 @@ -27,18 +27,12 @@ struct hvm_emulate_ctxt { unsigned long seg_reg_accessed; unsigned long seg_reg_dirty; - union { - struct { - unsigned int hlt:1; - unsigned int mov_ss:1; - unsigned int sti:1; - unsigned int exn_pending:1; - } flags; - unsigned int flag_word; - }; - + bool_t exn_pending; uint8_t exn_vector; uint8_t exn_insn_len; + int32_t exn_error_code; + + uint32_t intr_shadow; }; int hvm_emulate_one( diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/asm-x86/hvm/hvm.h Tue Feb 26 10:12:04 2008 -0700 @@ -49,6 +49,12 @@ enum hvm_intblk { hvm_intblk_nmi_iret /* NMI blocked until IRET */ }; +/* These happen to be the same as the VMX interrupt shadow definitions. */ +#define HVM_INTR_SHADOW_STI 0x00000001 +#define HVM_INTR_SHADOW_MOV_SS 0x00000002 +#define HVM_INTR_SHADOW_SMI 0x00000004 +#define HVM_INTR_SHADOW_NMI 0x00000008 + /* * The hardware virtual machine (HVM) interface abstracts away from the * x86/x86_64 CPU virtualization assist specifics. Currently this interface @@ -72,14 +78,9 @@ struct hvm_function_table { void (*save_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt); int (*load_cpu_ctxt)(struct vcpu *v, struct hvm_hw_cpu *ctxt); - /* - * Examine specifics of the guest state: - * 1) determine whether interrupts are enabled or not - * 2) determine the mode the guest is running in - * 3) return the current guest segment descriptor base - * 4) return the current guest segment descriptor - */ - enum hvm_intblk (*interrupt_blocked)(struct vcpu *v, struct hvm_intack); + /* Examine specifics of the guest state. */ + unsigned int (*get_interrupt_shadow)(struct vcpu *v); + void (*set_interrupt_shadow)(struct vcpu *v, unsigned int intr_shadow); int (*guest_x86_mode)(struct vcpu *v); void (*get_segment_register)(struct vcpu *v, enum x86_segment seg, struct segment_register *reg); diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/x86_emulate.h --- a/xen/include/asm-x86/x86_emulate.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/asm-x86/x86_emulate.h Tue Feb 26 10:12:04 2008 -0700 @@ -318,11 +318,6 @@ struct x86_emulate_ops uint64_t val, struct x86_emulate_ctxt *ctxt); - /* write_rflags: Modify privileged bits in RFLAGS. */ - int (*write_rflags)( - unsigned long val, - struct x86_emulate_ctxt *ctxt); - /* wbinvd: Write-back and invalidate cache contents. */ int (*wbinvd)( struct x86_emulate_ctxt *ctxt); @@ -335,14 +330,10 @@ struct x86_emulate_ops unsigned int *edx, struct x86_emulate_ctxt *ctxt); - /* hlt: Emulate HLT. */ - int (*hlt)( - struct x86_emulate_ctxt *ctxt); - /* inject_hw_exception */ int (*inject_hw_exception)( uint8_t vector, - uint16_t error_code, + int32_t error_code, struct x86_emulate_ctxt *ctxt); /* inject_sw_interrupt */ @@ -376,7 +367,17 @@ struct x86_emulate_ctxt unsigned int sp_size; /* Set this if writes may have side effects. */ - int force_writeback; + uint8_t force_writeback; + + /* Retirement state, set by the emulator (valid only on X86EMUL_OKAY). */ + union { + struct { + uint8_t hlt:1; /* Instruction HLTed. */ + uint8_t mov_ss:1; /* Instruction sets MOV-SS irq shadow. */ + uint8_t sti:1; /* Instruction sets STI irq shadow. */ + } flags; + uint8_t byte; + } retire; }; /* diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/asm-x86/xenoprof.h --- a/xen/include/asm-x86/xenoprof.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/asm-x86/xenoprof.h Tue Feb 26 10:12:04 2008 -0700 @@ -41,6 +41,7 @@ int xenoprof_arch_init(int *num_events, #define xenoprof_arch_release_counters() nmi_release_counters() int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg); +int compat_oprof_arch_counter(XEN_GUEST_HANDLE(void) arg); struct vcpu; struct cpu_user_regs; diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/public/io/protocols.h --- a/xen/include/public/io/protocols.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/public/io/protocols.h Tue Feb 26 10:12:04 2008 -0700 @@ -1,3 +1,25 @@ +/****************************************************************************** + * protocols.h + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + #ifndef __XEN_PROTOCOLS_H__ #define __XEN_PROTOCOLS_H__ diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/public/kexec.h --- a/xen/include/public/kexec.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/public/kexec.h Tue Feb 26 10:12:04 2008 -0700 @@ -1,5 +1,23 @@ /****************************************************************************** * kexec.h - Public portion + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Xen port written by: * - Simon 'Horms' Horman <horms@xxxxxxxxxxxx> diff -r 7e8334e651c4 -r f97a0b6152c3 xen/include/public/libelf.h --- a/xen/include/public/libelf.h Mon Feb 25 06:29:01 2008 -0700 +++ b/xen/include/public/libelf.h Tue Feb 26 10:12:04 2008 -0700 @@ -1,3 +1,25 @@ +/****************************************************************************** + * libelf.h + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + #ifndef __XC_LIBELF__ #define __XC_LIBELF__ 1 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |