WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 09 Aug 2006 18:20:19 +0000
Delivery-date: Wed, 09 Aug 2006 11:23:18 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Hollis Blanchard <hollisb@xxxxxxxxxx>
# Node ID 87cefa5f7c5e431eedfde8a500932abfe1f7a952
# Parent  61204c1d740ef3da8913c1f15bee79cc4a7ac134
# Parent  ec8dd0528fc69fc643268493d5a3d722a5650cd7
merge with xen-unstable.hg
---
 tools/ioemu/CVS/Entries                                         |  109 
 tools/ioemu/CVS/Repository                                      |    1 
 tools/ioemu/CVS/Root                                            |    1 
 tools/ioemu/CVS/Tag                                             |    1 
 tools/ioemu/audio/CVS/Entries                                   |   19 
 tools/ioemu/audio/CVS/Repository                                |    1 
 tools/ioemu/audio/CVS/Root                                      |    1 
 tools/ioemu/audio/CVS/Tag                                       |    1 
 tools/ioemu/fpu/CVS/Entries                                     |    7 
 tools/ioemu/fpu/CVS/Repository                                  |    1 
 tools/ioemu/fpu/CVS/Root                                        |    1 
 tools/ioemu/fpu/CVS/Tag                                         |    1 
 tools/ioemu/hw/CVS/Entries                                      |   72 
 tools/ioemu/hw/CVS/Repository                                   |    1 
 tools/ioemu/hw/CVS/Root                                         |    1 
 tools/ioemu/hw/CVS/Tag                                          |    1 
 tools/ioemu/keymaps/CVS/Entries                                 |   36 
 tools/ioemu/keymaps/CVS/Repository                              |    1 
 tools/ioemu/keymaps/CVS/Root                                    |    1 
 tools/ioemu/keymaps/CVS/Tag                                     |    1 
 tools/ioemu/pc-bios/CVS/Entries                                 |   15 
 tools/ioemu/pc-bios/CVS/Repository                              |    1 
 tools/ioemu/pc-bios/CVS/Root                                    |    1 
 tools/ioemu/pc-bios/CVS/Tag                                     |    1 
 tools/ioemu/pc-bios/proll.patch                                 | 3836 
----------
 tools/ioemu/target-i386/CVS/Entries                             |   13 
 tools/ioemu/target-i386/CVS/Repository                          |    1 
 tools/ioemu/target-i386/CVS/Root                                |    1 
 tools/ioemu/target-i386/CVS/Tag                                 |    1 
 tools/ioemu/tests/CVS/Entries                                   |   18 
 tools/ioemu/tests/CVS/Repository                                |    1 
 tools/ioemu/tests/CVS/Root                                      |    1 
 tools/ioemu/tests/CVS/Tag                                       |    1 
 xen/include/xen/reboot.h                                        |    8 
 .hgignore                                                       |    1 
 buildconfigs/linux-defconfig_xen0_ia64                          |   14 
 buildconfigs/linux-defconfig_xenU_ia64                          |   16 
 buildconfigs/linux-defconfig_xen_ia64                           |   14 
 docs/figs/acm_ezpolicy.eps                                      |  650 +
 docs/figs/acm_overview.eps                                      | 1459 +++
 docs/src/user.tex                                               |  984 ++
 extras/mini-os/console/xencons_ring.c                           |    2 
 extras/mini-os/events.c                                         |   72 
 extras/mini-os/gnttab.c                                         |   12 
 extras/mini-os/include/events.h                                 |   24 
 extras/mini-os/include/gnttab.h                                 |    1 
 extras/mini-os/time.c                                           |    2 
 extras/mini-os/xenbus/xenbus.c                                  |    3 
 linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c                 |    1 
 linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c                 |    2 
 linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c                 |    3 
 linux-2.6-xen-sparse/arch/ia64/Kconfig                          |   15 
 linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c              |    3 
 linux-2.6-xen-sparse/drivers/xen/Kconfig                        |    9 
 linux-2.6-xen-sparse/drivers/xen/netback/common.h               |   18 
 linux-2.6-xen-sparse/drivers/xen/netback/interface.c            |   84 
 linux-2.6-xen-sparse/drivers/xen/netback/netback.c              |  545 -
 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c               |   27 
 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c            |  582 +
 linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c             |    4 
 linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c               |    3 
 linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c              |   15 
 linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c              |   10 
 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c              |    1 
 linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c              |   39 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c            |  114 
 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c          |    4 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h |   16 
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h        |    3 
 linux-2.6-xen-sparse/include/asm-i386/spinlock.h                |    4 
 linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h      |    1 
 linux-2.6-xen-sparse/include/xen/pcifront.h                     |   42 
 tools/blktap/drivers/Makefile                                   |   19 
 tools/blktap/drivers/blktapctrl.c                               |   21 
 tools/blktap/lib/Makefile                                       |   14 
 tools/examples/block                                            |   18 
 tools/examples/xmexample.hvm                                    |   10 
 tools/firmware/Makefile                                         |    2 
 tools/firmware/acpi/acpi_dsdt.asl                               |  235 
 tools/firmware/acpi/acpi_dsdt.c                                 |  531 -
 tools/firmware/hvmloader/Makefile                               |    9 
 tools/firmware/hvmloader/acpi_madt.c                            |    4 
 tools/firmware/hvmloader/hvmloader.c                            |  125 
 tools/firmware/hvmloader/hypercall.h                            |  180 
 tools/firmware/hvmloader/mp_tables.c                            |    3 
 tools/firmware/hvmloader/util.c                                 |   96 
 tools/firmware/hvmloader/util.h                                 |   19 
 tools/firmware/vmxassist/vm86.c                                 |   31 
 tools/ioemu/.CVS/Entries                                        |  109 
 tools/ioemu/.CVS/Entries.Log                                    |    7 
 tools/ioemu/.CVS/Repository                                     |    1 
 tools/ioemu/.CVS/Root                                           |    1 
 tools/ioemu/.CVS/Tag                                            |    1 
 tools/ioemu/.cvsignore                                          |   13 
 tools/ioemu/Changelog                                           |   19 
 tools/ioemu/Makefile                                            |   31 
 tools/ioemu/Makefile.target                                     |   55 
 tools/ioemu/TODO                                                |    2 
 tools/ioemu/VERSION                                             |    2 
 tools/ioemu/audio/.CVS/Entries                                  |   20 
 tools/ioemu/audio/.CVS/Repository                               |    1 
 tools/ioemu/audio/.CVS/Root                                     |    1 
 tools/ioemu/audio/.CVS/Tag                                      |    1 
 tools/ioemu/audio/alsaaudio.c                                   |   23 
 tools/ioemu/audio/audio.c                                       |  452 +
 tools/ioemu/audio/audio.h                                       |   46 
 tools/ioemu/audio/audio_int.h                                   |   42 
 tools/ioemu/audio/audio_template.h                              |   33 
 tools/ioemu/audio/coreaudio.c                                   |   16 
 tools/ioemu/audio/dsound_template.h                             |   20 
 tools/ioemu/audio/dsoundaudio.c                                 |    8 
 tools/ioemu/audio/fmodaudio.c                                   |   10 
 tools/ioemu/audio/noaudio.c                                     |   40 
 tools/ioemu/audio/ossaudio.c                                    |   44 
 tools/ioemu/audio/rate_template.h                               |    2 
 tools/ioemu/audio/sdlaudio.c                                    |   10 
 tools/ioemu/audio/wavaudio.c                                    |    4 
 tools/ioemu/audio/wavcapture.c                                  |  164 
 tools/ioemu/block-bochs.c                                       |    2 
 tools/ioemu/block-cloop.c                                       |    2 
 tools/ioemu/block-cow.c                                         |    9 
 tools/ioemu/block-qcow.c                                        |    9 
 tools/ioemu/block-vmdk.c                                        |    9 
 tools/ioemu/block-vpc.c                                         |    2 
 tools/ioemu/block-vvfat.c                                       |    1 
 tools/ioemu/block.c                                             |   64 
 tools/ioemu/block_int.h                                         |    1 
 tools/ioemu/cocoa.m                                             |   60 
 tools/ioemu/configure                                           |   55 
 tools/ioemu/console.c                                           |  170 
 tools/ioemu/cpu-all.h                                           |  102 
 tools/ioemu/cpu-defs.h                                          |    2 
 tools/ioemu/cpu-exec.c                                          |   49 
 tools/ioemu/disas.c                                             |    4 
 tools/ioemu/dyngen-exec.h                                       |   27 
 tools/ioemu/dyngen.c                                            |   92 
 tools/ioemu/dyngen.h                                            |    8 
 tools/ioemu/elf.h                                               |    2 
 tools/ioemu/exec-all.h                                          |    2 
 tools/ioemu/exec.c                                              |   33 
 tools/ioemu/fpu/.CVS/Entries                                    |    7 
 tools/ioemu/fpu/.CVS/Repository                                 |    1 
 tools/ioemu/fpu/.CVS/Root                                       |    1 
 tools/ioemu/fpu/.CVS/Tag                                        |    1 
 tools/ioemu/fpu/softfloat-native.c                              |   13 
 tools/ioemu/gdbstub.c                                           |  131 
 tools/ioemu/hw/.CVS/Entries                                     |   89 
 tools/ioemu/hw/.CVS/Repository                                  |    1 
 tools/ioemu/hw/.CVS/Root                                        |    1 
 tools/ioemu/hw/.CVS/Tag                                         |    1 
 tools/ioemu/hw/acpi-dsdt.dsl                                    |  559 +
 tools/ioemu/hw/acpi-dsdt.hex                                    |  278 
 tools/ioemu/hw/acpi.c                                           |  615 +
 tools/ioemu/hw/adlib.c                                          |    4 
 tools/ioemu/hw/apb_pci.c                                        |  232 
 tools/ioemu/hw/apic.c                                           |    4 
 tools/ioemu/hw/cdrom.c                                          |  156 
 tools/ioemu/hw/cuda.c                                           |    2 
 tools/ioemu/hw/es1370.c                                         |   10 
 tools/ioemu/hw/esp.c                                            |  538 -
 tools/ioemu/hw/grackle_pci.c                                    |  156 
 tools/ioemu/hw/i8259.c                                          |    2 
 tools/ioemu/hw/ide.c                                            |  135 
 tools/ioemu/hw/lsi53c895a.c                                     | 1571 ++++
 tools/ioemu/hw/m48t59.c                                         |   10 
 tools/ioemu/hw/mips_r4k.c                                       |    6 
 tools/ioemu/hw/ne2000.c                                         |    2 
 tools/ioemu/hw/pc.c                                             |   61 
 tools/ioemu/hw/pci.c                                            | 1489 ---
 tools/ioemu/hw/pci_host.h                                       |   93 
 tools/ioemu/hw/pcnet.c                                          | 1789 ++++
 tools/ioemu/hw/pcspk.c                                          |    4 
 tools/ioemu/hw/pflash_cfi02.c                                   |  624 +
 tools/ioemu/hw/piix4acpi.c                                      |  153 
 tools/ioemu/hw/piix_pci.c                                       |  435 +
 tools/ioemu/hw/pl050.c                                          |    2 
 tools/ioemu/hw/ppc_chrp.c                                       |   20 
 tools/ioemu/hw/ppc_prep.c                                       |    4 
 tools/ioemu/hw/prep_pci.c                                       |  167 
 tools/ioemu/hw/rtl8139.c                                        | 1494 ++-
 tools/ioemu/hw/sb16.c                                           |   94 
 tools/ioemu/hw/scsi-disk.c                                      |  478 +
 tools/ioemu/hw/sh7750.c                                         |    2 
 tools/ioemu/hw/slavio_intctl.c                                  |    2 
 tools/ioemu/hw/slavio_timer.c                                   |    2 
 tools/ioemu/hw/sun4m.c                                          |   14 
 tools/ioemu/hw/sun4u.c                                          |   18 
 tools/ioemu/hw/unin_pci.c                                       |  261 
 tools/ioemu/hw/usb-hid.c                                        |   14 
 tools/ioemu/hw/usb-hub.c                                        |   26 
 tools/ioemu/hw/usb-msd.c                                        |  402 +
 tools/ioemu/hw/usb-ohci.c                                       | 1190 +++
 tools/ioemu/hw/usb-uhci.c                                       |   22 
 tools/ioemu/hw/usb.h                                            |   18 
 tools/ioemu/hw/versatile_pci.c                                  |  119 
 tools/ioemu/hw/versatilepb.c                                    |  216 
 tools/ioemu/hw/vga.c                                            |  137 
 tools/ioemu/hw/vga_int.h                                        |    9 
 tools/ioemu/hw/vga_template.h                                   |  234 
 tools/ioemu/keymaps/.CVS/Entries                                |   36 
 tools/ioemu/keymaps/.CVS/Repository                             |    1 
 tools/ioemu/keymaps/.CVS/Root                                   |    1 
 tools/ioemu/keymaps/.CVS/Tag                                    |    1 
 tools/ioemu/kqemu.c                                             |   11 
 tools/ioemu/loader.c                                            |    2 
 tools/ioemu/monitor.c                                           |  169 
 tools/ioemu/osdep.c                                             |   22 
 tools/ioemu/osdep.h                                             |    2 
 tools/ioemu/patches/acpi-poweroff-support                       |    8 
 tools/ioemu/patches/acpi-support                                |  158 
 tools/ioemu/patches/acpi-timer-support                          |  226 
 tools/ioemu/patches/domain-destroy                              |   21 
 tools/ioemu/patches/domain-reset                                |   12 
 tools/ioemu/patches/domain-timeoffset                           |   40 
 tools/ioemu/patches/hypervisor-pit                              |   18 
 tools/ioemu/patches/ide-hd-multithread                          |   24 
 tools/ioemu/patches/ioemu-ia64                                  |   43 
 tools/ioemu/patches/qemu-64bit                                  |   28 
 tools/ioemu/patches/qemu-allow-disable-sdl                      |   27 
 tools/ioemu/patches/qemu-bugfixes                               |   25 
 tools/ioemu/patches/qemu-cleanup                                |   22 
 tools/ioemu/patches/qemu-dm                                     |  126 
 tools/ioemu/patches/qemu-fix-memset-args                        |   15 
 tools/ioemu/patches/qemu-fix-write-to-disk-synchronous          |   66 
 tools/ioemu/patches/qemu-hvm-banner                             |    4 
 tools/ioemu/patches/qemu-init-vgabios                           |    6 
 tools/ioemu/patches/qemu-logging                                |   28 
 tools/ioemu/patches/qemu-no-apic                                |   16 
 tools/ioemu/patches/qemu-nobios                                 |   19 
 tools/ioemu/patches/qemu-smp                                    |   20 
 tools/ioemu/patches/qemu-target-i386-dm                         |   48 
 tools/ioemu/patches/qemu-timer                                  |   14 
 tools/ioemu/patches/serial-non-block                            |    4 
 tools/ioemu/patches/series                                      |    6 
 tools/ioemu/patches/shadow-vram                                 |   12 
 tools/ioemu/patches/shared-vram                                 |   26 
 tools/ioemu/patches/support-xm-console                          |    6 
 tools/ioemu/patches/vnc-access-monitor-vt                       |   16 
 tools/ioemu/patches/vnc-cleanup                                 |   19 
 tools/ioemu/patches/vnc-fixes                                   |  101 
 tools/ioemu/patches/vnc-start-vncviewer                         |   48 
 tools/ioemu/patches/vnc-title-domain-name                       |    6 
 tools/ioemu/patches/xen-build                                   |   57 
 tools/ioemu/patches/xen-domain-name                             |   30 
 tools/ioemu/patches/xen-domid                                   |   18 
 tools/ioemu/patches/xen-mm                                      |   27 
 tools/ioemu/patches/xen-network                                 |   12 
 tools/ioemu/patches/xenstore-block-device-config                |  221 
 tools/ioemu/patches/xenstore-write-vnc-port                     |   27 
 tools/ioemu/pc-bios/.CVS/Entries                                |   14 
 tools/ioemu/pc-bios/.CVS/Repository                             |    1 
 tools/ioemu/pc-bios/.CVS/Root                                   |    1 
 tools/ioemu/pc-bios/.CVS/Tag                                    |    1 
 tools/ioemu/pc-bios/README                                      |    8 
 tools/ioemu/pc-bios/bios.diff                                   |   87 
 tools/ioemu/pc-bios/vgabios.diff                                |  825 --
 tools/ioemu/qemu-doc.texi                                       |  250 
 tools/ioemu/qemu-img.c                                          |   33 
 tools/ioemu/sdl.c                                               |   27 
 tools/ioemu/tap-win32.c                                         |    8 
 tools/ioemu/target-i386/.CVS/Entries                            |   13 
 tools/ioemu/target-i386/.CVS/Repository                         |    1 
 tools/ioemu/target-i386/.CVS/Root                               |    1 
 tools/ioemu/target-i386/.CVS/Tag                                |    1 
 tools/ioemu/target-i386/exec.h                                  |    3 
 tools/ioemu/target-i386/helper.c                                |   39 
 tools/ioemu/target-i386/helper2.c                               |   33 
 tools/ioemu/target-i386/op.c                                    |   15 
 tools/ioemu/target-i386/translate.c                             |   93 
 tools/ioemu/tests/.CVS/Entries                                  |   18 
 tools/ioemu/tests/.CVS/Repository                               |    1 
 tools/ioemu/tests/.CVS/Root                                     |    1 
 tools/ioemu/tests/.CVS/Tag                                      |    1 
 tools/ioemu/tests/Makefile                                      |    3 
 tools/ioemu/tests/test-i386.c                                   |   22 
 tools/ioemu/usb-linux.c                                         |   44 
 tools/ioemu/vl.c                                                | 1370 ++-
 tools/ioemu/vl.h                                                |  148 
 tools/ioemu/vnc.c                                               |  258 
 tools/ioemu/vnchextile.h                                        |   48 
 tools/ioemu/xenstore.c                                          |  215 
 tools/libxc/Makefile                                            |    3 
 tools/libxc/ia64/Makefile                                       |    8 
 tools/libxc/xc_hvm_build.c                                      |   32 
 tools/libxc/xc_misc.c                                           |   13 
 tools/libxc/xenctrl.h                                           |    9 
 tools/misc/lomount/lomount.c                                    |    6 
 tools/misc/xend                                                 |    2 
 tools/misc/xenperf.c                                            |   60 
 tools/python/xen/sv/CreateDomain.py                             |    1 
 tools/python/xen/util/auxbin.py                                 |    4 
 tools/python/xen/xend/XendDomainInfo.py                         |    2 
 tools/python/xen/xend/image.py                                  |   30 
 tools/python/xen/xend/server/DevController.py                   |    2 
 tools/python/xen/xend/server/blkif.py                           |   26 
 tools/python/xen/xm/create.py                                   |   14 
 tools/python/xen/xm/main.py                                     |   11 
 tools/python/xen/xm/shutdown.py                                 |   15 
 tools/security/Makefile                                         |    2 
 tools/security/xensec_ezpolicy                                  | 1628 ++++
 tools/xenstore/Makefile                                         |    4 
 tools/xenstore/xenstore_client.c                                |  106 
 tools/xenstore/xenstored_core.c                                 |    9 
 tools/xenstore/xenstored_core.h                                 |    1 
 tools/xenstore/xenstored_transaction.c                          |    8 
 tools/xenstore/xsls.c                                           |  103 
 xen/Makefile                                                    |   22 
 xen/Rules.mk                                                    |    7 
 xen/arch/ia64/linux-xen/setup.c                                 |    2 
 xen/arch/ia64/vmx/vmx_support.c                                 |    3 
 xen/arch/ia64/xen/dom_fw.c                                      |   14 
 xen/arch/ia64/xen/domain.c                                      |    5 
 xen/arch/ia64/xen/xensetup.c                                    |   10 
 xen/arch/powerpc/boot_of.c                                      |    8 
 xen/arch/powerpc/domain.c                                       |    2 
 xen/arch/powerpc/domain_build.c                                 |    4 
 xen/arch/powerpc/mpic_init.c                                    |    1 
 xen/arch/powerpc/ofd_fixup.c                                    |    4 
 xen/arch/powerpc/powerpc64/traps.c                              |    4 
 xen/arch/x86/cpu/mcheck/mce.c                                   |    4 
 xen/arch/x86/dom0_ops.c                                         |    2 
 xen/arch/x86/domain.c                                           |    2 
 xen/arch/x86/domain_build.c                                     |    7 
 xen/arch/x86/genapic/es7000plat.c                               |    1 
 xen/arch/x86/hvm/hvm.c                                          |  364 
 xen/arch/x86/hvm/i8259.c                                        |    4 
 xen/arch/x86/hvm/io.c                                           |    5 
 xen/arch/x86/hvm/platform.c                                     |   29 
 xen/arch/x86/hvm/svm/intr.c                                     |   18 
 xen/arch/x86/hvm/svm/svm.c                                      |  106 
 xen/arch/x86/hvm/vioapic.c                                      |   37 
 xen/arch/x86/hvm/vlapic.c                                       |  562 -
 xen/arch/x86/hvm/vmx/io.c                                       |   17 
 xen/arch/x86/hvm/vmx/vmx.c                                      |  118 
 xen/arch/x86/mm.c                                               |   23 
 xen/arch/x86/setup.c                                            |   22 
 xen/arch/x86/shadow32.c                                         |    6 
 xen/arch/x86/shadow_public.c                                    |    6 
 xen/arch/x86/shutdown.c                                         |   17 
 xen/arch/x86/traps.c                                            |  124 
 xen/arch/x86/x86_32/entry.S                                     |    2 
 xen/arch/x86/x86_32/traps.c                                     |   16 
 xen/arch/x86/x86_64/entry.S                                     |    2 
 xen/arch/x86/x86_64/traps.c                                     |   18 
 xen/common/Makefile                                             |    4 
 xen/common/domain.c                                             |   27 
 xen/common/event_channel.c                                      |  108 
 xen/common/kernel.c                                             |   23 
 xen/common/keyhandler.c                                         |    2 
 xen/common/perfc.c                                              |   53 
 xen/common/sched_credit.c                                       |   17 
 xen/common/shutdown.c                                           |   66 
 xen/common/version.c                                            |   56 
 xen/drivers/char/Makefile                                       |    3 
 xen/drivers/char/console.c                                      |   31 
 xen/drivers/char/serial.c                                       |    1 
 xen/include/asm-ia64/perfc.h                                    |   16 
 xen/include/asm-ia64/vmx_platform.h                             |   11 
 xen/include/asm-powerpc/perfc.h                                 |   16 
 xen/include/asm-x86/domain.h                                    |    2 
 xen/include/asm-x86/guest_access.h                              |   25 
 xen/include/asm-x86/hvm/domain.h                                |    8 
 xen/include/asm-x86/hvm/guest_access.h                          |   10 
 xen/include/asm-x86/hvm/hvm.h                                   |    5 
 xen/include/asm-x86/hvm/support.h                               |    4 
 xen/include/asm-x86/hvm/svm/vmmcall.h                           |    8 
 xen/include/asm-x86/hvm/vlapic.h                                |  113 
 xen/include/asm-x86/hvm/vmx/vmcs.h                              |    1 
 xen/include/asm-x86/hvm/vmx/vmx.h                               |    2 
 xen/include/asm-x86/perfc.h                                     |   23 
 xen/include/asm-x86/processor.h                                 |    4 
 xen/include/asm-x86/shadow.h                                    |    7 
 xen/include/public/dom0_ops.h                                   |    7 
 xen/include/public/hvm/ioreq.h                                  |    1 
 xen/include/public/hvm/params.h                                 |   24 
 xen/include/public/io/netif.h                                   |   15 
 xen/include/public/version.h                                    |    3 
 xen/include/public/xen.h                                        |    1 
 xen/include/xen/event.h                                         |   37 
 xen/include/xen/hypercall.h                                     |    5 
 xen/include/xen/sched.h                                         |    8 
 xen/include/xen/shutdown.h                                      |   13 
 xen/include/xen/version.h                                       |   16 
 ioemu/pc-bios/video.x                                           |    0 
 384 files changed, 25173 insertions(+), 11053 deletions(-)

diff -r 61204c1d740e -r 87cefa5f7c5e .hgignore
--- a/.hgignore Thu Jul 27 20:07:02 2006 -0400
+++ b/.hgignore Mon Aug 07 18:00:22 2006 -0500
@@ -156,6 +156,7 @@
 ^tools/xenstat/xentop/xentop$
 ^tools/xenstore/testsuite/tmp/.*$
 ^tools/xenstore/xen$
+^tools/xenstore/xenstore-chmod$
 ^tools/xenstore/xenstore-exists$
 ^tools/xenstore/xenstore-list$
 ^tools/xenstore/xenstore-read$
diff -r 61204c1d740e -r 87cefa5f7c5e buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64    Thu Jul 27 20:07:02 2006 -0400
+++ b/buildconfigs/linux-defconfig_xen0_ia64    Mon Aug 07 18:00:22 2006 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.16.13-xen0
-# Fri Jun 30 12:59:19 2006
+# Fri Jul 28 16:33:47 2006
 #
 
 #
@@ -92,6 +92,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_XEN=y
 CONFIG_XEN_IA64_DOM0_VP=y
+CONFIG_XEN_IA64_VDSO_PARAVIRT=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_IS_DMA32=y
 # CONFIG_IA64_GENERIC is not set
@@ -180,6 +181,8 @@ CONFIG_ACPI_CONTAINER=y
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
 CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
@@ -1513,7 +1516,7 @@ CONFIG_XEN_NETDEV_BACKEND=y
 CONFIG_XEN_NETDEV_BACKEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 # CONFIG_XEN_DEVMEM is not set
-# CONFIG_XEN_REBOOT is not set
+CONFIG_XEN_REBOOT=y
 # CONFIG_XEN_SMPBOOT is not set
 CONFIG_XEN_INTERFACE_VERSION=0x00030202
 
@@ -1523,13 +1526,16 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_PRIVILEGED_GUEST=y
 # CONFIG_XEN_UNPRIVILEGED_GUEST is not set
 CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
-# CONFIG_XEN_PCIDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-CONFIG_XEN_XENBUS_DEV=y
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
+CONFIG_XEN_PCIDEV_BACKEND=y
+CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
+# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
+# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 # CONFIG_XEN_SCRUB_PAGES is not set
diff -r 61204c1d740e -r 87cefa5f7c5e buildconfigs/linux-defconfig_xenU_ia64
--- a/buildconfigs/linux-defconfig_xenU_ia64    Thu Jul 27 20:07:02 2006 -0400
+++ b/buildconfigs/linux-defconfig_xenU_ia64    Mon Aug 07 18:00:22 2006 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.16.13-xenU
-# Mon May 22 15:05:32 2006
+# Fri Jul 28 16:32:18 2006
 #
 
 #
@@ -89,6 +89,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_XEN=y
 CONFIG_XEN_IA64_DOM0_VP=y
+CONFIG_XEN_IA64_VDSO_PARAVIRT=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_IS_DMA32=y
 # CONFIG_IA64_GENERIC is not set
@@ -177,6 +178,8 @@ CONFIG_ACPI_SYSTEM=y
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
 CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
@@ -1380,8 +1383,15 @@ CONFIG_CRYPTO_DES=y
 #
 # Hardware crypto devices
 #
+# CONFIG_XEN_UTIL is not set
 CONFIG_HAVE_ARCH_ALLOC_SKB=y
 CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
+CONFIG_XEN_BALLOON=y
+CONFIG_XEN_SKBUFF=y
+CONFIG_XEN_NETDEV_FRONTEND=y
+# CONFIG_XEN_DEVMEM is not set
+CONFIG_XEN_REBOOT=y
+# CONFIG_XEN_SMPBOOT is not set
 CONFIG_XEN_INTERFACE_VERSION=0x00030202
 
 #
@@ -1389,13 +1399,15 @@ CONFIG_XEN_INTERFACE_VERSION=0x00030202
 #
 # CONFIG_XEN_PRIVILEGED_GUEST is not set
 CONFIG_XEN_UNPRIVILEGED_GUEST=y
+CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
 # CONFIG_XEN_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_FRONTEND=y
 # CONFIG_XEN_SCRUB_PAGES is not set
 # CONFIG_XEN_DISABLE_SERIAL is not set
 CONFIG_XEN_SYSFS=y
 CONFIG_XEN_COMPAT_030002_AND_LATER=y
 # CONFIG_XEN_COMPAT_LATEST_ONLY is not set
 CONFIG_XEN_COMPAT_030002=y
+CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
 CONFIG_NO_IDLE_HZ=y
diff -r 61204c1d740e -r 87cefa5f7c5e buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64     Thu Jul 27 20:07:02 2006 -0400
+++ b/buildconfigs/linux-defconfig_xen_ia64     Mon Aug 07 18:00:22 2006 -0500
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.16.13-xen
-# Thu Jun 29 16:23:48 2006
+# Fri Jul 28 16:33:08 2006
 #
 
 #
@@ -92,6 +92,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_XEN=y
 CONFIG_XEN_IA64_DOM0_VP=y
+CONFIG_XEN_IA64_VDSO_PARAVIRT=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_IS_DMA32=y
 # CONFIG_IA64_GENERIC is not set
@@ -180,6 +181,8 @@ CONFIG_ACPI_CONTAINER=y
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+CONFIG_XEN_PCIDEV_FRONTEND=y
+# CONFIG_XEN_PCIDEV_FE_DEBUG is not set
 CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
@@ -1519,7 +1522,7 @@ CONFIG_XEN_NETDEV_BACKEND=y
 CONFIG_XEN_NETDEV_BACKEND=y
 CONFIG_XEN_NETDEV_FRONTEND=y
 # CONFIG_XEN_DEVMEM is not set
-# CONFIG_XEN_REBOOT is not set
+CONFIG_XEN_REBOOT=y
 # CONFIG_XEN_SMPBOOT is not set
 CONFIG_XEN_INTERFACE_VERSION=0x00030202
 
@@ -1529,13 +1532,16 @@ CONFIG_XEN_PRIVILEGED_GUEST=y
 CONFIG_XEN_PRIVILEGED_GUEST=y
 # CONFIG_XEN_UNPRIVILEGED_GUEST is not set
 CONFIG_XEN_PRIVCMD=y
+CONFIG_XEN_XENBUS_DEV=y
 CONFIG_XEN_BACKEND=y
-# CONFIG_XEN_PCIDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_BACKEND=y
-CONFIG_XEN_XENBUS_DEV=y
 # CONFIG_XEN_BLKDEV_TAP is not set
 # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
 CONFIG_XEN_NETDEV_LOOPBACK=y
+CONFIG_XEN_PCIDEV_BACKEND=y
+CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
+# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
+# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
 # CONFIG_XEN_TPMDEV_BACKEND is not set
 CONFIG_XEN_BLKDEV_FRONTEND=y
 # CONFIG_XEN_SCRUB_PAGES is not set
diff -r 61204c1d740e -r 87cefa5f7c5e docs/src/user.tex
--- a/docs/src/user.tex Thu Jul 27 20:07:02 2006 -0400
+++ b/docs/src/user.tex Mon Aug 07 18:00:22 2006 -0500
@@ -2059,6 +2059,988 @@ iptables:
 # this command disables all access to the Xen relocation port
 iptables -A INPUT -p tcp -{}-destination-port 8002 -j REJECT
 \end{verbatim}
+
+%% Chapter Xen Mandatory Access Control Framework
+\chapter{sHype/Xen Access Control}
+
+The Xen mandatory access control framework is an implementation of the
+sHype Hypervisor Security Architecture
+(www.research.ibm.com/ssd\_shype). It permits or denies communication
+and resource access of domains based on a security policy. The
+mandatory access controls are enforced in addition to the Xen core
+controls, such as memory protection.  They are designed to remain
+transparent during normal operation of domains (policy-conform
+behavior) but to intervene when domains move outside their intended
+sharing behavior.  This chapter will describe how the sHype access
+controls in Xen can be configured to prevent viruses from spilling
+over from one into another workload type and secrets from leaking from
+one workload type to another. sHype/Xen depends on the correct
+behavior of Domain0 (cf previous chapter).
+
+Benefits of configuring sHype/ACM in Xen include:
+\begin{itemize}
+\item robust workload and resource protection effective against rogue
+  user domains
+\item simple, platform- and operating system-independent security
+  policies (ideal for heterogeneous distributed environments)
+\item safety net with minimal performance overhead in case operating
+  system security is missing, does not scale, or fails
+\end{itemize}
+
+These benefits are very valuable because today's operating systems
+become increasingly complex and often have no or insufficient
+mandatory access controls.  (Discretionary access controls, supported
+by of most operating systems, are not effective against viruses or
+misbehaving programs.)  Where mandatory access control exists (e.g.,
+SELinux), they usually deploy complex and difficult to understand
+security policies.  Additionally, multi-tier applications in business
+environments usually require different types of operating systems
+(e.g., AIX, Windows, Linux) which cannot be configured with compatible
+security policies. Related distributed transactions and workloads
+cannot be easily protected on the OS level. The Xen access control
+framework steps in to offer a coarse-grained but very robust security
+layer and safety net in case operating system security fails or is
+missing.
+
+To control sharing between domains, Xen mediates all inter-domain
+communication (shared memory, events) as well as the access of domains
+to resources such as disks. Thus, Xen can confine distributed
+workloads (domain payloads) by permitting sharing among domains
+running the same type of workload and denying sharing between pairs of
+domains that run different workload types. We assume that--from a Xen
+perspective--only one workload type is running per user domain. To
+enable Xen to associate domains and resources with workload types,
+security labels including the workload types are attached to domains
+and resources. These labels and the hypervisor sHype controls cannot
+be manipulated or bypassed and are effective even against rogue
+domains.
+
+\section{Overview}
+This section gives an overview of how workloads can be protected using
+the sHype mandatory access control framework in Xen.
+Figure~\ref{fig:acmoverview} shows the necessary steps in activating
+the Xen workload protection. These steps are described in detail in
+Section~\ref{section:acmexample}.
+
+\begin{figure}
+\centering
+\includegraphics[width=13cm]{figs/acm_overview.eps}
+\caption{Overview of activating sHype workload protection in Xen.
+  Section numbers point to representative examples.}
+\label{fig:acmoverview}
+\end{figure}
+
+First, the sHype/ACM access control must be enabled in the Xen
+distribution and the distribution must be built and installed (cf
+Subsection~\ref{subsection:acmexampleconfigure}). Before we can
+enforce security, a Xen security policy must be created (cf
+Subsection~\ref{subsection:acmexamplecreate}) and deployed (cf
+Subsection~\ref{subsection:acmexampleinstall}).  This policy defines
+the workload types differentiated during access control. It also
+defines the rules that compare workload types of domains and resources
+to provide access decisions. Workload types are represented by
+security labels that can be attached to domains and resources (cf
+Subsections~\ref{subsection:acmexamplelabeldomains}
+and~\ref{subsection:acmexamplelabelresources}).  The functioning of
+the active sHype/Xen workload protection is demonstrated using simple
+resource assignment, and domain creation tests in
+Subsection~\ref{subsection:acmexampletest}.
+Section~\ref{section:acmpolicy} describes the syntax and semantics of
+the sHype/Xen security policy in detail and introduces briefly the
+tools that are available to help create valid security policies.
+
+The next section describes all the necessary steps to create, deploy,
+and test a simple workload protection policy. It is meant to enable
+anybody to quickly try out the sHype/Xen workload protection. Those
+readers who are interested in learning more about how the sHype access
+control in Xen works and how it is configured using the XML security
+policy should read Section~\ref{section:acmpolicy} as well.
+Section~\ref{section:acmlimitations} concludes this chapter with
+current limitations of the sHype implementation for Xen.
+
+\section{Xen Workload Protection Step-by-Step}
+\label{section:acmexample}
+
+What you are about to do consists of the following sequence:
+\begin{itemize}
+\item configure and install sHype/Xen
+\item create a simple workload protection security policy
+\item deploy the sHype/Xen security policy
+\item associate domains and resources with workload labels,
+\item test the workload protection
+\end{itemize}
+The essential commands to create and deploy a sHype/Xen security
+policy are numbered throughout the following sections. If you want a
+quick-guide or return at a later time to go quickly through this
+demonstration, simply look for the numbered commands and apply them in
+order.
+
+\subsection{Configuring/Building sHype Support into Xen}
+\label{subsection:acmexampleconfigure}
+First, we need to configure the access control module in Xen and
+install the ACM-enabled Xen hypervisor. This step installs security
+tools and compiles sHype/ACM controls into the Xen hypervisor.
+
+To enable sHype/ACM in Xen, please edit the Config.mk file in the top
+Xen directory.
+
+\begin{verbatim}
+  (1) In Config.mk
+        Change: ACM_SECURITY ?= n
+            To: ACM_SECURITY ?= y
+\end{verbatim}
+
+Then install the security-enabled Xen environment as follows:
+
+\begin{verbatim}
+  (2) # make world
+      # make install
+\end{verbatim}
+
+\subsection{Creating A WLP Policy in 3 Simple Steps with ezPolicy}
+\label{subsection:acmexamplecreate}
+
+We will use the ezPolicy tool to quickly create a policy that protects
+workloads.  You will need both the Python and wxPython packages to run
+this tool.  To run the tool in Domain0, you can download the wxPython
+package from www.wxpython.org or use the command
+\verb|yum install wxPython| in Redhat/Fedora. To run the tool on MS
+Windows, you also need to download the Python package from
+www.python.org. After these packages are installed, start the ezPolicy
+tool with the following command:
+
+\begin{verbatim}
+  (3) # xensec_ezpolicy
+\end{verbatim}
+
+Figure~\ref{fig:acmezpolicy} shows a screen-shot of the tool. The
+following steps show you how to create the policy shown in
+Figure~\ref{fig:acmezpolicy}.  You can use \verb|<CTRL>-h| to pop up a
+help window at any time. The indicators (a), (b), and (c) in
+Figure~\ref{fig:acmezpolicy} show the buttons that are used during the
+3 steps of creating a policy:
+\begin{enumerate}
+\item defining workloads
+\item defining run-time conflicts
+\item translating the workload definition into a sHype/Xen access
+  control policy
+\end{enumerate}
+
+\paragraph{Defining workloads.} Workloads are defined for each
+organization and department that you enter in the left panel. Please
+use the ``New Org'' button (a) to create the organizations ``Avis'',
+``Hertz'', ``CocaCola'', and ``PepsiCo''.
+
+You can refine an organization to differentiate between multiple
+department workloads by right-clicking the organization and selecting
+\verb|Add Department| (or selecting an organization and pressing
+\verb|<CRTL>-a|). Create department workloads ``Intranet'',
+``Extranet'', ``HumanResources'', and ``Payroll'' for the ``CocaCola''
+organization and department workloads ``Intranet'' and ``Extranet''
+for the ``PepsiCo'' organization. The resulting layout of the tool
+should be similar to the left panel shown in
+Figure~\ref{fig:acmezpolicy}.
+
+\paragraph{Defining run-time conflicts.} Workloads that shall be
+prohibited from running concurrently on the same hypervisor platform
+are grouped into ``Run-time Exclusion rules'' on the right panel of
+the window.
+
+To prevent PepsiCo and CocaCola workloads (including their
+departmental workloads) from running simultaneously on the same
+hypervisor system, select the organization ``PepsiCo'' and, while
+pressing the \verb|<CTRL>|-key, select the organization ``CocaCola''.
+Now press the button (b) named ``Create run-time exclusion rule from
+selection''. A popup window will ask for the name for this run-time
+exclusion rule (enter a name or just hit \verb|<ENTER>|). A rule will
+appear on the right panel. The name is used as reference only and does
+not affect the hypervisor policy.
+
+Repeat the process to create a run-time exclusion rule just for the
+department workloads CocaCola.Extranet and CocaCola.Payroll.
+
+\begin{figure}[htb]
+\centering
+\includegraphics[width=13cm]{figs/acm_ezpolicy.eps}
+\caption{Final layout including workload definition and Run-time Exclusion 
rules.}
+\label{fig:acmezpolicy}
+\end{figure}
+
+The resulting layout of your window should be similar to
+Figure~\ref{fig:acmezpolicy}. Save this workload definition by
+selecting ``Save Workload Definition as ...'' in the ``File'' menu
+(c).  This workload definition can be later refined if required.
+
+\paragraph{Translating the workload definition into a sHype/Xen access
+  control policy.} To translate the workload definition into a access
+control policy understood by Xen, please select the ``Save as Xen ACM
+Security Policy'' in the ``File'' menu (c). Enter the following policy
+name in the popup window: \verb|example.chwall_ste.test-wld|. If you
+are running ezPolicy in Domain0, the resulting policy file
+test-wld\_security-policy.xml will automatically be placed into the
+right directory (/etc/xen/acm-security/ policies/example/chwall\_ste).
+If you run the tool on another system, then you need to copy the
+resulting policy file into Domain0 before continuing.  See
+Section~\ref{subsection:acmnaming} for naming conventions of security
+policies.
+
+\subsection{Deploying a WLP Policy}
+\label{subsection:acmexampleinstall}
+To deploy the workload protection policy we created in
+Section~\ref{subsection:acmexamplecreate}, we create a policy
+representation (test-wld.bin) that can be loaded into the Xen
+hypervisor and we configure Xen to actually load this policy at
+startup time.
+
+The following command translates the source policy representation
+into a format that can be loaded into Xen with sHype/ACM support.
+Refer to the \verb|xm| man page for further details:
+
+\begin{verbatim}
+  (4) # xm makepolicy example.chwall_ste.test-wld
+\end{verbatim}
+
+The easiest way to install a security policy for Xen is to include the
+policy in the boot sequence. The following command does just this:
+
+\begin{verbatim}
+  (5) # xm cfgbootpolicy example.chwall_ste.test-wld
+\end{verbatim}
+
+\textit{Alternatively, if this command fails} (e.g., because it cannot
+identify the Xen boot entry), you can manually install the policy in 2
+steps.  First, manually copy the policy binary file into the boot
+directory:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # cp /etc/xen/acm-security/policies/example/chwall_ste/test-wld.bin \
+         /boot/example.chwall_ste.test-wld.bin
+\end{verbatim}
+\end{scriptsize}
+
+Second, manually add a module line to your Xen boot entry so that grub
+loads this policy file during startup:
+
+\begin{scriptsize}
+\begin{verbatim}
+         title Xen (2.6.16.13)
+                root (hd0,0)
+                kernel /xen.gz dom0_mem=2000000 console=vga
+                module /vmlinuz-2.6.16.13-xen ro root=/dev/hda3
+                module /initrd-2.6.16.13-xen.img
+                module /example.chwall_ste.test-wld.bin
+\end{verbatim}
+\end{scriptsize}
+
+Now reboot into this Xen boot entry to activate the policy and the
+security-enabled Xen hypervisor.
+
+\begin{verbatim}
+  (6) # reboot
+\end{verbatim}
+
+After reboot, check if security is enabled:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # xm list --label
+         Name        ID Mem(MiB) VCPUs State  Time(s)  Label
+         Domain-0     0     1949     4 r-----   163.9  SystemManagement
+\end{verbatim}
+\end{scriptsize}
+
+If the security label at the end of the line says ``INACTIV'' then the
+security is not enabled. Verify the previous steps. Note: Domain0 is
+assigned a default label (see \verb|bootstrap| policy attribute
+explained in Section~\ref{section:acmpolicy}). All other domains must
+be labeled in order to start on this sHype/ACM-enabled Xen hypervisor
+(see following sections for labeling domains and resources).
+
+\subsection{Labeling Domains}
+\label{subsection:acmexamplelabeldomains}
+You should have a Xen domain configuration file that looks like the
+following (Note: www.jailtime.org or www.xen-get.org might be good
+places to look for example domU images). The following configuration
+file defines \verb|domain1|:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # cat domain1.xm
+         kernel = "/boot/vmlinuz-2.6.16.13-xen"
+         memory = 128
+         name = "domain1"
+         vif = [ '' ]
+         dhcp = "dhcp"
+         disk = ['file:/home/xen/dom_fc5/fedora.fc5.img,sda1,w', \
+                 'file:/home/xen/dom_fc5/fedora.swap,sda2,w']
+         root = "/dev/sda1 ro"
+\end{verbatim}
+\end{scriptsize}
+
+If you try to start domain1, you will get the following error:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # xm create domain1.xm
+         Using config file "domain1.xm".
+         domain1: DENIED
+         --> Domain not labeled
+         Checking resources: (skipped)
+         Security configuration prevents domain from starting
+\end{verbatim}
+\end{scriptsize}
+
+Every domain must be associated with a security label before it can
+start on sHype/Xen. Otherwise, sHype/Xen would not be able to enforce
+the policy consistently. The following command prints all domain
+labels available in the active policy:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # xm labels type=dom
+         Avis
+         CocaCola
+         CocaCola.Extranet
+         CocaCola.HumanResources
+         CocaCola.Intranet
+         CocaCola.Payroll
+         Hertz
+         PepsiCo
+         PepsiCo.Extranet
+         PepsiCo.Intranet
+         SystemManagement
+\end{verbatim}
+\end{scriptsize}
+
+Now label domain1 with the CocaCola label and another domain2 with the
+PepsiCo.Extranet label. Please refer to the xm man page for further
+information.
+
+\begin{verbatim}
+  (7) # xm addlabel CocaCola dom domain1.xm
+      # xm addlabel PepsiCo.Extranet dom domain2.xm
+\end{verbatim}
+
+Let us try to start the domain again:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # xm create domain1.xm
+         Using config file "domain1.xm".
+            file:/home/xen/dom_fc5/fedora.fc5.img: DENIED
+            --> res:__NULL_LABEL__ (NULL)
+            --> dom:CocaCola (example.chwall_ste.test-wld)
+            file:/home/xen/dom_fc5/fedora.swap: DENIED
+            --> res:__NULL_LABEL__ (NULL)
+            --> dom:CocaCola (example.chwall_ste.test-wld)
+         Security configuration prevents domain from starting
+\end{verbatim}
+\end{scriptsize}
+
+This error indicates that domain1, if started, would not be able to
+access its image and swap files because they are not labeled.  This
+makes sense because to confine workloads, access of domains to
+resources must be controlled.  Otherwise, domains that are not allowed
+to communicate or run simultaneously could share data through storage
+resources.
+
+\subsection{Labeling Resources}
+\label{subsection:acmexamplelabelresources}
+You can use the \verb|xm labels type=res| command to list available
+resource labels. Let us assign the CocaCola resource label to the domain1
+image file representing \verb|/dev/sda1| and to its swap file:
+
+\begin{verbatim}
+  (8) # xm addlabel CocaCola res \
+           file:/home/xen/dom_fc5/fedora.fc5.img
+      Resource file not found, creating new file at:
+      /etc/xen/acm-security/policies/resource_labels
+      # xm addlabel CocaCola res \
+           file:/home/xen/dom_fc5/fedora.swap
+\end{verbatim}
+
+Starting \verb|domain1| now will succeed:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # xm create domain1.xm
+         # xm list --label
+         Name           ID Mem(MiB) VCPUs State  Time(s)  Label
+         domain1         1      128     1 r-----     2.8  CocaCola
+         Domain-0        0     1949     4 r-----   387.7  SystemManagement
+\end{verbatim}
+\end{scriptsize}
+
+The following command lists all labeled resources on the
+system, e.g., to lookup or verify the labeling:
+
+\begin{scriptsize}
+\begin{verbatim}
+         # xm resources
+         file:/home/xen/dom_fc5/fedora.swap
+             policy: example.chwall_ste.test-wld
+             label:  CocaCola
+         file:/home/xen/dom_fc5/fedora.fc5.img
+             policy: example.chwall_ste.test-wld
+             label:  CocaCola
+\end{verbatim}
+\end{scriptsize}
+
+Currently, if a labeled resource is moved to another location, the
+label must first be manually removed, and after the move re-attached
+using the xm commands \verb|xm rmlabel| and \verb|xm addlabel|
+respectively.  Please see Section~\ref{section:acmlimitations} for
+further details.
+
+\begin{verbatim}
+  (9) Label the resources of domain2 as PepsiCo.Extranet
+      Do not try to start this domain yet
+\end{verbatim}
+
+\subsection{Testing The Xen Workload Protection}
+\label{subsection:acmexampletest}
+We are about to demonstrate how the workload protection works by
+verifying:
+\begin{itemize}
+\item that domains with conflicting workloads cannot run
+  simultaneously
+\item that domains cannot access resources of other workloads
+\item that domains cannot exchange network packets if they are not
+  associated with the same workload type
+\end{itemize}
+
+\paragraph{Test 1: Run-time exclusion rules.} We assume that domain1
+with the CocaCola label is still running. While domain1 is running,
+the run-time exclusion set of our policy says that domain2 cannot
+start because the label of domain1 includes the CHWALL type CocaCola
+and the label of domain2 includes the CHWALL type PepsiCo. The
+run-time exclusion rule of our policy enforces that PepsiCo and
+CocaCola cannot run at the same time on the same hypervisor platform.
+Once domain1 is stopped or saved, domain2 can start but domain1 can no
+longer start or be resumed. The ezPolicy tool, when creating the
+Chinese Wall types for the workload labels, ensures that department
+workloads inherit the organization type (and with it any organization
+exclusions).
+
+\begin{scriptsize}
+\begin{verbatim}
+# xm list --label
+Name           ID Mem(MiB) VCPUs State  Time(s)  Label
+domain1         2      128     1 -b----     6.9  CocaCola
+Domain-0        0     1949     4 r-----   273.1  SystemManagement
+
+# xm create domain2.xm
+Using config file "domain2.xm".
+Error: (1, 'Operation not permitted')
+
+# xm destroy domain1
+# xm create domain2.xm
+Using config file "domain2.xm".
+Started domain domain2
+
+# xm list --label
+Name           ID Mem(MiB) VCPUs State  Time(s)  Label
+domain2         4      164     1 r-----     4.3  PepsiCo.Extranet
+Domain-0        0     1949     4 r-----   298.4  SystemManagement
+
+# xm create domain1.xm
+Using config file "domain1.xm".
+Error: (1, 'Operation not permitted')
+
+# xm destroy domain2
+# xm list
+Name           ID Mem(MiB) VCPUs State  Time(s)
+Domain-0        0     1949     4 r-----   391.2
+\end{verbatim}
+\end{scriptsize}
+
+You can verify that domains with Avis label can run together with
+domains labeled CocaCola, PepsiCo, or Hertz.
+
+\paragraph{Test2: Resource access.} In this test, we will re-label the
+swap file for domain1 with the Avis resource label. We expect that
+Domain1 will no longer start because it cannot access this resource.
+This test checks the sharing abilities of domains, which are defined
+by the Simple Type Enforcement Policy component.
+
+\begin{scriptsize}
+\begin{verbatim}
+# xm rmlabel res file:/home/xen/dom_fc5/fedora.swap
+# xm addlabel Avis res file:/home/xen/dom_fc5/fedora.swap
+# xm resources
+file:/home/xen/dom_fc5/fedora.swap
+    policy: example.chwall_ste.test-wld
+    label:  Avis
+file:/home/xen/dom_fc5/fedora.fc5.img
+    policy: example.chwall_ste.test-wld
+    label:  CocaCola
+
+# xm create domain1.xm
+Using config file "domain1.xm".
+   file:/home/xen/dom_fc4/fedora.swap: DENIED
+   --> res:Avis (example.chwall_ste.test-wld)
+   --> dom:CocaCola (example.chwall_ste.test-wld)
+Security configuration prevents domain from starting
+\end{verbatim}
+\end{scriptsize}
+
+\paragraph{Test 3: Communication.} In this test we would verify that
+two domains with labels Hertz and Avis cannot exchange network packets
+by using the 'ping' connectivity test. It is also related to the STE
+policy.{\bf Note:} sHype/Xen does control direct communication between
+domains. However, domains associated with different workloads can
+currently still communicate through the Domain0 virtual network. We
+are working on the sHype/ACM controls for local and remote network
+traffic through Domain0.  Please monitor the xen-devel mailing list
+for updated information.
+
+\section{Xen Access Control Policy}
+\label{section:acmpolicy}
+
+This section describes the sHype/Xen access control policy in detail.
+It gives enough information to enable the reader to write custom
+access control policies and to use the available Xen policy tools. The
+policy language is expressive enough to specify most symmetric access
+relationships between domains and resources efficiently.
+
+The Xen access control policy consists of two policy components. The
+first component, called Chinese Wall (CHWALL) policy, controls which
+domains can run simultaneously on the same virtualized platform. The
+second component, called Simple Type Enforcement (STE) policy,
+controls the sharing between running domains, i.e., communication or
+access to shared resources. The CHWALL and STE policy components can
+be configured to run alone, however in our examples we will assume
+that both policy components are configured together since they
+complement each other. The XML policy file includes all information
+needed by Xen to enforce the policies.
+
+Figures~\ref{fig:acmxmlfilea} and \ref{fig:acmxmlfileb} show a fully
+functional but very simple example policy for Xen. The policy can
+distinguish two workload types \verb|CocaCola| and \verb|PepsiCo| and
+defines the labels necessary to associate domains and resources with
+one of these workload types. The XML Policy consists of four parts:
+\begin{enumerate}
+\item policy header including the policy name
+\item Simple Type Enforcement block
+\item Chinese Wall Policy block
+\item label definition block
+\end{enumerate}
+
+\begin{figure}
+\begin{scriptsize}
+\begin{verbatim}
+01 <?xml version="1.0" encoding="UTF-8"?>
+02 <!-- Auto-generated by ezPolicy        -->
+03 <SecurityPolicyDefinition
+      xmlns="http://www.ibm.com";
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+      xsi:schemaLocation=
+          "http://www.ibm.com ../../security_policy.xsd ">
+04     <PolicyHeader>
+05         <PolicyName>example.chwall_ste.test</PolicyName>
+06         <Date>Wed Jul 12 17:32:59 2006</Date>
+07     </PolicyHeader>
+08
+09     <SimpleTypeEnforcement>
+10         <SimpleTypeEnforcementTypes>
+11             <Type>SystemManagement</Type>
+12             <Type>PepsiCo</Type>
+13             <Type>CocaCola</Type>
+14         </SimpleTypeEnforcementTypes>
+15     </SimpleTypeEnforcement>
+16
+17     <ChineseWall priority="PrimaryPolicyComponent">
+18         <ChineseWallTypes>
+19             <Type>SystemManagement</Type>
+20             <Type>PepsiCo</Type>
+21             <Type>CocaCola</Type>
+22         </ChineseWallTypes>
+23
+24         <ConflictSets>
+25             <Conflict name="RER1">
+26                 <Type>CocaCola</Type>
+27                 <Type>PepsiCo</Type>
+28             </Conflict>
+29        </ConflictSets>
+30     </ChineseWall>
+31
+\end{verbatim}
+\end{scriptsize}
+\caption{Example XML security policy file -- Part I: Types and Rules 
Definition.}
+\label{fig:acmxmlfilea}
+\end{figure}
+
+\subsection{Policy Header and Policy Name}
+\label{subsection:acmnaming}
+Lines 1-2 (cf Figure~\ref{fig:acmxmlfilea}) include the usual XML
+header. The security policy definition starts in Line 3 and refers to
+the policy schema. The XML-Schema definition for the Xen policy can be
+found in the file
+\textit{/etc/xen/acm-security/policies/security-policy.xsd}. Examples
+for security policies can be found in the example subdirectory. The
+acm-security directory is only installed if ACM security is configured
+during installation (cf Section~\ref{subsection:acmexampleconfigure}).
+
+The \verb|Policy Header| spans lines 4-7. It includes a date field and
+defines the policy name \verb|example.chwall_ste.test|. It can also
+include optional fields that are not shown and are for future use (see
+schema definition).
+
+The policy name serves two purposes: First, it provides a unique name
+for the security policy. This name is also exported by the Xen
+hypervisor to the Xen management tools in order to ensure that both
+enforce the same policy. We plan to extend the policy name with a
+digital fingerprint of the policy contents to better protect this
+correlation.  Second, it implicitly points the xm tools to the
+location where the XML policy file is stored on the Xen system.
+Replacing the colons in the policy name by slashes yields the local
+path to the policy file starting from the global policy directory
+\verb|/etc/xen/acm-security/policies|. The last part of the policy
+name is the prefix for the XML policy file name, completed by
+\verb|-security_policy.xml|. Consequently, the policy with the name
+\verb|example.chwall_ste.test| can be found in the XML policy file
+named \verb|test-security_policy.xml| that is stored in the local
+directory \verb|example/chwall_ste| under the global policy directory.
+
+\subsection{Simple Type Enforcement Policy Component}
+
+The Simple Type Enforcement (STE) policy controls which domains can
+communicate or share resources. This way, Xen can enforce confinement
+of workload types by confining the domains running those workload
+types. The mandatory access control framework enforces its policy when
+domains access intended ways of communication or cooperation (shared
+memory, events, shared resources such as block devices). It builds on
+top of the core hypervisor isolation, which restricts the ways of
+inter-communication to those intended means.  STE does not protect or
+intend to protect from covert channels in the hypervisor or hardware;
+this is an orthogonal problem that can be mitigated by using the
+Run-time Exclusion rules described above or by fixing the problem in
+the core hypervisor.
+
+Xen controls sharing between domains on the resource and domain level
+because this is the abstraction the hypervisor and its management
+understand naturally. While this is coarse-grained, it is also very
+reliable and robust and it requires minimal changes to implement
+mandatory access controls in the hypervisor. It enables platform- and
+operation system-independent policies as part of a layered security
+approach.
+
+Lines 9-15 (cf Figure~\ref{fig:acmxmlfilea}) define the Simple Type
+Enforcement policy component.  Essentially, they define the workload
+type names \verb|SystemManagement|, \verb|PepsiCo|, and
+\verb|CocaCola| that are available in the STE policy component. The
+policy rules are implicit: Xen permits a domain to communicate with
+another domain if and only if the labels of the domains share an
+common STE type.  Xen permits a domain to access a resource if and
+only if the labels of the domain and the resource share a common STE
+workload type.
+
+\subsection{Chinese Wall Policy Component}
+
+The Chinese Wall security policy interpretation of sHype enables users
+to prevent certain workloads from running simultaneously on the same
+hypervisor platform.  Run-time Exclusion rules (RER), also called
+Conflict Sets, define a set of workload types that are not permitted
+to run simultaneously. Of all the workloads specified in a Run-time
+Exclusion rule, at most one type can run on the same hypervisor
+platform at a time.  Run-time Exclusion Rules implement a less
+rigorous variant of the original Chinese Wall security component. They
+do not implement the *-property of the policy, which would require to
+restrict also types that are not part of an exclusion rule once they
+are running together with a type in an exclusion rule (please refer to
+http://www.gammassl.co.uk/topics/chinesewall.html for more information
+on the original Chinese Wall policy).
+
+Xen considers the \verb|ChineseWallTypes| part of the label for the
+enforcement of the Run-time Exclusion rules.  It is illegal to define
+labels including conflicting Chinese Wall types.
+
+Lines 17-30 (cf Figure~\ref{fig:acmxmlfilea}) define the Chinese Wall
+policy component. Lines 17-22 define the known Chinese Wall types,
+which coincide here with the STE types defined above. This usually
+holds if the criteria for sharing among domains and sharing of the
+hardware platform are the same. Lines 24-29 define one Run-time
+Exclusion rule:
+
+\begin{scriptsize}
+\begin{verbatim}
+        <Conflict name="RER1">
+          <Type>CocaCola</Type>
+          <Type>PepsiCo</Type>
+        </Conflict>
+\end{verbatim}
+\end{scriptsize}
+
+Based on this rule, Xen enforces that only one of the types
+\verb|CocaCola| or \verb|PepsiCo| will run on a single hypervisor
+platform at a time. For example, once a domain assigned a
+\verb|CocaCola| workload type is started, domains with the
+\verb|PepsiCo| type will be denied to start. When the former domain
+stops and no other domains with the \verb|CocaCola| type are running,
+then domains with the \verb|PepsiCo| type can start.
+
+Xen maintains reference counts on each running workload type to keep
+track of which workload types are running. Every time a domain starts
+or resumes, the reference count on those Chinese Wall types that are
+referenced in the domain's label are incremented. Every time a domain
+is destroyed or saved, the reference counts of its Chinese Wall types
+are decremented. sHype in Xen covers migration and live-migration,
+which is treated the same way as saving a domain on the source
+platform and resuming it on the destination platform.
+
+Reasons why users would want to restrict which workloads or domains
+can share the system hardware include:
+
+\begin{itemize}
+\item Imperfect resource management or control might enable a rogue
+  domain to starve another domain and the workload running in it.
+\item Redundant domains might run the same workload to increase
+  availability; such domains should not run on the same hardware to
+  avoid single points of failure.
+\item Imperfect Xen core domain isolation might enable two rogue
+  domains running different workload types to use unintended and
+  unknown ways (covert channels) to exchange some data. This way, they
+  bypass the policed Xen access control mechanisms.  Such
+  imperfections cannot be completely eliminated and are a result of
+  trade-offs between security and other design requirements. For a
+  simple example of a covert channel see
+  http://www.multicians.org/timing-chn.html. Such covert channels
+  exist also between workloads running on different platforms if they
+  are connected through networks. The Xen Chinese Wall policy provides
+  an approximation of this imperfect ``air-gap'' between selected
+  workload types.
+\end{itemize}
+
+\subsection{Security Labels}
+
+To enable Xen to associate domains with workload types running in
+them, each domain is assigned a security label that includes the
+workload types of the domain.
+
+\begin{figure}
+\begin{scriptsize}
+\begin{verbatim}
+32     <SecurityLabelTemplate>
+33         <SubjectLabels bootstrap="SystemManagement">
+34             <VirtualMachineLabel>
+35                 <Name>SystemManagement</Name>
+36                 <SimpleTypeEnforcementTypes>
+37                     <Type>SystemManagement</Type>
+38                     <Type>PepsiCo</Type>
+39                     <Type>CocaCola</Type>
+40                 </SimpleTypeEnforcementTypes>
+41                 <ChineseWallTypes>
+42                     <Type>SystemManagement</Type>
+43                 </ChineseWallTypes>
+44             </VirtualMachineLabel>
+45
+46             <VirtualMachineLabel>
+47                 <Name>PepsiCo</Name>
+48                 <SimpleTypeEnforcementTypes>
+49                     <Type>PepsiCo</Type>
+50                 </SimpleTypeEnforcementTypes>
+51                 <ChineseWallTypes>
+52                     <Type>PepsiCo</Type>
+53                 </ChineseWallTypes>
+54             </VirtualMachineLabel>
+55
+56             <VirtualMachineLabel>
+57                 <Name>CocaCola</Name>
+58                 <SimpleTypeEnforcementTypes>
+59                     <Type>CocaCola</Type>
+60                 </SimpleTypeEnforcementTypes>
+61                 <ChineseWallTypes>
+62                     <Type>CocaCola</Type>
+63                 </ChineseWallTypes>
+64             </VirtualMachineLabel>
+65         </SubjectLabels>
+66
+67         <ObjectLabels>
+68             <ResourceLabel>
+69                 <Name>SystemManagement</Name>
+70                 <SimpleTypeEnforcementTypes>
+71                     <Type>SystemManagement</Type>
+72                 </SimpleTypeEnforcementTypes>
+73             </ResourceLabel>
+74
+75             <ResourceLabel>
+76                 <Name>PepsiCo</Name>
+77                 <SimpleTypeEnforcementTypes>
+78                     <Type>PepsiCo</Type>
+79                 </SimpleTypeEnforcementTypes>
+80             </ResourceLabel>
+81
+82             <ResourceLabel>
+83                 <Name>CocaCola</Name>
+84                 <SimpleTypeEnforcementTypes>
+85                     <Type>CocaCola</Type>
+86                 </SimpleTypeEnforcementTypes>
+87             </ResourceLabel>
+88         </ObjectLabels>
+89     </SecurityLabelTemplate>
+90  </SecurityPolicyDefinition>
+\end{verbatim}
+\end{scriptsize}
+\caption{Example XML security policy file -- Part II: Label Definition.}
+\label{fig:acmxmlfileb}
+\end{figure}
+
+Lines 32-89 (cf Figure~\ref{fig:acmxmlfileb}) define the
+\verb|SecurityLabelTemplate|, which includes the labels that can be
+attached to domains and resources when this policy is active. The
+domain labels include Chinese Wall types while resource labels do not
+include Chinese Wall types. Lines 33-65 define the
+\verb|SubjectLabels| that can be assigned to domains. For example, the
+virtual machine label \verb|CocaCola| (cf lines 56-64 in
+Figure~\ref{fig:acmxmlfileb}) associates the domain that carries it
+with the workload type \verb|CocaCola|.
+
+The \verb|bootstrap| attribute names the label
+\verb|SystemManagement|.  Xen will assign this label to Domain0 at
+boot time. All other domains are assigned labels according to their
+domain configuration file (see
+Section~\ref{subsection:acmexamplelabeldomains} for examples of how to
+label domains). Lines 67-88 define the \verb|ObjectLabels|. Those
+labels can be assigned to resources when this policy is active.
+
+In general, user domains should be assigned labels that have only a
+single SimpleTypeEnforcement workload type. This way, workloads remain
+confined even if user domains become rogue. Any domain that is
+assigned a label with multiple STE types must be trusted to keep
+information belonging to the different STE types separate (confined).
+For example, Domain0 is assigned the bootstrap label
+\verb|SystemsManagement|, which includes all existing STE types.
+Therefore, Domain0 must take care not to enable unauthorized
+information flow (eg. through block devices or virtual networking)
+between domains or resources that are assigned different STE types.
+
+Security administrators simply use the name of a label (specified in
+the \verb|<Name>| field) to associate a label with a domain (cf.
+Section~\ref{subsection:acmexamplelabeldomains}). The types inside the
+label are used by the Xen access control enforcement.  While the name
+can be arbitrarily chosen (as long as it is unique), it is advisable
+to choose the label name in accordance to the security types included.
+While the XML representation in the above label seems unnecessary
+flexible, labels in general can consist of multiple types as we will
+see in the following example.
+
+Assume that \verb|PepsiCo| and \verb|CocaCola| workloads use virtual
+disks that are provided by a virtual I/O domain hosting a physical
+storage device and carrying the following label:
+
+\begin{scriptsize}
+\begin{verbatim}
+        <VirtualMachineLabel>
+          <Name>VIO</Name>
+          <SimpleTypeEnforcementTypes>
+              <Type>CocaCola</Type>
+              <Type>PepsiCo</Type>
+          </SimpleTypeEnforcementTypes>
+          <ChineseWallTypes>
+              <Type>VIOServer</Type>
+          </ChineseWallTypes>
+        </VirtualMachineLabel>
+\end{verbatim}
+\end{scriptsize}
+
+This Virtual I/O domain (VIO) exports its virtualized disks by
+communicating both to domains labeled with the \verb|PepsiCo| label
+and domains labeled with the \verb|CocaCola| label. This requires the
+VIO domain to carry both the STE types \verb|CocaCola| and
+\verb|PepsiCo|. In this example, the confinement of \verb|CocaCola|
+and \verb|PepsiCo| workload depends on a VIO domain that must keep the
+data of those different workloads separate. The virtual disks are
+labeled as well (see Section~\ref{subsection:acmexamplelabelresources}
+for labeling resources) and enforcement functions inside the VIO
+domain must ensure that the labels of the domain mounting a virtual
+disk and the virtual disk label share a common STE type. The VIO label
+carrying its own VIOServer CHWALL type introduces the flexibility to
+permit the trusted VIO server to run together with CocaCola or PepsiCo
+workloads.
+
+Alternatively, a system that has two hard-drives does not need a VIO
+domain but can directly assign one hardware storage device to each of
+the workloads (if the platform offers an IO-MMU, cf
+Section~\ref{s:ddsecurity}.  Sharing hardware through virtualization
+is a trade-off between the amount of trusted code (size of the trusted
+computing base) and the amount of acceptable over-provisioning. This
+holds both for peripherals and for system platforms.
+
+\subsection{Tools For Creating sHype/Xen Security Policies}
+To create a security policy for Xen, you can use one of the following
+tools:
+\begin{itemize}
+\item \verb|ezPolicy| GUI tool -- start writing policies
+\item \verb|xensec_gen| tool -- refine policies created with \verb|ezPolicy|
+\item text or XML editor
+\end{itemize}
+
+We use the \verb|ezPolicy| tool in
+Section~\ref{subsection:acmexamplecreate} to quickly create a workload
+protection policy. If desired, the resulting XML policy file can be
+loaded into the \verb|xensec_gen| tool to refine it. It can also be
+directly edited using an XML editor. Any XML policy file is verified
+against the security policy schema when it is translated (see
+Subsection~\ref{subsection:acmexampleinstall}).
+
+\section{Current Limitations}
+\label{section:acmlimitations}
+
+The sHype/ACM configuration for Xen is work in progress. There is
+ongoing work for protecting virtualized resources and planned and
+ongoing work for protecting access to remote resources and domains.
+The following sections describe limitations of some of the areas into
+which access control is being extended.
+
+\subsection{Network Traffic}
+Local and remote network traffic is currently not controlled.
+Solutions to add sHype/ACM policy enforcement to the virtual network
+exist but need to be discussed before they can become part of Xen.
+Subjecting external network traffic to the ACM security policy is work
+in progress. Manually setting up filters in domain 0 is required for
+now but does not scale well.
+
+\subsection{Resource Access and Usage Control}
+
+Enforcing the security policy across multiple hypervisor systems and
+on access to remote shared resources is work in progress. Extending
+access control to new types of resources is ongoing work (e.g. network
+storage).
+
+On a single Xen system, information about the association of resources
+and security labels is stored in
+\verb|/etc/xen/acm-security/policy/resource_labels|. This file relates
+a full resource path with a security label. This association is weak
+and will break if resources are moved or renamed without adapting the
+label file. Improving the protection of label-resource relationships
+is ongoing work.
+
+Controlling resource usage and enforcing resource limits in general is
+ongoing work in the Xen community.
+
+\subsection{Domain Migration}
+
+Labels on domains are enforced during domain migration and the
+destination hypervisor will ensure that the domain label is valid and
+the domain is permitted to run (considering the Chinese Wall policy
+rules) before it accepts the migration.  However, the network between
+the source and destination hypervisor as well as both hypervisors must
+be trusted. Architectures and prototypes exist that both protect the
+network connection and ensure that the hypervisors enforce access
+control consistently but patches are not yet available for the main
+stream.
+
+\subsection{Covert Channels}
+
+The sHype access control aims at system independent security policies.
+It builds on top of the core hypervisor isolation. Any covert channels
+that exist in the core hypervisor or in the hardware (e.g., shared
+processor cache) will be inherited. If those covert channels are not
+the result of trade-offs between security and other system properties,
+then they are most effectively minimized or eliminated where they are
+caused. sHype offers however some means to mitigate their impact
+(cf. run-time exclusion rules).
 
 \part{Reference}
 
@@ -2188,7 +3170,7 @@ editing \path{grub.conf}.
 \item [ tbuf\_size=xxx ] Set the size of the per-cpu trace buffers, in
   pages (default 0).  
 \item [ sched=xxx ] Select the CPU scheduler Xen should use.  The
-  current possibilities are `sedf' (default), `credit', and `bvt'.
+  current possibilities are `credit' (default), `sedf', and `bvt'.
 \item [ apic\_verbosity=debug,verbose ] Print more detailed
   information about local APIC and IOAPIC configuration.
 \item [ lapic ] Force use of local APIC even when left disabled by
diff -r 61204c1d740e -r 87cefa5f7c5e extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/extras/mini-os/console/xencons_ring.c     Mon Aug 07 18:00:22 2006 -0500
@@ -53,7 +53,7 @@ int xencons_ring_send(const char *data, 
 
 
 
-static void handle_input(int port, struct pt_regs *regs, void *ign)
+static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
 {
        struct xencons_interface *intf = xencons_interface();
        XENCONS_RING_IDX cons, prod;
diff -r 61204c1d740e -r 87cefa5f7c5e extras/mini-os/events.c
--- a/extras/mini-os/events.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/extras/mini-os/events.c   Mon Aug 07 18:00:22 2006 -0500
@@ -26,20 +26,20 @@
 
 /* this represents a event handler. Chaining or sharing is not allowed */
 typedef struct _ev_action_t {
-       void (*handler)(int, struct pt_regs *, void *);
+       evtchn_handler_t handler;
        void *data;
     u32 count;
 } ev_action_t;
 
 
 static ev_action_t ev_actions[NR_EVS];
-void default_handler(int port, struct pt_regs *regs, void *data);
+void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
 
 
 /*
  * Demux events to different handlers.
  */
-int do_event(u32 port, struct pt_regs *regs)
+int do_event(evtchn_port_t port, struct pt_regs *regs)
 {
     ev_action_t  *action;
     if (port >= NR_EVS) {
@@ -60,8 +60,8 @@ int do_event(u32 port, struct pt_regs *r
 
 }
 
-int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *, void *),
-                                void *data )
+evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
+                                                 void *data)
 {
        if(ev_actions[port].handler != default_handler)
         printk("WARN: Handler for port %d already registered, replacing\n",
@@ -77,7 +77,7 @@ int bind_evtchn( u32 port, void (*handle
        return port;
 }
 
-void unbind_evtchn( u32 port )
+void unbind_evtchn(evtchn_port_t port )
 {
        if (ev_actions[port].handler == default_handler)
                printk("WARN: No handler for port %d when unbinding\n", port);
@@ -86,8 +86,7 @@ void unbind_evtchn( u32 port )
        ev_actions[port].data = NULL;
 }
 
-int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
-                          void *data)
+int bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
 {
        evtchn_op_t op;
 
@@ -103,11 +102,6 @@ int bind_virq( u32 virq, void (*handler)
     }
     bind_evtchn(op.u.bind_virq.port, handler, data);
        return 0;
-}
-
-void unbind_virq( u32 port )
-{
-       unbind_evtchn(port);
 }
 
 #if defined(__x86_64__)
@@ -142,32 +136,48 @@ void init_events(void)
     }
 }
 
-void default_handler(int port, struct pt_regs *regs, void *ignore)
+void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
 {
     printk("[Port %d] - event received\n", port);
 }
 
+/* Create a port available to the pal for exchanging notifications.
+   Returns the result of the hypervisor call. */
+
 /* Unfortunate confusion of terminology: the port is unbound as far
    as Xen is concerned, but we automatically bind a handler to it
    from inside mini-os. */
-int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
-                                                                               
 void *data),
-                                                void *data)
+
+int evtchn_alloc_unbound(domid_t pal, evtchn_handler_t handler,
+                                                void *data, evtchn_port_t 
*port)
 {
-       u32 port;
-       evtchn_op_t op;
-       int err;
+    evtchn_op_t op;
+    op.cmd = EVTCHNOP_alloc_unbound;
+    op.u.alloc_unbound.dom = DOMID_SELF;
+    op.u.alloc_unbound.remote_dom = pal;
+    int err = HYPERVISOR_event_channel_op(&op);
+    if (err)
+               return err;
+    *port = bind_evtchn(op.u.alloc_unbound.port, handler, data);
+    return err;
+}
 
-       op.cmd = EVTCHNOP_alloc_unbound;
-       op.u.alloc_unbound.dom = DOMID_SELF;
-       op.u.alloc_unbound.remote_dom = 0;
+/* Connect to a port so as to allow the exchange of notifications with
+   the pal. Returns the result of the hypervisor call. */
 
-       err = HYPERVISOR_event_channel_op(&op);
-       if (err) {
-               printk("Failed to alloc unbound evtchn: %d.\n", err);
-               return -1;
-       }
-       port = op.u.alloc_unbound.port;
-       bind_evtchn(port, handler, data);
-       return port;
+int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
+                           evtchn_handler_t handler, void *data,
+                           evtchn_port_t *local_port)
+{
+    evtchn_op_t op;
+    op.cmd = EVTCHNOP_bind_interdomain;
+    op.u.bind_interdomain.remote_dom = pal;
+    op.u.bind_interdomain.remote_port = remote_port;
+    int err = HYPERVISOR_event_channel_op(&op);
+    if (err)
+               return err;
+       evtchn_port_t port = op.u.bind_interdomain.local_port;
+    clear_evtchn(port);              /* Without, handler gets invoked now! */
+    *local_port = bind_evtchn(port, handler, data);
+    return err;
 }
diff -r 61204c1d740e -r 87cefa5f7c5e extras/mini-os/gnttab.c
--- a/extras/mini-os/gnttab.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/extras/mini-os/gnttab.c   Mon Aug 07 18:00:22 2006 -0500
@@ -137,6 +137,18 @@ gnttab_alloc_and_grant(void **map)
     return gref;
 }
 
+static const char *gnttabop_error_msgs[] = GNTTABOP_error_msgs;
+
+const char *
+gnttabop_error(int16_t status)
+{
+    status = -status;
+    if (status < 0 || status >= ARRAY_SIZE(gnttabop_error_msgs))
+       return "bad status";
+    else
+        return gnttabop_error_msgs[status];
+}
+
 void
 init_gnttab(void)
 {
diff -r 61204c1d740e -r 87cefa5f7c5e extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h   Thu Jul 27 20:07:02 2006 -0400
+++ b/extras/mini-os/include/events.h   Mon Aug 07 18:00:22 2006 -0500
@@ -22,20 +22,22 @@
 #include<traps.h>
 #include <xen/event_channel.h>
 
+typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *);
+
 /* prototypes */
-int do_event(u32 port, struct pt_regs *regs);
-int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
-                          void *data);
-int bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *, void *data),
-                                void *data );
-void unbind_evtchn( u32 port );
+int do_event(evtchn_port_t port, struct pt_regs *regs);
+int bind_virq(uint32_t virq, evtchn_handler_t handler, void *data);
+evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
+                                                 void *data);
+void unbind_evtchn(evtchn_port_t port);
 void init_events(void);
-void unbind_virq( u32 port );
-int evtchn_alloc_unbound(void (*handler)(int, struct pt_regs *regs,
-                                                                               
 void *data),
-                                                void *data);
+int evtchn_alloc_unbound(domid_t pal, evtchn_handler_t handler,
+                                                void *data, evtchn_port_t 
*port);
+int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
+                                                       evtchn_handler_t 
handler, void *data,
+                                                       evtchn_port_t 
*local_port);
 
-static inline int notify_remote_via_evtchn(int port)
+static inline int notify_remote_via_evtchn(evtchn_port_t port)
 {
     evtchn_op_t op;
     op.cmd = EVTCHNOP_send;
diff -r 61204c1d740e -r 87cefa5f7c5e extras/mini-os/include/gnttab.h
--- a/extras/mini-os/include/gnttab.h   Thu Jul 27 20:07:02 2006 -0400
+++ b/extras/mini-os/include/gnttab.h   Mon Aug 07 18:00:22 2006 -0500
@@ -10,5 +10,6 @@ grant_ref_t gnttab_grant_transfer(domid_
 grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn);
 unsigned long gnttab_end_transfer(grant_ref_t gref);
 int gnttab_end_access(grant_ref_t ref);
+const char *gnttabop_error(int16_t status);
 
 #endif /* !__GNTTAB_H__ */
diff -r 61204c1d740e -r 87cefa5f7c5e extras/mini-os/time.c
--- a/extras/mini-os/time.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/extras/mini-os/time.c     Mon Aug 07 18:00:22 2006 -0500
@@ -215,7 +215,7 @@ void block_domain(u32 millisecs)
 /*
  * Just a dummy 
  */
-static void timer_handler(int ev, struct pt_regs *regs, void *ign)
+static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign)
 {
     static int i;
 
diff -r 61204c1d740e -r 87cefa5f7c5e extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Thu Jul 27 20:07:02 2006 -0400
+++ b/extras/mini-os/xenbus/xenbus.c    Mon Aug 07 18:00:22 2006 -0500
@@ -112,7 +112,8 @@ static void xenbus_thread_func(void *ign
     }
 }
 
-static void xenbus_evtchn_handler(int port, struct pt_regs *regs, void *ign)
+static void xenbus_evtchn_handler(evtchn_port_t port, struct pt_regs *regs,
+                                 void *ign)
 {
     wake_up(&xb_waitq);
 }
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c   Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c   Mon Aug 07 18:00:22 
2006 -0500
@@ -109,6 +109,7 @@ int init_new_context(struct task_struct 
 
        init_MUTEX(&mm->context.sem);
        mm->context.size = 0;
+       mm->context.has_foreign_mappings = 0;
        old_mm = current->mm;
        if (old_mm && old_mm->context.size > 0) {
                down(&old_mm->context.sem);
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Mon Aug 07 18:00:22 
2006 -0500
@@ -126,6 +126,8 @@ int direct_remap_pfn_range(struct vm_are
        if (domid == DOMID_SELF)
                return -EINVAL;
 
+       vma->vm_mm->context.has_foreign_mappings = 1;
+
        return __direct_remap_pfn_range(
                vma->vm_mm, address, mfn, size, prot, domid);
 }
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Mon Aug 07 18:00:22 
2006 -0500
@@ -694,6 +694,7 @@ void _arch_exit_mmap(struct mm_struct *m
        task_unlock(tsk);
 
        if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) &&
-           (atomic_read(&mm->mm_count) == 1))
+           (atomic_read(&mm->mm_count) == 1) &&
+           !mm->context.has_foreign_mappings)
                mm_unpin(mm);
 }
diff -r 61204c1d740e -r 87cefa5f7c5e linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Thu Jul 27 20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Mon Aug 07 18:00:22 2006 -0500
@@ -438,6 +438,21 @@ config PCI_DOMAINS
        bool
        default PCI
 
+config XEN_PCIDEV_FRONTEND
+       bool "Xen PCI Frontend"
+       depends on PCI && XEN
+       default y
+       help
+         The PCI device frontend driver allows the kernel to import arbitrary
+         PCI devices from a PCI backend to support PCI driver domains.
+
+config XEN_PCIDEV_FE_DEBUG
+       bool "Xen PCI Frontend Debugging"
+       depends on XEN_PCIDEV_FRONTEND
+       default n
+       help
+         Enables some debug statements within the PCI Frontend.
+
 source "drivers/pci/Kconfig"
 
 source "drivers/pci/hotplug/Kconfig"
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c        Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c        Mon Aug 07 
18:00:22 2006 -0500
@@ -159,7 +159,8 @@ void _arch_exit_mmap(struct mm_struct *m
 
     task_unlock(tsk);
 
-    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) )
+    if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
+         !mm->context.has_foreign_mappings )
         mm_unpin(mm);
 }
 
diff -r 61204c1d740e -r 87cefa5f7c5e linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig  Thu Jul 27 20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig  Mon Aug 07 18:00:22 2006 -0500
@@ -143,15 +143,6 @@ config XEN_TPMDEV_BACKEND
        help
          The TPM-device backend driver
 
-config XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
-       bool "TPM backend closes upon vTPM failure"
-       depends on XEN_TPMDEV_BACKEND
-       default n
-       help
-         The TPM backend closes the channel if the vTPM in userspace indicates
-         a failure. The corresponding domain's channel will be closed.
-         Say Y if you want this feature.
-
 config XEN_BLKDEV_FRONTEND
        tristate "Block-device frontend driver"
        depends on XEN
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Mon Aug 07 18:00:22 
2006 -0500
@@ -76,6 +76,10 @@ typedef struct netif_st {
        struct vm_struct *tx_comms_area;
        struct vm_struct *rx_comms_area;
 
+       /* Set of features that can be turned on in dev->features. */
+       int features;
+       int can_queue;
+
        /* Allow netif_be_start_xmit() to peek ahead in the rx request ring. */
        RING_IDX rx_req_cons_peek;
 
@@ -86,8 +90,6 @@ typedef struct netif_st {
        struct timer_list credit_timeout;
 
        /* Miscellaneous private stuff. */
-       enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
-       int active;
        struct list_head list;  /* scheduling list */
        atomic_t         refcnt;
        struct net_device *dev;
@@ -121,4 +123,16 @@ struct net_device_stats *netif_be_get_st
 struct net_device_stats *netif_be_get_stats(struct net_device *dev);
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 
+static inline int netbk_can_queue(struct net_device *dev)
+{
+       netif_t *netif = netdev_priv(dev);
+       return netif->can_queue;
+}
+
+static inline int netbk_can_sg(struct net_device *dev)
+{
+       netif_t *netif = netdev_priv(dev);
+       return netif->features & NETIF_F_SG;
+}
+
 #endif /* __NETIF__BACKEND__COMMON_H__ */
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Mon Aug 07 
18:00:22 2006 -0500
@@ -36,46 +36,74 @@
 
 static void __netif_up(netif_t *netif)
 {
-       struct net_device *dev = netif->dev;
-       netif_tx_lock_bh(dev);
-       netif->active = 1;
-       netif_tx_unlock_bh(dev);
        enable_irq(netif->irq);
        netif_schedule_work(netif);
 }
 
 static void __netif_down(netif_t *netif)
 {
-       struct net_device *dev = netif->dev;
        disable_irq(netif->irq);
-       netif_tx_lock_bh(dev);
-       netif->active = 0;
-       netif_tx_unlock_bh(dev);
        netif_deschedule_work(netif);
 }
 
 static int net_open(struct net_device *dev)
 {
        netif_t *netif = netdev_priv(dev);
-       if (netif->status == CONNECTED)
+       if (netif_carrier_ok(dev))
                __netif_up(netif);
-       netif_start_queue(dev);
        return 0;
 }
 
 static int net_close(struct net_device *dev)
 {
        netif_t *netif = netdev_priv(dev);
-       netif_stop_queue(dev);
-       if (netif->status == CONNECTED)
+       if (netif_carrier_ok(dev))
                __netif_down(netif);
        return 0;
+}
+
+static int netbk_change_mtu(struct net_device *dev, int mtu)
+{
+       int max = netbk_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN;
+
+       if (mtu > max)
+               return -EINVAL;
+       dev->mtu = mtu;
+       return 0;
+}
+
+static int netbk_set_sg(struct net_device *dev, u32 data)
+{
+       if (data) {
+               netif_t *netif = netdev_priv(dev);
+
+               if (!(netif->features & NETIF_F_SG))
+                       return -ENOSYS;
+       }
+
+       return ethtool_op_set_sg(dev, data);
+}
+
+static int netbk_set_tso(struct net_device *dev, u32 data)
+{
+       if (data) {
+               netif_t *netif = netdev_priv(dev);
+
+               if (!(netif->features & NETIF_F_TSO))
+                       return -ENOSYS;
+       }
+
+       return ethtool_op_set_tso(dev, data);
 }
 
 static struct ethtool_ops network_ethtool_ops =
 {
        .get_tx_csum = ethtool_op_get_tx_csum,
        .set_tx_csum = ethtool_op_set_tx_csum,
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = netbk_set_sg,
+       .get_tso = ethtool_op_get_tso,
+       .set_tso = netbk_set_tso,
        .get_link = ethtool_op_get_link,
 };
 
@@ -93,11 +121,12 @@ netif_t *netif_alloc(domid_t domid, unsi
                return ERR_PTR(-ENOMEM);
        }
 
+       netif_carrier_off(dev);
+
        netif = netdev_priv(dev);
        memset(netif, 0, sizeof(*netif));
        netif->domid  = domid;
        netif->handle = handle;
-       netif->status = DISCONNECTED;
        atomic_set(&netif->refcnt, 1);
        init_waitqueue_head(&netif->waiting_to_free);
        netif->dev = dev;
@@ -110,12 +139,16 @@ netif_t *netif_alloc(domid_t domid, unsi
        dev->get_stats       = netif_be_get_stats;
        dev->open            = net_open;
        dev->stop            = net_close;
+       dev->change_mtu      = netbk_change_mtu;
        dev->features        = NETIF_F_IP_CSUM;
 
        SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
 
-       /* Disable queuing. */
-       dev->tx_queue_len = 0;
+       /*
+        * Reduce default TX queuelen so that each guest interface only
+        * allows it to eat around 6.4MB of host memory.
+        */
+       dev->tx_queue_len = 100;
 
        for (i = 0; i < ETH_ALEN; i++)
                if (be_mac[i] != 0)
@@ -256,11 +289,9 @@ int netif_map(netif_t *netif, unsigned l
        netif->rx_req_cons_peek = 0;
 
        netif_get(netif);
-       wmb(); /* Other CPUs see new state before interface is started. */
 
        rtnl_lock();
-       netif->status = CONNECTED;
-       wmb();
+       netif_carrier_on(netif->dev);
        if (netif_running(netif->dev))
                __netif_up(netif);
        rtnl_unlock();
@@ -296,20 +327,13 @@ static void netif_free(netif_t *netif)
 
 void netif_disconnect(netif_t *netif)
 {
-       switch (netif->status) {
-       case CONNECTED:
+       if (netif_carrier_ok(netif->dev)) {
                rtnl_lock();
-               netif->status = DISCONNECTING;
-               wmb();
+               netif_carrier_off(netif->dev);
                if (netif_running(netif->dev))
                        __netif_down(netif);
                rtnl_unlock();
                netif_put(netif);
-               /* fall through */
-       case DISCONNECTED:
-               netif_free(netif);
-               break;
-       default:
-               BUG();
-       }
-}
+       }
+       netif_free(netif);
+}
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Mon Aug 07 
18:00:22 2006 -0500
@@ -40,17 +40,22 @@
 
 /*#define NETBE_DEBUG_INTERRUPT*/
 
+struct netbk_rx_meta {
+       skb_frag_t frag;
+       int id;
+};
+
 static void netif_idx_release(u16 pending_idx);
 static void netif_page_release(struct page *page);
 static void make_tx_response(netif_t *netif, 
                             netif_tx_request_t *txp,
                             s8       st);
-static int  make_rx_response(netif_t *netif, 
-                            u16      id, 
-                            s8       st,
-                            u16      offset,
-                            u16      size,
-                            u16      flags);
+static netif_rx_response_t *make_rx_response(netif_t *netif, 
+                                            u16      id, 
+                                            s8       st,
+                                            u16      offset,
+                                            u16      size,
+                                            u16      flags);
 
 static void net_tx_action(unsigned long unused);
 static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0);
@@ -100,21 +105,27 @@ static unsigned long mfn_list[MAX_MFN_AL
 static unsigned long mfn_list[MAX_MFN_ALLOC];
 static unsigned int alloc_index = 0;
 
-static unsigned long alloc_mfn(void)
-{
-       unsigned long mfn = 0;
+static inline unsigned long alloc_mfn(void)
+{
+       return mfn_list[--alloc_index];
+}
+
+static int check_mfn(int nr)
+{
        struct xen_memory_reservation reservation = {
-               .nr_extents   = MAX_MFN_ALLOC,
                .extent_order = 0,
                .domid        = DOMID_SELF
        };
-       set_xen_guest_handle(reservation.extent_start, mfn_list);
-       if ( unlikely(alloc_index == 0) )
-               alloc_index = HYPERVISOR_memory_op(
-                       XENMEM_increase_reservation, &reservation);
-       if ( alloc_index != 0 )
-               mfn = mfn_list[--alloc_index];
-       return mfn;
+
+       if (likely(alloc_index >= nr))
+               return 0;
+
+       set_xen_guest_handle(reservation.extent_start, mfn_list + alloc_index);
+       reservation.nr_extents = MAX_MFN_ALLOC - alloc_index;
+       alloc_index += HYPERVISOR_memory_op(XENMEM_increase_reservation,
+                                           &reservation);
+
+       return alloc_index >= nr ? 0 : -ENOMEM;
 }
 
 static inline void maybe_schedule_tx_action(void)
@@ -136,6 +147,96 @@ static inline int is_xen_skb(struct sk_b
        return (cp == skbuff_cachep);
 }
 
+static struct sk_buff *netbk_copy_skb(struct sk_buff *skb)
+{
+       struct skb_shared_info *ninfo;
+       struct sk_buff *nskb;
+       unsigned long offset;
+       int ret;
+       int len;
+       int headlen;
+
+       nskb = alloc_skb(SKB_MAX_HEAD(0), GFP_ATOMIC);
+       if (unlikely(!nskb))
+               goto err;
+
+       skb_reserve(nskb, 16);
+       headlen = nskb->end - nskb->data;
+       if (headlen > skb_headlen(skb))
+               headlen = skb_headlen(skb);
+       ret = skb_copy_bits(skb, 0, __skb_put(nskb, headlen), headlen);
+       BUG_ON(ret);
+
+       ninfo = skb_shinfo(nskb);
+       ninfo->gso_size = skb_shinfo(skb)->gso_size;
+       ninfo->gso_type = skb_shinfo(skb)->gso_type;
+
+       offset = headlen;
+       len = skb->len - headlen;
+
+       nskb->len = skb->len;
+       nskb->data_len = len;
+       nskb->truesize += len;
+
+       while (len) {
+               struct page *page;
+               int copy;
+               int zero;
+
+               if (unlikely(ninfo->nr_frags >= MAX_SKB_FRAGS)) {
+                       dump_stack();
+                       goto err_free;
+               }
+
+               copy = len >= PAGE_SIZE ? PAGE_SIZE : len;
+               zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO;
+
+               page = alloc_page(GFP_ATOMIC | zero);
+               if (unlikely(!page))
+                       goto err_free;
+
+               ret = skb_copy_bits(skb, offset, page_address(page), copy);
+               BUG_ON(ret);
+
+               ninfo->frags[ninfo->nr_frags].page = page;
+               ninfo->frags[ninfo->nr_frags].page_offset = 0;
+               ninfo->frags[ninfo->nr_frags].size = copy;
+               ninfo->nr_frags++;
+
+               offset += copy;
+               len -= copy;
+       }
+
+       offset = nskb->data - skb->data;
+
+       nskb->h.raw = skb->h.raw + offset;
+       nskb->nh.raw = skb->nh.raw + offset;
+       nskb->mac.raw = skb->mac.raw + offset;
+
+       return nskb;
+
+ err_free:
+       kfree_skb(nskb);
+ err:
+       return NULL;
+}
+
+static inline int netbk_max_required_rx_slots(netif_t *netif)
+{
+       if (netif->features & (NETIF_F_SG|NETIF_F_TSO))
+               return MAX_SKB_FRAGS + 2; /* header + extra_info + frags */
+       return 1; /* all in one */
+}
+
+static inline int netbk_queue_full(netif_t *netif)
+{
+       RING_IDX peek   = netif->rx_req_cons_peek;
+       RING_IDX needed = netbk_max_required_rx_slots(netif);
+
+       return ((netif->rx.sring->req_prod - peek) < needed) ||
+              ((netif->rx.rsp_prod_pvt + NET_RX_RING_SIZE - peek) < needed);
+}
+
 int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        netif_t *netif = netdev_priv(dev);
@@ -143,30 +244,26 @@ int netif_be_start_xmit(struct sk_buff *
        BUG_ON(skb->dev != dev);
 
        /* Drop the packet if the target domain has no receive buffers. */
-       if (!netif->active || 
-           (netif->rx_req_cons_peek == netif->rx.sring->req_prod) ||
-           ((netif->rx_req_cons_peek - netif->rx.rsp_prod_pvt) ==
-            NET_RX_RING_SIZE))
+       if (unlikely(!netif_running(dev) || !netif_carrier_ok(dev)))
                goto drop;
+
+       if (unlikely(netbk_queue_full(netif))) {
+               /* Not a BUG_ON() -- misbehaving netfront can trigger this. */
+               if (netbk_can_queue(dev))
+                       DPRINTK("Queue full but not stopped!\n");
+               goto drop;
+       }
 
        /*
         * We do not copy the packet unless:
         *  1. The data is shared; or
         *  2. The data is not allocated from our special cache.
-        * NB. We also couldn't cope with fragmented packets, but we won't get
-        *     any because we not advertise the NETIF_F_SG feature.
+        *  3. The data is fragmented.
         */
-       if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) {
-               int hlen = skb->data - skb->head;
-               int ret;
-               struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len);
+       if (skb_cloned(skb) || skb_is_nonlinear(skb) || !is_xen_skb(skb)) {
+               struct sk_buff *nskb = netbk_copy_skb(skb);
                if ( unlikely(nskb == NULL) )
                        goto drop;
-               skb_reserve(nskb, hlen);
-               __skb_put(nskb, skb->len);
-               ret = skb_copy_bits(skb, -hlen, nskb->data - hlen,
-                                    skb->len + hlen);
-               BUG_ON(ret);
                /* Copy only the header fields we use in this driver. */
                nskb->dev = skb->dev;
                nskb->ip_summed = skb->ip_summed;
@@ -175,8 +272,17 @@ int netif_be_start_xmit(struct sk_buff *
                skb = nskb;
        }
 
-       netif->rx_req_cons_peek++;
+       netif->rx_req_cons_peek += skb_shinfo(skb)->nr_frags + 1 +
+                                  !!skb_shinfo(skb)->gso_size;
        netif_get(netif);
+
+       if (netbk_can_queue(dev) && netbk_queue_full(netif)) {
+               netif->rx.sring->req_event = netif->rx_req_cons_peek +
+                       netbk_max_required_rx_slots(netif);
+               mb(); /* request notification /then/ check & stop the queue */
+               if (netbk_queue_full(netif))
+                       netif_stop_queue(dev);
+       }
 
        skb_queue_tail(&rx_queue, skb);
        tasklet_schedule(&net_rx_tasklet);
@@ -208,116 +314,85 @@ int xen_network_done(void)
 }
 #endif
 
-static void net_rx_action(unsigned long unused)
-{
-       netif_t *netif = NULL; 
-       s8 status;
-       u16 size, id, irq, flags;
-       multicall_entry_t *mcl;
-       mmu_update_t *mmu;
-       gnttab_transfer_t *gop;
-       unsigned long vdata, old_mfn, new_mfn;
-       struct sk_buff_head rxq;
-       struct sk_buff *skb;
-       int notify_nr = 0;
-       int ret;
+static u16 netbk_gop_frag(netif_t *netif, struct page *page, int count, int i)
+{
+       multicall_entry_t *mcl = rx_mcl + count;
+       mmu_update_t *mmu = rx_mmu + count;
+       gnttab_transfer_t *gop = grant_rx_op + count;
+       netif_rx_request_t *req;
+       unsigned long old_mfn, new_mfn;
+
+       old_mfn = virt_to_mfn(page_address(page));
+
+       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               new_mfn = alloc_mfn();
+
+               /*
+                * Set the new P2M table entry before reassigning
+                * the old data page. Heed the comment in
+                * pgtable-2level.h:pte_page(). :-)
+                */
+               set_phys_to_machine(page_to_pfn(page), new_mfn);
+
+               MULTI_update_va_mapping(mcl, (unsigned long)page_address(page),
+                                       pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
+
+               mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
+                       MMU_MACHPHYS_UPDATE;
+               mmu->val = page_to_pfn(page);
+       }
+
+       req = RING_GET_REQUEST(&netif->rx, netif->rx.req_cons + i);
+       gop->mfn = old_mfn;
+       gop->domid = netif->domid;
+       gop->ref = req->gref;
+       return req->id;
+}
+
+static void netbk_gop_skb(struct sk_buff *skb, struct netbk_rx_meta *meta,
+                         int count)
+{
+       netif_t *netif = netdev_priv(skb->dev);
+       int nr_frags = skb_shinfo(skb)->nr_frags;
+       int i;
+       int extra;
+
+       meta[count].frag.page_offset = skb_shinfo(skb)->gso_type;
+       meta[count].frag.size = skb_shinfo(skb)->gso_size;
+       extra = !!meta[count].frag.size + 1;
+
+       for (i = 0; i < nr_frags; i++) {
+               meta[++count].frag = skb_shinfo(skb)->frags[i];
+               meta[count].id = netbk_gop_frag(netif, meta[count].frag.page,
+                                               count, i + extra);
+       }
+
        /*
-        * Putting hundreds of bytes on the stack is considered rude.
-        * Static works because a tasklet can only be on one CPU at any time.
+        * This must occur at the end to ensure that we don't trash
+        * skb_shinfo until we're done.
         */
-       static u16 notify_list[NET_RX_RING_SIZE];
-
-       skb_queue_head_init(&rxq);
-
-       mcl = rx_mcl;
-       mmu = rx_mmu;
-       gop = grant_rx_op;
-
-       while ((skb = skb_dequeue(&rx_queue)) != NULL) {
-               netif   = netdev_priv(skb->dev);
-               vdata   = (unsigned long)skb->data;
-               old_mfn = virt_to_mfn(vdata);
-
-               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-                       /* Memory squeeze? Back off for an arbitrary while. */
-                       if ((new_mfn = alloc_mfn()) == 0) {
-                               if ( net_ratelimit() )
-                                       WPRINTK("Memory squeeze in netback "
-                                               "driver.\n");
-                               mod_timer(&net_timer, jiffies + HZ);
-                               skb_queue_head(&rx_queue, skb);
-                               break;
-                       }
-                       /*
-                        * Set the new P2M table entry before reassigning
-                        * the old data page. Heed the comment in
-                        * pgtable-2level.h:pte_page(). :-)
-                        */
-                       set_phys_to_machine(
-                               __pa(skb->data) >> PAGE_SHIFT,
-                               new_mfn);
-
-                       MULTI_update_va_mapping(mcl, vdata,
-                                               pfn_pte_ma(new_mfn,
-                                                          PAGE_KERNEL), 0);
-                       mcl++;
-
-                       mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
-                               MMU_MACHPHYS_UPDATE;
-                       mmu->val = __pa(vdata) >> PAGE_SHIFT;
-                       mmu++;
-               }
-
-               gop->mfn = old_mfn;
-               gop->domid = netif->domid;
-               gop->ref = RING_GET_REQUEST(
-                       &netif->rx, netif->rx.req_cons)->gref;
-               netif->rx.req_cons++;
-               gop++;
-
-               __skb_queue_tail(&rxq, skb);
-
-               /* Filled the batch queue? */
-               if ((gop - grant_rx_op) == ARRAY_SIZE(grant_rx_op))
-                       break;
-       }
-
-       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-               if (mcl == rx_mcl)
-                       return;
-
-               mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-
-               if (mmu - rx_mmu) {
-                       mcl->op = __HYPERVISOR_mmu_update;
-                       mcl->args[0] = (unsigned long)rx_mmu;
-                       mcl->args[1] = mmu - rx_mmu;
-                       mcl->args[2] = 0;
-                       mcl->args[3] = DOMID_SELF;
-                       mcl++;
-               }
-
-               ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
-               BUG_ON(ret != 0);
-       }
-
-       ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, 
-                                       gop - grant_rx_op);
-       BUG_ON(ret != 0);
-
-       mcl = rx_mcl;
-       gop = grant_rx_op;
-       while ((skb = __skb_dequeue(&rxq)) != NULL) {
-               netif   = netdev_priv(skb->dev);
-               size    = skb->tail - skb->data;
-
-               atomic_set(&(skb_shinfo(skb)->dataref), 1);
-               skb_shinfo(skb)->nr_frags = 0;
-               skb_shinfo(skb)->frag_list = NULL;
-
-               netif->stats.tx_bytes += size;
-               netif->stats.tx_packets++;
-
+       meta[count - nr_frags].id = netbk_gop_frag(netif,
+                                                  virt_to_page(skb->data),
+                                                  count - nr_frags, 0);
+       netif->rx.req_cons += nr_frags + extra;
+}
+
+static inline void netbk_free_pages(int nr_frags, struct netbk_rx_meta *meta)
+{
+       int i;
+
+       for (i = 0; i < nr_frags; i++)
+               put_page(meta[i].frag.page);
+}
+
+static int netbk_check_gop(int nr_frags, domid_t domid, int count)
+{
+       multicall_entry_t *mcl = rx_mcl + count;
+       gnttab_transfer_t *gop = grant_rx_op + count;
+       int status = NETIF_RSP_OKAY;
+       int i;
+
+       for (i = 0; i <= nr_frags; i++) {
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* The update_va_mapping() must not fail. */
                        BUG_ON(mcl->result != 0);
@@ -325,10 +400,9 @@ static void net_rx_action(unsigned long 
                }
 
                /* Check the reassignment error code. */
-               status = NETIF_RSP_OKAY;
                if (gop->status != 0) { 
                        DPRINTK("Bad status %d from grant transfer to DOM%u\n",
-                               gop->status, netif->domid);
+                               gop->status, domid);
                        /*
                         * Page no longer belongs to us unless GNTST_bad_page,
                         * but that should be a fatal error anyway.
@@ -336,24 +410,166 @@ static void net_rx_action(unsigned long 
                        BUG_ON(gop->status == GNTST_bad_page);
                        status = NETIF_RSP_ERROR; 
                }
-               irq = netif->irq;
-               id = RING_GET_REQUEST(&netif->rx, netif->rx.rsp_prod_pvt)->id;
-               flags = 0;
+               gop++;
+       }
+
+       return status;
+}
+
+static void netbk_add_frag_responses(netif_t *netif, int status,
+                                    struct netbk_rx_meta *meta, int nr_frags)
+{
+       int i;
+
+       for (i = 0; i < nr_frags; i++) {
+               int id = meta[i].id;
+               int flags = (i == nr_frags - 1) ? 0 : NETRXF_more_data;
+
+               make_rx_response(netif, id, status, meta[i].frag.page_offset,
+                                meta[i].frag.size, flags);
+       }
+}
+
+static void net_rx_action(unsigned long unused)
+{
+       netif_t *netif = NULL; 
+       s8 status;
+       u16 id, irq, flags;
+       netif_rx_response_t *resp;
+       struct netif_extra_info *extra;
+       multicall_entry_t *mcl;
+       struct sk_buff_head rxq;
+       struct sk_buff *skb;
+       int notify_nr = 0;
+       int ret;
+       int nr_frags;
+       int count;
+
+       /*
+        * Putting hundreds of bytes on the stack is considered rude.
+        * Static works because a tasklet can only be on one CPU at any time.
+        */
+       static u16 notify_list[NET_RX_RING_SIZE];
+       static struct netbk_rx_meta meta[NET_RX_RING_SIZE];
+
+       skb_queue_head_init(&rxq);
+
+       count = 0;
+
+       while ((skb = skb_dequeue(&rx_queue)) != NULL) {
+               nr_frags = skb_shinfo(skb)->nr_frags;
+               *(int *)skb->cb = nr_frags;
+
+               if (!xen_feature(XENFEAT_auto_translated_physmap) &&
+                   check_mfn(nr_frags + 1)) {
+                       /* Memory squeeze? Back off for an arbitrary while. */
+                       if ( net_ratelimit() )
+                               WPRINTK("Memory squeeze in netback "
+                                       "driver.\n");
+                       mod_timer(&net_timer, jiffies + HZ);
+                       skb_queue_head(&rx_queue, skb);
+                       break;
+               }
+
+               netbk_gop_skb(skb, meta, count);
+
+               count += nr_frags + 1;
+
+               __skb_queue_tail(&rxq, skb);
+
+               /* Filled the batch queue? */
+               if (count + MAX_SKB_FRAGS >= NET_RX_RING_SIZE)
+                       break;
+       }
+
+       if (!count)
+               return;
+
+       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               mcl = rx_mcl + count;
+
+               mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+
+               mcl->op = __HYPERVISOR_mmu_update;
+               mcl->args[0] = (unsigned long)rx_mmu;
+               mcl->args[1] = count;
+               mcl->args[2] = 0;
+               mcl->args[3] = DOMID_SELF;
+
+               ret = HYPERVISOR_multicall(rx_mcl, count + 1);
+               BUG_ON(ret != 0);
+       }
+
+       ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, count);
+       BUG_ON(ret != 0);
+
+       count = 0;
+       while ((skb = __skb_dequeue(&rxq)) != NULL) {
+               nr_frags = *(int *)skb->cb;
+
+               atomic_set(&(skb_shinfo(skb)->dataref), 1);
+               skb_shinfo(skb)->nr_frags = 0;
+               skb_shinfo(skb)->frag_list = NULL;
+
+               netif = netdev_priv(skb->dev);
+               netif->stats.tx_bytes += skb->len;
+               netif->stats.tx_packets++;
+
+               netbk_free_pages(nr_frags, meta + count + 1);
+               status = netbk_check_gop(nr_frags, netif->domid, count);
+
+               id = meta[count].id;
+               flags = nr_frags ? NETRXF_more_data : 0;
+
                if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
                        flags |= NETRXF_csum_blank | NETRXF_data_validated;
                else if (skb->proto_data_valid) /* remote but checksummed? */
                        flags |= NETRXF_data_validated;
-               if (make_rx_response(netif, id, status,
-                                    (unsigned long)skb->data & ~PAGE_MASK,
-                                    size, flags) &&
-                   (rx_notify[irq] == 0)) {
+
+               resp = make_rx_response(netif, id, status,
+                                       offset_in_page(skb->data),
+                                       skb_headlen(skb), flags);
+
+               extra = NULL;
+
+               if (meta[count].frag.size) {
+                       struct netif_extra_info *gso =
+                               (struct netif_extra_info *)
+                               RING_GET_RESPONSE(&netif->rx,
+                                                 netif->rx.rsp_prod_pvt++);
+
+                       if (extra)
+                               extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE;
+                       else
+                               resp->flags |= NETRXF_extra_info;
+
+                       gso->u.gso.size = meta[count].frag.size;
+                       gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
+                       gso->u.gso.pad = 0;
+                       gso->u.gso.features = 0;
+
+                       gso->type = XEN_NETIF_EXTRA_TYPE_GSO;
+                       gso->flags = 0;
+                       extra = gso;
+               }
+
+               netbk_add_frag_responses(netif, status, meta + count + 1,
+                                        nr_frags);
+
+               RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, ret);
+               irq = netif->irq;
+               if (ret && !rx_notify[irq]) {
                        rx_notify[irq] = 1;
                        notify_list[notify_nr++] = irq;
                }
 
+               if (netif_queue_stopped(netif->dev) &&
+                   !netbk_queue_full(netif))
+                       netif_wake_queue(netif->dev);
+
                netif_put(netif);
                dev_kfree_skb(skb);
-               gop++;
+               count += nr_frags + 1;
        }
 
        while (notify_nr != 0) {
@@ -404,7 +620,9 @@ static void add_to_net_schedule_list_tai
                return;
 
        spin_lock_irq(&net_schedule_list_lock);
-       if (!__on_net_schedule_list(netif) && netif->active) {
+       if (!__on_net_schedule_list(netif) &&
+           likely(netif_running(netif->dev) &&
+                  netif_carrier_ok(netif->dev))) {
                list_add_tail(&netif->list, &net_schedule_list);
                netif_get(netif);
        }
@@ -972,8 +1190,13 @@ irqreturn_t netif_be_int(int irq, void *
 irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
 {
        netif_t *netif = dev_id;
+
        add_to_net_schedule_list_tail(netif);
        maybe_schedule_tx_action();
+
+       if (netif_queue_stopped(netif->dev) && !netbk_queue_full(netif))
+               netif_wake_queue(netif->dev);
+
        return IRQ_HANDLED;
 }
 
@@ -1007,16 +1230,15 @@ static void make_tx_response(netif_t *ne
 #endif
 }
 
-static int make_rx_response(netif_t *netif, 
-                           u16      id, 
-                           s8       st,
-                           u16      offset,
-                           u16      size,
-                           u16      flags)
+static netif_rx_response_t *make_rx_response(netif_t *netif, 
+                                            u16      id, 
+                                            s8       st,
+                                            u16      offset,
+                                            u16      size,
+                                            u16      flags)
 {
        RING_IDX i = netif->rx.rsp_prod_pvt;
        netif_rx_response_t *resp;
-       int notify;
 
        resp = RING_GET_RESPONSE(&netif->rx, i);
        resp->offset     = offset;
@@ -1027,9 +1249,8 @@ static int make_rx_response(netif_t *net
                resp->status = (s16)st;
 
        netif->rx.rsp_prod_pvt = ++i;
-       RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, notify);
-
-       return notify;
+
+       return resp;
 }
 
 #ifdef NETBE_DEBUG_INTERRUPT
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Mon Aug 07 18:00:22 
2006 -0500
@@ -101,14 +101,12 @@ static int netback_probe(struct xenbus_d
                        goto abort_transaction;
                }
 
-#if 0 /* KAF: After the protocol is finalised. */
                err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
                                    "%d", 1);
                if (err) {
                        message = "writing feature-gso-tcpv4";
                        goto abort_transaction;
                }
-#endif
 
                err = xenbus_transaction_end(xbt, 0);
        } while (err == -EAGAIN);
@@ -353,6 +351,7 @@ static int connect_rings(struct backend_
        unsigned long tx_ring_ref, rx_ring_ref;
        unsigned int evtchn;
        int err;
+       int val;
 
        DPRINTK("");
 
@@ -365,6 +364,30 @@ static int connect_rings(struct backend_
                                 "reading %s/ring-ref and event-channel",
                                 dev->otherend);
                return err;
+       }
+
+       if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-notify", "%d",
+                        &val) < 0)
+               val = 0;
+       if (val)
+               be->netif->can_queue = 1;
+       else
+               /* Must be non-zero for pfifo_fast to work. */
+               be->netif->dev->tx_queue_len = 1;
+
+       if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0)
+               val = 0;
+       if (val) {
+               be->netif->features |= NETIF_F_SG;
+               be->netif->dev->features |= NETIF_F_SG;
+       }
+
+       if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-gso-tcpv4", "%d",
+                        &val) < 0)
+               val = 0;
+       if (val) {
+               be->netif->features |= NETIF_F_TSO;
+               be->netif->dev->features |= NETIF_F_TSO;
        }
 
        /* Map the shared frame, irq etc. */
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Mon Aug 07 
18:00:22 2006 -0500
@@ -46,11 +46,11 @@
 #include <linux/ethtool.h>
 #include <linux/in.h>
 #include <linux/if_ether.h>
+#include <linux/io.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <net/arp.h>
 #include <net/route.h>
-#include <asm/io.h>
 #include <asm/uaccess.h>
 #include <xen/evtchn.h>
 #include <xen/xenbus.h>
@@ -62,17 +62,12 @@
 #include <xen/interface/grant_table.h>
 #include <xen/gnttab.h>
 
+#define RX_COPY_THRESHOLD 256
+
 #define GRANT_INVALID_REF      0
 
 #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
-
-static inline void init_skb_shinfo(struct sk_buff *skb)
-{
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags = 0;
-       skb_shinfo(skb)->frag_list = NULL;
-}
 
 struct netfront_info {
        struct list_head list;
@@ -99,17 +94,17 @@ struct netfront_info {
        struct timer_list rx_refill_timer;
 
        /*
-        * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
-        * array is an index into a chain of free entries.
+        * {tx,rx}_skbs store outstanding skbuffs. The first entry in tx_skbs
+        * is an index into a chain of free entries.
         */
        struct sk_buff *tx_skbs[NET_TX_RING_SIZE+1];
-       struct sk_buff *rx_skbs[NET_RX_RING_SIZE+1];
+       struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
 
 #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
        grant_ref_t gref_tx_head;
        grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
        grant_ref_t gref_rx_head;
-       grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1];
+       grant_ref_t grant_rx_ref[NET_TX_RING_SIZE];
 
        struct xenbus_device *xbdev;
        int tx_ring_ref;
@@ -121,8 +116,13 @@ struct netfront_info {
        struct mmu_update rx_mmu[NET_RX_RING_SIZE];
 };
 
+struct netfront_rx_info {
+       struct netif_rx_response rx;
+       struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
+};
+
 /*
- * Access macros for acquiring freeing slots in {tx,rx}_skbs[].
+ * Access macros for acquiring freeing slots in tx_skbs[].
  */
 
 static inline void add_id_to_freelist(struct sk_buff **list, unsigned short id)
@@ -136,6 +136,29 @@ static inline unsigned short get_id_from
        unsigned int id = (unsigned int)(unsigned long)list[0];
        list[0] = list[id];
        return id;
+}
+
+static inline int xennet_rxidx(RING_IDX idx)
+{
+       return idx & (NET_RX_RING_SIZE - 1);
+}
+
+static inline struct sk_buff *xennet_get_rx_skb(struct netfront_info *np,
+                                               RING_IDX ri)
+{
+       int i = xennet_rxidx(ri);
+       struct sk_buff *skb = np->rx_skbs[i];
+       np->rx_skbs[i] = NULL;
+       return skb;
+}
+
+static inline grant_ref_t xennet_get_rx_ref(struct netfront_info *np,
+                                           RING_IDX ri)
+{
+       int i = xennet_rxidx(ri);
+       grant_ref_t ref = np->grant_rx_ref[i];
+       np->grant_rx_ref[i] = GRANT_INVALID_REF;
+       return ref;
 }
 
 #define DPRINTK(fmt, args...)                          \
@@ -303,6 +326,24 @@ again:
                goto abort_transaction;
        }
 
+       err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1);
+       if (err) {
+               message = "writing feature-rx-notify";
+               goto abort_transaction;
+       }
+
+       err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1);
+       if (err) {
+               message = "writing feature-sg";
+               goto abort_transaction;
+       }
+
+       err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1);
+       if (err) {
+               message = "writing feature-gso-tcpv4";
+               goto abort_transaction;
+       }
+
        err = xenbus_transaction_end(xbt, 0);
        if (err) {
                if (err == -EAGAIN)
@@ -455,6 +496,9 @@ static int network_open(struct net_devic
 
        network_alloc_rx_buffers(dev);
        np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
+
+       if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
+               netif_rx_schedule(dev);
 
        netif_start_queue(dev);
 
@@ -546,10 +590,13 @@ static void network_alloc_rx_buffers(str
        unsigned short id;
        struct netfront_info *np = netdev_priv(dev);
        struct sk_buff *skb;
-       int i, batch_target;
+       struct page *page;
+       int i, batch_target, notify;
        RING_IDX req_prod = np->rx.req_prod_pvt;
        struct xen_memory_reservation reservation;
        grant_ref_t ref;
+       unsigned long pfn;
+       void *vaddr;
 
        if (unlikely(!netif_carrier_ok(dev)))
                return;
@@ -562,29 +609,36 @@ static void network_alloc_rx_buffers(str
         */
        batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
        for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
-               /*
-                * Subtract dev_alloc_skb headroom (16 bytes) and shared info
-                * tailroom then round down to SKB_DATA_ALIGN boundary.
-                */
-               skb = __dev_alloc_skb(
-                       ((PAGE_SIZE - sizeof(struct skb_shared_info)) &
-                        (-SKB_DATA_ALIGN(1))) - 16,
-                       GFP_ATOMIC|__GFP_NOWARN);
-               if (skb == NULL) {
+               /* Allocate an skb and a page. */
+               skb = __dev_alloc_skb(RX_COPY_THRESHOLD,
+                                     GFP_ATOMIC | __GFP_NOWARN);
+               if (unlikely(!skb))
+                       goto no_skb;
+
+               page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
+               if (!page) {
+                       kfree_skb(skb);
+no_skb:
                        /* Any skbuffs queued for refill? Force them out. */
                        if (i != 0)
                                goto refill;
                        /* Could not allocate any skbuffs. Try again later. */
                        mod_timer(&np->rx_refill_timer,
                                  jiffies + (HZ/10));
-                       return;
+                       break;
                }
+
+               skb_shinfo(skb)->frags[0].page = page;
+               skb_shinfo(skb)->nr_frags = 1;
                __skb_queue_tail(&np->rx_batch, skb);
        }
 
        /* Is the batch large enough to be worthwhile? */
-       if (i < (np->rx_target/2))
+       if (i < (np->rx_target/2)) {
+               if (req_prod > np->rx.sring->req_prod)
+                       goto push;
                return;
+       }
 
        /* Adjust our fill target if we risked running out of buffers. */
        if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
@@ -598,26 +652,29 @@ static void network_alloc_rx_buffers(str
 
                skb->dev = dev;
 
-               id = get_id_from_freelist(np->rx_skbs);
-
+               id = xennet_rxidx(req_prod + i);
+
+               BUG_ON(np->rx_skbs[id]);
                np->rx_skbs[id] = skb;
 
                RING_GET_REQUEST(&np->rx, req_prod + i)->id = id;
                ref = gnttab_claim_grant_reference(&np->gref_rx_head);
                BUG_ON((signed short)ref < 0);
                np->grant_rx_ref[id] = ref;
+
+               pfn = page_to_pfn(skb_shinfo(skb)->frags[0].page);
+               vaddr = page_address(skb_shinfo(skb)->frags[0].page);
+
                gnttab_grant_foreign_transfer_ref(ref,
-                                                 np->xbdev->otherend_id,
-                                                 __pa(skb->head)>>PAGE_SHIFT);
+                                                 np->xbdev->otherend_id, pfn);
                RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
-               np->rx_pfn_array[i] = virt_to_mfn(skb->head);
+               np->rx_pfn_array[i] = pfn_to_mfn(pfn);
 
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Remove this page before passing back to Xen. */
-                       set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
-                                           INVALID_P2M_ENTRY);
+                       set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
                        MULTI_update_va_mapping(np->rx_mcl+i,
-                                               (unsigned long)skb->head,
+                                               (unsigned long)vaddr,
                                                __pte(0), 0);
                }
        }
@@ -654,7 +711,10 @@ static void network_alloc_rx_buffers(str
 
        /* Above is a suitable barrier to ensure backend will see requests. */
        np->rx.req_prod_pvt = req_prod + i;
-       RING_PUSH_REQUESTS(&np->rx);
+ push:
+       RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
+       if (notify)
+               notify_remote_via_irq(np->irq);
 }
 
 static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
@@ -840,49 +900,99 @@ static irqreturn_t netif_int(int irq, vo
        return IRQ_HANDLED;
 }
 
-
-static int netif_poll(struct net_device *dev, int *pbudget)
-{
-       struct netfront_info *np = netdev_priv(dev);
-       struct sk_buff *skb, *nskb;
-       struct netif_rx_response *rx;
-       RING_IDX i, rp;
-       struct mmu_update *mmu = np->rx_mmu;
-       struct multicall_entry *mcl = np->rx_mcl;
-       int work_done, budget, more_to_do = 1;
-       struct sk_buff_head rxq;
-       unsigned long flags;
-       unsigned long mfn;
-       grant_ref_t ref;
-
-       spin_lock(&np->rx_lock);
-
-       if (unlikely(!netif_carrier_ok(dev))) {
-               spin_unlock(&np->rx_lock);
-               return 0;
-       }
-
-       skb_queue_head_init(&rxq);
-
-       if ((budget = *pbudget) > dev->quota)
-               budget = dev->quota;
-       rp = np->rx.sring->rsp_prod;
-       rmb(); /* Ensure we see queued responses up to 'rp'. */
-
-       for (i = np->rx.rsp_cons, work_done = 0;
-            (i != rp) && (work_done < budget);
-            i++, work_done++) {
-               rx = RING_GET_RESPONSE(&np->rx, i);
+static void xennet_move_rx_slot(struct netfront_info *np, struct sk_buff *skb,
+                               grant_ref_t ref)
+{
+       int new = xennet_rxidx(np->rx.req_prod_pvt);
+
+       BUG_ON(np->rx_skbs[new]);
+       np->rx_skbs[new] = skb;
+       np->grant_rx_ref[new] = ref;
+       RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id = new;
+       RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref = ref;
+       np->rx.req_prod_pvt++;
+}
+
+int xennet_get_extras(struct netfront_info *np,
+                     struct netif_extra_info *extras, RING_IDX rp)
+
+{
+       struct netif_extra_info *extra;
+       RING_IDX cons = np->rx.rsp_cons;
+       int err = 0;
+
+       do {
+               struct sk_buff *skb;
+               grant_ref_t ref;
+
+               if (unlikely(cons + 1 == rp)) {
+                       if (net_ratelimit())
+                               WPRINTK("Missing extra info\n");
+                       err = -EBADR;
+                       break;
+               }
+
+               extra = (struct netif_extra_info *)
+                       RING_GET_RESPONSE(&np->rx, ++cons);
+
+               if (unlikely(!extra->type ||
+                            extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+                       if (net_ratelimit())
+                               WPRINTK("Invalid extra type: %d\n",
+                                       extra->type);
+                       err = -EINVAL;
+               } else
+                       memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+
+               skb = xennet_get_rx_skb(np, cons);
+               ref = xennet_get_rx_ref(np, cons);
+               xennet_move_rx_slot(np, skb, ref);
+       } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+
+       np->rx.rsp_cons = cons;
+       return err;
+}
+
+static int xennet_get_responses(struct netfront_info *np,
+                               struct netfront_rx_info *rinfo, RING_IDX rp,
+                               struct sk_buff_head *list, int count)
+{
+       struct mmu_update *mmu = np->rx_mmu + count;
+       struct multicall_entry *mcl = np->rx_mcl + count;
+       struct netif_rx_response *rx = &rinfo->rx;
+       struct netif_extra_info *extras = rinfo->extras;
+       RING_IDX cons = np->rx.rsp_cons;
+       struct sk_buff *skb = xennet_get_rx_skb(np, cons);
+       grant_ref_t ref = xennet_get_rx_ref(np, cons);
+       int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD);
+       int frags = 1;
+       int err = 0;
+
+       if (rx->flags & NETRXF_extra_info) {
+               err = xennet_get_extras(np, extras, rp);
+               cons = np->rx.rsp_cons;
+       }
+
+       for (;;) {
+               unsigned long mfn;
+
+               if (unlikely(rx->status < 0 ||
+                            rx->offset + rx->status > PAGE_SIZE)) {
+                       if (net_ratelimit())
+                               WPRINTK("rx->offset: %x, size: %u\n",
+                                       rx->offset, rx->status);
+                       err = -EINVAL;
+               }
 
                /*
                 * This definitely indicates a bug, either in this driver or in
                 * the backend driver. In future this should flag the bad
                 * situation to the system controller to reboot the backed.
                 */
-               if ((ref = np->grant_rx_ref[rx->id]) == GRANT_INVALID_REF) {
+               if (ref == GRANT_INVALID_REF) {
                        WPRINTK("Bad rx response id %d.\n", rx->id);
-                       work_done--;
-                       continue;
+                       err = -EINVAL;
+                       goto next;
                }
 
                /* Memory pressure, insufficient buffer headroom, ... */
@@ -890,26 +1000,201 @@ static int netif_poll(struct net_device 
                        if (net_ratelimit())
                                WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n",
                                        rx->id, rx->status);
-                       RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id =
-                               rx->id;
-                       RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref =
-                               ref;
-                       np->rx.req_prod_pvt++;
-                       RING_PUSH_REQUESTS(&np->rx);
+                       xennet_move_rx_slot(np, skb, ref);
+                       err = -ENOMEM;
+                       goto next;
+               }
+
+               gnttab_release_grant_reference(&np->gref_rx_head, ref);
+
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       /* Remap the page. */
+                       struct page *page = skb_shinfo(skb)->frags[0].page;
+                       unsigned long pfn = page_to_pfn(page);
+                       void *vaddr = page_address(page);
+
+                       MULTI_update_va_mapping(mcl, (unsigned long)vaddr,
+                                               pfn_pte_ma(mfn, PAGE_KERNEL),
+                                               0);
+                       mcl++;
+                       mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
+                               | MMU_MACHPHYS_UPDATE;
+                       mmu->val = pfn;
+                       mmu++;
+
+                       set_phys_to_machine(pfn, mfn);
+               }
+
+               __skb_queue_tail(list, skb);
+
+next:
+               if (!(rx->flags & NETRXF_more_data))
+                       break;
+
+               if (cons + frags == rp) {
+                       if (net_ratelimit())
+                               WPRINTK("Need more frags\n");
+                       err = -ENOENT;
+                       break;
+               }
+
+               rx = RING_GET_RESPONSE(&np->rx, cons + frags);
+               skb = xennet_get_rx_skb(np, cons + frags);
+               ref = xennet_get_rx_ref(np, cons + frags);
+               frags++;
+       }
+
+       if (unlikely(frags > max)) {
+               if (net_ratelimit())
+                       WPRINTK("Too many frags\n");
+               err = -E2BIG;
+       }
+
+       return err;
+}
+
+static RING_IDX xennet_fill_frags(struct netfront_info *np,
+                                 struct sk_buff *skb,
+                                 struct sk_buff_head *list)
+{
+       struct skb_shared_info *shinfo = skb_shinfo(skb);
+       int nr_frags = shinfo->nr_frags;
+       RING_IDX cons = np->rx.rsp_cons;
+       skb_frag_t *frag = shinfo->frags + nr_frags;
+       struct sk_buff *nskb;
+
+       while ((nskb = __skb_dequeue(list))) {
+               struct netif_rx_response *rx =
+                       RING_GET_RESPONSE(&np->rx, ++cons);
+
+               frag->page = skb_shinfo(nskb)->frags[0].page;
+               frag->page_offset = rx->offset;
+               frag->size = rx->status;
+
+               skb->data_len += rx->status;
+
+               skb_shinfo(nskb)->nr_frags = 0;
+               kfree_skb(nskb);
+
+               frag++;
+               nr_frags++;
+       }
+
+       shinfo->nr_frags = nr_frags;
+       return cons;
+}
+
+static int xennet_set_skb_gso(struct sk_buff *skb, struct netif_extra_info 
*gso)
+{
+       if (!gso->u.gso.size) {
+               if (net_ratelimit())
+                       WPRINTK("GSO size must not be zero.\n");
+               return -EINVAL;
+       }
+
+       /* Currently only TCPv4 S.O. is supported. */
+       if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
+               if (net_ratelimit())
+                       WPRINTK("Bad GSO type %d.\n", gso->u.gso.type);
+               return -EINVAL;
+       }
+
+       skb_shinfo(skb)->gso_size = gso->u.gso.size;
+       skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+
+       /* Header must be checked, and gso_segs computed. */
+       skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+       skb_shinfo(skb)->gso_segs = 0;
+
+       return 0;
+}
+
+static int netif_poll(struct net_device *dev, int *pbudget)
+{
+       struct netfront_info *np = netdev_priv(dev);
+       struct sk_buff *skb;
+       struct netfront_rx_info rinfo;
+       struct netif_rx_response *rx = &rinfo.rx;
+       struct netif_extra_info *extras = rinfo.extras;
+       RING_IDX i, rp;
+       struct multicall_entry *mcl;
+       int work_done, budget, more_to_do = 1;
+       struct sk_buff_head rxq;
+       struct sk_buff_head errq;
+       struct sk_buff_head tmpq;
+       unsigned long flags;
+       unsigned int len;
+       int pages_done;
+       int err;
+
+       spin_lock(&np->rx_lock);
+
+       if (unlikely(!netif_carrier_ok(dev))) {
+               spin_unlock(&np->rx_lock);
+               return 0;
+       }
+
+       skb_queue_head_init(&rxq);
+       skb_queue_head_init(&errq);
+       skb_queue_head_init(&tmpq);
+
+       if ((budget = *pbudget) > dev->quota)
+               budget = dev->quota;
+       rp = np->rx.sring->rsp_prod;
+       rmb(); /* Ensure we see queued responses up to 'rp'. */
+
+       for (i = np->rx.rsp_cons, work_done = 0, pages_done = 0;
+            (i != rp) && (work_done < budget);
+            np->rx.rsp_cons = ++i, work_done++) {
+               memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
+               memset(extras, 0, sizeof(extras));
+
+               err = xennet_get_responses(np, &rinfo, rp, &tmpq, pages_done);
+               pages_done += skb_queue_len(&tmpq);
+
+               if (unlikely(err)) {
+err:
+                       i = np->rx.rsp_cons + skb_queue_len(&tmpq) - 1;
                        work_done--;
+                       while ((skb = __skb_dequeue(&tmpq)))
+                               __skb_queue_tail(&errq, skb);
+                       np->stats.rx_errors++;
                        continue;
                }
 
-               gnttab_release_grant_reference(&np->gref_rx_head, ref);
-               np->grant_rx_ref[rx->id] = GRANT_INVALID_REF;
-
-               skb = np->rx_skbs[rx->id];
-               add_id_to_freelist(np->rx_skbs, rx->id);
-
-               /* NB. We handle skb overflow later. */
-               skb->data = skb->head + rx->offset;
-               skb->len  = rx->status;
-               skb->tail = skb->data + skb->len;
+               skb = __skb_dequeue(&tmpq);
+
+               if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) {
+                       struct netif_extra_info *gso;
+                       gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
+
+                       if (unlikely(xennet_set_skb_gso(skb, gso))) {
+                               __skb_queue_head(&tmpq, skb);
+                               goto err;
+                       }
+               }
+
+               skb->nh.raw = (void *)skb_shinfo(skb)->frags[0].page;
+               skb->h.raw = skb->nh.raw + rx->offset;
+
+               len = rx->status;
+               if (len > RX_COPY_THRESHOLD)
+                       len = RX_COPY_THRESHOLD;
+               skb_put(skb, len);
+
+               if (rx->status > len) {
+                       skb_shinfo(skb)->frags[0].page_offset =
+                               rx->offset + len;
+                       skb_shinfo(skb)->frags[0].size = rx->status - len;
+                       skb->data_len = rx->status - len;
+               } else {
+                       skb_shinfo(skb)->frags[0].page = NULL;
+                       skb_shinfo(skb)->nr_frags = 0;
+               }
+
+               i = xennet_fill_frags(np, skb, &tmpq);
+               skb->truesize += skb->data_len;
+               skb->len += skb->data_len;
 
                /*
                 * Old backends do not assert data_validated but we
@@ -925,96 +1210,38 @@ static int netif_poll(struct net_device 
                skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank);
 
                np->stats.rx_packets++;
-               np->stats.rx_bytes += rx->status;
-
-               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-                       /* Remap the page. */
-                       MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
-                                               pfn_pte_ma(mfn, PAGE_KERNEL),
-                                               0);
-                       mcl++;
-                       mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
-                               | MMU_MACHPHYS_UPDATE;
-                       mmu->val = __pa(skb->head) >> PAGE_SHIFT;
-                       mmu++;
-
-                       set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
-                                           mfn);
-               }
+               np->stats.rx_bytes += skb->len;
 
                __skb_queue_tail(&rxq, skb);
        }
 
        /* Some pages are no longer absent... */
-       balloon_update_driver_allowance(-work_done);
+       balloon_update_driver_allowance(-pages_done);
 
        /* Do all the remapping work, and M2P updates, in one big hypercall. */
-       if (likely((mcl - np->rx_mcl) != 0)) {
+       if (likely(pages_done)) {
+               mcl = np->rx_mcl + pages_done;
                mcl->op = __HYPERVISOR_mmu_update;
                mcl->args[0] = (unsigned long)np->rx_mmu;
-               mcl->args[1] = mmu - np->rx_mmu;
+               mcl->args[1] = pages_done;
                mcl->args[2] = 0;
                mcl->args[3] = DOMID_SELF;
-               mcl++;
-               (void)HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
-       }
+               (void)HYPERVISOR_multicall(np->rx_mcl, pages_done + 1);
+       }
+
+       while ((skb = __skb_dequeue(&errq)))
+               kfree_skb(skb);
 
        while ((skb = __skb_dequeue(&rxq)) != NULL) {
-               if (skb->len > (dev->mtu + ETH_HLEN + 4)) {
-                       if (net_ratelimit())
-                               printk(KERN_INFO "Received packet too big for "
-                                      "MTU (%d > %d)\n",
-                                      skb->len - ETH_HLEN - 4, dev->mtu);
-                       skb->len  = 0;
-                       skb->tail = skb->data;
-                       init_skb_shinfo(skb);
-                       dev_kfree_skb(skb);
-                       continue;
-               }
-
-               /*
-                * Enough room in skbuff for the data we were passed? Also,
-                * Linux expects at least 16 bytes headroom in each rx buffer.
-                */
-               if (unlikely(skb->tail > skb->end) ||
-                   unlikely((skb->data - skb->head) < 16)) {
-                       if (net_ratelimit()) {
-                               if (skb->tail > skb->end)
-                                       printk(KERN_INFO "Received packet "
-                                              "is %zd bytes beyond tail.\n",
-                                              skb->tail - skb->end);
-                               else
-                                       printk(KERN_INFO "Received packet "
-                                              "is %zd bytes before head.\n",
-                                              16 - (skb->data - skb->head));
-                       }
-
-                       nskb = __dev_alloc_skb(skb->len + 2,
-                                              GFP_ATOMIC|__GFP_NOWARN);
-                       if (nskb != NULL) {
-                               skb_reserve(nskb, 2);
-                               skb_put(nskb, skb->len);
-                               memcpy(nskb->data, skb->data, skb->len);
-                               /* Copy any other fields we already set up. */
-                               nskb->dev = skb->dev;
-                               nskb->ip_summed = skb->ip_summed;
-                               nskb->proto_data_valid = skb->proto_data_valid;
-                               nskb->proto_csum_blank = skb->proto_csum_blank;
-                       }
-
-                       /* Reinitialise and then destroy the old skbuff. */
-                       skb->len  = 0;
-                       skb->tail = skb->data;
-                       init_skb_shinfo(skb);
-                       dev_kfree_skb(skb);
-
-                       /* Switch old for new, if we copied the buffer. */
-                       if ((skb = nskb) == NULL)
-                               continue;
-               }
-
-               /* Set the shinfo area, which is hidden behind the data. */
-               init_skb_shinfo(skb);
+               struct page *page = (struct page *)skb->nh.raw;
+               void *vaddr = page_address(page);
+
+               memcpy(skb->data, vaddr + (skb->h.raw - skb->nh.raw),
+                      skb_headlen(skb));
+
+               if (page != skb_shinfo(skb)->frags[0].page)
+                       __free_page(page);
+
                /* Ethernet work: Delayed to here as it peeks the header. */
                skb->protocol = eth_type_trans(skb, dev);
 
@@ -1022,8 +1249,6 @@ static int netif_poll(struct net_device 
                netif_receive_skb(skb);
                dev->last_rx = jiffies;
        }
-
-       np->rx.rsp_cons = i;
 
        /* If we get a callback with very few responses, reduce fill target. */
        /* NB. Note exponential increase, linear decrease. */
@@ -1103,9 +1328,7 @@ static int xennet_set_tso(struct net_dev
                if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
                                 "feature-gso-tcpv4", "%d", &val) < 0)
                        val = 0;
-#if 0 /* KAF: After the protocol is finalised. */
                if (!val)
-#endif
                        return -ENOSYS;
        }
 
@@ -1128,6 +1351,7 @@ static void network_connect(struct net_d
        struct netfront_info *np = netdev_priv(dev);
        int i, requeue_idx;
        struct sk_buff *skb;
+       grant_ref_t ref;
 
        xennet_set_features(dev);
 
@@ -1158,20 +1382,24 @@ static void network_connect(struct net_d
        }
 
        /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */
-       for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) {
-               if ((unsigned long)np->rx_skbs[i] < PAGE_OFFSET)
+       for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) {
+               if (!np->rx_skbs[i])
                        continue;
+
+               skb = np->rx_skbs[requeue_idx] = xennet_get_rx_skb(np, i);
+               ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i);
+
                gnttab_grant_foreign_transfer_ref(
-                       np->grant_rx_ref[i], np->xbdev->otherend_id,
-                       __pa(np->rx_skbs[i]->data) >> PAGE_SHIFT);
-               RING_GET_REQUEST(&np->rx, requeue_idx)->gref =
-                       np->grant_rx_ref[i];
-               RING_GET_REQUEST(&np->rx, requeue_idx)->id = i;
+                       ref, np->xbdev->otherend_id,
+                       page_to_pfn(skb_shinfo(skb)->frags->page));
+
+               RING_GET_REQUEST(&np->rx, requeue_idx)->gref = ref;
+               RING_GET_REQUEST(&np->rx, requeue_idx)->id   = requeue_idx;
+
                requeue_idx++;
        }
 
        np->rx.req_prod_pvt = requeue_idx;
-       RING_PUSH_REQUESTS(&np->rx);
 
        /*
         * Step 3: All public and private state should now be sane.  Get
@@ -1392,8 +1620,8 @@ static struct net_device * __devinit cre
                np->grant_tx_ref[i] = GRANT_INVALID_REF;
        }
 
-       for (i = 0; i <= NET_RX_RING_SIZE; i++) {
-               np->rx_skbs[i] = (void *)((unsigned long) i+1);
+       for (i = 0; i < NET_RX_RING_SIZE; i++) {
+               np->rx_skbs[i] = NULL;
                np->grant_rx_ref[i] = GRANT_INVALID_REF;
        }
 
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/pci_stub.c       Mon Aug 07 
18:00:22 2006 -0500
@@ -232,6 +232,10 @@ static int __devinit pcistub_match_one(s
                    && dev->bus->number == pdev_id->bus
                    && dev->devfn == pdev_id->devfn)
                        return 1;
+
+               /* Sometimes topmost bridge links to itself. */
+               if (dev == dev->bus->self)
+                       break;
        }
 
        return 0;
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c Mon Aug 07 18:00:22 
2006 -0500
@@ -445,6 +445,9 @@ static struct xenbus_driver xenbus_pciba
 
 int __init pciback_xenbus_register(void)
 {
+       if (!is_running_on_xen())
+               return -ENODEV;
+
        return xenbus_register_backend(&xenbus_pciback_driver);
 }
 
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c        Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c        Mon Aug 07 
18:00:22 2006 -0500
@@ -105,7 +105,7 @@ static int pcifront_bus_read(struct pci_
                .size   = size,
        };
        struct pcifront_sd *sd = bus->sysdata;
-       struct pcifront_device *pdev = sd->pdev;
+       struct pcifront_device *pdev = pcifront_get_pdev(sd);
 
        if (verbose_request)
                dev_info(&pdev->xdev->dev,
@@ -144,7 +144,7 @@ static int pcifront_bus_write(struct pci
                .value  = val,
        };
        struct pcifront_sd *sd = bus->sysdata;
-       struct pcifront_device *pdev = sd->pdev;
+       struct pcifront_device *pdev = pcifront_get_pdev(sd);
 
        if (verbose_request)
                dev_info(&pdev->xdev->dev,
@@ -207,12 +207,13 @@ int pcifront_scan_root(struct pcifront_d
                err = -ENOMEM;
                goto err_out;
        }
-       sd->domain = domain;
-       sd->pdev = pdev;
-
-       b = pci_scan_bus_parented(&pdev->xdev->dev, bus, &pcifront_bus_ops, sd);
+       pcifront_init_sd(sd, domain, pdev);
+
+       b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
+                                 &pcifront_bus_ops, sd);
        if (!b) {
-               dev_err(&pdev->xdev->dev, "Error creating PCI Frontend Bus!\n");
+               dev_err(&pdev->xdev->dev,
+                       "Error creating PCI Frontend Bus!\n");
                err = -ENOMEM;
                goto err_out;
        }
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c        Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/xenbus.c        Mon Aug 07 
18:00:22 2006 -0500
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <xen/xenbus.h>
+#include <xen/gnttab.h>
 #include "pcifront.h"
 
 #define INVALID_GRANT_REF (0)
@@ -283,11 +284,10 @@ static struct xenbus_driver xenbus_pcifr
 
 static int __init pcifront_init(void)
 {
-       int err = 0;
-
-       err = xenbus_register_frontend(&xenbus_pcifront_driver);
-
-       return err;
+       if (!is_running_on_xen())
+               return -ENODEV;
+
+       return xenbus_register_frontend(&xenbus_pcifront_driver);
 }
 
 /* Initialize after the Xen PCI Frontend Stub is initialized */
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Mon Aug 07 
18:00:22 2006 -0500
@@ -270,6 +270,7 @@ static int __init privcmd_init(void)
        set_bit(__HYPERVISOR_sched_op_compat,  hypercall_permission_map);
        set_bit(__HYPERVISOR_event_channel_op_compat,
                hypercall_permission_map);
+       set_bit(__HYPERVISOR_hvm_op,           hypercall_permission_map);
 
        privcmd_intf = create_xen_proc_entry("privcmd", 0400);
        if (privcmd_intf != NULL)
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c        Mon Aug 07 
18:00:22 2006 -0500
@@ -55,7 +55,6 @@ struct packet {
 
 enum {
        PACKET_FLAG_DISCARD_RESPONSE = 1,
-       PACKET_FLAG_CHECK_RESPONSESTATUS = 2,
 };
 
 /* local variables */
@@ -201,21 +200,6 @@ static void packet_free(struct packet *p
        kfree(pak);
 }
 
-static int packet_set(struct packet *pak,
-                     const unsigned char *buffer, u32 size)
-{
-       int rc = 0;
-       unsigned char *buf = kmalloc(size, GFP_KERNEL);
-
-       if (buf) {
-               pak->data_buffer = buf;
-               memcpy(buf, buffer, size);
-               pak->data_len = size;
-       } else {
-               rc = -ENOMEM;
-       }
-       return rc;
-}
 
 /*
  * Write data to the shared memory and send it to the FE.
@@ -224,29 +208,6 @@ static int packet_write(struct packet *p
                        const char *data, size_t size, int isuserbuffer)
 {
        int rc = 0;
-
-       if ((pak->flags & PACKET_FLAG_CHECK_RESPONSESTATUS)) {
-#ifdef CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS
-               u32 res;
-
-               if (copy_from_buffer(&res,
-                                    &data[2 + 4], sizeof (res),
-                                    isuserbuffer)) {
-                       return -EFAULT;
-               }
-
-               if (res != 0) {
-                       /*
-                        * Close down this device. Should have the
-                        * FE notified about closure.
-                        */
-                       if (!pak->tpmif) {
-                               return -EFAULT;
-                       }
-                       pak->tpmif->status = DISCONNECTING;
-               }
-#endif
-       }
 
        if (0 != (pak->flags & PACKET_FLAG_DISCARD_RESPONSE)) {
                /* Don't send a respone to this packet. Just acknowledge it. */
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c      Mon Aug 07 
18:00:22 2006 -0500
@@ -58,6 +58,9 @@ struct xenbus_dev_data {
        /* In-progress transaction. */
        struct list_head transactions;
 
+       /* Active watches. */
+       struct list_head watches;
+
        /* Partial request. */
        unsigned int len;
        union {
@@ -70,6 +73,8 @@ struct xenbus_dev_data {
        char read_buffer[PAGE_SIZE];
        unsigned int read_cons, read_prod;
        wait_queue_head_t read_waitq;
+
+       struct mutex reply_mutex;
 };
 
 static struct proc_dir_entry *xenbus_dev_intf;
@@ -100,13 +105,59 @@ static void queue_reply(struct xenbus_de
 {
        int i;
 
+       mutex_lock(&u->reply_mutex);
+
        for (i = 0; i < len; i++, u->read_prod++)
                u->read_buffer[MASK_READ_IDX(u->read_prod)] = data[i];
 
        BUG_ON((u->read_prod - u->read_cons) > sizeof(u->read_buffer));
 
+       mutex_unlock(&u->reply_mutex);
+
        wake_up(&u->read_waitq);
 }
+
+struct watch_adapter
+{
+       struct list_head list;
+       struct xenbus_watch watch;
+       struct xenbus_dev_data *dev_data;
+       char *token;
+};
+
+static void free_watch_adapter (struct watch_adapter *watch)
+{
+       kfree(watch->watch.node);
+       kfree(watch->token);
+       kfree(watch);
+}
+
+static void watch_fired(struct xenbus_watch *watch,
+                       const char **vec,
+                       unsigned int len)
+{
+       struct watch_adapter *adap =
+            container_of(watch, struct watch_adapter, watch);
+       struct xsd_sockmsg hdr;
+       const char *path, *token;
+       int path_len, tok_len, body_len;
+
+       path = vec[XS_WATCH_PATH];
+       token = adap->token;
+
+       path_len = strlen(path) + 1;
+       tok_len = strlen(token) + 1;
+       body_len = path_len + tok_len;
+
+       hdr.type = XS_WATCH_EVENT;
+       hdr.len = body_len;
+       
+       queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr));
+       queue_reply(adap->dev_data, (char *)path, path_len);
+       queue_reply(adap->dev_data, (char *)token, tok_len);
+}
+
+static LIST_HEAD(watch_list);
 
 static ssize_t xenbus_dev_write(struct file *filp,
                                const char __user *ubuf,
@@ -116,6 +167,9 @@ static ssize_t xenbus_dev_write(struct f
        struct xenbus_dev_transaction *trans = NULL;
        uint32_t msg_type;
        void *reply;
+       char *path, *token;
+       struct watch_adapter *watch, *tmp_watch;
+       int err;
 
        if ((len + u->len) > sizeof(u->u.buffer))
                return -EINVAL;
@@ -169,6 +223,56 @@ static ssize_t xenbus_dev_write(struct f
                kfree(reply);
                break;
 
+       case XS_WATCH:
+       case XS_UNWATCH:
+               path = u->u.buffer + sizeof(u->u.msg);
+               token = memchr(path, 0, u->u.msg.len);
+               if (token == NULL)
+                       return -EILSEQ;
+               token++;
+
+               if (msg_type == XS_WATCH) {
+                       static const char * XS_WATCH_RESP = "OK";
+                       struct xsd_sockmsg hdr;
+
+                       watch = kmalloc(sizeof(*watch), GFP_KERNEL);
+                       watch->watch.node = kmalloc(strlen(path)+1,
+                                                    GFP_KERNEL);
+                       strcpy((char *)watch->watch.node, path);
+                       watch->watch.callback = watch_fired;
+                       watch->token = kmalloc(strlen(token)+1, GFP_KERNEL);
+                       strcpy(watch->token, token);
+                       watch->dev_data = u;
+
+                       err = register_xenbus_watch(&watch->watch);
+                       if (err) {
+                               free_watch_adapter(watch);
+                               return err;
+                       }
+                       
+                       list_add(&watch->list, &u->watches);
+
+                       hdr.type = XS_WATCH;
+                       hdr.len = strlen(XS_WATCH_RESP) + 1;
+                       queue_reply(u, (char *)&hdr, sizeof(hdr));
+                       queue_reply(u, (char *)XS_WATCH_RESP, hdr.len);
+               } else {
+                       list_for_each_entry_safe(watch, tmp_watch,
+                                                 &u->watches, list) {
+                               if (!strcmp(watch->token, token) &&
+                                   !strcmp(watch->watch.node, path))
+                                       break;
+                               {
+                                       unregister_xenbus_watch(&watch->watch);
+                                       list_del(&watch->list);
+                                       free_watch_adapter(watch);
+                                       break;
+                               }
+                       }
+               }
+
+               break;
+
        default:
                return -EINVAL;
        }
@@ -191,7 +295,10 @@ static int xenbus_dev_open(struct inode 
                return -ENOMEM;
 
        INIT_LIST_HEAD(&u->transactions);
+       INIT_LIST_HEAD(&u->watches);
        init_waitqueue_head(&u->read_waitq);
+
+       mutex_init(&u->reply_mutex);
 
        filp->private_data = u;
 
@@ -202,11 +309,18 @@ static int xenbus_dev_release(struct ino
 {
        struct xenbus_dev_data *u = filp->private_data;
        struct xenbus_dev_transaction *trans, *tmp;
+       struct watch_adapter *watch, *tmp_watch;
 
        list_for_each_entry_safe(trans, tmp, &u->transactions, list) {
                xenbus_transaction_end(trans->handle, 1);
                list_del(&trans->list);
                kfree(trans);
+       }
+
+       list_for_each_entry_safe(watch, tmp_watch, &u->watches, list) {
+               unregister_xenbus_watch(&watch->watch);
+               list_del(&watch->list);
+               free_watch_adapter(watch);
        }
 
        kfree(u);
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Mon Aug 07 
18:00:22 2006 -0500
@@ -141,7 +141,9 @@ static int read_otherend_details(struct 
        }
        if (strlen(xendev->otherend) == 0 ||
            !xenbus_exists(XBT_NIL, xendev->otherend, "")) {
-               xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
+               xenbus_dev_fatal(xendev, -ENOENT,
+                                "unable to read other end from %s.  "
+                                "missing or inaccessible.",
                                 xendev->nodename);
                free_otherend_details(xendev);
                return -ENOENT;
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h   Thu Jul 
27 20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h   Mon Aug 
07 18:00:22 2006 -0500
@@ -187,16 +187,14 @@ MULTI_update_va_mapping(
     mcl->args[0] = va;
 #if defined(CONFIG_X86_64)
     mcl->args[1] = new_val.pte;
-    mcl->args[2] = flags;
 #elif defined(CONFIG_X86_PAE)
     mcl->args[1] = new_val.pte_low;
     mcl->args[2] = new_val.pte_high;
-    mcl->args[3] = flags;
 #else
     mcl->args[1] = new_val.pte_low;
     mcl->args[2] = 0;
-    mcl->args[3] = flags;
-#endif
+#endif
+    mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
 }
 
 static inline void
@@ -208,19 +206,15 @@ MULTI_update_va_mapping_otherdomain(
     mcl->args[0] = va;
 #if defined(CONFIG_X86_64)
     mcl->args[1] = new_val.pte;
-    mcl->args[2] = flags;
-    mcl->args[3] = domid;
 #elif defined(CONFIG_X86_PAE)
     mcl->args[1] = new_val.pte_low;
     mcl->args[2] = new_val.pte_high;
-    mcl->args[3] = flags;
-    mcl->args[4] = domid;
 #else
     mcl->args[1] = new_val.pte_low;
     mcl->args[2] = 0;
-    mcl->args[3] = flags;
-    mcl->args[4] = domid;
-#endif
+#endif
+    mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
+    mcl->args[MULTI_UVMDOMID_INDEX] = domid;
 }
 
 #endif /* __HYPERVISOR_H__ */
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h  Thu Jul 27 
20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h  Mon Aug 07 
18:00:22 2006 -0500
@@ -12,6 +12,9 @@ typedef struct {
        int size;
        struct semaphore sem;
        void *ldt;
+#ifdef CONFIG_XEN
+       int has_foreign_mappings;
+#endif
 } mm_context_t;
 
 /* mm/memory.c:exit_mmap hook */
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/include/asm-i386/spinlock.h
--- a/linux-2.6-xen-sparse/include/asm-i386/spinlock.h  Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/include/asm-i386/spinlock.h  Mon Aug 07 18:00:22 
2006 -0500
@@ -23,7 +23,7 @@
                (*(volatile signed char *)(&(x)->slock) <= 0)
 
 #define __raw_spin_lock_string \
-       "\n1:\n" \
+       "\n1:\t" \
        LOCK \
        "decb %0\n\t" \
        "jns 3f\n" \
@@ -35,7 +35,7 @@
        "3:\n\t"
 
 #define __raw_spin_lock_string_flags \
-       "\n1:\n" \
+       "\n1:\t" \
        LOCK \
        "decb %0\n\t" \
        "jns 4f\n\t" \
diff -r 61204c1d740e -r 87cefa5f7c5e 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h        Thu Jul 
27 20:07:02 2006 -0400
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h        Mon Aug 
07 18:00:22 2006 -0500
@@ -17,6 +17,7 @@ typedef struct {
        struct semaphore sem; 
 #ifdef CONFIG_XEN
        unsigned pinned:1;
+       unsigned has_foreign_mappings:1;
        struct list_head unpinned;
 #endif
 } mm_context_t;
diff -r 61204c1d740e -r 87cefa5f7c5e linux-2.6-xen-sparse/include/xen/pcifront.h
--- a/linux-2.6-xen-sparse/include/xen/pcifront.h       Thu Jul 27 20:07:02 
2006 -0400
+++ b/linux-2.6-xen-sparse/include/xen/pcifront.h       Mon Aug 07 18:00:22 
2006 -0500
@@ -11,16 +11,30 @@
 
 #ifdef __KERNEL__
 
+#ifndef __ia64__
+
 struct pcifront_device;
+struct pci_bus;
 
 struct pcifront_sd {
        int domain;
        struct pcifront_device *pdev;
 };
 
-struct pci_bus;
+static inline struct pcifront_device *
+pcifront_get_pdev(struct pcifront_sd *sd)
+{
+       return sd->pdev;
+}
 
-#ifdef CONFIG_PCI_DOMAINS
+static inline void pcifront_init_sd(struct pcifront_sd *sd, int domain,
+                                   struct pcifront_device *pdev)
+{
+       sd->domain = domain;
+       sd->pdev = pdev;
+}
+
+#if defined(CONFIG_PCI_DOMAINS)
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
        struct pcifront_sd *sd = bus->sysdata;
@@ -32,6 +46,30 @@ static inline int pci_proc_domain(struct
 }
 #endif /* CONFIG_PCI_DOMAINS */
 
+#else /* __ia64__ */
+
+#include <asm/pci.h>
+#define pcifront_sd pci_controller
+
+static inline struct pcifront_device *
+pcifront_get_pdev(struct pcifront_sd *sd)
+{
+       return (struct pcifront_device *)sd->platform_data;
+}
+
+static inline void pcifront_init_sd(struct pcifront_sd *sd, int domain,
+                                   struct pcifront_device *pdev)
+{
+       sd->segment = domain;
+       sd->acpi_handle = NULL;
+       sd->iommu = NULL;
+       sd->windows = 0;
+       sd->window = NULL;
+       sd->platform_data = pdev;
+}
+
+#endif /* __ia64__ */
+
 extern spinlock_t pci_bus_lock;
 
 #endif /* __KERNEL__ */
diff -r 61204c1d740e -r 87cefa5f7c5e tools/blktap/drivers/Makefile
--- a/tools/blktap/drivers/Makefile     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/blktap/drivers/Makefile     Mon Aug 07 18:00:22 2006 -0500
@@ -33,9 +33,7 @@ LIBS      += -lz
 LIBS      += -lz
 LIBS      += -L$(XEN_XENSTORE) -lxenstore
 
-AIOLIBS   := -L $(LIBAIO_DIR)
-AIOLIBS   += -laio
-AIOLIBS   += -static
+AIOLIBS   := $(LIBAIO_DIR)/libaio.a
 
 BLK-OBJS  := block-aio.o 
 BLK-OBJS  += block-sync.o 
@@ -49,21 +47,18 @@ LINUX_ROOT := $(wildcard $(XEN_ROOT)/lin
 LINUX_ROOT := $(wildcard $(XEN_ROOT)/linux-2.6.*-xen-sparse)
 
 
-blktapctrl: 
+blktapctrl: blktapctrl.c
        $(CC) $(CFLAGS) -o blktapctrl $(LIBS) blktapctrl.c
 
-tapdisk: $(BLK-OBJS)
+tapdisk: $(BLK-OBJS) tapdisk.c
        $(CC) $(CFLAGS) -o tapdisk $(BLK-OBJS) tapdisk.c \
                $(AIOLIBS) $(LIBS)
 
+.PHONY: qcow-util
+qcow-util: img2qcow qcow2raw qcow-create
 
-qcow-util: $(BLK-OBJS)
-       $(CC) $(CFLAGS) -o img2qcow $(BLK-OBJS) img2qcow.c \
-               $(AIOLIBS)  $(LIBS)
-       $(CC) $(CFLAGS) -o qcow2raw $(BLK-OBJS) qcow2raw.c  \
-               $(AIOLIBS)  $(LIBS)
-       $(CC) $(CFLAGS) -o qcow-create $(BLK-OBJS) qcow-create.c  \
-               $(AIOLIBS)  $(LIBS)
+img2qcow qcow2raw qcow-create: %: $(BLK-OBJS)
+       $(CC) $(CFLAGS) -o $* $(BLK-OBJS) $*.c $(AIOLIBS)  $(LIBS)
 
 install: all
        $(INSTALL_PROG) $(IBIN) $(QCOW_UTIL) $(DESTDIR)$(INSTALL_DIR)
diff -r 61204c1d740e -r 87cefa5f7c5e tools/blktap/drivers/blktapctrl.c
--- a/tools/blktap/drivers/blktapctrl.c Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/blktap/drivers/blktapctrl.c Mon Aug 07 18:00:22 2006 -0500
@@ -61,6 +61,7 @@
 #define MSG_SIZE 4096
 #define MAX_TIMEOUT 10
 #define MAX_RAND_VAL 0xFFFF
+#define MAX_ATTEMPTS 10
 
 int run = 1;
 int max_timeout = MAX_TIMEOUT;
@@ -626,13 +627,14 @@ int main(int argc, char *argv[])
 {
        char *devname;
        tapdev_info_t *ctlinfo;
-       int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count;
+       int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count, count=0;
        struct xs_handle *h;
        struct pollfd  pfd[NUM_POLL_FDS];
        pid_t process;
 
        __init_blkif();
        openlog("BLKTAPCTRL", LOG_CONS|LOG_ODELAY, LOG_DAEMON);
+       daemon(0,0);
 
        print_drivers();
        init_driver_list();
@@ -651,18 +653,28 @@ int main(int argc, char *argv[])
                goto open_failed;
        }
 
+ retry:
        /* Set up store connection and watch. */
        h = xs_daemon_open();
        if (h == NULL) {
                DPRINTF("xs_daemon_open failed -- "
                        "is xenstore running?\n");
-               goto open_failed;
+                if (count < MAX_ATTEMPTS) {
+                        count++;
+                        sleep(2);
+                        goto retry;
+                } else goto open_failed;
        }
        
        ret = add_blockdevice_probe_watch(h, "Domain-0");
        if (ret != 0) {
-               DPRINTF("adding device probewatch\n");
-               goto open_failed;
+               DPRINTF("Failed adding device probewatch\n");
+                if (count < MAX_ATTEMPTS) {
+                        count++;
+                        sleep(2);
+                        xs_daemon_close(h);
+                        goto retry;
+                } else goto open_failed;
        }
 
        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
@@ -691,6 +703,7 @@ int main(int argc, char *argv[])
                }
        }
 
+       xs_daemon_close(h);
        ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH );
        close(ctlfd);
        closelog();
diff -r 61204c1d740e -r 87cefa5f7c5e tools/blktap/lib/Makefile
--- a/tools/blktap/lib/Makefile Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/blktap/lib/Makefile Mon Aug 07 18:00:22 2006 -0500
@@ -35,10 +35,14 @@ IBINS   :=
 
 LIB      = libblktap.a libblktap.so.$(MAJOR).$(MINOR)
 
+.PHONY: all
 all: build
 
-build:
-       $(MAKE) libblktap
+.PHONY: build
+build: libblktap.a
+
+.PHONY: libblktap
+libblktap: libblktap.a
 
 install: all
        $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
@@ -51,13 +55,13 @@ clean:
 clean:
        rm -rf *.a *.so* *.o *.rpm $(LIB) *~ $(DEPS) xen TAGS
 
-libblktap: $(OBJS) 
+libblktap.a: $(OBJS) 
        $(CC) $(CFLAGS) -Wl,-soname -Wl,$(SONAME) -shared         \
              -L$(XEN_XENSTORE) -l xenstore                       \
              -o libblktap.so.$(MAJOR).$(MINOR) $^ $(LIBS)
        ln -sf libblktap.so.$(MAJOR).$(MINOR) libblktap.so.$(MAJOR)
-       ln -sf libblktap.so.$(MAJOR) $@.so
-       ar rc libblktap.a $@.so
+       ln -sf libblktap.so.$(MAJOR) libblktap.so
+       ar rc $@ libblktap.so
 
 .PHONY: TAGS all build clean install libblktap
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/examples/block
--- a/tools/examples/block      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/examples/block      Mon Aug 07 18:00:22 2006 -0500
@@ -239,8 +239,11 @@ case "$command" in
       exit 0
     fi
 
-    p=$(xenstore_read "$XENBUS_PATH/params")
-    mode=$(xenstore_read "$XENBUS_PATH/mode")
+    if [ -n "$t" ]
+    then
+      p=$(xenstore_read "$XENBUS_PATH/params")
+      mode=$(xenstore_read "$XENBUS_PATH/mode")
+    fi
 
     case $t in 
       phy)
@@ -370,6 +373,13 @@ mount it read-write in a guest domain."
         release_lock "block"
         exit 0
        ;;
+
+      "")
+        claim_lock "block"
+        success
+        echo happy gun \"$t\" >>/tmp/block.$$
+        release_lock "block"
+       ;;
     esac
     ;;
 
@@ -384,6 +394,10 @@ mount it read-write in a guest domain."
        losetup -d "$node"
        exit 0
        ;;
+
+      "")
+        exit 0
+       ;;
     esac
     ;;
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/examples/xmexample.hvm      Mon Aug 07 18:00:22 2006 -0500
@@ -66,7 +66,7 @@ vif = [ 'type=ioemu, bridge=xenbr0' ]
 # and MODE is r for read-only, w for read-write.
 
 #disk = [ 'phy:hda1,hda1,r' ]
-disk = [ 'file:/var/images/min-el3-i386.img,ioemu:hda,w' ]
+disk = [ 'file:/var/images/min-el3-i386.img,hda,w', ',hdc:cdrom,r' ]
 
 #----------------------------------------------------------------------------
 # Configure the behaviour when a domain exits.  There are three 'reasons'
@@ -111,10 +111,6 @@ device_model = '/usr/' + arch_libdir + '
 device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
 
 #-----------------------------------------------------------------------------
-# Disk image for 
-#cdrom=
-
-#-----------------------------------------------------------------------------
 # boot on floppy (a), hard disk (c) or CD-ROM (d) 
 #boot=[a|c|d]
 #-----------------------------------------------------------------------------
@@ -153,8 +149,8 @@ serial='pty'
 
 
 #-----------------------------------------------------------------------------
-#   enable audio support
-#audio=1
+#   enable sound card support, [sb16|es1370|all|..,..], default none
+#soundhw='sb16'
 
 
 #-----------------------------------------------------------------------------
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/Makefile
--- a/tools/firmware/Makefile   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/Makefile   Mon Aug 07 18:00:22 2006 -0500
@@ -30,7 +30,7 @@ all:
 .PHONY: install
 install: all
        [ -d $(INSTALL_DIR) ] || install -d -m0755 $(INSTALL_DIR)
-       [ ! -e $(TARGET) ] || install -m0644 $(TARGET) $(INSTALL_DIR)
+       install -m0644 $(TARGET) $(INSTALL_DIR)
 
 .PHONY: clean
 clean: 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/acpi/acpi_dsdt.asl
--- a/tools/firmware/acpi/acpi_dsdt.asl Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/acpi/acpi_dsdt.asl Mon Aug 07 18:00:22 2006 -0500
@@ -16,7 +16,7 @@
 //* Place - Suite 330, Boston, MA 02111-1307 USA.
 
 //**
-//**           DSDT for Xen with Qemu device model
+//**  DSDT for Xen with Qemu device model
 //**
 //**
 
@@ -50,21 +50,36 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
     })
 
 
-       Name(PICD, 0)   
-
-       Method(_PIC, 1) { 
+    Name(PICD, 0)
+
+    Method(_PIC, 1) { 
  
-               Store(Arg0, PICD) 
-       }
+    Store(Arg0, PICD) 
+    }
     Scope (\_SB)
     {
-        Device (PCI0)
+       /* Fix HCT test for 0x400 pci memory - need to report low 640 MB mem as 
motherboard resource            */
+
+       Device(MEM0) {
+           Name(_HID, EISAID("PNP0C02"))
+           Name(_CRS, ResourceTemplate() {
+           QWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, 
Cacheable, ReadWrite,
+                    0x00000000,
+                    0x00000000,
+                    0x0009ffff,
+                    0x00000000,
+                    0x000a0000)
+           }
+           )
+       }
+
+       Device (PCI0)
         {
-            Name (_HID, EisaId ("PNP0A03"))
-            Name (_UID, 0x00)
-            Name (_ADR, 0x00)
-            Name (_BBN, 0x00)
-            OperationRegion (PIRP, PCI_Config, 0x3c, 0x10)
+           Name (_HID, EisaId ("PNP0A03"))
+           Name (_UID, 0x00)
+           Name (_ADR, 0x00)
+           Name (_BBN, 0x00)
+           OperationRegion (PIRP, PCI_Config, 0x3c, 0x10)
            Field(PIRP, ByteAcc, NoLock, Preserve){        
           IRQ3,3,
           IRQ5,5,
@@ -79,7 +94,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
           
                Name (PRT0, ResourceTemplate ()
                 {
-                                       /* bus number is from 0 - 255*/
+         /* bus number is from 0 - 255*/
                     WordBusNumber (ResourceConsumer, MinFixed, MaxFixed, 
SubDecode,
                         0x0000,
                         0x0000,
@@ -122,7 +137,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                         0x00000000,
                         0x00030000)
 
-                 /* reserve what device model consumed for PCI VGA device      
  */
+                /* reserve what device model consumed for PCI VGA device       
 */
 
                     DWordMemory (ResourceConsumer, PosDecode, MinFixed, 
MaxFixed, Cacheable, ReadWrite,
                         0x00000000,
@@ -146,9 +161,9 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                 })
                 Return (PRT0)
             }
-       Name(BUFA, ResourceTemplate() {
+       Name(BUFA, ResourceTemplate() {
                 IRQ(Level, ActiveLow, Shared) {
-                        3,4,5,6,7,10,11,12,14,15}               
+                        3,4,5,6,7,10,11,12,14,15} 
                 }) 
 
                 Name(BUFB, Buffer(){
@@ -156,7 +171,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                 0x79, 0})
 
                 CreateWordField(BUFB, 0x01, IRQV)
-               
+
                 Name(BUFC, Buffer(){
                 5, 7, 10, 11
                  })
@@ -165,17 +180,17 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                 CreateByteField(BUFC, 0x01, PIQB)
                 CreateByteField(BUFC, 0x01, PIQC)
                 CreateByteField(BUFC, 0x01, PIQD)
-                               
-               Device(LNKA)    {
-                Name(_HID, EISAID("PNP0C0F"))  // PCI interrupt link
+                
+                Device(LNKA)    {
+                Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
                 Name(_UID, 1)
                 Method(_STA, 0) {
                                And(PIRA, 0x80, Local0)
                         If(LEqual(Local0, 0x80)) {
-                                Return(0x09)   
+                                Return(0x09)   
                                 }
                         Else {
-                                Return(0x0B)   
+                                Return(0x0B) 
                                 }
                         }
 
@@ -189,34 +204,34 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                 }
 
                 Method(_CRS) {
-                        And(PIRB, 0x0f, Local0)                 
-                        ShiftLeft(0x1, Local0, IRQV)    
-                        Return(BUFB)                    
+                        And(PIRB, 0x0f, Local0) 
+                        ShiftLeft(0x1, Local0, IRQV) 
+                        Return(BUFB) 
                 } 
 
                 Method(_SRS, 1) {
-                                CreateWordField(ARG0, 0x01, IRQ1)       
-                        FindSetRightBit(IRQ1, Local0)           
-                        Decrement(Local0)                       
-                        Store(Local0, PIRA)                     
+                                CreateWordField(ARG0, 0x01, IRQ1) 
+                        FindSetRightBit(IRQ1, Local0) 
+                        Decrement(Local0) 
+                        Store(Local0, PIRA)
                  } // Method(_SRS)
         }
 
-        Device(LNKB)   {
-                Name(_HID, EISAID("PNP0C0F"))   
+        Device(LNKB){
+                Name(_HID, EISAID("PNP0C0F"))  
                 Name(_UID, 2)
                 Method(_STA, 0) {
                                And(PIRB, 0x80, Local0)
                         If(LEqual(Local0, 0x80)) {
-                                Return(0x09)    
+                                Return(0x09) 
                                 }
                         Else {
-                                Return(0x0B)    
+                                Return(0x0B) 
                                 }
                         }
 
                 Method(_PRS) {
-                                Return(BUFA)                    
+                                Return(BUFA) 
                 } // Method(_PRS)
 
                 Method(_DIS) {
@@ -225,35 +240,35 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                 }
 
                 Method(_CRS) {
-                        And(PIRB, 0x0f, Local0)                 
-                        ShiftLeft(0x1, Local0, IRQV)    
-                        Return(BUFB)                    
+                        And(PIRB, 0x0f, Local0) 
+                        ShiftLeft(0x1, Local0, IRQV) 
+                        Return(BUFB) 
                 } // Method(_CRS)
 
                 Method(_SRS, 1) {
-                                CreateWordField(ARG0, 0x01, IRQ1)       
-                        FindSetRightBit(IRQ1, Local0)           
-                        Decrement(Local0)                       
-                        Store(Local0, PIRB)                     
+                        CreateWordField(ARG0, 0x01, IRQ1) 
+                        FindSetRightBit(IRQ1, Local0) 
+                        Decrement(Local0)
+                        Store(Local0, PIRB) 
                  } // Method(_SRS)
         }
 
-        Device(LNKC)   {
-                Name(_HID, EISAID("PNP0C0F"))  // PCI interrupt link
+        Device(LNKC){
+                Name(_HID, EISAID("PNP0C0F")) // PCI interrupt link
                 Name(_UID, 3)
                 Method(_STA, 0) {
-                               And(PIRC, 0x80, Local0)
+                        And(PIRC, 0x80, Local0)
                         If(LEqual(Local0, 0x80)) {
-                                Return(0x09)    
+                                Return(0x09) 
                         }
                         Else {
-                                Return(0x0B)    
-                        }
-                }
-
-                Method(_PRS) {                          
-                        Return(BUFA)                    
-                } // Method(_PRS)                       
+                                Return(0x0B)
+                        }
+                }
+
+                Method(_PRS) { 
+                        Return(BUFA)
+                } // Method(_PRS)
 
                 Method(_DIS) {
 
@@ -261,91 +276,89 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                 }
 
                 Method(_CRS) {
-                        And(PIRC, 0x0f, Local0)                 
-                        ShiftLeft(0x1, Local0, IRQV)    
-                        Return(BUFB)                    
+                        And(PIRC, 0x0f, Local0) 
+                        ShiftLeft(0x1, Local0, IRQV) 
+                        Return(BUFB) 
                 } // Method(_CRS)
 
                 Method(_SRS, 1) {
-                                CreateWordField(ARG0, 0x01, IRQ1)       
-                        FindSetRightBit(IRQ1, Local0)           
-                        Decrement(Local0)                       
-                        Store(Local0, PIRC)                     
+                                CreateWordField(ARG0, 0x01, IRQ1) 
+                        FindSetRightBit(IRQ1, Local0) 
+                        Decrement(Local0) 
+                        Store(Local0, PIRC)
                  } // Method(_SRS)
         }
 
-        Device(LNKD)   {
-                Name(_HID, EISAID("PNP0C0F"))   
+        Device(LNKD) {
+                Name(_HID, EISAID("PNP0C0F"))  
                 Name(_UID, 4)
                 Method(_STA, 0) {
                                And(PIRD, 0x80, Local0)
                         If(LEqual(Local0, 0x80)) {
-                                Return(0x09)    
+                                Return(0x09) 
                         }
                         Else {
-                                Return(0x0B)    
-                        }
-                }
-
-                Method(_PRS) {                          
-                        Return(BUFA)                    
-                } // Method(_PRS)                       
+                                Return(0x0B) 
+                        }
+                }
+
+                Method(_PRS) { 
+                        Return(BUFA) 
+                } // Method(_PRS)
 
                 Method(_DIS) {
                                Or(PIRD, 0x80, PIRD)
                 }
 
                 Method(_CRS) {
-                        And(PIRD, 0x0f, Local0)                 
-                        ShiftLeft(0x1, Local0, IRQV)    
-                        Return(BUFB)                    
+                        And(PIRD, 0x0f, Local0) 
+                        ShiftLeft(0x1, Local0, IRQV) 
+                        Return(BUFB) 
                 } // Method(_CRS)
 
                 Method(_SRS, 1) {
-                                CreateWordField(ARG0, 0x01, IRQ1)       
-                        FindSetRightBit(IRQ1, Local0)           
-                        Decrement(Local0)                       
-                        Store(Local0, PIRD)                     
+                                CreateWordField(ARG0, 0x01, IRQ1) 
+                        FindSetRightBit(IRQ1, Local0) 
+                        Decrement(Local0) 
+                        Store(Local0, PIRD) 
                  } // Method(_SRS)
         }
         Method(_PRT,0) {
-                       If(PICD) {Return(PRTA)}  
-                       Return (PRTP)  
-               } // end _PRT
-               
-               
+               If(PICD) {Return(PRTA)}  
+               Return (PRTP)  
+               } // end _PRT
+
         Name(PRTP, Package(){
-                        Package(){0x0000ffff, 0, \_SB.PCI0.LNKA, 0},   // Slot 
1, INTA
-                        Package(){0x0000ffff, 1, \_SB.PCI0.LNKB, 0},   // Slot 
1, INTB
-                        Package(){0x0000ffff, 2, \_SB.PCI0.LNKC, 0},   // Slot 
1, INTC
-                        Package(){0x0000ffff, 3, \_SB.PCI0.LNKD, 0},   // Slot 
1, INTD
-
-                        Package(){0x0001ffff, 0, \_SB.PCI0.LNKB, 0},   // Slot 
2, INTB
-                        Package(){0x0001ffff, 1, \_SB.PCI0.LNKC, 0},   // Slot 
2, INTC
-                        Package(){0x0001ffff, 2, \_SB.PCI0.LNKD, 0},   // Slot 
2, INTD
-                        Package(){0x0001ffff, 3, \_SB.PCI0.LNKA, 0},   // Slot 
2, INTA
+                        Package(){0x0000ffff, 0, \_SB.PCI0.LNKA, 0}, // Slot 
1, INTA
+                        Package(){0x0000ffff, 1, \_SB.PCI0.LNKB, 0}, // Slot 
1, INTB
+                        Package(){0x0000ffff, 2, \_SB.PCI0.LNKC, 0}, // Slot 
1, INTC
+                        Package(){0x0000ffff, 3, \_SB.PCI0.LNKD, 0}, // Slot 
1, INTD
+
+                        Package(){0x0001ffff, 0, \_SB.PCI0.LNKB, 0}, // Slot 
2, INTB
+                        Package(){0x0001ffff, 1, \_SB.PCI0.LNKC, 0}, // Slot 
2, INTC
+                        Package(){0x0001ffff, 2, \_SB.PCI0.LNKD, 0}, // Slot 
2, INTD
+                        Package(){0x0001ffff, 3, \_SB.PCI0.LNKA, 0}, // Slot 
2, INTA
                         
-                        Package(){0x0002ffff, 0, \_SB.PCI0.LNKC, 0},   // Slot 
3, INTC
-                        Package(){0x0002ffff, 1, \_SB.PCI0.LNKD, 0},   // Slot 
3, INTD
-                        Package(){0x0002ffff, 2, \_SB.PCI0.LNKA, 0},   // Slot 
3, INTA
-                        Package(){0x0002ffff, 3, \_SB.PCI0.LNKB, 0},   // Slot 
3, INTB
+                        Package(){0x0002ffff, 0, \_SB.PCI0.LNKC, 0}, // Slot 
3, INTC
+                        Package(){0x0002ffff, 1, \_SB.PCI0.LNKD, 0}, // Slot 
3, INTD
+                        Package(){0x0002ffff, 2, \_SB.PCI0.LNKA, 0}, // Slot 
3, INTA
+                        Package(){0x0002ffff, 3, \_SB.PCI0.LNKB, 0}, // Slot 
3, INTB
                         
-                        Package(){0x0003ffff, 0, \_SB.PCI0.LNKD, 0},   // Slot 
2, INTD
-                        Package(){0x0003ffff, 1, \_SB.PCI0.LNKA, 0},   // Slot 
2, INTA
-                        Package(){0x0003ffff, 2, \_SB.PCI0.LNKB, 0},   // Slot 
2, INTB
-                        Package(){0x0003ffff, 3, \_SB.PCI0.LNKC, 0},   // Slot 
2, INTC
+                        Package(){0x0003ffff, 0, \_SB.PCI0.LNKD, 0}, // Slot 
2, INTD
+                        Package(){0x0003ffff, 1, \_SB.PCI0.LNKA, 0}, // Slot 
2, INTA
+                        Package(){0x0003ffff, 2, \_SB.PCI0.LNKB, 0}, // Slot 
2, INTB
+                        Package(){0x0003ffff, 3, \_SB.PCI0.LNKC, 0}, // Slot 
2, INTC
                         
                         }
             )
-       Name(PRTA, Package(){
-                        Package(){0x0001ffff, 0, 0, 5},        // Device 1, 
INTA
-
-                        Package(){0x0002ffff, 0, 0, 7},        // Device 2, 
INTA
+        Name(PRTA, Package(){
+                        Package(){0x0001ffff, 0, 0, 5}, // Device 1, INTA
+
+                        Package(){0x0002ffff, 0, 0, 7},  // Device 2, INTA
                        
-                        Package(){0x0003ffff, 0, 0, 10},       // Device 3, 
INTA
-
-                        Package(){0x0003ffff, 0, 0, 11},       // Device 4, 
INTA
-                                   
+                        Package(){0x0003ffff, 0, 0, 10}, // Device 3, INTA
+
+                        Package(){0x0004ffff, 0, 0, 11},  // Device 4, INTA    
                            
                         
                         }
             )
@@ -354,22 +367,22 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
             {
                 Name (_ADR, 0x00000000) /* device id, PCI bus num, ... */
  
-               OperationRegion(PIRQ, PCI_Config, 0x60, 0x4)
+            OperationRegion(PIRQ, PCI_Config, 0x60, 0x4)
                         Scope(\) {
-                                Field (\_SB.PCI0.ISA.PIRQ, ByteAcc, NoLock, 
Preserve) {
+                                 Field (\_SB.PCI0.ISA.PIRQ, ByteAcc, NoLock, 
Preserve) {
                                         PIRA, 8,
                                         PIRB, 8,
                                         PIRC, 8,
                                         PIRD, 8
                                         }
-                                }
+                                 }
                 Device (SYSR)
                 {
                     Name (_HID, EisaId ("PNP0C02"))
                     Name (_UID, 0x01)
                     Name (CRS, ResourceTemplate ()
                     {
-                                               /* TODO: list hidden resources 
*/
+               /* TODO: list hidden resources */
                         IO (Decode16, 0x0010, 0x0010, 0x00, 0x10)
                         IO (Decode16, 0x0022, 0x0022, 0x00, 0x0C)
                         IO (Decode16, 0x0030, 0x0030, 0x00, 0x10)
@@ -417,7 +430,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 
                         IO (Decode16, 0x0089, 0x0089, 0x00, 0x03)
                         IO (Decode16, 0x008F, 0x008F, 0x00, 0x01)
                         IO (Decode16, 0x00C0, 0x00C0, 0x00, 0x20)
-                                               IO (Decode16, 0x0480, 0x0480, 
0x00, 0x10)
+                        IO (Decode16, 0x0480, 0x0480, 0x00, 0x10)
                     })
                 }
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/acpi/acpi_dsdt.c
--- a/tools/firmware/acpi/acpi_dsdt.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/acpi/acpi_dsdt.c   Mon Aug 07 18:00:22 2006 -0500
@@ -5,15 +5,15 @@
  * Copyright (C) 2000 - 2005 Intel Corporation
  * Supports ACPI Specification Revision 3.0
  * 
- * Compilation of "acpi_dsdt.asl" - Mon Jun 12 22:33:41 2006
+ * Compilation of "acpi_dsdt.asl" - Thu Aug  3 11:05:15 2006
  * 
  * C source code output
  *
  */
 unsigned char AmlCode[] = 
 {
-    0x44,0x53,0x44,0x54,0xC3,0x08,0x00,0x00,  /* 00000000    "DSDT...." */
-    0x01,0x0C,0x49,0x4E,0x54,0x45,0x4C,0x00,  /* 00000008    "..INTEL." */
+    0x44,0x53,0x44,0x54,0x0E,0x09,0x00,0x00,  /* 00000000    "DSDT...." */
+    0x01,0x03,0x49,0x4E,0x54,0x45,0x4C,0x00,  /* 00000008    "..INTEL." */
     0x69,0x6E,0x74,0x2D,0x78,0x65,0x6E,0x00,  /* 00000010    "int-xen." */
     0xD6,0x07,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
     0x13,0x05,0x05,0x20,0x08,0x50,0x4D,0x42,  /* 00000020    "... .PMB" */
@@ -34,264 +34,273 @@ unsigned char AmlCode[] =
     0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00,  /* 00000098    "........" */
     0x00,0x08,0x50,0x49,0x43,0x44,0x00,0x14,  /* 000000A0    "..PICD.." */
     0x0C,0x5F,0x50,0x49,0x43,0x01,0x70,0x68,  /* 000000A8    "._PIC.ph" */
-    0x50,0x49,0x43,0x44,0x10,0x4E,0x80,0x5F,  /* 000000B0    "PICD.N._" */
-    0x53,0x42,0x5F,0x5B,0x82,0x46,0x80,0x50,  /* 000000B8    "SB_[.F.P" */
-    0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 000000C0    "CI0._HID" */
-    0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x55,  /* 000000C8    ".A...._U" */
-    0x49,0x44,0x00,0x08,0x5F,0x41,0x44,0x52,  /* 000000D0    "ID.._ADR" */
-    0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x5B,  /* 000000D8    ".._BBN.[" */
-    0x80,0x50,0x49,0x52,0x50,0x02,0x0A,0x3C,  /* 000000E0    ".PIRP..<" */
-    0x0A,0x10,0x5B,0x81,0x24,0x50,0x49,0x52,  /* 000000E8    "..[.$PIR" */
-    0x50,0x01,0x49,0x52,0x51,0x33,0x03,0x49,  /* 000000F0    "P.IRQ3.I" */
-    0x52,0x51,0x35,0x05,0x49,0x52,0x51,0x37,  /* 000000F8    "RQ5.IRQ7" */
-    0x07,0x49,0x52,0x51,0x39,0x09,0x49,0x52,  /* 00000100    ".IRQ9.IR" */
-    0x51,0x41,0x0A,0x49,0x52,0x51,0x42,0x0B,  /* 00000108    "QA.IRQB." */
-    0x14,0x48,0x0D,0x5F,0x43,0x52,0x53,0x00,  /* 00000110    ".H._CRS." */
-    0x08,0x50,0x52,0x54,0x30,0x11,0x46,0x0C,  /* 00000118    ".PRT0.F." */
-    0x0A,0xC2,0x88,0x0D,0x00,0x02,0x0F,0x00,  /* 00000120    "........" */
-    0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,  /* 00000128    "........" */
-    0x00,0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C,  /* 00000130    "..G....." */
-    0x01,0x08,0x88,0x0D,0x00,0x01,0x0C,0x03,  /* 00000138    "........" */
-    0x00,0x00,0x00,0x00,0xF7,0x0C,0x00,0x00,  /* 00000140    "........" */
-    0xF8,0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03,  /* 00000148    "........" */
-    0x00,0x00,0x00,0x0D,0xFF,0x0F,0x00,0x00,  /* 00000150    "........" */
-    0x00,0x03,0x88,0x0D,0x00,0x01,0x0D,0x03,  /* 00000158    "........" */
-    0x00,0x00,0x00,0xC0,0x1F,0xC0,0x00,0x00,  /* 00000160    "........" */
-    0x20,0x00,0x88,0x0D,0x00,0x01,0x0D,0x03,  /* 00000168    " ......." */
-    0x00,0x00,0x20,0xC0,0x3F,0xC0,0x00,0x00,  /* 00000170    ".. .?..." */
-    0x10,0x00,0x87,0x17,0x00,0x00,0x0C,0x02,  /* 00000178    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,  /* 00000180    "........" */
-    0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,  /* 00000188    "........" */
-    0x00,0x00,0x03,0x00,0x87,0x17,0x00,0x00,  /* 00000190    "........" */
-    0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,  /* 00000198    "........" */
-    0x00,0xF0,0xFF,0xFF,0xFF,0xF1,0x00,0x00,  /* 000001A0    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x02,0x87,0x17,  /* 000001A8    "........" */
-    0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00,  /* 000001B0    "........" */
-    0x00,0x00,0x00,0xF2,0xFF,0x0F,0x00,0xF2,  /* 000001B8    "........" */
-    0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,  /* 000001C0    "........" */
-    0x87,0x17,0x00,0x00,0x0D,0x03,0x00,0x00,  /* 000001C8    "........" */
-    0x00,0x00,0x00,0x10,0x00,0xF2,0x1F,0x10,  /* 000001D0    "........" */
-    0x00,0xF2,0x00,0x00,0x00,0x00,0x20,0x00,  /* 000001D8    "...... ." */
-    0x00,0x00,0x79,0x00,0xA4,0x50,0x52,0x54,  /* 000001E0    "..y..PRT" */
-    0x30,0x08,0x42,0x55,0x46,0x41,0x11,0x09,  /* 000001E8    "0.BUFA.." */
-    0x0A,0x06,0x23,0xF8,0xDC,0x18,0x79,0x00,  /* 000001F0    "..#...y." */
-    0x08,0x42,0x55,0x46,0x42,0x11,0x09,0x0A,  /* 000001F8    ".BUFB..." */
-    0x06,0x23,0x00,0x00,0x18,0x79,0x00,0x8B,  /* 00000200    ".#...y.." */
-    0x42,0x55,0x46,0x42,0x01,0x49,0x52,0x51,  /* 00000208    "BUFB.IRQ" */
-    0x56,0x08,0x42,0x55,0x46,0x43,0x11,0x07,  /* 00000210    "V.BUFC.." */
-    0x0A,0x04,0x05,0x07,0x0A,0x0B,0x8C,0x42,  /* 00000218    ".......B" */
-    0x55,0x46,0x43,0x01,0x50,0x49,0x51,0x41,  /* 00000220    "UFC.PIQA" */
-    0x8C,0x42,0x55,0x46,0x43,0x01,0x50,0x49,  /* 00000228    ".BUFC.PI" */
-    0x51,0x42,0x8C,0x42,0x55,0x46,0x43,0x01,  /* 00000230    "QB.BUFC." */
-    0x50,0x49,0x51,0x43,0x8C,0x42,0x55,0x46,  /* 00000238    "PIQC.BUF" */
-    0x43,0x01,0x50,0x49,0x51,0x44,0x5B,0x82,  /* 00000240    "C.PIQD[." */
-    0x48,0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,  /* 00000248    "H.LNKA._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 00000250    "HID.A..." */
-    0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,  /* 00000258    "._UID..." */
-    0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49,  /* 00000260    "_STA.{PI" */
-    0x52,0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,  /* 00000268    "RA..`..." */
-    0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,  /* 00000270    "`......." */
-    0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,  /* 00000278    "....._PR" */
-    0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14,  /* 00000280    "S..BUFA." */
-    0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,  /* 00000288    "._DIS.}P" */
-    0x49,0x52,0x41,0x0A,0x80,0x50,0x49,0x52,  /* 00000290    "IRA..PIR" */
-    0x41,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 00000298    "A.._CRS." */
-    0x7B,0x50,0x49,0x52,0x42,0x0A,0x0F,0x60,  /* 000002A0    "{PIRB..`" */
-    0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4,  /* 000002A8    "y.`IRQV." */
-    0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,  /* 000002B0    "BUFB.._S" */
-    0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52,  /* 000002B8    "RS..h.IR" */
-    0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60,  /* 000002C0    "Q1.IRQ1`" */
-    0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x41,  /* 000002C8    "v`p`PIRA" */
-    0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,  /* 000002D0    "[.I.LNKB" */
-    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000002D8    "._HID.A." */
-    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,  /* 000002E0    "..._UID." */
-    0x02,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,  /* 000002E8    "..._STA." */
-    0x7B,0x50,0x49,0x52,0x42,0x0A,0x80,0x60,  /* 000002F0    "{PIRB..`" */
-    0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,  /* 000002F8    "...`...." */
-    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,  /* 00000300    "........" */
-    0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55,  /* 00000308    "_PRS..BU" */
-    0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 00000310    "FA.._DIS" */
-    0x00,0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,  /* 00000318    ".}PIRB.." */
-    0x50,0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,  /* 00000320    "PIRB.._C" */
-    0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x42,  /* 00000328    "RS.{PIRB" */
-    0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52,  /* 00000330    "..`y.`IR" */
-    0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14,  /* 00000338    "QV.BUFB." */
-    0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00000340    "._SRS..h" */
-    0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52,  /* 00000348    ".IRQ1.IR" */
-    0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50,  /* 00000350    "Q1`v`p`P" */
-    0x49,0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,  /* 00000358    "IRB[.I.L" */
-    0x4E,0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,  /* 00000360    "NKC._HID" */
-    0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,  /* 00000368    ".A...._U" */
-    0x49,0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,  /* 00000370    "ID...._S" */
-    0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x43,  /* 00000378    "TA.{PIRC" */
-    0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,  /* 00000380    "..`...`." */
-    0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,  /* 00000388    "........" */
-    0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,  /* 00000390    "..._PRS." */
-    0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F,  /* 00000398    ".BUFA.._" */
-    0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52,  /* 000003A0    "DIS.}PIR" */
-    0x43,0x0A,0x80,0x50,0x49,0x52,0x43,0x14,  /* 000003A8    "C..PIRC." */
-    0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,  /* 000003B0    "._CRS.{P" */
-    0x49,0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,  /* 000003B8    "IRC..`y." */
-    0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55,  /* 000003C0    "`IRQV.BU" */
-    0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,  /* 000003C8    "FB.._SRS" */
-    0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31,  /* 000003D0    "..h.IRQ1" */
-    0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60,  /* 000003D8    ".IRQ1`v`" */
-    0x70,0x60,0x50,0x49,0x52,0x43,0x5B,0x82,  /* 000003E0    "p`PIRC[." */
-    0x49,0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,  /* 000003E8    "I.LNKD._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 000003F0    "HID.A..." */
-    0x08,0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,  /* 000003F8    "._UID..." */
-    0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,  /* 00000400    "._STA.{P" */
-    0x49,0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,  /* 00000408    "IRD..`.." */
-    0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,  /* 00000410    ".`......" */
-    0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,  /* 00000418    "......_P" */
-    0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41,  /* 00000420    "RS..BUFA" */
-    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 00000428    ".._DIS.}" */
-    0x50,0x49,0x52,0x44,0x0A,0x80,0x50,0x49,  /* 00000430    "PIRD..PI" */
-    0x52,0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000438    "RD.._CRS" */
-    0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,  /* 00000440    ".{PIRD.." */
-    0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56,  /* 00000448    "`y.`IRQV" */
-    0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,  /* 00000450    ".BUFB.._" */
-    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00000458    "SRS..h.I" */
-    0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31,  /* 00000460    "RQ1.IRQ1" */
-    0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52,  /* 00000468    "`v`p`PIR" */
-    0x44,0x14,0x16,0x5F,0x50,0x52,0x54,0x00,  /* 00000470    "D.._PRT." */
-    0xA0,0x0A,0x50,0x49,0x43,0x44,0xA4,0x50,  /* 00000478    "..PICD.P" */
-    0x52,0x54,0x41,0xA4,0x50,0x52,0x54,0x50,  /* 00000480    "RTA.PRTP" */
-    0x08,0x50,0x52,0x54,0x50,0x12,0x43,0x0E,  /* 00000488    ".PRTP.C." */
-    0x10,0x12,0x0B,0x04,0x0B,0xFF,0xFF,0x00,  /* 00000490    "........" */
-    0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0B,0x04,  /* 00000498    "LNKA...." */
-    0x0B,0xFF,0xFF,0x01,0x4C,0x4E,0x4B,0x42,  /* 000004A0    "....LNKB" */
-    0x00,0x12,0x0C,0x04,0x0B,0xFF,0xFF,0x0A,  /* 000004A8    "........" */
-    0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0C,  /* 000004B0    ".LNKC..." */
-    0x04,0x0B,0xFF,0xFF,0x0A,0x03,0x4C,0x4E,  /* 000004B8    "......LN" */
-    0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 000004C0    "KD......" */
-    0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42,  /* 000004C8    "....LNKB" */
-    0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,  /* 000004D0    "........" */
-    0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000004D8    "..LNKC.." */
-    0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,  /* 000004E0    "........" */
-    0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,  /* 000004E8    ".LNKD..." */
-    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,  /* 000004F0    "........" */
-    0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,  /* 000004F8    "LNKA...." */
-    0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E,  /* 00000500    "......LN" */
-    0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,  /* 00000508    "KC......" */
-    0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44,  /* 00000510    "....LNKD" */
-    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,  /* 00000518    "........" */
-    0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000520    "...LNKA." */
-    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000528    "........" */
-    0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,  /* 00000530    "..LNKB.." */
-    0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,  /* 00000538    "........" */
-    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,  /* 00000540    "LNKD...." */
-    0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E,  /* 00000548    "......LN" */
-    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000550    "KA......" */
-    0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B,  /* 00000558    ".....LNK" */
-    0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000560    "B......." */
-    0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,  /* 00000568    "....LNKC" */
-    0x00,0x08,0x50,0x52,0x54,0x41,0x12,0x32,  /* 00000570    "..PRTA.2" */
-    0x04,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,  /* 00000578    "........" */
-    0x00,0x00,0x00,0x0A,0x05,0x12,0x0B,0x04,  /* 00000580    "........" */
-    0x0C,0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A,  /* 00000588    "........" */
-    0x07,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,  /* 00000590    "........" */
-    0x00,0x00,0x00,0x0A,0x0A,0x12,0x0B,0x04,  /* 00000598    "........" */
-    0x0C,0xFF,0xFF,0x03,0x00,0x00,0x00,0x0A,  /* 000005A0    "........" */
-    0x0B,0x5B,0x82,0x48,0x31,0x49,0x53,0x41,  /* 000005A8    ".[.H1ISA" */
-    0x5F,0x08,0x5F,0x41,0x44,0x52,0x00,0x5B,  /* 000005B0    "_._ADR.[" */
-    0x80,0x50,0x49,0x52,0x51,0x02,0x0A,0x60,  /* 000005B8    ".PIRQ..`" */
-    0x0A,0x04,0x10,0x2E,0x5C,0x00,0x5B,0x81,  /* 000005C0    "....\.[." */
-    0x29,0x5C,0x2F,0x04,0x5F,0x53,0x42,0x5F,  /* 000005C8    ")\/._SB_" */
-    0x50,0x43,0x49,0x30,0x49,0x53,0x41,0x5F,  /* 000005D0    "PCI0ISA_" */
-    0x50,0x49,0x52,0x51,0x01,0x50,0x49,0x52,  /* 000005D8    "PIRQ.PIR" */
-    0x41,0x08,0x50,0x49,0x52,0x42,0x08,0x50,  /* 000005E0    "A.PIRB.P" */
-    0x49,0x52,0x43,0x08,0x50,0x49,0x52,0x44,  /* 000005E8    "IRC.PIRD" */
-    0x08,0x5B,0x82,0x46,0x0B,0x53,0x59,0x53,  /* 000005F0    ".[.F.SYS" */
-    0x52,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 000005F8    "R._HID.A" */
-    0xD0,0x0C,0x02,0x08,0x5F,0x55,0x49,0x44,  /* 00000600    "...._UID" */
-    0x01,0x08,0x43,0x52,0x53,0x5F,0x11,0x4E,  /* 00000608    "..CRS_.N" */
-    0x08,0x0A,0x8A,0x47,0x01,0x10,0x00,0x10,  /* 00000610    "...G...." */
-    0x00,0x00,0x10,0x47,0x01,0x22,0x00,0x22,  /* 00000618    "...G."."" */
-    0x00,0x00,0x0C,0x47,0x01,0x30,0x00,0x30,  /* 00000620    "...G.0.0" */
-    0x00,0x00,0x10,0x47,0x01,0x44,0x00,0x44,  /* 00000628    "...G.D.D" */
-    0x00,0x00,0x1C,0x47,0x01,0x62,0x00,0x62,  /* 00000630    "...G.b.b" */
-    0x00,0x00,0x02,0x47,0x01,0x65,0x00,0x65,  /* 00000638    "...G.e.e" */
-    0x00,0x00,0x0B,0x47,0x01,0x72,0x00,0x72,  /* 00000640    "...G.r.r" */
-    0x00,0x00,0x0E,0x47,0x01,0x80,0x00,0x80,  /* 00000648    "...G...." */
-    0x00,0x00,0x01,0x47,0x01,0x84,0x00,0x84,  /* 00000650    "...G...." */
-    0x00,0x00,0x03,0x47,0x01,0x88,0x00,0x88,  /* 00000658    "...G...." */
-    0x00,0x00,0x01,0x47,0x01,0x8C,0x00,0x8C,  /* 00000660    "...G...." */
-    0x00,0x00,0x03,0x47,0x01,0x90,0x00,0x90,  /* 00000668    "...G...." */
-    0x00,0x00,0x10,0x47,0x01,0xA2,0x00,0xA2,  /* 00000670    "...G...." */
-    0x00,0x00,0x1C,0x47,0x01,0xE0,0x00,0xE0,  /* 00000678    "...G...." */
-    0x00,0x00,0x10,0x47,0x01,0xA0,0x08,0xA0,  /* 00000680    "...G...." */
-    0x08,0x00,0x04,0x47,0x01,0xC0,0x0C,0xC0,  /* 00000688    "...G...." */
-    0x0C,0x00,0x10,0x47,0x01,0xD0,0x04,0xD0,  /* 00000690    "...G...." */
-    0x04,0x00,0x02,0x79,0x00,0x14,0x0B,0x5F,  /* 00000698    "...y..._" */
-    0x43,0x52,0x53,0x00,0xA4,0x43,0x52,0x53,  /* 000006A0    "CRS..CRS" */
-    0x5F,0x5B,0x82,0x2B,0x50,0x49,0x43,0x5F,  /* 000006A8    "_[.+PIC_" */
-    0x08,0x5F,0x48,0x49,0x44,0x0B,0x41,0xD0,  /* 000006B0    "._HID.A." */
-    0x08,0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,  /* 000006B8    "._CRS..." */
-    0x15,0x47,0x01,0x20,0x00,0x20,0x00,0x01,  /* 000006C0    ".G. . .." */
-    0x02,0x47,0x01,0xA0,0x00,0xA0,0x00,0x01,  /* 000006C8    ".G......" */
-    0x02,0x22,0x04,0x00,0x79,0x00,0x5B,0x82,  /* 000006D0    "."..y.[." */
-    0x47,0x05,0x44,0x4D,0x41,0x30,0x08,0x5F,  /* 000006D8    "G.DMA0._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x02,0x00,  /* 000006E0    "HID.A..." */
-    0x08,0x5F,0x43,0x52,0x53,0x11,0x41,0x04,  /* 000006E8    "._CRS.A." */
-    0x0A,0x3D,0x2A,0x10,0x04,0x47,0x01,0x00,  /* 000006F0    ".=*..G.." */
-    0x00,0x00,0x00,0x00,0x10,0x47,0x01,0x81,  /* 000006F8    ".....G.." */
-    0x00,0x81,0x00,0x00,0x03,0x47,0x01,0x87,  /* 00000700    ".....G.." */
-    0x00,0x87,0x00,0x00,0x01,0x47,0x01,0x89,  /* 00000708    ".....G.." */
-    0x00,0x89,0x00,0x00,0x03,0x47,0x01,0x8F,  /* 00000710    ".....G.." */
-    0x00,0x8F,0x00,0x00,0x01,0x47,0x01,0xC0,  /* 00000718    ".....G.." */
-    0x00,0xC0,0x00,0x00,0x20,0x47,0x01,0x80,  /* 00000720    ".... G.." */
-    0x04,0x80,0x04,0x00,0x10,0x79,0x00,0x5B,  /* 00000728    ".....y.[" */
-    0x82,0x25,0x54,0x4D,0x52,0x5F,0x08,0x5F,  /* 00000730    ".%TMR_._" */
-    0x48,0x49,0x44,0x0C,0x41,0xD0,0x01,0x00,  /* 00000738    "HID.A..." */
-    0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,  /* 00000740    "._CRS..." */
-    0x0D,0x47,0x01,0x40,0x00,0x40,0x00,0x00,  /* 00000748    ".G.@.@.." */
-    0x04,0x22,0x01,0x00,0x79,0x00,0x5B,0x82,  /* 00000750    "."..y.[." */
-    0x25,0x52,0x54,0x43,0x5F,0x08,0x5F,0x48,  /* 00000758    "%RTC_._H" */
-    0x49,0x44,0x0C,0x41,0xD0,0x0B,0x00,0x08,  /* 00000760    "ID.A...." */
-    0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,  /* 00000768    "_CRS...." */
-    0x47,0x01,0x70,0x00,0x70,0x00,0x00,0x02,  /* 00000770    "G.p.p..." */
-    0x22,0x00,0x01,0x79,0x00,0x5B,0x82,0x22,  /* 00000778    ""..y.[."" */
-    0x53,0x50,0x4B,0x52,0x08,0x5F,0x48,0x49,  /* 00000780    "SPKR._HI" */
-    0x44,0x0C,0x41,0xD0,0x08,0x00,0x08,0x5F,  /* 00000788    "D.A...._" */
-    0x43,0x52,0x53,0x11,0x0D,0x0A,0x0A,0x47,  /* 00000790    "CRS....G" */
-    0x01,0x61,0x00,0x61,0x00,0x00,0x01,0x79,  /* 00000798    ".a.a...y" */
-    0x00,0x5B,0x82,0x31,0x50,0x53,0x32,0x4D,  /* 000007A0    ".[.1PS2M" */
+    0x50,0x49,0x43,0x44,0x10,0x49,0x85,0x5F,  /* 000000B0    "PICD.I._" */
+    0x53,0x42,0x5F,0x5B,0x82,0x49,0x04,0x4D,  /* 000000B8    "SB_[.I.M" */
+    0x45,0x4D,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 000000C0    "EM0._HID" */
+    0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43,  /* 000000C8    ".A...._C" */
+    0x52,0x53,0x11,0x33,0x0A,0x30,0x8A,0x2B,  /* 000000D0    "RS.3.0.+" */
+    0x00,0x00,0x0D,0x03,0x00,0x00,0x00,0x00,  /* 000000D8    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000E0    "........" */
+    0x00,0x00,0x00,0x00,0xFF,0xFF,0x09,0x00,  /* 000000E8    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000000F0    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,  /* 000000F8    "........" */
+    0x00,0x00,0x00,0x00,0x79,0x00,0x5B,0x82,  /* 00000100    "....y.[." */
+    0x46,0x80,0x50,0x43,0x49,0x30,0x08,0x5F,  /* 00000108    "F.PCI0._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,  /* 00000110    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,  /* 00000118    "._UID.._" */
+    0x41,0x44,0x52,0x00,0x08,0x5F,0x42,0x42,  /* 00000120    "ADR.._BB" */
+    0x4E,0x00,0x5B,0x80,0x50,0x49,0x52,0x50,  /* 00000128    "N.[.PIRP" */
+    0x02,0x0A,0x3C,0x0A,0x10,0x5B,0x81,0x24,  /* 00000130    "..<..[.$" */
+    0x50,0x49,0x52,0x50,0x01,0x49,0x52,0x51,  /* 00000138    "PIRP.IRQ" */
+    0x33,0x03,0x49,0x52,0x51,0x35,0x05,0x49,  /* 00000140    "3.IRQ5.I" */
+    0x52,0x51,0x37,0x07,0x49,0x52,0x51,0x39,  /* 00000148    "RQ7.IRQ9" */
+    0x09,0x49,0x52,0x51,0x41,0x0A,0x49,0x52,  /* 00000150    ".IRQA.IR" */
+    0x51,0x42,0x0B,0x14,0x48,0x0D,0x5F,0x43,  /* 00000158    "QB..H._C" */
+    0x52,0x53,0x00,0x08,0x50,0x52,0x54,0x30,  /* 00000160    "RS..PRT0" */
+    0x11,0x46,0x0C,0x0A,0xC2,0x88,0x0D,0x00,  /* 00000168    ".F......" */
+    0x02,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF,  /* 00000170    "........" */
+    0x00,0x00,0x00,0x00,0x01,0x47,0x01,0xF8,  /* 00000178    ".....G.." */
+    0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00,  /* 00000180    "........" */
+    0x01,0x0C,0x03,0x00,0x00,0x00,0x00,0xF7,  /* 00000188    "........" */
+    0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00,  /* 00000190    "........" */
+    0x01,0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF,  /* 00000198    "........" */
+    0x0F,0x00,0x00,0x00,0x03,0x88,0x0D,0x00,  /* 000001A0    "........" */
+    0x01,0x0D,0x03,0x00,0x00,0x00,0xC0,0x1F,  /* 000001A8    "........" */
+    0xC0,0x00,0x00,0x20,0x00,0x88,0x0D,0x00,  /* 000001B0    "... ...." */
+    0x01,0x0D,0x03,0x00,0x00,0x20,0xC0,0x3F,  /* 000001B8    "..... .?" */
+    0xC0,0x00,0x00,0x10,0x00,0x87,0x17,0x00,  /* 000001C0    "........" */
+    0x00,0x0C,0x02,0x00,0x00,0x00,0x00,0x00,  /* 000001C8    "........" */
+    0x00,0x0C,0x00,0xFF,0xFF,0x0F,0x00,0x00,  /* 000001D0    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x87,  /* 000001D8    "........" */
+    0x17,0x00,0x00,0x0D,0x03,0x00,0x00,0x00,  /* 000001E0    "........" */
+    0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,  /* 000001E8    "........" */
+    0xF1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  /* 000001F0    "........" */
+    0x02,0x87,0x17,0x00,0x00,0x0D,0x03,0x00,  /* 000001F8    "........" */
+    0x00,0x00,0x00,0x00,0x00,0x00,0xF2,0xFF,  /* 00000200    "........" */
+    0x0F,0x00,0xF2,0x00,0x00,0x00,0x00,0x00,  /* 00000208    "........" */
+    0x10,0x00,0x00,0x87,0x17,0x00,0x00,0x0D,  /* 00000210    "........" */
+    0x03,0x00,0x00,0x00,0x00,0x00,0x10,0x00,  /* 00000218    "........" */
+    0xF2,0x1F,0x10,0x00,0xF2,0x00,0x00,0x00,  /* 00000220    "........" */
+    0x00,0x20,0x00,0x00,0x00,0x79,0x00,0xA4,  /* 00000228    ". ...y.." */
+    0x50,0x52,0x54,0x30,0x08,0x42,0x55,0x46,  /* 00000230    "PRT0.BUF" */
+    0x41,0x11,0x09,0x0A,0x06,0x23,0xF8,0xDC,  /* 00000238    "A....#.." */
+    0x18,0x79,0x00,0x08,0x42,0x55,0x46,0x42,  /* 00000240    ".y..BUFB" */
+    0x11,0x09,0x0A,0x06,0x23,0x00,0x00,0x18,  /* 00000248    "....#..." */
+    0x79,0x00,0x8B,0x42,0x55,0x46,0x42,0x01,  /* 00000250    "y..BUFB." */
+    0x49,0x52,0x51,0x56,0x08,0x42,0x55,0x46,  /* 00000258    "IRQV.BUF" */
+    0x43,0x11,0x07,0x0A,0x04,0x05,0x07,0x0A,  /* 00000260    "C......." */
+    0x0B,0x8C,0x42,0x55,0x46,0x43,0x01,0x50,  /* 00000268    "..BUFC.P" */
+    0x49,0x51,0x41,0x8C,0x42,0x55,0x46,0x43,  /* 00000270    "IQA.BUFC" */
+    0x01,0x50,0x49,0x51,0x42,0x8C,0x42,0x55,  /* 00000278    ".PIQB.BU" */
+    0x46,0x43,0x01,0x50,0x49,0x51,0x43,0x8C,  /* 00000280    "FC.PIQC." */
+    0x42,0x55,0x46,0x43,0x01,0x50,0x49,0x51,  /* 00000288    "BUFC.PIQ" */
+    0x44,0x5B,0x82,0x48,0x08,0x4C,0x4E,0x4B,  /* 00000290    "D[.H.LNK" */
+    0x41,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000298    "A._HID.A" */
+    0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,  /* 000002A0    "...._UID" */
+    0x01,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,  /* 000002A8    "..._STA." */
+    0x7B,0x50,0x49,0x52,0x41,0x0A,0x80,0x60,  /* 000002B0    "{PIRA..`" */
+    0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,  /* 000002B8    "...`...." */
+    0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,  /* 000002C0    "........" */
+    0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55,  /* 000002C8    "_PRS..BU" */
+    0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53,  /* 000002D0    "FA.._DIS" */
+    0x00,0x7D,0x50,0x49,0x52,0x41,0x0A,0x80,  /* 000002D8    ".}PIRA.." */
+    0x50,0x49,0x52,0x41,0x14,0x1A,0x5F,0x43,  /* 000002E0    "PIRA.._C" */
+    0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x42,  /* 000002E8    "RS.{PIRB" */
+    0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52,  /* 000002F0    "..`y.`IR" */
+    0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14,  /* 000002F8    "QV.BUFB." */
+    0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,  /* 00000300    "._SRS..h" */
+    0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52,  /* 00000308    ".IRQ1.IR" */
+    0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50,  /* 00000310    "Q1`v`p`P" */
+    0x49,0x52,0x41,0x5B,0x82,0x49,0x08,0x4C,  /* 00000318    "IRA[.I.L" */
+    0x4E,0x4B,0x42,0x08,0x5F,0x48,0x49,0x44,  /* 00000320    "NKB._HID" */
+    0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,  /* 00000328    ".A...._U" */
+    0x49,0x44,0x0A,0x02,0x14,0x1C,0x5F,0x53,  /* 00000330    "ID...._S" */
+    0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x42,  /* 00000338    "TA.{PIRB" */
+    0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,  /* 00000340    "..`...`." */
+    0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,  /* 00000348    "........" */
+    0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,  /* 00000350    "..._PRS." */
+    0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F,  /* 00000358    ".BUFA.._" */
+    0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52,  /* 00000360    "DIS.}PIR" */
+    0x42,0x0A,0x80,0x50,0x49,0x52,0x42,0x14,  /* 00000368    "B..PIRB." */
+    0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,  /* 00000370    "._CRS.{P" */
+    0x49,0x52,0x42,0x0A,0x0F,0x60,0x79,0x01,  /* 00000378    "IRB..`y." */
+    0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55,  /* 00000380    "`IRQV.BU" */
+    0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,  /* 00000388    "FB.._SRS" */
+    0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31,  /* 00000390    "..h.IRQ1" */
+    0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60,  /* 00000398    ".IRQ1`v`" */
+    0x70,0x60,0x50,0x49,0x52,0x42,0x5B,0x82,  /* 000003A0    "p`PIRB[." */
+    0x49,0x08,0x4C,0x4E,0x4B,0x43,0x08,0x5F,  /* 000003A8    "I.LNKC._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 000003B0    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x0A,0x03,0x14,  /* 000003B8    "._UID..." */
+    0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,  /* 000003C0    "._STA.{P" */
+    0x49,0x52,0x43,0x0A,0x80,0x60,0xA0,0x08,  /* 000003C8    "IRC..`.." */
+    0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,  /* 000003D0    ".`......" */
+    0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,  /* 000003D8    "......_P" */
+    0x52,0x53,0x00,0xA4,0x42,0x55,0x46,0x41,  /* 000003E0    "RS..BUFA" */
+    0x14,0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,  /* 000003E8    ".._DIS.}" */
+    0x50,0x49,0x52,0x43,0x0A,0x80,0x50,0x49,  /* 000003F0    "PIRC..PI" */
+    0x52,0x43,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 000003F8    "RC.._CRS" */
+    0x00,0x7B,0x50,0x49,0x52,0x43,0x0A,0x0F,  /* 00000400    ".{PIRC.." */
+    0x60,0x79,0x01,0x60,0x49,0x52,0x51,0x56,  /* 00000408    "`y.`IRQV" */
+    0xA4,0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,  /* 00000410    ".BUFB.._" */
+    0x53,0x52,0x53,0x01,0x8B,0x68,0x01,0x49,  /* 00000418    "SRS..h.I" */
+    0x52,0x51,0x31,0x82,0x49,0x52,0x51,0x31,  /* 00000420    "RQ1.IRQ1" */
+    0x60,0x76,0x60,0x70,0x60,0x50,0x49,0x52,  /* 00000428    "`v`p`PIR" */
+    0x43,0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,  /* 00000430    "C[.I.LNK" */
+    0x44,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000438    "D._HID.A" */
+    0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,  /* 00000440    "...._UID" */
+    0x0A,0x04,0x14,0x1C,0x5F,0x53,0x54,0x41,  /* 00000448    "...._STA" */
+    0x00,0x7B,0x50,0x49,0x52,0x44,0x0A,0x80,  /* 00000450    ".{PIRD.." */
+    0x60,0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,  /* 00000458    "`...`..." */
+    0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,  /* 00000460    "........" */
+    0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,  /* 00000468    "._PRS..B" */
+    0x55,0x46,0x41,0x14,0x11,0x5F,0x44,0x49,  /* 00000470    "UFA.._DI" */
+    0x53,0x00,0x7D,0x50,0x49,0x52,0x44,0x0A,  /* 00000478    "S.}PIRD." */
+    0x80,0x50,0x49,0x52,0x44,0x14,0x1A,0x5F,  /* 00000480    ".PIRD.._" */
+    0x43,0x52,0x53,0x00,0x7B,0x50,0x49,0x52,  /* 00000488    "CRS.{PIR" */
+    0x44,0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,  /* 00000490    "D..`y.`I" */
+    0x52,0x51,0x56,0xA4,0x42,0x55,0x46,0x42,  /* 00000498    "RQV.BUFB" */
+    0x14,0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,  /* 000004A0    ".._SRS.." */
+    0x68,0x01,0x49,0x52,0x51,0x31,0x82,0x49,  /* 000004A8    "h.IRQ1.I" */
+    0x52,0x51,0x31,0x60,0x76,0x60,0x70,0x60,  /* 000004B0    "RQ1`v`p`" */
+    0x50,0x49,0x52,0x44,0x14,0x16,0x5F,0x50,  /* 000004B8    "PIRD.._P" */
+    0x52,0x54,0x00,0xA0,0x0A,0x50,0x49,0x43,  /* 000004C0    "RT...PIC" */
+    0x44,0xA4,0x50,0x52,0x54,0x41,0xA4,0x50,  /* 000004C8    "D.PRTA.P" */
+    0x52,0x54,0x50,0x08,0x50,0x52,0x54,0x50,  /* 000004D0    "RTP.PRTP" */
+    0x12,0x43,0x0E,0x10,0x12,0x0B,0x04,0x0B,  /* 000004D8    ".C......" */
+    0xFF,0xFF,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 000004E0    "...LNKA." */
+    0x12,0x0B,0x04,0x0B,0xFF,0xFF,0x01,0x4C,  /* 000004E8    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0C,0x04,0x0B,  /* 000004F0    "NKB....." */
+    0xFF,0xFF,0x0A,0x02,0x4C,0x4E,0x4B,0x43,  /* 000004F8    "....LNKC" */
+    0x00,0x12,0x0C,0x04,0x0B,0xFF,0xFF,0x0A,  /* 00000500    "........" */
+    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000508    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C,  /* 00000510    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C,  /* 00000518    "NKB....." */
+    0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B,  /* 00000520    ".....LNK" */
+    0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 00000528    "C......." */
+    0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x44,  /* 00000530    "....LNKD" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,  /* 00000538    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000540    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 00000548    "........" */
+    0x00,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D,  /* 00000550    ".LNKC..." */
+    0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x4C,  /* 00000558    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,  /* 00000560    "NKD....." */
+    0xFF,0xFF,0x02,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000568    "......LN" */
+    0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000570    "KA......" */
+    0xFF,0x02,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000578    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000580    "B......." */
+    0x03,0x00,0x00,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000588    "...LNKD." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00,  /* 00000590    "........" */
+    0x01,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,  /* 00000598    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,  /* 000005A0    "........" */
+    0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,  /* 000005A8    "LNKB...." */
+    0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x03,0x4C,  /* 000005B0    ".......L" */
+    0x4E,0x4B,0x43,0x00,0x08,0x50,0x52,0x54,  /* 000005B8    "NKC..PRT" */
+    0x41,0x12,0x32,0x04,0x12,0x0B,0x04,0x0C,  /* 000005C0    "A.2....." */
+    0xFF,0xFF,0x01,0x00,0x00,0x00,0x0A,0x05,  /* 000005C8    "........" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,  /* 000005D0    "........" */
+    0x00,0x00,0x0A,0x07,0x12,0x0B,0x04,0x0C,  /* 000005D8    "........" */
+    0xFF,0xFF,0x03,0x00,0x00,0x00,0x0A,0x0A,  /* 000005E0    "........" */
+    0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,  /* 000005E8    "........" */
+    0x00,0x00,0x0A,0x0B,0x5B,0x82,0x48,0x31,  /* 000005F0    "....[.H1" */
+    0x49,0x53,0x41,0x5F,0x08,0x5F,0x41,0x44,  /* 000005F8    "ISA_._AD" */
+    0x52,0x00,0x5B,0x80,0x50,0x49,0x52,0x51,  /* 00000600    "R.[.PIRQ" */
+    0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E,0x5C,  /* 00000608    "..`....\" */
+    0x00,0x5B,0x81,0x29,0x5C,0x2F,0x04,0x5F,  /* 00000610    ".[.)\/._" */
+    0x53,0x42,0x5F,0x50,0x43,0x49,0x30,0x49,  /* 00000618    "SB_PCI0I" */
+    0x53,0x41,0x5F,0x50,0x49,0x52,0x51,0x01,  /* 00000620    "SA_PIRQ." */
+    0x50,0x49,0x52,0x41,0x08,0x50,0x49,0x52,  /* 00000628    "PIRA.PIR" */
+    0x42,0x08,0x50,0x49,0x52,0x43,0x08,0x50,  /* 00000630    "B.PIRC.P" */
+    0x49,0x52,0x44,0x08,0x5B,0x82,0x46,0x0B,  /* 00000638    "IRD.[.F." */
+    0x53,0x59,0x53,0x52,0x08,0x5F,0x48,0x49,  /* 00000640    "SYSR._HI" */
+    0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,  /* 00000648    "D.A...._" */
+    0x55,0x49,0x44,0x01,0x08,0x43,0x52,0x53,  /* 00000650    "UID..CRS" */
+    0x5F,0x11,0x4E,0x08,0x0A,0x8A,0x47,0x01,  /* 00000658    "_.N...G." */
+    0x10,0x00,0x10,0x00,0x00,0x10,0x47,0x01,  /* 00000660    "......G." */
+    0x22,0x00,0x22,0x00,0x00,0x0C,0x47,0x01,  /* 00000668    ""."...G." */
+    0x30,0x00,0x30,0x00,0x00,0x10,0x47,0x01,  /* 00000670    "0.0...G." */
+    0x44,0x00,0x44,0x00,0x00,0x1C,0x47,0x01,  /* 00000678    "D.D...G." */
+    0x62,0x00,0x62,0x00,0x00,0x02,0x47,0x01,  /* 00000680    "b.b...G." */
+    0x65,0x00,0x65,0x00,0x00,0x0B,0x47,0x01,  /* 00000688    "e.e...G." */
+    0x72,0x00,0x72,0x00,0x00,0x0E,0x47,0x01,  /* 00000690    "r.r...G." */
+    0x80,0x00,0x80,0x00,0x00,0x01,0x47,0x01,  /* 00000698    "......G." */
+    0x84,0x00,0x84,0x00,0x00,0x03,0x47,0x01,  /* 000006A0    "......G." */
+    0x88,0x00,0x88,0x00,0x00,0x01,0x47,0x01,  /* 000006A8    "......G." */
+    0x8C,0x00,0x8C,0x00,0x00,0x03,0x47,0x01,  /* 000006B0    "......G." */
+    0x90,0x00,0x90,0x00,0x00,0x10,0x47,0x01,  /* 000006B8    "......G." */
+    0xA2,0x00,0xA2,0x00,0x00,0x1C,0x47,0x01,  /* 000006C0    "......G." */
+    0xE0,0x00,0xE0,0x00,0x00,0x10,0x47,0x01,  /* 000006C8    "......G." */
+    0xA0,0x08,0xA0,0x08,0x00,0x04,0x47,0x01,  /* 000006D0    "......G." */
+    0xC0,0x0C,0xC0,0x0C,0x00,0x10,0x47,0x01,  /* 000006D8    "......G." */
+    0xD0,0x04,0xD0,0x04,0x00,0x02,0x79,0x00,  /* 000006E0    "......y." */
+    0x14,0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,  /* 000006E8    ".._CRS.." */
+    0x43,0x52,0x53,0x5F,0x5B,0x82,0x2B,0x50,  /* 000006F0    "CRS_[.+P" */
+    0x49,0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,  /* 000006F8    "IC_._HID" */
+    0x0B,0x41,0xD0,0x08,0x5F,0x43,0x52,0x53,  /* 00000700    ".A.._CRS" */
+    0x11,0x18,0x0A,0x15,0x47,0x01,0x20,0x00,  /* 00000708    "....G. ." */
+    0x20,0x00,0x01,0x02,0x47,0x01,0xA0,0x00,  /* 00000710    " ...G..." */
+    0xA0,0x00,0x01,0x02,0x22,0x04,0x00,0x79,  /* 00000718    "...."..y" */
+    0x00,0x5B,0x82,0x47,0x05,0x44,0x4D,0x41,  /* 00000720    ".[.G.DMA" */
+    0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000728    "0._HID.A" */
+    0xD0,0x02,0x00,0x08,0x5F,0x43,0x52,0x53,  /* 00000730    "...._CRS" */
+    0x11,0x41,0x04,0x0A,0x3D,0x2A,0x10,0x04,  /* 00000738    ".A..=*.." */
+    0x47,0x01,0x00,0x00,0x00,0x00,0x00,0x10,  /* 00000740    "G......." */
+    0x47,0x01,0x81,0x00,0x81,0x00,0x00,0x03,  /* 00000748    "G......." */
+    0x47,0x01,0x87,0x00,0x87,0x00,0x00,0x01,  /* 00000750    "G......." */
+    0x47,0x01,0x89,0x00,0x89,0x00,0x00,0x03,  /* 00000758    "G......." */
+    0x47,0x01,0x8F,0x00,0x8F,0x00,0x00,0x01,  /* 00000760    "G......." */
+    0x47,0x01,0xC0,0x00,0xC0,0x00,0x00,0x20,  /* 00000768    "G...... " */
+    0x47,0x01,0x80,0x04,0x80,0x04,0x00,0x10,  /* 00000770    "G......." */
+    0x79,0x00,0x5B,0x82,0x25,0x54,0x4D,0x52,  /* 00000778    "y.[.%TMR" */
+    0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,  /* 00000780    "_._HID.A" */
+    0xD0,0x01,0x00,0x08,0x5F,0x43,0x52,0x53,  /* 00000788    "...._CRS" */
+    0x11,0x10,0x0A,0x0D,0x47,0x01,0x40,0x00,  /* 00000790    "....G.@." */
+    0x40,0x00,0x00,0x04,0x22,0x01,0x00,0x79,  /* 00000798    "@..."..y" */
+    0x00,0x5B,0x82,0x25,0x52,0x54,0x43,0x5F,  /* 000007A0    ".[.%RTC_" */
     0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 000007A8    "._HID.A." */
-    0x0F,0x13,0x08,0x5F,0x43,0x49,0x44,0x0C,  /* 000007B0    "..._CID." */
-    0x41,0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,  /* 000007B8    "A....._S" */
-    0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,  /* 000007C0    "TA....._" */
-    0x43,0x52,0x53,0x11,0x08,0x0A,0x05,0x22,  /* 000007C8    "CRS...."" */
-    0x00,0x10,0x79,0x00,0x5B,0x82,0x42,0x04,  /* 000007D0    "..y.[.B." */
-    0x50,0x53,0x32,0x4B,0x08,0x5F,0x48,0x49,  /* 000007D8    "PS2K._HI" */
-    0x44,0x0C,0x41,0xD0,0x03,0x03,0x08,0x5F,  /* 000007E0    "D.A...._" */
-    0x43,0x49,0x44,0x0C,0x41,0xD0,0x03,0x0B,  /* 000007E8    "CID.A..." */
-    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 000007F0    ".._STA.." */
-    0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 000007F8    "..._CRS." */
-    0x18,0x0A,0x15,0x47,0x01,0x60,0x00,0x60,  /* 00000800    "...G.`.`" */
-    0x00,0x00,0x01,0x47,0x01,0x64,0x00,0x64,  /* 00000808    "...G.d.d" */
-    0x00,0x00,0x01,0x22,0x02,0x00,0x79,0x00,  /* 00000810    "..."..y." */
-    0x5B,0x82,0x3A,0x46,0x44,0x43,0x30,0x08,  /* 00000818    "[.:FDC0." */
-    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,  /* 00000820    "_HID.A.." */
-    0x00,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000828    "..._STA." */
-    0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,  /* 00000830    "...._CRS" */
-    0x11,0x1B,0x0A,0x18,0x47,0x01,0xF0,0x03,  /* 00000838    "....G..." */
-    0xF0,0x03,0x01,0x06,0x47,0x01,0xF7,0x03,  /* 00000840    "....G..." */
-    0xF7,0x03,0x01,0x01,0x22,0x40,0x00,0x2A,  /* 00000848    "...."@.*" */
-    0x04,0x00,0x79,0x00,0x5B,0x82,0x35,0x55,  /* 00000850    "..y.[.5U" */
-    0x41,0x52,0x31,0x08,0x5F,0x48,0x49,0x44,  /* 00000858    "AR1._HID" */
-    0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,  /* 00000860    ".A...._U" */
-    0x49,0x44,0x01,0x14,0x09,0x5F,0x53,0x54,  /* 00000868    "ID..._ST" */
-    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000870    "A....._C" */
-    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 00000878    "RS....G." */
-    0xF8,0x03,0xF8,0x03,0x01,0x08,0x22,0x10,  /* 00000880    "......"." */
-    0x00,0x79,0x00,0x5B,0x82,0x36,0x55,0x41,  /* 00000888    ".y.[.6UA" */
-    0x52,0x32,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000890    "R2._HID." */
-    0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49,  /* 00000898    "A...._UI" */
-    0x44,0x0A,0x02,0x14,0x09,0x5F,0x53,0x54,  /* 000008A0    "D...._ST" */
-    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 000008A8    "A....._C" */
-    0x52,0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,  /* 000008B0    "RS....G." */
-    0xF8,0x02,0xF8,0x02,0x01,0x08,0x22,0x08,  /* 000008B8    "......"." */
-    0x00,0x79,0x00,
+    0x0B,0x00,0x08,0x5F,0x43,0x52,0x53,0x11,  /* 000007B0    "..._CRS." */
+    0x10,0x0A,0x0D,0x47,0x01,0x70,0x00,0x70,  /* 000007B8    "...G.p.p" */
+    0x00,0x00,0x02,0x22,0x00,0x01,0x79,0x00,  /* 000007C0    "..."..y." */
+    0x5B,0x82,0x22,0x53,0x50,0x4B,0x52,0x08,  /* 000007C8    "[."SPKR." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x08,  /* 000007D0    "_HID.A.." */
+    0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x0D,  /* 000007D8    ".._CRS.." */
+    0x0A,0x0A,0x47,0x01,0x61,0x00,0x61,0x00,  /* 000007E0    "..G.a.a." */
+    0x00,0x01,0x79,0x00,0x5B,0x82,0x31,0x50,  /* 000007E8    "..y.[.1P" */
+    0x53,0x32,0x4D,0x08,0x5F,0x48,0x49,0x44,  /* 000007F0    "S2M._HID" */
+    0x0C,0x41,0xD0,0x0F,0x13,0x08,0x5F,0x43,  /* 000007F8    ".A...._C" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14,  /* 00000800    "ID.A...." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 00000808    "._STA..." */
+    0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x08,  /* 00000810    ".._CRS.." */
+    0x0A,0x05,0x22,0x00,0x10,0x79,0x00,0x5B,  /* 00000818    ".."..y.[" */
+    0x82,0x42,0x04,0x50,0x53,0x32,0x4B,0x08,  /* 00000820    ".B.PS2K." */
+    0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x03,  /* 00000828    "_HID.A.." */
+    0x03,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,  /* 00000830    ".._CID.A" */
+    0xD0,0x03,0x0B,0x14,0x09,0x5F,0x53,0x54,  /* 00000838    "....._ST" */
+    0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,  /* 00000840    "A....._C" */
+    0x52,0x53,0x11,0x18,0x0A,0x15,0x47,0x01,  /* 00000848    "RS....G." */
+    0x60,0x00,0x60,0x00,0x00,0x01,0x47,0x01,  /* 00000850    "`.`...G." */
+    0x64,0x00,0x64,0x00,0x00,0x01,0x22,0x02,  /* 00000858    "d.d..."." */
+    0x00,0x79,0x00,0x5B,0x82,0x3A,0x46,0x44,  /* 00000860    ".y.[.:FD" */
+    0x43,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,  /* 00000868    "C0._HID." */
+    0x41,0xD0,0x07,0x00,0x14,0x09,0x5F,0x53,  /* 00000870    "A....._S" */
+    0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,  /* 00000878    "TA....._" */
+    0x43,0x52,0x53,0x11,0x1B,0x0A,0x18,0x47,  /* 00000880    "CRS....G" */
+    0x01,0xF0,0x03,0xF0,0x03,0x01,0x06,0x47,  /* 00000888    ".......G" */
+    0x01,0xF7,0x03,0xF7,0x03,0x01,0x01,0x22,  /* 00000890    "......."" */
+    0x40,0x00,0x2A,0x04,0x00,0x79,0x00,0x5B,  /* 00000898    "@.*..y.[" */
+    0x82,0x35,0x55,0x41,0x52,0x31,0x08,0x5F,  /* 000008A0    ".5UAR1._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,  /* 000008A8    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x09,  /* 000008B0    "._UID..." */
+    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 000008B8    "_STA...." */
+    0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,  /* 000008C0    "._CRS..." */
+    0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03,0x01,  /* 000008C8    ".G......" */
+    0x08,0x22,0x10,0x00,0x79,0x00,0x5B,0x82,  /* 000008D0    "."..y.[." */
+    0x36,0x55,0x41,0x52,0x32,0x08,0x5F,0x48,  /* 000008D8    "6UAR2._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,  /* 000008E0    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x09,  /* 000008E8    "_UID...." */
+    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,  /* 000008F0    "_STA...." */
+    0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,  /* 000008F8    "._CRS..." */
+    0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02,0x01,  /* 00000900    ".G......" */
+    0x08,0x22,0x08,0x00,0x79,0x00,
 };
 int DsdtLen=sizeof(AmlCode);
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/hvmloader/Makefile Mon Aug 07 18:00:22 2006 -0500
@@ -42,12 +42,15 @@ CFLAGS  += $(DEFINES) -I. $(XENINC) -fno
 CFLAGS  += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
 LDFLAGS  = -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR)
 
+SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c
+OBJS = $(patsubst %.c,%.o,$(SRCS))
+
 .PHONY: all
 all: hvmloader
 
-hvmloader: roms.h hvmloader.c acpi_madt.c mp_tables.c
-       $(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c mp_tables.c
-       $(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o mp_tables.o
+hvmloader: roms.h $(SRCS)
+       $(CC) $(CFLAGS) -c $(SRCS)
+       $(CC) $(LDFLAGS) -o hvmloader.tmp $(OBJS)
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/hvmloader/acpi_madt.c      Mon Aug 07 18:00:22 2006 -0500
@@ -20,12 +20,10 @@
 
 #include "../acpi/acpi2_0.h"
 #include "../acpi/acpi_madt.h"
-
+#include "util.h"
 #include <xen/hvm/hvm_info_table.h>
 
 #define NULL ((void*)0)
-
-extern int puts(const char *s);
 
 static struct hvm_info_table *table = NULL;
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/hvmloader/hvmloader.c      Mon Aug 07 18:00:22 2006 -0500
@@ -23,15 +23,19 @@
  */
 #include "roms.h"
 #include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include "hypercall.h"
+#include "util.h"
+#include <xen/version.h>
 #include <xen/hvm/hvm_info_table.h>
 
 /* memory map */
+#define HYPERCALL_PHYSICAL_ADDRESS     0x00080000
 #define VGABIOS_PHYSICAL_ADDRESS       0x000C0000
 #define        VMXASSIST_PHYSICAL_ADDRESS      0x000D0000
 #define        ROMBIOS_PHYSICAL_ADDRESS        0x000F0000
 
 /* invoke SVM's paged realmode support */
-#define SVM_VMMCALL_RESET_TO_REALMODE  0x00000001
+#define SVM_VMMCALL_RESET_TO_REALMODE  0x80000001
 
 /*
  * C runtime start off
@@ -75,79 +79,28 @@ extern void create_mp_tables(void);
 extern void create_mp_tables(void);
 struct hvm_info_table *get_hvm_info_table(void);
 
-static inline void
-outw(unsigned short addr, unsigned short val)
-{
-        __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline void
-outb(unsigned short addr, unsigned char val)
-{
-        __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline unsigned char
-inb(unsigned short addr)
-{
-        unsigned char val;
-
-        __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
-        return val;
-}
-
-void *
-memcpy(void *dest, const void *src, unsigned n)
-{
-       int t0, t1, t2;
-
-       __asm__ __volatile__(
-               "cld\n"
-               "rep; movsl\n"
-               "testb $2,%b4\n"
-               "je 1f\n"
-               "movsw\n"
-               "1: testb $1,%b4\n"
-               "je 2f\n"
-               "movsb\n"
-               "2:"
-               : "=&c" (t0), "=&D" (t1), "=&S" (t2)
-               : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
-               : "memory"
-       );
-       return dest;
-}
-
-int
-puts(const char *s)
-{
-       while (*s)
-               outb(0xE9, *s++);
-       return 0;
-}
-
-int
+static int
 cirrus_check(void)
 {
        outw(0x3C4, 0x9206);
        return inb(0x3C5) == 0x12;
 }
 
-int 
-vmmcall(int edi, int esi, int edx, int ecx, int ebx)
+static int
+vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
 {
         int eax;
 
         __asm__ __volatile__(
                ".byte 0x0F,0x01,0xD9"
                 : "=a" (eax)
-               : "a"(0x58454E00), /* XEN\0 key */
+               : "a"(function),
                  "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi)
        );
         return eax;
 }
 
-int
+static int
 check_amd(void)
 {
        char id[12];
@@ -162,12 +115,68 @@ check_amd(void)
        return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
 }
 
+static void
+cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
+{
+       __asm__ __volatile__(
+               "cpuid"
+               : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+               : "0" (idx) );
+}
+
+static void
+wrmsr(uint32_t idx, uint64_t v)
+{
+       __asm__ __volatile__(
+               "wrmsr"
+               : : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) );
+}
+
+static void
+init_hypercalls(void)
+{
+       uint32_t eax, ebx, ecx, edx;
+       unsigned long i;
+       char signature[13], number[13];
+       xen_extraversion_t extraversion;
+
+       cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
+
+       *(uint32_t *)(signature + 0) = ebx;
+       *(uint32_t *)(signature + 4) = ecx;
+       *(uint32_t *)(signature + 8) = edx;
+       signature[12] = '\0';
+
+       if (strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002)) {
+               puts("FATAL: Xen hypervisor not detected\n");
+               __asm__ __volatile__( "ud2" );
+       }
+
+       cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
+
+       puts("Detected Xen v");
+       puts(itoa(number, eax >> 16));
+       puts(".");
+       puts(itoa(number, eax & 0xffff));
+
+       cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
+
+       for (i = 0; i < eax; i++)
+               wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
+
+       hypercall_xen_version(XENVER_extraversion, extraversion);
+       puts(extraversion);
+       puts("\n");
+}
+
 int
 main(void)
 {
        struct hvm_info_table *t = get_hvm_info_table();
 
        puts("HVM Loader\n");
+
+       init_hypercalls();
 
        puts("Loading ROMBIOS ...\n");
        memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
@@ -200,7 +209,7 @@ main(void)
        if (check_amd()) {
                /* AMD implies this is SVM */
                 puts("SVM go ...\n");
-                vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0);
+                vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
        } else {
                puts("Loading VMXAssist ...\n");
                memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/hvmloader/mp_tables.c
--- a/tools/firmware/hvmloader/mp_tables.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/hvmloader/mp_tables.c      Mon Aug 07 18:00:22 2006 -0500
@@ -93,7 +93,8 @@ typedef   signed long int64_t;
 
 #define INTR_MAX_NR            16
 
-extern int puts(const char *); /* for printing */
+#include "util.h"
+
 extern int get_vcpu_nr(void);  /* for the guest's VCPU count */
 
 /*
diff -r 61204c1d740e -r 87cefa5f7c5e tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/firmware/vmxassist/vm86.c   Mon Aug 07 18:00:22 2006 -0500
@@ -52,6 +52,31 @@ static char *rnames[] = { "ax", "cx", "d
 static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
 #endif /* DEBUG */
 
+#define PT_ENTRY_PRESENT 0x1
+
+static unsigned
+guest_linear_to_real(unsigned long base, unsigned off)
+{
+       unsigned int gcr3 = oldctx.cr3;
+       unsigned int l1_mfn;
+       unsigned int l0_mfn;
+
+       if (!(oldctx.cr0 & CR0_PG))
+               return base + off;
+
+       l1_mfn = ((unsigned int *)gcr3)[(base >> 22) & 0x3ff ];
+       if (!(l1_mfn & PT_ENTRY_PRESENT))
+               panic("l2 entry not present\n");
+       l1_mfn = l1_mfn & 0xfffff000 ;
+
+       l0_mfn = ((unsigned int *)l1_mfn)[(base >> 12) & 0x3ff];
+       if (!(l0_mfn & PT_ENTRY_PRESENT))
+               panic("l1 entry not present\n");
+       l0_mfn = l0_mfn & 0xfffff000;
+
+       return l0_mfn + off + (base & 0xfff);
+}
+
 static unsigned
 address(struct regs *regs, unsigned seg, unsigned off)
 {
@@ -70,7 +95,7 @@ address(struct regs *regs, unsigned seg,
            (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
                return ((seg & 0xFFFF) << 4) + off;
 
-       entry = ((unsigned long long *) oldctx.gdtr_base)[seg >> 3];
+       entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 
0))[seg >> 3];
        entry_high = entry >> 32;
        entry_low = entry & 0xFFFFFFFF;
 
@@ -94,7 +119,7 @@ trace(struct regs *regs, int adjust, cha
 trace(struct regs *regs, int adjust, char *fmt, ...)
 {
        unsigned off = regs->eip - adjust;
-        va_list ap;
+       va_list ap;
 
        if ((traceset & (1 << mode)) &&
           (mode == VM86_REAL_TO_PROTECTED || mode == VM86_REAL)) {
@@ -755,7 +780,7 @@ load_seg(unsigned long sel, uint32_t *ba
                return 1;
        }
 
-       entry =  ((unsigned long long *) oldctx.gdtr_base)[sel >> 3];
+       entry = ((unsigned long long *) guest_linear_to_real(oldctx.gdtr_base, 
0))[sel >> 3];
 
        /* Check the P bit first */
        if (!((entry >> (15+32)) & 0x1) && sel != 0)
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/.cvsignore
--- a/tools/ioemu/.cvsignore    Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/.cvsignore    Mon Aug 07 18:00:22 2006 -0500
@@ -11,6 +11,8 @@ ppc-user
 ppc-user
 qemu-doc.html
 qemu-tech.html
+qemu-doc.info
+qemu-tech.info
 qemu.1
 qemu.pod
 qemu-img.1
@@ -25,5 +27,16 @@ mipsel-softmmu
 mipsel-softmmu
 mips-user
 mipsel-user
+.gdbinit
 sh4-user
 sh4-softmmu
+*.aux
+*.cp
+*.dvi
+*.fn
+*.ky
+*.log
+*.pg
+*.toc
+*.tp
+*.vr
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/Changelog
--- a/tools/ioemu/Changelog     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/Changelog     Mon Aug 07 18:00:22 2006 -0500
@@ -1,3 +1,22 @@ version 0.8.1:
+version 0.8.2:
+
+  - ACPI support
+  - PC VGA BIOS fixes
+  - switch to OpenBios for SPARC targets (Blue Swirl)
+  - VNC server fixes
+  - MIPS FPU support (Marius Groeger)
+  - Solaris/SPARC host support (Ben Taylor)
+  - PPC breakpoints and single stepping (Jason Wessel)
+  - USB updates (Paul Brook)
+  - UDP/TCP/telnet character devices (Jason Wessel)
+  - Windows sparse file support (Frediano Ziglio)
+  - RTL8139 NIC TCP segmentation offloading (Igor Kovalenko)
+  - PCNET NIC support (Antony T Curtis)
+  - Support for variable frequency host CPUs
+  - Workaround for win32 SMP hosts
+  - Support for AMD Flash memories (Jocelyn Mayer)
+  - Audio capture to WAV files support (malc)
+
 version 0.8.1:
 
   - USB tablet support (Brad Campbell, Anthony Liguori)
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/Makefile
--- a/tools/ioemu/Makefile      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/Makefile      Mon Aug 07 18:00:22 2006 -0500
@@ -1,11 +1,19 @@ XEN_ROOT=../..
+# Makefile for QEMU.
+
 XEN_ROOT=../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 -include config-host.mak
 
+.PHONY: all clean distclean dvi info install install-doc tar tarbin \
+       speed test test2 html dvi info
+
 CFLAGS+=-Wall -O2 -g -fno-strict-aliasing -I.
 ifdef CONFIG_DARWIN
 CFLAGS+= -mdynamic-no-pic
+endif
+ifeq ($(ARCH),sparc)
+CFLAGS+=-mcpu=ultrasparc
 endif
 LDFLAGS=-g
 LIBS=
@@ -20,11 +28,15 @@ DOCS=
 DOCS=
 endif
 
-all: $(DOCS)
-       for d in $(TARGET_DIRS); do \
-       $(MAKE) -C $$d $@ || exit 1 ; \
-        done
+TOOLS=
 
+all: $(TOOLS) $(DOCS) recurse-all
+
+subdir-%:
+       $(MAKE) -C $(subst subdir-,,$@) all
+
+recurse-all: $(patsubst %,subdir-%, $(TARGET_DIRS))
+        
 qemu-img$(EXESUF): qemu-img.c block.c block-cow.c block-qcow.c aes.c 
block-vmdk.c block-cloop.c block-dmg.c block-bochs.c block-vpc.c block-vvfat.c
        $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
 
@@ -42,6 +54,7 @@ clean:
 
 distclean: clean
        rm -f config-host.mak config-host.h $(DOCS)
+       rm -f qemu-{doc,tech}.{info,aux,cp,dvi,fn,info,ky,log,pg,toc,tp,vr}
        for d in $(TARGET_DIRS); do \
        rm -rf $$d || exit 1 ; \
         done
@@ -63,7 +76,7 @@ install: all $(if $(BUILD_DOCS),install-
 #      $(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
 #      mkdir -p "$(DESTDIR)$(datadir)"
 #      for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
-#                      video.x proll.elf linux_boot.bin; do \
+#                      video.x openbios-sparc32 linux_boot.bin; do \
 #              $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x 
"$(DESTDIR)$(datadir)"; \
 #      done
 ifndef CONFIG_WIN32
@@ -106,6 +119,12 @@ qemu-img.1: qemu-img.texi
        perl -w $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
        pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@
 
+info: qemu-doc.info qemu-tech.info
+
+dvi: qemu-doc.dvi qemu-tech.dvi
+
+html: qemu-doc.html qemu-tech.html
+
 FILE=qemu-$(shell cat VERSION)
 
 # tar release (use 'make -k tar' on a checkouted tree)
@@ -138,7 +157,7 @@ tarbin:
        $(datadir)/vgabios-cirrus.bin \
        $(datadir)/ppc_rom.bin \
        $(datadir)/video.x \
-       $(datadir)/proll.elf \
+       $(datadir)/openbios-sparc32 \
        $(datadir)/linux_boot.bin \
        $(docdir)/qemu-doc.html \
        $(docdir)/qemu-tech.html \
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target       Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/Makefile.target       Mon Aug 07 18:00:22 2006 -0500
@@ -40,6 +40,11 @@ ifeq ($(TARGET_ARCH),arm)
     TARGET_ARCH2=armeb
   endif
 endif
+ifeq ($(TARGET_ARCH),sh4)
+  ifeq ($(TARGET_WORDS_BIGENDIAN),yes)
+    TARGET_ARCH2=sh4eb
+  endif
+endif
 ifeq ($(TARGET_ARCH),mips)
   ifneq ($(TARGET_WORDS_BIGENDIAN),yes)
     TARGET_ARCH2=mipsel
@@ -114,17 +119,24 @@ endif
 endif
 
 ifeq ($(ARCH),sparc)
-CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
+ifeq ($(CONFIG_SOLARIS),yes)
+CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g2 -ffixed-g3
+LDFLAGS+=-m32
+OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -fno-omit-frame-pointer -ffixed-i0
+else
+CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
 LDFLAGS+=-m32
 OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
 HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
 # -static is used to avoid g1/g3 usage by the dynamic linker
 LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static
 endif
+endif
 
 ifeq ($(ARCH),sparc64)
-CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
+CFLAGS+=-mcpu=ultrasparc -m64 -ffixed-g1 -ffixed-g4 -ffixed-g5 -ffixed-g7
 LDFLAGS+=-m64
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc64.ld
 OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
 endif
 
@@ -186,7 +198,12 @@ main.o: CFLAGS+=-p
 main.o: CFLAGS+=-p
 endif
 
-OBJS= elfload.o main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o 
+OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \
+      elfload.o linuxload.o
+ifdef TARGET_HAS_BFLT
+OBJS+= flatload.o
+endif
+
 ifeq ($(TARGET_ARCH), i386)
 OBJS+= vm86.o
 endif
@@ -323,25 +340,32 @@ ifdef CONFIG_ADLIB
 ifdef CONFIG_ADLIB
 SOUND_HW += fmopl.o adlib.o
 endif
+AUDIODRV+= wavcapture.o
+
+# SCSI layer
+VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
 
 # USB layer
-VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o
+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
+VL_OBJS+= ne2000.o rtl8139.o pcnet.o
 
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
 VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
 VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
-VL_OBJS+= cirrus_vga.o mixeng.o parallel.o
+VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o piix_pci.o
+VL_OBJS+= usb-uhci.o
 VL_OBJS+= piix4acpi.o
+VL_OBJS+= xenstore.o
 DEFINES += -DHAS_AUDIO
 endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
 VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
 VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
+VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o
 DEFINES += -DHAS_AUDIO
 endif
 ifeq ($(TARGET_ARCH), mips)
@@ -350,7 +374,7 @@ endif
 endif
 ifeq ($(TARGET_BASE_ARCH), sparc)
 ifeq ($(TARGET_ARCH), sparc64)
-VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o
+VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
 VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
 VL_OBJS+= cirrus_vga.o parallel.o
 else
@@ -361,6 +385,7 @@ ifeq ($(TARGET_BASE_ARCH), arm)
 ifeq ($(TARGET_BASE_ARCH), arm)
 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
 VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
+VL_OBJS+= versatile_pci.o
 endif
 ifeq ($(TARGET_BASE_ARCH), sh4)
 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
@@ -398,7 +423,7 @@ ifndef CONFIG_DARWIN
 ifndef CONFIG_DARWIN
 ifndef CONFIG_WIN32
 ifndef CONFIG_SOLARIS
-VL_LIBS=-lutil
+VL_LIBS=-lutil -lrt
 endif
 endif
 endif
@@ -409,6 +434,11 @@ endif
 
 ifeq ($(ARCH),ia64)
 VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld
+endif
+
+ifeq ($(ARCH),sparc64)
+VL_LDFLAGS+=-m64
+VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc64.ld
 endif
 
 ifdef CONFIG_WIN32
@@ -489,6 +519,13 @@ endif
 endif
 
 loader.o: loader.c elf_ops.h
+
+acpi.o: acpi.c acpi-dsdt.hex
+
+ifdef BUILD_ACPI_TABLES
+$(SRC_PATH)/hw/acpi-dsdt.hex: acpi-dsdt.dsl
+       iasl -tc -p $@ $<
+endif
 
 ifeq ($(TARGET_ARCH), sh4)
 op.o: op.c op_mem.c cpu.h
@@ -500,6 +537,8 @@ tc58128.o: tc58128.c
 tc58128.o: tc58128.c
 endif
 
+$(OBJS) $(LIBOBJS) $(VL_OBJS): config.h ../config-host.h
+
 %.o: %.c
        $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/TODO
--- a/tools/ioemu/TODO  Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/TODO  Mon Aug 07 18:00:22 2006 -0500
@@ -1,24 +1,20 @@ short term:
 short term:
 ----------
+- cycle counter for all archs
+- cpu_interrupt() win32/SMP fix
 - support variable tsc freq
-- cpu_interrupt() win32/SMP fix
 - USB host async
 - IDE async
 - debug option in 'configure' script + disable -fomit-frame-pointer
 - Precise VGA timings for old games/demos (malc patch)
 - merge PIC spurious interrupt patch
-- merge Solaris patch
 - warning for OS/2: must not use 128 MB memory (merge bochs cmos patch ?)
 - config file (at least for windows/Mac OS X)
-- commit message if execution of code in IO memory
 - update doc: PCI infos.
-- VNC patch + Synaptic patch.
 - basic VGA optimizations
-- physical memory cache (reduce qemu-fast address space size to about 32 MB)
 - better code fetch (different exception handling + CS.limit support)
 - do not resize vga if invalid size.
 - avoid looping if only exceptions
-- cycle counter for all archs
 - TLB code protection support for PPC
 - see openMosix Doc 
 - disable SMC handling for ARM/SPARC/PPC (not finished)
@@ -31,12 +27,10 @@ short term:
 - fix CCOP optimisation
 - fix all remaining thread lock issues (must put TBs in a specific invalid
   state, find a solution for tb_flush()).
-- fix arm fpu rounding (at least for float->integer conversions)
 
 ppc specific:
 ------------
 - TLB invalidate not needed if msr_pr changes
-- SPR_ENCODE() not useful
 - enable shift optimizations ?
 
 linux-user specific:
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/VERSION
--- a/tools/ioemu/VERSION       Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/VERSION       Mon Aug 07 18:00:22 2006 -0500
@@ -1,1 +1,1 @@ 0.8.1
-0.8.1
\ No newline at end of file
+0.8.2
\ No newline at end of file
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/alsaaudio.c
--- a/tools/ioemu/audio/alsaaudio.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/alsaaudio.c     Mon Aug 07 18:00:22 2006 -0500
@@ -61,8 +61,8 @@ static struct {
     .size_in_usec_in = 1,
     .size_in_usec_out = 1,
 #endif
-    .pcm_name_out = "hw:0,0",
-    .pcm_name_in = "hw:0,0",
+    .pcm_name_out = "default",
+    .pcm_name_in = "default",
 #ifdef HIGH_LATENCY
     .buffer_size_in = 400000,
     .period_size_in = 400000 / 4,
@@ -606,7 +606,6 @@ static int alsa_run_out (HWVoiceOut *hw)
                 }
             }
 
-            mixeng_clear (src, written);
             rpos = (rpos + written) % hw->samples;
             samples -= written;
             len -= written;
@@ -663,12 +662,9 @@ static int alsa_init_out (HWVoiceOut *hw
     obt_as.freq = obt.freq;
     obt_as.nchannels = obt.nchannels;
     obt_as.fmt = effective_fmt;
-
-    audio_pcm_init_info (
-        &hw->info,
-        &obt_as,
-        audio_need_to_swap_endian (endianness)
-        );
+    obt_as.endianness = endianness;
+
+    audio_pcm_init_info (&hw->info, &obt_as);
     hw->samples = obt.samples;
 
     alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << 
hw->info.shift);
@@ -752,12 +748,9 @@ static int alsa_init_in (HWVoiceIn *hw, 
     obt_as.freq = obt.freq;
     obt_as.nchannels = obt.nchannels;
     obt_as.fmt = effective_fmt;
-
-    audio_pcm_init_info (
-        &hw->info,
-        &obt_as,
-        audio_need_to_swap_endian (endianness)
-        );
+    obt_as.endianness = endianness;
+
+    audio_pcm_init_info (&hw->info, &obt_as);
     hw->samples = obt.samples;
 
     alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << 
hw->info.shift);
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/audio.c
--- a/tools/ioemu/audio/audio.c Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/audio.c Mon Aug 07 18:00:22 2006 -0500
@@ -29,6 +29,7 @@
 /* #define DEBUG_PLIVE */
 /* #define DEBUG_LIVE */
 /* #define DEBUG_OUT */
+/* #define DEBUG_CAPTURE */
 
 #define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
 
@@ -137,7 +138,7 @@ int audio_bug (const char *funcname, int
     if (cond) {
         static int shown;
 
-        AUD_log (NULL, "Error a bug that was just triggered in %s\n", 
funcname);
+        AUD_log (NULL, "A bug was just triggered in %s\n", funcname);
         if (!shown) {
             shown = 1;
             AUD_log (NULL, "Save all your work and restart without audio\n");
@@ -509,14 +510,28 @@ static void audio_print_settings (audset
         AUD_log (NULL, "invalid(%d)", as->fmt);
         break;
     }
+
+    AUD_log (NULL, " endianness=");
+    switch (as->endianness) {
+    case 0:
+        AUD_log (NULL, "little");
+        break;
+    case 1:
+        AUD_log (NULL, "big");
+        break;
+    default:
+        AUD_log (NULL, "invalid");
+        break;
+    }
     AUD_log (NULL, "\n");
 }
 
-static int audio_validate_settigs (audsettings_t *as)
+static int audio_validate_settings (audsettings_t *as)
 {
     int invalid;
 
     invalid = as->nchannels != 1 && as->nchannels != 2;
+    invalid |= as->endianness != 0 && as->endianness != 1;
 
     switch (as->fmt) {
     case AUD_FMT_S8:
@@ -530,11 +545,7 @@ static int audio_validate_settigs (audse
     }
 
     invalid |= as->freq <= 0;
-
-    if (invalid) {
-        return -1;
-    }
-    return 0;
+    return invalid ? -1 : 0;
 }
 
 static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
@@ -556,14 +567,11 @@ static int audio_pcm_info_eq (struct aud
     return info->freq == as->freq
         && info->nchannels == as->nchannels
         && info->sign == sign
-        && info->bits == bits;
-}
-
-void audio_pcm_init_info (
-    struct audio_pcm_info *info,
-    audsettings_t *as,
-    int swap_endian
-    )
+        && info->bits == bits
+        && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS);
+}
+
+void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as)
 {
     int bits = 8, sign = 0;
 
@@ -587,7 +595,7 @@ void audio_pcm_init_info (
     info->shift = (as->nchannels == 2) + (bits == 16);
     info->align = (1 << info->shift) - 1;
     info->bytes_per_second = info->freq << info->shift;
-    info->swap_endian = swap_endian;
+    info->swap_endianness = (as->endianness != AUDIO_HOST_ENDIANNESS);
 }
 
 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
@@ -597,11 +605,11 @@ void audio_pcm_info_clear_buf (struct au
     }
 
     if (info->sign) {
-        memset (buf, len << info->shift, 0x00);
+        memset (buf, 0x00, len << info->shift);
     }
     else {
         if (info->bits == 8) {
-            memset (buf, len << info->shift, 0x80);
+            memset (buf, 0x80, len << info->shift);
         }
         else {
             int i;
@@ -609,7 +617,7 @@ void audio_pcm_info_clear_buf (struct au
             int shift = info->nchannels - 1;
             short s = INT16_MAX;
 
-            if (info->swap_endian) {
+            if (info->swap_endianness) {
                 s = bswap16 (s);
             }
 
@@ -618,6 +626,143 @@ void audio_pcm_info_clear_buf (struct au
             }
         }
     }
+}
+
+/*
+ * Capture
+ */
+static void noop_conv (st_sample_t *dst, const void *src,
+                       int samples, volume_t *vol)
+{
+    (void) src;
+    (void) dst;
+    (void) samples;
+    (void) vol;
+}
+
+static CaptureVoiceOut *audio_pcm_capture_find_specific (
+    AudioState *s,
+    audsettings_t *as
+    )
+{
+    CaptureVoiceOut *cap;
+
+    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
+        if (audio_pcm_info_eq (&cap->hw.info, as)) {
+            return cap;
+        }
+    }
+    return NULL;
+}
+
+static void audio_notify_capture (CaptureVoiceOut *cap, audcnotification_e cmd)
+{
+    struct capture_callback *cb;
+
+#ifdef DEBUG_CAPTURE
+    dolog ("notification %d sent\n", cmd);
+#endif
+    for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
+        cb->ops.notify (cb->opaque, cmd);
+    }
+}
+
+static void audio_capture_maybe_changed (CaptureVoiceOut *cap, int enabled)
+{
+    if (cap->hw.enabled != enabled) {
+        audcnotification_e cmd;
+        cap->hw.enabled = enabled;
+        cmd = enabled ? AUD_CNOTIFY_ENABLE : AUD_CNOTIFY_DISABLE;
+        audio_notify_capture (cap, cmd);
+    }
+}
+
+static void audio_recalc_and_notify_capture (CaptureVoiceOut *cap)
+{
+    HWVoiceOut *hw = &cap->hw;
+    SWVoiceOut *sw;
+    int enabled = 0;
+
+    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+        if (sw->active) {
+            enabled = 1;
+            break;
+        }
+    }
+    audio_capture_maybe_changed (cap, enabled);
+}
+
+static void audio_detach_capture (HWVoiceOut *hw)
+{
+    SWVoiceCap *sc = hw->cap_head.lh_first;
+
+    while (sc) {
+        SWVoiceCap *sc1 = sc->entries.le_next;
+        SWVoiceOut *sw = &sc->sw;
+        CaptureVoiceOut *cap = sc->cap;
+        int was_active = sw->active;
+
+        if (sw->rate) {
+            st_rate_stop (sw->rate);
+            sw->rate = NULL;
+        }
+
+        LIST_REMOVE (sw, entries);
+        LIST_REMOVE (sc, entries);
+        qemu_free (sc);
+        if (was_active) {
+            /* We have removed soft voice from the capture:
+               this might have changed the overall status of the capture
+               since this might have been the only active voice */
+            audio_recalc_and_notify_capture (cap);
+        }
+        sc = sc1;
+    }
+}
+
+static int audio_attach_capture (AudioState *s, HWVoiceOut *hw)
+{
+    CaptureVoiceOut *cap;
+
+    audio_detach_capture (hw);
+    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
+        SWVoiceCap *sc;
+        SWVoiceOut *sw;
+        HWVoiceOut *hw_cap = &cap->hw;
+
+        sc = audio_calloc (AUDIO_FUNC, 1, sizeof (*sc));
+        if (!sc) {
+            dolog ("Could not allocate soft capture voice (%zu bytes)\n",
+                   sizeof (*sc));
+            return -1;
+        }
+
+        sc->cap = cap;
+        sw = &sc->sw;
+        sw->hw = hw_cap;
+        sw->info = hw->info;
+        sw->empty = 1;
+        sw->active = hw->enabled;
+        sw->conv = noop_conv;
+        sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
+        sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
+        if (!sw->rate) {
+            dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
+            qemu_free (sw);
+            return -1;
+        }
+        LIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
+        LIST_INSERT_HEAD (&hw->cap_head, sc, entries);
+#ifdef DEBUG_CAPTURE
+        asprintf (&sw->name, "for %p %d,%d,%d",
+                  hw, sw->info.freq, sw->info.bits, sw->info.nchannels);
+        dolog ("Added %s active = %d\n", sw->name, sw->active);
+#endif
+        if (sw->active) {
+            audio_capture_maybe_changed (cap, 1);
+        }
+    }
+    return 0;
 }
 
 /*
@@ -796,6 +941,9 @@ int audio_pcm_sw_write (SWVoiceOut *sw, 
     }
 
     if (live == hwsamples) {
+#ifdef DEBUG_OUT
+        dolog ("%s is full %d\n", sw->name, live);
+#endif
         return 0;
     }
 
@@ -914,19 +1062,14 @@ void AUD_set_active_out (SWVoiceOut *sw,
     hw = sw->hw;
     if (sw->active != on) {
         SWVoiceOut *temp_sw;
+        SWVoiceCap *sc;
 
         if (on) {
-            int total;
-
             hw->pending_disable = 0;
             if (!hw->enabled) {
                 hw->enabled = 1;
                 hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);
             }
-
-            if (sw->empty) {
-                total = 0;
-            }
         }
         else {
             if (hw->enabled) {
@@ -940,6 +1083,13 @@ void AUD_set_active_out (SWVoiceOut *sw,
                 hw->pending_disable = nb_active == 1;
             }
         }
+
+        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
+            sc->sw.active = hw->enabled;
+            if (hw->enabled) {
+                audio_capture_maybe_changed (sc->cap, 1);
+            }
+        }
         sw->active = on;
     }
 }
@@ -997,7 +1147,7 @@ static int audio_get_avail (SWVoiceIn *s
     }
 
     ldebug (
-        "%s: get_avail live %d ret %lld\n",
+        "%s: get_avail live %d ret %" PRId64 "\n",
         SW_NAME (sw),
         live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
         );
@@ -1023,7 +1173,7 @@ static int audio_get_free (SWVoiceOut *s
     dead = sw->hw->samples - live;
 
 #ifdef DEBUG_OUT
-    dolog ("%s: get_free live %d dead %d ret %lld\n",
+    dolog ("%s: get_free live %d dead %d ret %" PRId64 "\n",
            SW_NAME (sw),
            live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
 #endif
@@ -1031,6 +1181,43 @@ static int audio_get_free (SWVoiceOut *s
     return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
 }
 
+static void audio_capture_mix_and_clear (HWVoiceOut *hw, int rpos, int samples)
+{
+    int n;
+
+    if (hw->enabled) {
+        SWVoiceCap *sc;
+
+        for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
+            SWVoiceOut *sw = &sc->sw;
+            int rpos2 = rpos;
+
+            n = samples;
+            while (n) {
+                int till_end_of_hw = hw->samples - rpos2;
+                int to_write = audio_MIN (till_end_of_hw, n);
+                int bytes = to_write << hw->info.shift;
+                int written;
+
+                sw->buf = hw->mix_buf + rpos2;
+                written = audio_pcm_sw_write (sw, NULL, bytes);
+                if (written - bytes) {
+                    dolog ("Could not mix %d bytes into a capture "
+                           "buffer, mixed %d\n",
+                           bytes, written);
+                    break;
+                }
+                n -= to_write;
+                rpos2 = (rpos2 + to_write) % hw->samples;
+            }
+        }
+    }
+
+    n = audio_MIN (samples, hw->samples - rpos);
+    mixeng_clear (hw->mix_buf + rpos, n);
+    mixeng_clear (hw->mix_buf, samples - n);
+}
+
 static void audio_run_out (AudioState *s)
 {
     HWVoiceOut *hw = NULL;
@@ -1038,7 +1225,7 @@ static void audio_run_out (AudioState *s
 
     while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
         int played;
-        int live, free, nb_live, cleanup_required;
+        int live, free, nb_live, cleanup_required, prev_rpos;
 
         live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
         if (!nb_live) {
@@ -1051,12 +1238,17 @@ static void audio_run_out (AudioState *s
         }
 
         if (hw->pending_disable && !nb_live) {
+            SWVoiceCap *sc;
 #ifdef DEBUG_OUT
             dolog ("Disabling voice\n");
 #endif
             hw->enabled = 0;
             hw->pending_disable = 0;
             hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
+            for (sc = hw->cap_head.lh_first; sc; sc = sc->entries.le_next) {
+                sc->sw.active = 0;
+                audio_recalc_and_notify_capture (sc->cap);
+            }
             continue;
         }
 
@@ -1072,6 +1264,7 @@ static void audio_run_out (AudioState *s
             continue;
         }
 
+        prev_rpos = hw->rpos;
         played = hw->pcm_ops->run_out (hw);
         if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
             dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
@@ -1085,6 +1278,7 @@ static void audio_run_out (AudioState *s
 
         if (played) {
             hw->ts_helper += played;
+            audio_capture_mix_and_clear (hw, prev_rpos, played);
         }
 
         cleanup_required = 0;
@@ -1115,15 +1309,18 @@ static void audio_run_out (AudioState *s
         }
 
         if (cleanup_required) {
-        restart:
-            for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+            SWVoiceOut *sw1;
+
+            sw = hw->sw_head.lh_first;
+            while (sw) {
+                sw1 = sw->entries.le_next;
                 if (!sw->active && !sw->callback.fn) {
 #ifdef DEBUG_PLIVE
                     dolog ("Finishing with old voice\n");
 #endif
                     audio_close_out (s, sw);
-                    goto restart; /* play it safe */
                 }
+                sw = sw1;
             }
         }
     }
@@ -1158,12 +1355,60 @@ static void audio_run_in (AudioState *s)
     }
 }
 
+static void audio_run_capture (AudioState *s)
+{
+    CaptureVoiceOut *cap;
+
+    for (cap = s->cap_head.lh_first; cap; cap = cap->entries.le_next) {
+        int live, rpos, captured;
+        HWVoiceOut *hw = &cap->hw;
+        SWVoiceOut *sw;
+
+        captured = live = audio_pcm_hw_get_live_out (hw);
+        rpos = hw->rpos;
+        while (live) {
+            int left = hw->samples - rpos;
+            int to_capture = audio_MIN (live, left);
+            st_sample_t *src;
+            struct capture_callback *cb;
+
+            src = hw->mix_buf + rpos;
+            hw->clip (cap->buf, src, to_capture);
+            mixeng_clear (src, to_capture);
+
+            for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
+                cb->ops.capture (cb->opaque, cap->buf,
+                                 to_capture << hw->info.shift);
+            }
+            rpos = (rpos + to_capture) % hw->samples;
+            live -= to_capture;
+        }
+        hw->rpos = rpos;
+
+        for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+            if (!sw->active && sw->empty) {
+                continue;
+            }
+
+            if (audio_bug (AUDIO_FUNC, captured > sw->total_hw_samples_mixed)) 
{
+                dolog ("captured=%d sw->total_hw_samples_mixed=%d\n",
+                       captured, sw->total_hw_samples_mixed);
+                captured = sw->total_hw_samples_mixed;
+            }
+
+            sw->total_hw_samples_mixed -= captured;
+            sw->empty = sw->total_hw_samples_mixed == 0;
+        }
+    }
+}
+
 static void audio_timer (void *opaque)
 {
     AudioState *s = opaque;
 
     audio_run_out (s);
     audio_run_in (s);
+    audio_run_capture (s);
 
     qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
 }
@@ -1327,8 +1572,19 @@ static void audio_atexit (void)
     HWVoiceIn *hwi = NULL;
 
     while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
+        SWVoiceCap *sc;
+
         hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
         hwo->pcm_ops->fini_out (hwo);
+
+        for (sc = hwo->cap_head.lh_first; sc; sc = sc->entries.le_next) {
+            CaptureVoiceOut *cap = sc->cap;
+            struct capture_callback *cb;
+
+            for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
+                cb->ops.destroy (cb->opaque);
+            }
+        }
     }
 
     while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
@@ -1383,6 +1639,7 @@ AudioState *AUD_init (void)
 
     LIST_INIT (&s->hw_head_out);
     LIST_INIT (&s->hw_head_in);
+    LIST_INIT (&s->cap_head);
     atexit (audio_atexit);
 
     s->ts = qemu_new_timer (vm_clock, audio_timer, s);
@@ -1479,3 +1736,136 @@ AudioState *AUD_init (void)
     qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
     return s;
 }
+
+CaptureVoiceOut *AUD_add_capture (
+    AudioState *s,
+    audsettings_t *as,
+    struct audio_capture_ops *ops,
+    void *cb_opaque
+    )
+{
+    CaptureVoiceOut *cap;
+    struct capture_callback *cb;
+
+    if (!s) {
+        /* XXX suppress */
+        s = &glob_audio_state;
+    }
+
+    if (audio_validate_settings (as)) {
+        dolog ("Invalid settings were passed when trying to add capture\n");
+        audio_print_settings (as);
+        goto err0;
+    }
+
+    cb = audio_calloc (AUDIO_FUNC, 1, sizeof (*cb));
+    if (!cb) {
+        dolog ("Could not allocate capture callback information, size %zu\n",
+               sizeof (*cb));
+        goto err0;
+    }
+    cb->ops = *ops;
+    cb->opaque = cb_opaque;
+
+    cap = audio_pcm_capture_find_specific (s, as);
+    if (cap) {
+        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
+        return cap;
+    }
+    else {
+        HWVoiceOut *hw;
+        CaptureVoiceOut *cap;
+
+        cap = audio_calloc (AUDIO_FUNC, 1, sizeof (*cap));
+        if (!cap) {
+            dolog ("Could not allocate capture voice, size %zu\n",
+                   sizeof (*cap));
+            goto err1;
+        }
+
+        hw = &cap->hw;
+        LIST_INIT (&hw->sw_head);
+        LIST_INIT (&cap->cb_head);
+
+        /* XXX find a more elegant way */
+        hw->samples = 4096 * 4;
+        hw->mix_buf = audio_calloc (AUDIO_FUNC, hw->samples,
+                                    sizeof (st_sample_t));
+        if (!hw->mix_buf) {
+            dolog ("Could not allocate capture mix buffer (%d samples)\n",
+                   hw->samples);
+            goto err2;
+        }
+
+        audio_pcm_init_info (&hw->info, as);
+
+        cap->buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
+        if (!cap->buf) {
+            dolog ("Could not allocate capture buffer "
+                   "(%d samples, each %d bytes)\n",
+                   hw->samples, 1 << hw->info.shift);
+            goto err3;
+        }
+
+        hw->clip = mixeng_clip
+            [hw->info.nchannels == 2]
+            [hw->info.sign]
+            [hw->info.swap_endianness]
+            [hw->info.bits == 16];
+
+        LIST_INSERT_HEAD (&s->cap_head, cap, entries);
+        LIST_INSERT_HEAD (&cap->cb_head, cb, entries);
+
+        hw = NULL;
+        while ((hw = audio_pcm_hw_find_any_out (s, hw))) {
+            audio_attach_capture (s, hw);
+        }
+        return cap;
+
+    err3:
+        qemu_free (cap->hw.mix_buf);
+    err2:
+        qemu_free (cap);
+    err1:
+        qemu_free (cb);
+    err0:
+        return NULL;
+    }
+}
+
+void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
+{
+    struct capture_callback *cb;
+
+    for (cb = cap->cb_head.lh_first; cb; cb = cb->entries.le_next) {
+        if (cb->opaque == cb_opaque) {
+            cb->ops.destroy (cb_opaque);
+            LIST_REMOVE (cb, entries);
+            qemu_free (cb);
+
+            if (!cap->cb_head.lh_first) {
+                SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
+
+                while (sw) {
+                    SWVoiceCap *sc = (SWVoiceCap *) sw;
+#ifdef DEBUG_CAPTURE
+                    dolog ("freeing %s\n", sw->name);
+#endif
+
+                    sw1 = sw->entries.le_next;
+                    if (sw->rate) {
+                        st_rate_stop (sw->rate);
+                        sw->rate = NULL;
+                    }
+                    LIST_REMOVE (sw, entries);
+                    LIST_REMOVE (sc, entries);
+                    qemu_free (sc);
+                    sw = sw1;
+                }
+                LIST_REMOVE (cap, entries);
+                qemu_free (cap);
+            }
+            return;
+        }
+    }
+}
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/audio.h
--- a/tools/ioemu/audio/audio.h Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/audio.h Mon Aug 07 18:00:22 2006 -0500
@@ -24,6 +24,7 @@
 #ifndef QEMU_AUDIO_H
 #define QEMU_AUDIO_H
 
+#include "config.h"
 #include "sys-queue.h"
 
 typedef void (*audio_callback_fn_t) (void *opaque, int avail);
@@ -35,14 +36,44 @@ typedef enum {
     AUD_FMT_S16
 } audfmt_e;
 
+#ifdef WORDS_BIGENDIAN
+#define AUDIO_HOST_ENDIANNESS 1
+#else
+#define AUDIO_HOST_ENDIANNESS 0
+#endif
+
 typedef struct {
     int freq;
     int nchannels;
     audfmt_e fmt;
+    int endianness;
 } audsettings_t;
+
+typedef enum {
+    AUD_CNOTIFY_ENABLE,
+    AUD_CNOTIFY_DISABLE
+} audcnotification_e;
+
+struct audio_capture_ops {
+    void (*notify) (void *opaque, audcnotification_e cmd);
+    void (*capture) (void *opaque, void *buf, int size);
+    void (*destroy) (void *opaque);
+};
+
+struct capture_ops {
+    void (*info) (void *opaque);
+    void (*destroy) (void *opaque);
+};
+
+typedef struct CaptureState {
+    void *opaque;
+    struct capture_ops ops;
+    LIST_ENTRY (CaptureState) entries;
+} CaptureState;
 
 typedef struct AudioState AudioState;
 typedef struct SWVoiceOut SWVoiceOut;
+typedef struct CaptureVoiceOut CaptureVoiceOut;
 typedef struct SWVoiceIn SWVoiceIn;
 
 typedef struct QEMUSoundCard {
@@ -66,6 +97,13 @@ void AUD_help (void);
 void AUD_help (void);
 void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card);
 void AUD_remove_card (QEMUSoundCard *card);
+CaptureVoiceOut *AUD_add_capture (
+    AudioState *s,
+    audsettings_t *as,
+    struct audio_capture_ops *ops,
+    void *opaque
+    );
+void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque);
 
 SWVoiceOut *AUD_open_out (
     QEMUSoundCard *card,
@@ -73,8 +111,7 @@ SWVoiceOut *AUD_open_out (
     const char *name,
     void *callback_opaque,
     audio_callback_fn_t callback_fn,
-    audsettings_t *settings,
-    int sw_endian
+    audsettings_t *settings
     );
 
 void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
@@ -92,8 +129,7 @@ SWVoiceIn *AUD_open_in (
     const char *name,
     void *callback_opaque,
     audio_callback_fn_t callback_fn,
-    audsettings_t *settings,
-    int sw_endian
+    audsettings_t *settings
     );
 
 void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
@@ -111,7 +147,7 @@ static inline void *advance (void *p, in
 }
 
 uint32_t popcount (uint32_t u);
-inline uint32_t lsbindex (uint32_t u);
+uint32_t lsbindex (uint32_t u);
 
 #ifdef __GNUC__
 #define audio_MIN(a, b) ( __extension__ ({      \
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/audio_int.h
--- a/tools/ioemu/audio/audio_int.h     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/audio_int.h     Mon Aug 07 18:00:22 2006 -0500
@@ -61,13 +61,14 @@ struct audio_pcm_info {
     int align;
     int shift;
     int bytes_per_second;
-    int swap_endian;
-};
+    int swap_endianness;
+};
+
+typedef struct SWVoiceCap SWVoiceCap;
 
 typedef struct HWVoiceOut {
     int enabled;
     int pending_disable;
-    int valid;
     struct audio_pcm_info info;
 
     f_sample *clip;
@@ -79,6 +80,7 @@ typedef struct HWVoiceOut {
 
     int samples;
     LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
+    LIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
     struct audio_pcm_ops *pcm_ops;
     LIST_ENTRY (HWVoiceOut) entries;
 } HWVoiceOut;
@@ -160,14 +162,34 @@ struct audio_pcm_ops {
     int  (*ctl_in)  (HWVoiceIn *hw, int cmd, ...);
 };
 
+struct capture_callback {
+    struct audio_capture_ops ops;
+    void *opaque;
+    LIST_ENTRY (capture_callback) entries;
+};
+
+struct CaptureVoiceOut {
+    HWVoiceOut hw;
+    void *buf;
+    LIST_HEAD (cb_listhead, capture_callback) cb_head;
+    LIST_ENTRY (CaptureVoiceOut) entries;
+};
+
+struct SWVoiceCap {
+    SWVoiceOut sw;
+    CaptureVoiceOut *cap;
+    LIST_ENTRY (SWVoiceCap) entries;
+};
+
 struct AudioState {
     struct audio_driver *drv;
     void *drv_opaque;
 
     QEMUTimer *ts;
-    LIST_HEAD (card_head, QEMUSoundCard) card_head;
+    LIST_HEAD (card_listhead, QEMUSoundCard) card_head;
     LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
     LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
+    LIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
     int nb_hw_voices_out;
     int nb_hw_voices_in;
 };
@@ -182,8 +204,7 @@ extern struct audio_driver dsound_audio_
 extern struct audio_driver dsound_audio_driver;
 extern volume_t nominal_volume;
 
-void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as,
-                          int swap_endian);
+void audio_pcm_init_info (struct audio_pcm_info *info, audsettings_t *as);
 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int 
len);
 
 int  audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
@@ -202,15 +223,6 @@ static inline int audio_ring_dist (int d
 static inline int audio_ring_dist (int dst, int src, int len)
 {
     return (dst >= src) ? (dst - src) : (len - src + dst);
-}
-
-static inline int audio_need_to_swap_endian (int endianness)
-{
-#ifdef WORDS_BIGENDIAN
-    return endianness != 1;
-#else
-    return endianness != 0;
-#endif
 }
 
 #if defined __GNUC__
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/audio_template.h
--- a/tools/ioemu/audio/audio_template.h        Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/audio_template.h        Mon Aug 07 18:00:22 2006 -0500
@@ -140,13 +140,12 @@ static int glue (audio_pcm_sw_init_, TYP
     SW *sw,
     HW *hw,
     const char *name,
-    audsettings_t *as,
-    int endian
+    audsettings_t *as
     )
 {
     int err;
 
-    audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (endian));
+    audio_pcm_init_info (&sw->info, as);
     sw->hw = hw;
     sw->active = 0;
 #ifdef DAC
@@ -164,7 +163,7 @@ static int glue (audio_pcm_sw_init_, TYP
 #endif
         [sw->info.nchannels == 2]
         [sw->info.sign]
-        [sw->info.swap_endian]
+        [sw->info.swap_endianness]
         [sw->info.bits == 16];
 
     sw->name = qemu_strdup (name);
@@ -200,6 +199,9 @@ static void glue (audio_pcm_hw_gc_, TYPE
     HW *hw = *hwp;
 
     if (!hw->sw_head.lh_first) {
+#ifdef DAC
+        audio_detach_capture (hw);
+#endif
         LIST_REMOVE (hw, entries);
         glue (s->nb_hw_voices_, TYPE) += 1;
         glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
@@ -266,7 +268,9 @@ static HW *glue (audio_pcm_hw_add_new_, 
 
     hw->pcm_ops = drv->pcm_ops;
     LIST_INIT (&hw->sw_head);
-
+#ifdef DAC
+    LIST_INIT (&hw->cap_head);
+#endif
     if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
         goto err0;
     }
@@ -283,7 +287,7 @@ static HW *glue (audio_pcm_hw_add_new_, 
 #endif
         [hw->info.nchannels == 2]
         [hw->info.sign]
-        [hw->info.swap_endian]
+        [hw->info.swap_endianness]
         [hw->info.bits == 16];
 
     if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
@@ -292,6 +296,9 @@ static HW *glue (audio_pcm_hw_add_new_, 
 
     LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
     glue (s->nb_hw_voices_, TYPE) -= 1;
+#ifdef DAC
+    audio_attach_capture (s, hw);
+#endif
     return hw;
 
  err1:
@@ -328,8 +335,7 @@ static SW *glue (audio_pcm_create_voice_
 static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
     AudioState *s,
     const char *sw_name,
-    audsettings_t *as,
-    int sw_endian
+    audsettings_t *as
     )
 {
     SW *sw;
@@ -357,7 +363,7 @@ static SW *glue (audio_pcm_create_voice_
 
     glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
 
-    if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as, sw_endian)) {
+    if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) {
         goto err3;
     }
 
@@ -399,8 +405,7 @@ SW *glue (AUD_open_, TYPE) (
     const char *name,
     void *callback_opaque ,
     audio_callback_fn_t callback_fn,
-    audsettings_t *as,
-    int sw_endian
+    audsettings_t *as
     )
 {
     AudioState *s;
@@ -421,7 +426,7 @@ SW *glue (AUD_open_, TYPE) (
 
     s = card->audio;
 
-    if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
+    if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
         audio_print_settings (as);
         goto fail;
     }
@@ -473,12 +478,12 @@ SW *glue (AUD_open_, TYPE) (
         }
 
         glue (audio_pcm_sw_fini_, TYPE) (sw);
-        if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as, sw_endian)) {
+        if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) {
             goto fail;
         }
     }
     else {
-        sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as, 
sw_endian);
+        sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as);
         if (!sw) {
             dolog ("Failed to create voice `%s'\n", name);
             return NULL;
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/coreaudio.c
--- a/tools/ioemu/audio/coreaudio.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/coreaudio.c     Mon Aug 07 18:00:22 2006 -0500
@@ -275,8 +275,6 @@ static OSStatus audioDeviceIOProc(
 #endif
     }
 
-    /* cleanup */
-    mixeng_clear (src, frameCount);
     rpos = (rpos + frameCount) % hw->samples;
     core->decr += frameCount;
     core->rpos = rpos;
@@ -297,7 +295,6 @@ static int coreaudio_init_out (HWVoiceOu
     UInt32 propertySize;
     int err;
     int bits = 8;
-    int endianess = 0;
     const char *typ = "playback";
     AudioValueRange frameRange;
 
@@ -310,16 +307,9 @@ static int coreaudio_init_out (HWVoiceOu
 
     if (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) {
         bits = 16;
-        endianess = 1;
-    }
-
-    audio_pcm_init_info (
-        &hw->info,
-        as,
-        /* Following is irrelevant actually since we do not use
-           mixengs clipping routines */
-        audio_need_to_swap_endian (endianess)
-        );
+    }
+
+    audio_pcm_init_info (&hw->info, as);
 
     /* open default output device */
     propertySize = sizeof(core->outputDeviceID);
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/dsound_template.h
--- a/tools/ioemu/audio/dsound_template.h       Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/dsound_template.h       Mon Aug 07 18:00:22 2006 -0500
@@ -70,7 +70,13 @@ static int glue (dsound_lock_, TYPE) (
     int i;
     LPVOID p1 = NULL, p2 = NULL;
     DWORD blen1 = 0, blen2 = 0;
-
+    DWORD flag;
+
+#ifdef DSBTYPE_IN
+    flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
+#else
+    flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
+#endif
     for (i = 0; i < conf.lock_retries; ++i) {
         hr = glue (IFACE, _Lock) (
             buf,
@@ -80,13 +86,7 @@ static int glue (dsound_lock_, TYPE) (
             &blen1,
             &p2,
             &blen2,
-            (entire
-#ifdef DSBTYPE_IN
-             ? DSCBLOCK_ENTIREBUFFER
-#else
-             ? DSBLOCK_ENTIREBUFFER
-#endif
-             : 0)
+            flag
             );
 
         if (FAILED (hr)) {
@@ -250,8 +250,8 @@ static int dsound_init_out (HWVoiceOut *
     }
 
     ds->first_time = 1;
-
-    audio_pcm_init_info (&hw->info, &obt_as, audio_need_to_swap_endian (0));
+    obt_as.endianness = 0;
+    audio_pcm_init_info (&hw->info, &obt_as);
 
     if (bc.dwBufferBytes & hw->info.align) {
         dolog (
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/dsoundaudio.c
--- a/tools/ioemu/audio/dsoundaudio.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/dsoundaudio.c   Mon Aug 07 18:00:22 2006 -0500
@@ -453,13 +453,11 @@ static void dsound_write_sample (HWVoice
 
     if (src_len1) {
         hw->clip (dst, src1, src_len1);
-        mixeng_clear (src1, src_len1);
     }
 
     if (src_len2) {
         dst = advance (dst, src_len1 << hw->info.shift);
         hw->clip (dst, src2, src_len2);
-        mixeng_clear (src2, src_len2);
     }
 
     hw->rpos = pos % hw->samples;
@@ -987,6 +985,12 @@ static void *dsound_audio_init (void)
     hr = IDirectSound_Initialize (s->dsound, NULL);
     if (FAILED (hr)) {
         dsound_logerr (hr, "Could not initialize DirectSound\n");
+
+        hr = IDirectSound_Release (s->dsound);
+        if (FAILED (hr)) {
+            dsound_logerr (hr, "Could not release DirectSound\n");
+        }
+        s->dsound = NULL;
         return NULL;
     }
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/fmodaudio.c
--- a/tools/ioemu/audio/fmodaudio.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/fmodaudio.c     Mon Aug 07 18:00:22 2006 -0500
@@ -153,13 +153,11 @@ static void fmod_write_sample (HWVoiceOu
 
     if (src_len1) {
         hw->clip (dst, src1, src_len1);
-        mixeng_clear (src1, src_len1);
     }
 
     if (src_len2) {
         dst = advance (dst, src_len1 << hw->info.shift);
         hw->clip (dst, src2, src_len2);
-        mixeng_clear (src2, src_len2);
     }
 
     hw->rpos = pos % hw->samples;
@@ -360,6 +358,7 @@ static int fmod_init_out (HWVoiceOut *hw
 {
     int bits16, mode, channel;
     FMODVoiceOut *fmd = (FMODVoiceOut *) hw;
+    audsettings_t obt_as = *as;
 
     mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);
     fmd->fmod_sample = FSOUND_Sample_Alloc (
@@ -386,7 +385,8 @@ static int fmod_init_out (HWVoiceOut *hw
     fmd->channel = channel;
 
     /* FMOD always operates on little endian frames? */
-    audio_pcm_init_info (&hw->info, as, audio_need_to_swap_endian (0));
+    obt_as.endianness = 0;
+    audio_pcm_init_info (&hw->info, &obt_as);
     bits16 = (mode & FSOUND_16BITS) != 0;
     hw->samples = conf.nb_samples;
     return 0;
@@ -420,6 +420,7 @@ static int fmod_init_in (HWVoiceIn *hw, 
 {
     int bits16, mode;
     FMODVoiceIn *fmd = (FMODVoiceIn *) hw;
+    audsettings_t obt_as = *as;
 
     if (conf.broken_adc) {
         return -1;
@@ -442,7 +443,8 @@ static int fmod_init_in (HWVoiceIn *hw, 
     }
 
     /* FMOD always operates on little endian frames? */
-    audio_pcm_init_info (&hw->info, as, audio_need_to_swap_endian (0));
+    obt_as.endianness = 0;
+    audio_pcm_init_info (&hw->info, &obt_as);
     bits16 = (mode & FSOUND_16BITS) != 0;
     hw->samples = conf.nb_samples;
     return 0;
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/noaudio.c
--- a/tools/ioemu/audio/noaudio.c       Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/noaudio.c       Mon Aug 07 18:00:22 2006 -0500
@@ -40,21 +40,20 @@ static int no_run_out (HWVoiceOut *hw)
 {
     NoVoiceOut *no = (NoVoiceOut *) hw;
     int live, decr, samples;
-    int64_t now = qemu_get_clock (vm_clock);
-    int64_t ticks = now - no->old_ticks;
-    int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
-
-    if (bytes > INT_MAX) {
-        samples = INT_MAX >> hw->info.shift;
-    }
-    else {
-        samples = bytes >> hw->info.shift;
-    }
+    int64_t now;
+    int64_t ticks;
+    int64_t bytes;
 
     live = audio_pcm_hw_get_live_out (&no->hw);
     if (!live) {
         return 0;
     }
+
+    now = qemu_get_clock (vm_clock);
+    ticks = now - no->old_ticks;
+    bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
+    bytes = audio_MIN (bytes, INT_MAX);
+    samples = bytes >> hw->info.shift;
 
     no->old_ticks = now;
     decr = audio_MIN (live, samples);
@@ -69,7 +68,7 @@ static int no_write (SWVoiceOut *sw, voi
 
 static int no_init_out (HWVoiceOut *hw, audsettings_t *as)
 {
-    audio_pcm_init_info (&hw->info, as, 0);
+    audio_pcm_init_info (&hw->info, as);
     hw->samples = 1024;
     return 0;
 }
@@ -88,7 +87,7 @@ static int no_ctl_out (HWVoiceOut *hw, i
 
 static int no_init_in (HWVoiceIn *hw, audsettings_t *as)
 {
-    audio_pcm_init_info (&hw->info, as, 0);
+    audio_pcm_init_info (&hw->info, as);
     hw->samples = 1024;
     return 0;
 }
@@ -101,17 +100,20 @@ static int no_run_in (HWVoiceIn *hw)
 static int no_run_in (HWVoiceIn *hw)
 {
     NoVoiceIn *no = (NoVoiceIn *) hw;
-    int64_t now = qemu_get_clock (vm_clock);
-    int64_t ticks = now - no->old_ticks;
-    int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
     int live = audio_pcm_hw_get_live_in (hw);
     int dead = hw->samples - live;
-    int samples;
+    int samples = 0;
 
-    bytes = audio_MIN (bytes, INT_MAX);
-    samples = bytes >> hw->info.shift;
-    samples = audio_MIN (samples, dead);
+    if (dead) {
+        int64_t now = qemu_get_clock (vm_clock);
+        int64_t ticks = now - no->old_ticks;
+        int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
 
+        no->old_ticks = now;
+        bytes = audio_MIN (bytes, INT_MAX);
+        samples = bytes >> hw->info.shift;
+        samples = audio_MIN (samples, dead);
+    }
     return samples;
 }
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/ossaudio.c
--- a/tools/ioemu/audio/ossaudio.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/ossaudio.c      Mon Aug 07 18:00:22 2006 -0500
@@ -55,12 +55,14 @@ static struct {
     int fragsize;
     const char *devpath_out;
     const char *devpath_in;
+    int debug;
 } conf = {
     .try_mmap = 0,
     .nfrags = 4,
     .fragsize = 4096,
     .devpath_out = "/dev/dsp",
-    .devpath_in = "/dev/dsp"
+    .devpath_in = "/dev/dsp",
+    .debug = 0
 };
 
 struct oss_params {
@@ -324,9 +326,20 @@ static int oss_run_out (HWVoiceOut *hw)
             return 0;
         }
 
-        if (abinfo.bytes < 0 || abinfo.bytes > bufsize) {
-            ldebug ("warning: Invalid available size, size=%d bufsize=%d\n",
-                    abinfo.bytes, bufsize);
+        if (abinfo.bytes > bufsize) {
+            if (conf.debug) {
+                dolog ("warning: Invalid available size, size=%d bufsize=%d\n"
+                       "please report your OS/audio hw to 
malc@xxxxxxxxxxxxx\n",
+                       abinfo.bytes, bufsize);
+            }
+            abinfo.bytes = bufsize;
+        }
+
+        if (abinfo.bytes < 0) {
+            if (conf.debug) {
+                dolog ("warning: Invalid available size, size=%d bufsize=%d\n",
+                       abinfo.bytes, bufsize);
+            }
             return 0;
         }
 
@@ -369,14 +382,11 @@ static int oss_run_out (HWVoiceOut *hw)
                            "alignment %d\n",
                            wbytes, written, hw->info.align + 1);
                 }
-                mixeng_clear (src, wsamples);
                 decr -= wsamples;
                 rpos = (rpos + wsamples) % hw->samples;
                 break;
             }
         }
-
-        mixeng_clear (src, convert_samples);
 
         rpos = (rpos + convert_samples) % hw->samples;
         samples -= convert_samples;
@@ -443,12 +453,9 @@ static int oss_init_out (HWVoiceOut *hw,
     obt_as.freq = obt.freq;
     obt_as.nchannels = obt.nchannels;
     obt_as.fmt = effective_fmt;
-
-    audio_pcm_init_info (
-        &hw->info,
-        &obt_as,
-        audio_need_to_swap_endian (endianness)
-        );
+    obt_as.endianness = endianness;
+
+    audio_pcm_init_info (&hw->info, &obt_as);
     oss->nfrags = obt.nfrags;
     oss->fragsize = obt.fragsize;
 
@@ -587,12 +594,9 @@ static int oss_init_in (HWVoiceIn *hw, a
     obt_as.freq = obt.freq;
     obt_as.nchannels = obt.nchannels;
     obt_as.fmt = effective_fmt;
-
-    audio_pcm_init_info (
-        &hw->info,
-        &obt_as,
-        audio_need_to_swap_endian (endianness)
-        );
+    obt_as.endianness = endianness;
+
+    audio_pcm_init_info (&hw->info, &obt_as);
     oss->nfrags = obt.nfrags;
     oss->fragsize = obt.fragsize;
 
@@ -730,6 +734,8 @@ static struct audio_option oss_options[]
      "Path to DAC device", NULL, 0},
     {"ADC_DEV", AUD_OPT_STR, &conf.devpath_in,
      "Path to ADC device", NULL, 0},
+    {"DEBUG", AUD_OPT_BOOL, &conf.debug,
+     "Turn on some debugging messages", NULL, 0},
     {NULL, 0, NULL, NULL, NULL, 0}
 };
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/rate_template.h
--- a/tools/ioemu/audio/rate_template.h Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/rate_template.h Mon Aug 07 18:00:22 2006 -0500
@@ -51,7 +51,7 @@ void NAME (void *opaque, st_sample_t *ib
     if (rate->opos_inc == (1ULL + UINT_MAX)) {
         int i, n = *isamp > *osamp ? *osamp : *isamp;
         for (i = 0; i < n; i++) {
-            OP (obuf[i].l, ibuf[i].r);
+            OP (obuf[i].l, ibuf[i].l);
             OP (obuf[i].r, ibuf[i].r);
         }
         *isamp = n;
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/sdlaudio.c
--- a/tools/ioemu/audio/sdlaudio.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/sdlaudio.c      Mon Aug 07 18:00:22 2006 -0500
@@ -240,7 +240,6 @@ static void sdl_callback (void *opaque, 
 
             /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
             hw->clip (buf, src, chunk);
-            mixeng_clear (src, chunk);
             sdl->rpos = (sdl->rpos + chunk) % hw->samples;
             to_mix -= chunk;
             buf += chunk << hw->info.shift;
@@ -336,12 +335,9 @@ static int sdl_init_out (HWVoiceOut *hw,
     obt_as.freq = obt.freq;
     obt_as.nchannels = obt.channels;
     obt_as.fmt = effective_fmt;
-
-    audio_pcm_init_info (
-        &hw->info,
-        &obt_as,
-        audio_need_to_swap_endian (endianess)
-        );
+    obt_as.endianness = endianess;
+
+    audio_pcm_init_info (&hw->info, &obt_as);
     hw->samples = obt.samples;
 
     s->initialized = 1;
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/audio/wavaudio.c
--- a/tools/ioemu/audio/wavaudio.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/audio/wavaudio.c      Mon Aug 07 18:00:22 2006 -0500
@@ -81,7 +81,6 @@ static int wav_run_out (HWVoiceOut *hw)
 
         hw->clip (dst, src, convert_samples);
         qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift);
-        mixeng_clear (src, convert_samples);
 
         rpos = (rpos + convert_samples) % hw->samples;
         samples -= convert_samples;
@@ -136,7 +135,8 @@ static int wav_init_out (HWVoiceOut *hw,
 
     hdr[34] = bits16 ? 0x10 : 0x08;
 
-    audio_pcm_init_info (&hw->info, &wav_as, audio_need_to_swap_endian (0));
+    wav_as.endianness = 0;
+    audio_pcm_init_info (&hw->info, &wav_as);
 
     hw->samples = 1024;
     wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block-bochs.c
--- a/tools/ioemu/block-bochs.c Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block-bochs.c Mon Aug 07 18:00:22 2006 -0500
@@ -91,7 +91,7 @@ static int bochs_open(BlockDriverState *
     int fd, i;
     struct bochs_header bochs;
 
-    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE | O_SYNC);
     if (fd < 0) {
         fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
         if (fd < 0)
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block-cloop.c
--- a/tools/ioemu/block-cloop.c Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block-cloop.c Mon Aug 07 18:00:22 2006 -0500
@@ -55,7 +55,7 @@ static int cloop_open(BlockDriverState *
     BDRVCloopState *s = bs->opaque;
     uint32_t offsets_size,max_compressed_block_size=1,i;
 
-    s->fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+    s->fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE | O_SYNC);
     if (s->fd < 0)
         return -1;
     bs->read_only = 1;
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block-cow.c
--- a/tools/ioemu/block-cow.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block-cow.c   Mon Aug 07 18:00:22 2006 -0500
@@ -69,7 +69,7 @@ static int cow_open(BlockDriverState *bs
     struct cow_header_v2 cow_header;
     int64_t size;
 
-    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE | O_SYNC);
     if (fd < 0) {
         fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
         if (fd < 0)
@@ -250,6 +250,12 @@ static int cow_create(const char *filena
     return 0;
 }
 
+static void cow_flush(BlockDriverState *bs)
+{
+    BDRVCowState *s = bs->opaque;
+    fsync(s->fd);
+}
+
 BlockDriver bdrv_cow = {
     "cow",
     sizeof(BDRVCowState),
@@ -259,6 +265,7 @@ BlockDriver bdrv_cow = {
     cow_write,
     cow_close,
     cow_create,
+    cow_flush,
     cow_is_allocated,
 };
 #endif
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block-qcow.c
--- a/tools/ioemu/block-qcow.c  Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block-qcow.c  Mon Aug 07 18:00:22 2006 -0500
@@ -95,7 +95,7 @@ static int qcow_open(BlockDriverState *b
     int fd, len, i, shift;
     QCowHeader header;
     
-    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE | O_SYNC);
     if (fd < 0) {
         fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
         if (fd < 0)
@@ -693,6 +693,12 @@ int qcow_compress_cluster(BlockDriverSta
     return 0;
 }
 
+static void qcow_flush(BlockDriverState *bs)
+{
+    BDRVQcowState *s = bs->opaque;
+    fsync(s->fd);
+}
+
 BlockDriver bdrv_qcow = {
     "qcow",
     sizeof(BDRVQcowState),
@@ -702,6 +708,7 @@ BlockDriver bdrv_qcow = {
     qcow_write,
     qcow_close,
     qcow_create,
+    qcow_flush,
     qcow_is_allocated,
     qcow_set_key,
     qcow_make_empty
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block-vmdk.c
--- a/tools/ioemu/block-vmdk.c  Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block-vmdk.c  Mon Aug 07 18:00:22 2006 -0500
@@ -96,7 +96,7 @@ static int vmdk_open(BlockDriverState *b
     uint32_t magic;
     int l1_size;
 
-    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE | O_SYNC);
     if (fd < 0) {
         fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
         if (fd < 0)
@@ -426,6 +426,12 @@ static void vmdk_close(BlockDriverState 
     close(s->fd);
 }
 
+static void vmdk_flush(BlockDriverState *bs)
+{
+    BDRVVmdkState *s = bs->opaque;
+    fsync(s->fd);
+}
+
 BlockDriver bdrv_vmdk = {
     "vmdk",
     sizeof(BDRVVmdkState),
@@ -435,5 +441,6 @@ BlockDriver bdrv_vmdk = {
     vmdk_write,
     vmdk_close,
     vmdk_create,
+    vmdk_flush,
     vmdk_is_allocated,
 };
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block-vpc.c
--- a/tools/ioemu/block-vpc.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block-vpc.c   Mon Aug 07 18:00:22 2006 -0500
@@ -163,7 +163,7 @@ static inline int seek_to_sector(BlockDr
     bitmap_offset = 512 * s->pagetable[pagetable_index];
     block_offset = bitmap_offset + 512 + (512 * pageentry_index);
     
-//    printf("sector: %llx, index: %x, offset: %x, bioff: %llx, bloff: %llx\n",
+//    printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", 
bloff: %" PRIx64 "\n",
 //     sector_num, pagetable_index, pageentry_index,
 //     bitmap_offset, block_offset);
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block-vvfat.c
--- a/tools/ioemu/block-vvfat.c Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block-vvfat.c Mon Aug 07 18:00:22 2006 -0500
@@ -2772,6 +2772,7 @@ BlockDriver bdrv_vvfat = {
     vvfat_read,
     vvfat_write,
     vvfat_close,
+    NULL, /* ??? Not sure if we can do any meaningful flushing.  */
     NULL,
     vvfat_is_allocated
 };
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block.c
--- a/tools/ioemu/block.c       Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block.c       Mon Aug 07 18:00:22 2006 -0500
@@ -615,6 +615,14 @@ const char *bdrv_get_device_name(BlockDr
     return bs->device_name;
 }
 
+void bdrv_flush(BlockDriverState *bs)
+{
+    if (bs->drv->bdrv_flush)
+        bs->drv->bdrv_flush(bs);
+    if (bs->backing_hd)
+        bdrv_flush(bs->backing_hd);
+}
+
 void bdrv_info(void)
 {
     BlockDriverState *bs;
@@ -677,7 +685,7 @@ static int raw_open(BlockDriverState *bs
     int rv;
 #endif
 
-    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE | O_SYNC);
     if (fd < 0) {
         fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
         if (fd < 0)
@@ -750,8 +758,54 @@ static void raw_close(BlockDriverState *
 static void raw_close(BlockDriverState *bs)
 {
     BDRVRawState *s = bs->opaque;
+    bs->total_sectors = 0;
     close(s->fd);
 }
+
+#ifdef _WIN32
+#include <windows.h>
+#include <winioctl.h>
+
+int qemu_ftruncate64(int fd, int64_t length)
+{
+    LARGE_INTEGER li;
+    LONG high;
+    HANDLE h;
+    BOOL res;
+
+    if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
+       return -1;
+
+    h = (HANDLE)_get_osfhandle(fd);
+
+    /* get current position, ftruncate do not change position */
+    li.HighPart = 0;
+    li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
+    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
+       return -1;
+
+    high = length >> 32;
+    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
+       return -1;
+    res = SetEndOfFile(h);
+
+    /* back to old position */
+    SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
+    return res ? 0 : -1;
+}
+
+static int set_sparse(int fd)
+{
+    DWORD returned;
+    return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
+                                NULL, 0, NULL, 0, &returned, NULL);
+}
+#else
+static inline int set_sparse(int fd)
+{
+    return 1;
+}
+#endif
 
 static int raw_create(const char *filename, int64_t total_size,
                       const char *backing_file, int flags)
@@ -765,9 +819,16 @@ static int raw_create(const char *filena
               0644);
     if (fd < 0)
         return -EIO;
+    set_sparse(fd);
     ftruncate(fd, total_size * 512);
     close(fd);
     return 0;
+}
+
+static void raw_flush(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    fsync(s->fd);
 }
 
 BlockDriver bdrv_raw = {
@@ -779,6 +840,7 @@ BlockDriver bdrv_raw = {
     raw_write,
     raw_close,
     raw_create,
+    raw_flush,
 };
 
 void bdrv_init(void)
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/block_int.h
--- a/tools/ioemu/block_int.h   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/block_int.h   Mon Aug 07 18:00:22 2006 -0500
@@ -36,6 +36,7 @@ struct BlockDriver {
     void (*bdrv_close)(BlockDriverState *bs);
     int (*bdrv_create)(const char *filename, int64_t total_sectors, 
                        const char *backing_file, int flags);
+    void (*bdrv_flush)(BlockDriverState *bs);
     int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/cocoa.m
--- a/tools/ioemu/cocoa.m       Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/cocoa.m       Mon Aug 07 18:00:22 2006 -0500
@@ -439,23 +439,40 @@ static void cocoa_refresh(DisplayState *
                                 kbd_put_keycode(keycode & 0x7f); //remove e0 
bit in front
                             /* handle monitor key events */
                             } else {
+                                int keysym = 0;
+
                                 switch([event keyCode]) {
-                                    case 123:
-                                        kbd_put_keysym(QEMU_KEY_LEFT);
-                                        break;
-                                    case 124:
-                                        kbd_put_keysym(QEMU_KEY_RIGHT);
-                                        break;
-                                    case 125:
-                                        kbd_put_keysym(QEMU_KEY_DOWN);
-                                        break;
-                                    case 126:
-                                        kbd_put_keysym(QEMU_KEY_UP);
-                                        break;
-                                    default:
-                                        kbd_put_keysym([[event characters] 
characterAtIndex:0]);
-                                        break;
+                                case 115:
+                                    keysym = QEMU_KEY_HOME;
+                                    break;
+                                case 117:
+                                    keysym = QEMU_KEY_DELETE;
+                                    break;
+                                case 119:
+                                    keysym = QEMU_KEY_END;
+                                    break;
+                                case 123:
+                                    keysym = QEMU_KEY_LEFT;
+                                    break;
+                                case 124:
+                                    keysym = QEMU_KEY_RIGHT;
+                                    break;
+                                case 125:
+                                    keysym = QEMU_KEY_DOWN;
+                                    break;
+                                case 126:
+                                    keysym = QEMU_KEY_UP;
+                                    break;
+                                default:
+                                    {
+                                        NSString *ks = [event characters];
+
+                                        if ([ks length] > 0)
+                                            keysym = [ks characterAtIndex:0];
+                                    }
                                 }
+                                if (keysym)
+                                    kbd_put_keysym(keysym);
                             }
                         }
                     }
@@ -867,10 +884,9 @@ static void setupWindowMenu(void)
     /* Finally give up our references to the objects */
     [windowMenu release];
     [windowMenuItem release];
- 
-}
-
-static void CustomApplicationMain (argc, argv)
+}
+
+static void CustomApplicationMain(void)
 {
     NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
     QemuCocoaGUIController *gui_controller;
@@ -904,8 +920,8 @@ int main(int argc, char **argv)
 {
     gArgc = argc;
     gArgv = argv;
-    
-    CustomApplicationMain (argc, argv);
-    
+
+    CustomApplicationMain();
+
     return 0;
 }
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/configure
--- a/tools/ioemu/configure     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/configure     Mon Aug 07 18:00:22 2006 -0500
@@ -96,6 +96,8 @@ softmmu="yes"
 softmmu="yes"
 user="no"
 build_docs="no"
+build_acpi_tables="no"
+uname_release=""
 
 # OS specific
 targetos=`uname -s`
@@ -212,7 +214,7 @@ for opt do
   ;;
   --fmod-inc=*) fmod_inc="$optarg"
   ;;
-  --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
+  --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" ; user="no"
   ;;
   --disable-slirp) slirp="no"
   ;;
@@ -226,8 +228,6 @@ for opt do
   ;;
   --enable-cocoa) cocoa="yes" ; coreaudio="yes" ; sdl="no"
   ;;
-  --disable-gfx-check) check_gfx="no"
-  ;;
   --disable-gcc-check) check_gcc="no"
   ;;
   --disable-system) softmmu="no"
@@ -237,6 +237,10 @@ for opt do
   --disable-user) user="no"
   ;;
   --enable-user) user="yes"
+  ;;
+  --enable-uname-release=*) uname_release="$optarg"
+  ;;
+  --enable-iasl) build_acpi_tables="yes"
   ;;
   esac
 done
@@ -285,6 +289,8 @@ echo "  --disable-user           disable
 echo "  --disable-user           disable all linux usermode emulation targets"
 echo "  --fmod-lib               path to FMOD library"
 echo "  --fmod-inc               path to FMOD includes"
+echo "  --enable-uname-release=R Return R for uname -r in usermode emulation"
+echo "  --enable-iasl            compilation of ACPI tables with the IASL 
compiler"
 echo ""
 echo "NOTE: The object files are build at the place where configure is 
launched"
 exit 1
@@ -294,15 +300,21 @@ ar="${cross_prefix}${ar}"
 ar="${cross_prefix}${ar}"
 strip="${cross_prefix}${strip}"
 
-if [ ! -x "`which $cc`" ] ; then
-    echo "Compiler $cc could not be found"
-    exit
+# check that the C compiler works.
+cat > $TMPC <<EOF
+int main(void) {}
+EOF
+
+if $cc -c -o $TMPO $TMPC 2>/dev/null ; then
+  : C compiler works ok
+else
+    echo "ERROR: \"$cc\" either does not exist or does not work"
+    exit 1
 fi
 
 if test "$mingw32" = "yes" ; then
     linux="no"
     EXESUF=".exe"
-    gdbstub="no"
     oss="no"
     if [ "$cpu" = "i386" ] ; then
         kqemu="yes"
@@ -553,6 +565,8 @@ echo "FMOD support      $fmod $fmod_supp
 echo "FMOD support      $fmod $fmod_support"
 echo "kqemu support     $kqemu"
 echo "Documentation     $build_docs"
+[ ! -z "$uname_release" ] && \
+echo "uname -r          $uname_release"
 
 if test $sdl_too_old = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -705,6 +719,9 @@ if [ "$build_docs" = "yes" ] ; then
 if [ "$build_docs" = "yes" ] ; then
   echo "BUILD_DOCS=yes" >> $config_mak
 fi
+if [ "$build_acpi_tables" = "yes" ] ; then
+  echo "BUILD_ACPI_TABLES=yes" >> $config_mak
+fi
 
 # XXX: suppress that
 if [ "$bsd" = "yes" ] ; then
@@ -712,6 +729,8 @@ if [ "$bsd" = "yes" ] ; then
   echo "#define MAP_ANONYMOUS MAP_ANON" >> $config_h
   echo "#define _BSD 1" >> $config_h
 fi
+
+echo "#define CONFIG_UNAME_RELEASE \"$uname_release\"" >> $config_h
 
 for target in $target_list; do
 target_dir="$target"
@@ -725,6 +744,7 @@ target_bigendian="no"
 [ "$target_cpu" = "ppc" ] && target_bigendian=yes
 [ "$target_cpu" = "ppc64" ] && target_bigendian=yes
 [ "$target_cpu" = "mips" ] && target_bigendian=yes
+[ "$target_cpu" = "sh4eb" ] && target_bigendian=yes
 target_softmmu="no"
 if expr $target : '.*-softmmu' > /dev/null ; then
   target_softmmu="yes"
@@ -736,14 +756,6 @@ if expr $target : '.*-user' > /dev/null 
   target_user_only="yes"
 fi
 
-if test "$target_user_only" = "no" -a "$check_gfx" = "yes" \
-        -a "$sdl" = "no" -a "$cocoa" = "no" ; then
-    echo "ERROR: QEMU requires SDL or Cocoa for graphical output"
-    echo "To build QEMU without graphical output configure with 
--disable-gfx-check"
-    echo "Note that this will disable all output from the virtual graphics 
card."
-    exit 1;
-fi
-
 #echo "Creating $config_mak, $config_h and $target_dir/Makefile"
 
 mkdir -p $target_dir
@@ -769,6 +781,7 @@ echo "include ../config-host.mak" >> $co
 echo "include ../config-host.mak" >> $config_mak
 echo "#include \"../config-host.h\"" >> $config_h
 
+bflt="no"
 interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
 echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
 
@@ -789,6 +802,7 @@ elif test "$target_cpu" = "arm" -o "$tar
   echo "TARGET_ARCH=arm" >> $config_mak
   echo "#define TARGET_ARCH \"arm\"" >> $config_h
   echo "#define TARGET_ARM 1" >> $config_h
+  bflt="yes"
 elif test "$target_cpu" = "sparc" ; then
   echo "TARGET_ARCH=sparc" >> $config_mak
   echo "#define TARGET_ARCH \"sparc\"" >> $config_h
@@ -819,10 +833,13 @@ elif test "$target_cpu" = "mips" -o "$ta
   echo "TARGET_ARCH=mips" >> $config_mak
   echo "#define TARGET_ARCH \"mips\"" >> $config_h
   echo "#define TARGET_MIPS 1" >> $config_h
-elif test "$target_cpu" = "sh4" ; then
+  echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
+  echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
+elif test "$target_cpu" = "sh4" -o "$target_cpu" = "sh4eb" ; then
   echo "TARGET_ARCH=sh4" >> $config_mak
   echo "#define TARGET_ARCH \"sh4\"" >> $config_h
   echo "#define TARGET_SH4 1" >> $config_h
+  bflt="yes"
 else
   echo "Unsupported target CPU"
   exit 1
@@ -844,9 +861,13 @@ if expr $target : '.*-dm' > /dev/null ; 
   echo "#define CONFIG_DM 1" >> $config_h
 fi
 
-if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" ; then
+if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = 
"sparc" -o "$target_cpu" = "sparc64"; then
   echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
   echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
+fi
+if test "$target_user_only" = "yes" -a "$bflt" = "yes"; then
+  echo "TARGET_HAS_BFLT=yes" >> $config_mak
+  echo "#define TARGET_HAS_BFLT 1" >> $config_h
 fi
 # sdl defines
 
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/console.c
--- a/tools/ioemu/console.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/console.c     Mon Aug 07 18:00:22 2006 -0500
@@ -27,8 +27,8 @@
 #define DEFAULT_BACKSCROLL 512
 #define MAX_CONSOLES 12
 
-#define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-#define RGB(r, g, b) RGBA(r, g, b, 0xff)
+#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
 
 typedef struct TextAttributes {
     uint8_t fgcol:4;
@@ -52,6 +52,57 @@ enum TTYState {
     TTY_STATE_ESC,
     TTY_STATE_CSI,
 };
+
+typedef struct QEMUFIFO {
+    uint8_t *buf;
+    int buf_size;
+    int count, wptr, rptr;
+} QEMUFIFO;
+
+int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
+{
+    int l, len;
+
+    l = f->buf_size - f->count;
+    if (len1 > l)
+        len1 = l;
+    len = len1;
+    while (len > 0) {
+        l = f->buf_size - f->wptr;
+        if (l > len)
+            l = len;
+        memcpy(f->buf + f->wptr, buf, l);
+        f->wptr += l;
+        if (f->wptr >= f->buf_size)
+            f->wptr = 0;
+        buf += l;
+        len -= l;
+    }
+    f->count += len1;
+    return len1;
+}
+
+int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
+{
+    int l, len;
+
+    if (len1 > f->count)
+        len1 = f->count;
+    len = len1;
+    while (len > 0) {
+        l = f->buf_size - f->rptr;
+        if (l > len)
+            l = len;
+        memcpy(buf, f->buf + f->rptr, l);
+        f->rptr += l;
+        if (f->rptr >= f->buf_size)
+            f->rptr = 0;
+        buf += l;
+        len -= l;
+    }
+    f->count -= len1;
+    return len1;
+}
 
 /* ??? This is mis-named.
    It is used for both text and graphical consoles.  */
@@ -81,8 +132,13 @@ struct TextConsole {
     int nb_esc_params;
 
     /* kbd read handler */
+    IOCanRWHandler *fd_can_read; 
     IOReadHandler *fd_read;
     void *fd_opaque;
+    /* fifo for key pressed */
+    QEMUFIFO out_fifo;
+    uint8_t out_fifo_buf[16];
+    QEMUTimer *kbd_timer;
 };
 
 static TextConsole *active_console;
@@ -274,24 +330,24 @@ enum color_names {
 
 static const uint32_t color_table_rgb[2][8] = {
     {   /* dark */
-        RGB(0x00, 0x00, 0x00),  /* black */
-        RGB(0xaa, 0x00, 0x00),  /* red */
-        RGB(0x00, 0xaa, 0x00),  /* green */
-        RGB(0xaa, 0xaa, 0x00),  /* yellow */
-        RGB(0x00, 0x00, 0xaa),  /* blue */
-        RGB(0xaa, 0x00, 0xaa),  /* magenta */
-        RGB(0x00, 0xaa, 0xaa),  /* cyan */
-        RGB(0xaa, 0xaa, 0xaa),  /* white */
+        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
+        QEMU_RGB(0xaa, 0x00, 0x00),  /* red */
+        QEMU_RGB(0x00, 0xaa, 0x00),  /* green */
+        QEMU_RGB(0xaa, 0xaa, 0x00),  /* yellow */
+        QEMU_RGB(0x00, 0x00, 0xaa),  /* blue */
+        QEMU_RGB(0xaa, 0x00, 0xaa),  /* magenta */
+        QEMU_RGB(0x00, 0xaa, 0xaa),  /* cyan */
+        QEMU_RGB(0xaa, 0xaa, 0xaa),  /* white */
     },
     {   /* bright */
-        RGB(0x00, 0x00, 0x00),  /* black */
-        RGB(0xff, 0x00, 0x00),  /* red */
-        RGB(0x00, 0xff, 0x00),  /* green */
-        RGB(0xff, 0xff, 0x00),  /* yellow */
-        RGB(0x00, 0x00, 0xff),  /* blue */
-        RGB(0xff, 0x00, 0xff),  /* magenta */
-        RGB(0x00, 0xff, 0xff),  /* cyan */
-        RGB(0xff, 0xff, 0xff),  /* white */
+        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
+        QEMU_RGB(0xff, 0x00, 0x00),  /* red */
+        QEMU_RGB(0x00, 0xff, 0x00),  /* green */
+        QEMU_RGB(0xff, 0xff, 0x00),  /* yellow */
+        QEMU_RGB(0x00, 0x00, 0xff),  /* blue */
+        QEMU_RGB(0xff, 0x00, 0xff),  /* magenta */
+        QEMU_RGB(0x00, 0xff, 0xff),  /* cyan */
+        QEMU_RGB(0xff, 0xff, 0xff),  /* white */
     }
 };
 
@@ -563,7 +619,6 @@ static void console_put_lf(TextConsole *
     TextCell *c;
     int x, y1;
 
-    s->x = 0;
     s->y++;
     if (s->y >= s->height) {
         s->y = s->height - 1;
@@ -712,15 +767,12 @@ static void console_putchar(TextConsole 
             console_put_lf(s);
             break;
         case '\b':  /* backspace */
-            if(s->x > 0) s->x--;
-            y1 = (s->y_base + s->y) % s->total_height;
-            c = &s->cells[y1 * s->width + s->x];
-            c->ch = ' ';
-            c->t_attrib = s->t_attrib;
-            update_xy(s, s->x, s->y);
+            if (s->x > 0) 
+                s->x--;
             break;
         case '\t':  /* tabspace */
             if (s->x + (8 - (s->x % 8)) > s->width) {
+                s->x = 0;
                 console_put_lf(s);
             } else {
                 s->x = s->x + (8 - (s->x % 8));
@@ -739,8 +791,10 @@ static void console_putchar(TextConsole 
             c->t_attrib = s->t_attrib;
             update_xy(s, s->x, s->y);
             s->x++;
-            if (s->x >= s->width)
+            if (s->x >= s->width) {
+                s->x = 0;
                 console_put_lf(s);
+            }
             break;
         }
         break;
@@ -835,6 +889,7 @@ static void console_chr_add_read_handler
                                          IOReadHandler *fd_read, void *opaque)
 {
     TextConsole *s = chr->opaque;
+    s->fd_can_read = fd_can_read;
     s->fd_read = fd_read;
     s->fd_opaque = opaque;
 }
@@ -854,6 +909,28 @@ static void console_send_event(CharDrive
     }
 }
 
+static void kbd_send_chars(void *opaque)
+{
+    TextConsole *s = opaque;
+    int len;
+    uint8_t buf[16];
+    
+    len = s->fd_can_read(s->fd_opaque);
+    if (len > s->out_fifo.count)
+        len = s->out_fifo.count;
+    if (len > 0) {
+        if (len > sizeof(buf))
+            len = sizeof(buf);
+        qemu_fifo_read(&s->out_fifo, buf, len);
+        s->fd_read(s->fd_opaque, buf, len);
+    }
+    /* characters are pending: we send them a bit later (XXX:
+       horrible, should change char device API) */
+    if (s->out_fifo.count > 0) {
+        qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
+    }
+}
+
 /* called when an ascii key is pressed */
 void kbd_put_keysym(int keysym)
 {
@@ -879,25 +956,26 @@ void kbd_put_keysym(int keysym)
         console_scroll(10);
         break;
     default:
+        /* convert the QEMU keysym to VT100 key string */
+        q = buf;
+        if (keysym >= 0xe100 && keysym <= 0xe11f) {
+            *q++ = '\033';
+            *q++ = '[';
+            c = keysym - 0xe100;
+            if (c >= 10)
+                *q++ = '0' + (c / 10);
+            *q++ = '0' + (c % 10);
+            *q++ = '~';
+        } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
+            *q++ = '\033';
+            *q++ = '[';
+            *q++ = keysym & 0xff;
+        } else {
+                *q++ = keysym;
+        }
         if (s->fd_read) {
-            /* convert the QEMU keysym to VT100 key string */
-            q = buf;
-            if (keysym >= 0xe100 && keysym <= 0xe11f) {
-                *q++ = '\033';
-                *q++ = '[';
-                c = keysym - 0xe100;
-                if (c >= 10)
-                    *q++ = '0' + (c / 10);
-                *q++ = '0' + (c % 10);
-                *q++ = '~';
-            } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
-                *q++ = '\033';
-                *q++ = '[';
-                *q++ = keysym & 0xff;
-            } else {
-                *q++ = keysym;
-            }
-            s->fd_read(s->fd_opaque, buf, q - buf);
+            qemu_fifo_write(&s->out_fifo, buf, q - buf);
+            kbd_send_chars(s);
         }
         break;
     }
@@ -984,6 +1062,10 @@ CharDriverState *text_console_init(Displ
     chr->chr_add_read_handler = console_chr_add_read_handler;
     chr->chr_send_event = console_send_event;
 
+    s->out_fifo.buf = s->out_fifo_buf;
+    s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
+    s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
+    
     if (!color_inited) {
         color_inited = 1;
         set_color_table(ds);
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/cpu-all.h
--- a/tools/ioemu/cpu-all.h     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/cpu-all.h     Mon Aug 07 18:00:22 2006 -0500
@@ -878,6 +878,10 @@ extern uint8_t *phys_ram_dirty;
 #define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
 #define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
 #define IO_MEM_NOTDIRTY    (4 << IO_MEM_SHIFT) /* used internally, never use 
directly */
+/* acts like a ROM when read and like a device when written. As an
+   exception, the write memory callback gets the ram offset instead of
+   the physical address */
+#define IO_MEM_ROMD        (1)
 
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, 
uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
@@ -946,13 +950,105 @@ void dump_exec_info(FILE *f,
 void dump_exec_info(FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
 
+/*******************************************/
+/* host CPU ticks (if available) */
+
+#if defined(__powerpc__)
+
+static inline uint32_t get_tbl(void) 
+{
+    uint32_t tbl;
+    asm volatile("mftb %0" : "=r" (tbl));
+    return tbl;
+}
+
+static inline uint32_t get_tbu(void) 
+{
+       uint32_t tbl;
+       asm volatile("mftbu %0" : "=r" (tbl));
+       return tbl;
+}
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    uint32_t l, h, h1;
+    /* NOTE: we test if wrapping has occurred */
+    do {
+        h = get_tbu();
+        l = get_tbl();
+        h1 = get_tbu();
+    } while (h != h1);
+    return ((int64_t)h << 32) | l;
+}
+
+#elif defined(__i386__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    int64_t val;
+    asm volatile ("rdtsc" : "=A" (val));
+    return val;
+}
+
+#elif defined(__x86_64__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    uint32_t low,high;
+    int64_t val;
+    asm volatile("rdtsc" : "=a" (low), "=d" (high));
+    val = high;
+    val <<= 32;
+    val |= low;
+    return val;
+}
+
+#elif defined(__ia64)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+       int64_t val;
+       asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
+       return val;
+}
+
+#elif defined(__s390__)
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+    int64_t val;
+    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
+    return val;
+}
+
+#elif defined(__sparc_v9__)
+
+static inline int64_t cpu_get_real_ticks (void)
+{
+#if     defined(_LP64)
+        uint64_t        rval;
+        asm volatile("rd %%tick,%0" : "=r"(rval));
+        return rval;
+#else
+        union {
+                uint64_t i64;
+                struct {
+                        uint32_t high;
+                        uint32_t low;
+                }       i32;
+        } rval;
+        asm volatile("rd %%tick,%1; srlx %1,32,%0"
+                : "=r"(rval.i32.high), "=r"(rval.i32.low));
+        return rval.i64;
+#endif
+}
+#endif
+
 /* profiling */
 #ifdef CONFIG_PROFILER
 static inline int64_t profile_getclock(void)
 {
-    int64_t val;
-    asm volatile ("rdtsc" : "=A" (val));
-    return val;
+    return cpu_get_real_ticks();
 }
 
 extern int64_t kqemu_time, kqemu_time_start;
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/cpu-defs.h
--- a/tools/ioemu/cpu-defs.h    Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/cpu-defs.h    Mon Aug 07 18:00:22 2006 -0500
@@ -47,7 +47,7 @@ typedef uint32_t target_ulong;
 #elif TARGET_LONG_SIZE == 8
 typedef int64_t target_long;
 typedef uint64_t target_ulong;
-#define TARGET_FMT_lx "%016llx"
+#define TARGET_FMT_lx "%016" PRIx64
 #else
 #error TARGET_LONG_SIZE undefined
 #endif
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/cpu-exec.c
--- a/tools/ioemu/cpu-exec.c    Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/cpu-exec.c    Mon Aug 07 18:00:22 2006 -0500
@@ -47,7 +47,7 @@ void cpu_loop_exit(void)
     longjmp(env->jmp_env, 1);
 }
 #endif
-#ifndef TARGET_SPARC
+#if !(defined(TARGET_SPARC) || defined(TARGET_SH4))
 #define reg_T2
 #endif
 
@@ -175,9 +175,13 @@ static inline TranslationBlock *tb_find_
     pc = env->regs[15];
 #elif defined(TARGET_SPARC)
 #ifdef TARGET_SPARC64
-    flags = (env->pstate << 2) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
-#else
-    flags = env->psrs | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1);
+    // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
+    flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
+        | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
+#else
+    // FPU enable . MMU enabled . MMU no-fault . Supervisor
+    flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
+        | env->psrs;
 #endif
     cs_base = env->npc;
     pc = env->pc;
@@ -253,7 +257,7 @@ int cpu_exec(CPUState *env1)
     uint32_t *saved_regwptr;
 #endif
 #endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
     int saved_i7, tmp_T0;
 #endif
     int ret, interrupt_request;
@@ -323,7 +327,7 @@ int cpu_exec(CPUState *env1)
 #if defined(reg_T2)
     saved_T2 = T2;
 #endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
     /* we also save i7 because longjmp may not restore it */
     asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
 #endif
@@ -447,7 +451,7 @@ int cpu_exec(CPUState *env1)
 
             T0 = 0; /* force lookup of first TB */
             for(;;) {
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                 /* g1 can be modified by some libc? functions */ 
                 tmp_T0 = T0;
 #endif     
@@ -467,7 +471,7 @@ int cpu_exec(CPUState *env1)
                         do_interrupt(intno, 0, 0, 0, 1);
                         /* ensure that no TB jump will be modified as
                            the program flow was changed */
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                         tmp_T0 = 0;
 #else
                         T0 = 0;
@@ -486,7 +490,7 @@ int cpu_exec(CPUState *env1)
                            env->error_code = 0;
                             do_interrupt(env);
                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                             tmp_T0 = 0;
 #else
                             T0 = 0;
@@ -497,7 +501,7 @@ int cpu_exec(CPUState *env1)
                             env->error_code = 0;
                             do_interrupt(env);
                             env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                             tmp_T0 = 0;
 #else
                             T0 = 0;
@@ -516,7 +520,7 @@ int cpu_exec(CPUState *env1)
                         env->error_code = 0;
                         do_interrupt(env);
                         env->interrupt_request &= ~CPU_INTERRUPT_HARD;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                         tmp_T0 = 0;
 #else
                         T0 = 0;
@@ -534,7 +538,7 @@ int cpu_exec(CPUState *env1)
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
                            do_interrupt(env->interrupt_index);
                            env->interrupt_index = 0;
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                             tmp_T0 = 0;
 #else
                             T0 = 0;
@@ -561,11 +565,13 @@ int cpu_exec(CPUState *env1)
 #elif defined(TARGET_SH4)
                    /* XXXXX */
 #endif
+                   /* Don't use the cached interupt_request value,
+                      do_interrupt may have updated the EXITTB flag. */
                     if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
                         env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
                         /* ensure that no TB jump will be modified as
                            the program flow was changed */
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                         tmp_T0 = 0;
 #else
                         T0 = 0;
@@ -633,7 +639,7 @@ int cpu_exec(CPUState *env1)
                             lookup_symbol(tb->pc));
                 }
 #endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
                 T0 = tmp_T0;
 #endif     
                 /* see if we can patch the calling TB. When the TB
@@ -669,7 +675,9 @@ int cpu_exec(CPUState *env1)
                                      "mov      %%o7,%%i0"
                                      : /* no outputs */
                                      : "r" (gen_func) 
-                                     : "i0", "i1", "i2", "i3", "i4", "i5");
+                                     : "i0", "i1", "i2", "i3", "i4", "i5",
+                                       "l0", "l1", "l2", "l3", "l4", "l5",
+                                       "l6", "l7");
 #elif defined(__arm__)
                 asm volatile ("mov pc, %0\n\t"
                               ".global exec_loop\n\t"
@@ -834,7 +842,7 @@ int cpu_exec(CPUState *env1)
 #else
 #error unsupported target CPU
 #endif
-#ifdef __sparc__
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
     asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
 #endif
     T0 = saved_T0;
@@ -1168,19 +1176,14 @@ static inline int handle_cpu_signal(unsi
            a virtual CPU fault */
         cpu_restore_state(tb, env, pc, puc);
     }
-    if (ret == 1) {
 #if 0
         printf("PF exception: NIP=0x%08x error=0x%x %p\n", 
                env->nip, env->error_code, tb);
 #endif
     /* we restore the process signal mask as the sigreturn should
        do it (XXX: use sigsetjmp) */
-        sigprocmask(SIG_SETMASK, old_set, NULL);
-        //        do_raise_exception_err(env->exception_index, 
env->error_code);
-    } else {
-        /* activate soft MMU for this block */
-        cpu_resume_from_signal(env, puc);
-    }
+    sigprocmask(SIG_SETMASK, old_set, NULL);
+    cpu_loop_exit();
     /* never comes here */
     return 1;
 }
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/disas.c
--- a/tools/ioemu/disas.c       Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/disas.c       Mon Aug 07 18:00:22 2006 -0500
@@ -58,7 +58,7 @@ perror_memory (status, memaddr, info)
     /* Actually, address between memaddr and memaddr + len was
        out of bounds.  */
     (*info->fprintf_func) (info->stream,
-                          "Address 0x%llx is out of bounds.\n", memaddr);
+                          "Address 0x%" PRIx64 " is out of bounds.\n", 
memaddr);
 }
 
 /* This could be in a separate file, to save miniscule amounts of space
@@ -73,7 +73,7 @@ generic_print_address (addr, info)
      bfd_vma addr;
      struct disassemble_info *info;
 {
-    (*info->fprintf_func) (info->stream, "0x%llx", addr);
+    (*info->fprintf_func) (info->stream, "0x%" PRIx64, addr);
 }
 
 /* Just return the given address.  */
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/dyngen-exec.h
--- a/tools/ioemu/dyngen-exec.h Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/dyngen-exec.h Mon Aug 07 18:00:22 2006 -0500
@@ -35,11 +35,14 @@ typedef unsigned char uint8_t;
 typedef unsigned char uint8_t;
 typedef unsigned short uint16_t;
 typedef unsigned int uint32_t;
+// Linux/Sparc64 defines uint64_t
+#if !(defined (__sparc_v9__) && defined(__linux__))
 /* XXX may be done for all 64 bits targets ? */
 #if defined (__x86_64__) || defined(__ia64)
 typedef unsigned long uint64_t;
 #else
 typedef unsigned long long uint64_t;
+#endif
 #endif
 
 /* if Solaris/__sun__, don't typedef int8_t, as it will be typedef'd
@@ -50,10 +53,13 @@ typedef signed char int8_t;
 #endif
 typedef signed short int16_t;
 typedef signed int int32_t;
+// Linux/Sparc64 defines int64_t
+#if !(defined (__sparc_v9__) && defined(__linux__))
 #if defined (__x86_64__) || defined(__ia64)
 typedef signed long int64_t;
 #else
 typedef signed long long int64_t;
+#endif
 #endif
 
 #define INT8_MIN               (-128)
@@ -121,6 +127,19 @@ extern int printf(const char *, ...);
 #define AREG3 "s2"
 #endif
 #ifdef __sparc__
+#ifdef HOST_SOLARIS
+#define AREG0 "g2"
+#define AREG1 "g3"
+#define AREG2 "g4"
+#define AREG3 "g5"
+#define AREG4 "g6"
+#else
+#ifdef __sparc_v9__
+#define AREG0 "g1"
+#define AREG1 "g4"
+#define AREG2 "g5"
+#define AREG3 "g7"
+#else
 #define AREG0 "g6"
 #define AREG1 "g1"
 #define AREG2 "g2"
@@ -133,6 +152,8 @@ extern int printf(const char *, ...);
 #define AREG9 "l5"
 #define AREG10 "l6"
 #define AREG11 "l7"
+#endif
+#endif
 #define USE_FP_CONVERT
 #endif
 #ifdef __s390__
@@ -241,10 +262,8 @@ extern int __op_jmp0, __op_jmp1, __op_jm
                                          ASM_NAME(__op_gen_label) #n)
 #endif
 #ifdef __sparc__
-#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0\n" \
-                                "nop")
-#define        GOTO_LABEL_PARAM(n) asm volatile ( \
-               "set " ASM_NAME(__op_gen_label) #n ", %g1; jmp %g1; nop")
+#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
+#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n 
";nop")
 #endif
 #ifdef __arm__
 #define EXIT_TB() asm volatile ("b exec_loop")
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/dyngen.c
--- a/tools/ioemu/dyngen.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/dyngen.c      Mon Aug 07 18:00:22 2006 -0500
@@ -1196,7 +1196,7 @@ void get_reloc_expr(char *name, int name
     } else {
 #ifdef HOST_SPARC
         if (sym_name[0] == '.')
-            snprintf(name, sizeof(name),
+            snprintf(name, name_size,
                      "(long)(&__dot_%s)",
                      sym_name + 1);
         else
@@ -1440,6 +1440,15 @@ void gen_code(const char *name, host_ulo
     }
 #elif defined(HOST_SPARC)
     {
+#define INSN_SAVE       0x9de3a000
+#define INSN_RET        0x81c7e008
+#define INSN_RETL       0x81c3e008
+#define INSN_RESTORE    0x81e80000
+#define INSN_RETURN     0x81cfe008
+#define INSN_NOP        0x01000000
+#define INSN_ADD_SP     0x9c03a000 // add %sp, nn, %sp
+#define INSN_SUB_SP     0x9c23a000 // sub %sp, nn, %sp
+
         uint32_t start_insn, end_insn1, end_insn2;
         uint8_t *p;
         p = (void *)(p_end - 8);
@@ -1448,13 +1457,21 @@ void gen_code(const char *name, host_ulo
         start_insn = get32((uint32_t *)(p_start + 0x0));
         end_insn1 = get32((uint32_t *)(p + 0x0));
         end_insn2 = get32((uint32_t *)(p + 0x4));
-        if ((start_insn & ~0x1fff) == 0x9de3a000) {
+        if (((start_insn & ~0x1fff) == INSN_SAVE) ||
+            (start_insn & ~0x1fff) == INSN_ADD_SP) {
             p_start += 0x4;
             start_offset += 0x4;
-            if ((int)(start_insn | ~0x1fff) < -128)
-                error("Found bogus save at the start of %s", name);
-            if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
+            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
+                /* SPARC v7: ret; restore; */ ;
+            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
+                /* SPARC v9: return; nop; */ ;
+            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == 
INSN_SUB_SP)
+                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
+            else
+
                 error("ret; restore; not found at end of %s", name);
+        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
+            ;
         } else {
             error("No save at the beginning of %s", name);
         }
@@ -1462,7 +1479,7 @@ void gen_code(const char *name, host_ulo
         /* Skip a preceeding nop, if present.  */
         if (p > p_start) {
             skip_insn = get32((uint32_t *)(p - 0x4));
-            if (skip_insn == 0x01000000)
+            if (skip_insn == INSN_NOP)
                 p -= 4;
         }
 #endif
@@ -1470,21 +1487,41 @@ void gen_code(const char *name, host_ulo
     }
 #elif defined(HOST_SPARC64)
     {
+#define INSN_SAVE       0x9de3a000
+#define INSN_RET        0x81c7e008
+#define INSN_RETL       0x81c3e008
+#define INSN_RESTORE    0x81e80000
+#define INSN_RETURN     0x81cfe008
+#define INSN_NOP        0x01000000
+#define INSN_ADD_SP     0x9c03a000 // add %sp, nn, %sp
+#define INSN_SUB_SP     0x9c23a000 // sub %sp, nn, %sp
+
         uint32_t start_insn, end_insn1, end_insn2, skip_insn;
         uint8_t *p;
         p = (void *)(p_end - 8);
+#if 0
+        /* XXX: check why it occurs */
         if (p <= p_start)
             error("empty code for %s", name);
+#endif
         start_insn = get32((uint32_t *)(p_start + 0x0));
         end_insn1 = get32((uint32_t *)(p + 0x0));
         end_insn2 = get32((uint32_t *)(p + 0x4));
-        if ((start_insn & ~0x1fff) == 0x9de3a000) {
+        if (((start_insn & ~0x1fff) == INSN_SAVE) ||
+            (start_insn & ~0x1fff) == INSN_ADD_SP) {
             p_start += 0x4;
             start_offset += 0x4;
-            if ((int)(start_insn | ~0x1fff) < -256)
-                error("Found bogus save at the start of %s", name);
-            if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
+            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
+                /* SPARC v7: ret; restore; */ ;
+            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
+                /* SPARC v9: return; nop; */ ;
+            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == 
INSN_SUB_SP)
+                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;
+            else
+
                 error("ret; restore; not found at end of %s", name);
+        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {
+            ;
         } else {
             error("No save at the beginning of %s", name);
         }
@@ -2151,6 +2188,18 @@ void gen_code(const char *name, host_ulo
                                    reloc_offset, reloc_offset, name, addend,
                                    reloc_offset);
                            break;
+                        case R_SPARC_WDISP22:
+                            fprintf(outfile,
+                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
+                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
+                                    " & ~0x3fffff) "
+                                    " | ((((%s + %d) - (long)(gen_code_ptr + 
%d))>>2) "
+                                    "    & 0x3fffff);\n",
+                                    rel->r_offset - start_offset,
+                                    rel->r_offset - start_offset,
+                                    name, addend,
+                                    rel->r_offset - start_offset);
+                            break;
                         default:
                             error("unsupported sparc relocation (%d)", type);
                         }
@@ -2168,7 +2217,7 @@ void gen_code(const char *name, host_ulo
                        rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + 
symtab[ELF64_R_SYM(rel->r_info)].st_name;
                         get_reloc_expr(name, sizeof(name), sym_name);
-                        type = ELF64_R_TYPE(rel->r_info);
+                        type = ELF32_R_TYPE(rel->r_info);
                         addend = rel->r_addend;
                         reloc_offset = rel->r_offset - start_offset;
                         switch(type) {
@@ -2192,6 +2241,15 @@ void gen_code(const char *name, host_ulo
                                    " | ((%s + %d) & 0x3ff);\n",
                                     reloc_offset, reloc_offset, name, addend);
                            break;
+                        case R_SPARC_OLO10:
+                            addend += ELF64_R_TYPE_DATA (rel->r_info);
+                            fprintf(outfile,
+                                   "    *(uint32_t *)(gen_code_ptr + %d) = "
+                                   "((*(uint32_t *)(gen_code_ptr + %d)) "
+                                   " & ~0x3ff) "
+                                   " | ((%s + %d) & 0x3ff);\n",
+                                    reloc_offset, reloc_offset, name, addend);
+                           break;
                        case R_SPARC_WDISP30:
                            fprintf(outfile,
                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
@@ -2202,8 +2260,18 @@ void gen_code(const char *name, host_ulo
                                    reloc_offset, reloc_offset, name, addend,
                                    reloc_offset);
                            break;
+                        case R_SPARC_WDISP22:
+                            fprintf(outfile,
+                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
+                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
+                                    " & ~0x3fffff) "
+                                    " | ((((%s + %d) - (long)(gen_code_ptr + 
%d))>>2) "
+                                    "    & 0x3fffff);\n",
+                                    reloc_offset, reloc_offset, name, addend,
+                                   reloc_offset);
+                            break;
                         default:
-                           error("unsupported sparc64 relocation (%d)", type);
+                           error("unsupported sparc64 relocation (%d) for 
symbol %s", type, name);
                         }
                     }
                 }
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/dyngen.h
--- a/tools/ioemu/dyngen.h      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/dyngen.h      Mon Aug 07 18:00:22 2006 -0500
@@ -19,7 +19,13 @@
  */
 
 int __op_param1, __op_param2, __op_param3;
-int __op_gen_label1, __op_gen_label2, __op_gen_label3;
+#ifdef __sparc__
+  void __op_gen_label1(){}
+  void __op_gen_label2(){}
+  void __op_gen_label3(){}
+#else
+  int __op_gen_label1, __op_gen_label2, __op_gen_label3;
+#endif
 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
 
 #ifdef __i386__
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/elf.h
--- a/tools/ioemu/elf.h Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/elf.h Mon Aug 07 18:00:22 2006 -0500
@@ -227,6 +227,7 @@ typedef struct {
 
 #define ELF64_R_SYM(i)                 ((i) >> 32)
 #define ELF64_R_TYPE(i)                        ((i) & 0xffffffff)
+#define ELF64_R_TYPE_DATA(i)            (((ELF64_R_TYPE(i) >> 8) ^ 0x00800000) 
- 0x00800000)
 
 #define R_386_NONE     0
 #define R_386_32       1
@@ -326,6 +327,7 @@ typedef struct {
 #define R_SPARC_10             30
 #define R_SPARC_11             31
 #define R_SPARC_64             32
+#define R_SPARC_OLO10           33
 #define R_SPARC_WDISP16                40
 #define R_SPARC_WDISP19                41
 #define R_SPARC_7              43
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/exec-all.h
--- a/tools/ioemu/exec-all.h    Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/exec-all.h    Mon Aug 07 18:00:22 2006 -0500
@@ -571,7 +571,7 @@ static inline target_ulong get_phys_addr
         ldub_code(addr);
     }
     pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
-    if (pd > IO_MEM_ROM) {
+    if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
         cpu_abort(env, "Trying to execute code outside RAM or ROM at 
0x%08lx\n", addr);
     }
     return addr + env->tlb_table[is_user][index].addend - (unsigned 
long)phys_ram_base;
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/exec.c
--- a/tools/ioemu/exec.c        Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/exec.c        Mon Aug 07 18:00:22 2006 -0500
@@ -1488,7 +1488,7 @@ int tlb_set_page_exec(CPUState *env, tar
     if (is_softmmu) 
 #endif
     {
-        if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
+        if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
             /* IO memory case */
             address = vaddr | pd;
             addend = paddr;
@@ -1513,9 +1513,11 @@ int tlb_set_page_exec(CPUState *env, tar
             te->addr_code = -1;
         }
         if (prot & PAGE_WRITE) {
-            if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
-                /* ROM: access is ignored (same as unassigned) */
-                te->addr_write = vaddr | IO_MEM_ROM;
+            if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
+                (pd & IO_MEM_ROMD)) {
+                /* write access calls the I/O callback */
+                te->addr_write = vaddr | 
+                    (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
             } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
                        !cpu_physical_memory_is_dirty(pd)) {
                 te->addr_write = vaddr | IO_MEM_NOTDIRTY;
@@ -1779,14 +1781,23 @@ void cpu_register_physical_memory(target
 {
     target_phys_addr_t addr, end_addr;
     PhysPageDesc *p;
+    CPUState *env;
 
     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
     end_addr = start_addr + size;
     for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
         p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
         p->phys_offset = phys_offset;
-        if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM)
+        if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
+            (phys_offset & IO_MEM_ROMD))
             phys_offset += TARGET_PAGE_SIZE;
+    }
+    
+    /* since each CPU stores ram addresses in its TLB cache, we must
+       reset the modified entries */
+    /* XXX: slow ! */
+    for(env = first_cpu; env != NULL; env = env->next_cpu) {
+        tlb_flush(env, 1);
     }
 }
 
@@ -2048,7 +2059,8 @@ void cpu_physical_memory_rw(target_phys_
                 }
             }
         } else {
-            if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
+            if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
+                !(pd & IO_MEM_ROMD)) {
                 /* I/O case */
                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
                 if (l >= 4 && ((addr & 3) == 0)) {
@@ -2103,7 +2115,8 @@ void cpu_physical_memory_write_rom(targe
         }
         
         if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
-            (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM) {
+            (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
+            !(pd & IO_MEM_ROMD)) {
             /* do nothing */
         } else {
             unsigned long addr1;
@@ -2135,7 +2148,8 @@ uint32_t ldl_phys(target_phys_addr_t add
         pd = p->phys_offset;
     }
         
-    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
+    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
+        !(pd & IO_MEM_ROMD)) {
         /* I/O case */
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
         val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
@@ -2164,7 +2178,8 @@ uint64_t ldq_phys(target_phys_addr_t add
         pd = p->phys_offset;
     }
         
-    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
+    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
+        !(pd & IO_MEM_ROMD)) {
         /* I/O case */
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 #ifdef TARGET_WORDS_BIGENDIAN
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/fpu/softfloat-native.c
--- a/tools/ioemu/fpu/softfloat-native.c        Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/fpu/softfloat-native.c        Mon Aug 07 18:00:22 2006 -0500
@@ -6,7 +6,7 @@ void set_float_rounding_mode(int val STA
 void set_float_rounding_mode(int val STATUS_PARAM)
 {
     STATUS(float_rounding_mode) = val;
-#if defined(_BSD) && !defined(__APPLE__)
+#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && 
HOST_SOLARIS < 10)
     fpsetround(val);
 #elif defined(__arm__)
     /* nothing to do */
@@ -22,9 +22,14 @@ void set_floatx80_rounding_precision(int
 }
 #endif
 
-#if defined(_BSD)
-#define lrint(d)               ((long)rint(d))
-#define llrint(d)              ((long long)rint(d))
+#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
+#define lrint(d)               ((int32_t)rint(d))
+#define llrint(d)              ((int64_t)rint(d))
+#define lrintf(f)              ((int32_t)rint(f))
+#define llrintf(f)             ((int64_t)rint(f))
+#define sqrtf(f)               ((float)sqrt(f))
+#define remainderf(fa, fb)     ((float)remainder(fa, fb))
+#define rintf(f)               ((float)rint(f))
 #endif
 
 #if defined(__powerpc__)
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/gdbstub.c
--- a/tools/ioemu/gdbstub.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/gdbstub.c     Mon Aug 07 18:00:22 2006 -0500
@@ -17,6 +17,7 @@
  * 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 "config.h"
 #ifdef CONFIG_USER_ONLY
 #include <stdlib.h>
 #include <stdio.h>
@@ -24,16 +25,25 @@
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include "qemu.h"
 #else
 #include "vl.h"
 #endif
 
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
+#include "qemu_socket.h"
+#ifdef _WIN32
+/* XXX: these constants may be independent of the host ones even for Unix */
+#ifndef SIGTRAP
+#define SIGTRAP 5
+#endif
+#ifndef SIGINT
+#define SIGINT 2
+#endif
+#else
 #include <signal.h>
+#endif
 
 //#define DEBUG_GDB
 
@@ -69,7 +79,7 @@ static int get_char(GDBState *s)
     int ret;
 
     for(;;) {
-        ret = read(s->fd, &ch, 1);
+        ret = recv(s->fd, &ch, 1, 0);
         if (ret < 0) {
             if (errno != EINTR && errno != EAGAIN)
                 return -1;
@@ -87,7 +97,7 @@ static void put_buffer(GDBState *s, cons
     int ret;
 
     while (len > 0) {
-        ret = write(s->fd, buf, len);
+        ret = send(s->fd, buf, len, 0);
         if (ret < 0) {
             if (errno != EINTR && errno != EAGAIN)
                 return;
@@ -305,11 +315,11 @@ static int cpu_gdb_read_registers(CPUSta
     for(i = 0; i < 24; i++) {
         registers[i + 8] = tswapl(env->regwptr[i]);
     }
+#ifndef TARGET_SPARC64
     /* fill in fprs */
     for (i = 0; i < 32; i++) {
         registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
     }
-#ifndef TARGET_SPARC64
     /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
     registers[64] = tswapl(env->y);
     {
@@ -327,16 +337,21 @@ static int cpu_gdb_read_registers(CPUSta
     registers[72] = 0;
     return 73 * sizeof(target_ulong);
 #else
-    for (i = 0; i < 32; i += 2) {
-        registers[i/2 + 64] = tswapl(*((uint64_t *)&env->fpr[i]));
-    }
-    registers[81] = tswapl(env->pc);
-    registers[82] = tswapl(env->npc);
-    registers[83] = tswapl(env->tstate[env->tl]);
-    registers[84] = tswapl(env->fsr);
-    registers[85] = tswapl(env->fprs);
-    registers[86] = tswapl(env->y);
-    return 87 * sizeof(target_ulong);
+    /* fill in fprs */
+    for (i = 0; i < 64; i += 2) {
+       uint64_t tmp;
+
+        tmp = (uint64_t)tswap32(*((uint32_t *)&env->fpr[i])) << 32;
+        tmp |= tswap32(*((uint32_t *)&env->fpr[i + 1]));
+        registers[i/2 + 32] = tmp;
+    }
+    registers[64] = tswapl(env->pc);
+    registers[65] = tswapl(env->npc);
+    registers[66] = tswapl(env->tstate[env->tl]);
+    registers[67] = tswapl(env->fsr);
+    registers[68] = tswapl(env->fprs);
+    registers[69] = tswapl(env->y);
+    return 70 * sizeof(target_ulong);
 #endif
 }
 
@@ -353,11 +368,11 @@ static void cpu_gdb_write_registers(CPUS
     for(i = 0; i < 24; i++) {
         env->regwptr[i] = tswapl(registers[i + 8]);
     }
+#ifndef TARGET_SPARC64
     /* fill in fprs */
     for (i = 0; i < 32; i++) {
         *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
     }
-#ifndef TARGET_SPARC64
     /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
     env->y = tswapl(registers[64]);
     PUT_PSR(env, tswapl(registers[65]));
@@ -367,18 +382,16 @@ static void cpu_gdb_write_registers(CPUS
     env->npc = tswapl(registers[69]);
     env->fsr = tswapl(registers[70]);
 #else
-    for (i = 0; i < 32; i += 2) {
-       uint64_t tmp;
-       tmp = tswapl(registers[i/2 + 64]) << 32;
-       tmp |= tswapl(registers[i/2 + 64 + 1]);
-        *((uint64_t *)&env->fpr[i]) = tmp;
-    }
-    env->pc = tswapl(registers[81]);
-    env->npc = tswapl(registers[82]);
-    env->tstate[env->tl] = tswapl(registers[83]);
-    env->fsr = tswapl(registers[84]);
-    env->fprs = tswapl(registers[85]);
-    env->y = tswapl(registers[86]);
+    for (i = 0; i < 64; i += 2) {
+       *((uint32_t *)&env->fpr[i]) = tswap32(registers[i/2 + 32] >> 32);
+       *((uint32_t *)&env->fpr[i + 1]) = tswap32(registers[i/2 + 32] & 
0xffffffff);
+    }
+    env->pc = tswapl(registers[64]);
+    env->npc = tswapl(registers[65]);
+    env->tstate[env->tl] = tswapl(registers[66]);
+    env->fsr = tswapl(registers[67]);
+    env->fprs = tswapl(registers[68]);
+    env->y = tswapl(registers[69]);
 #endif
 }
 #elif defined (TARGET_ARM)
@@ -494,7 +507,12 @@ static int cpu_gdb_read_registers(CPUSta
   int i;
 
 #define SAVE(x) *ptr++=tswapl(x)
-  for (i = 0; i < 16; i++) SAVE(env->gregs[i]);
+  if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+      for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
+  } else {
+      for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
+  }
+  for (i = 8; i < 16; i++) SAVE(env->gregs[i]);
   SAVE (env->pc);
   SAVE (env->pr);
   SAVE (env->gbr);
@@ -517,7 +535,12 @@ static void cpu_gdb_write_registers(CPUS
   int i;
 
 #define LOAD(x) (x)=*ptr++;
-  for (i = 0; i < 16; i++) LOAD(env->gregs[i]);
+  if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+      for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
+  } else {
+      for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
+  }
+  for (i = 8; i < 16; i++) LOAD(env->gregs[i]);
   LOAD (env->pc);
   LOAD (env->pr);
   LOAD (env->gbr);
@@ -545,7 +568,7 @@ static int gdb_handle_packet(GDBState *s
     char buf[4096];
     uint8_t mem_buf[2000];
     uint32_t *registers;
-    uint32_t addr, len;
+    target_ulong addr, len;
     
 #ifdef DEBUG_GDB
     printf("command='%s'\n", line_buf);
@@ -560,7 +583,7 @@ static int gdb_handle_packet(GDBState *s
         break;
     case 'c':
         if (*p != '\0') {
-            addr = strtoul(p, (char **)&p, 16);
+            addr = strtoull(p, (char **)&p, 16);
 #if defined(TARGET_I386)
             env->eip = addr;
 #elif defined (TARGET_PPC)
@@ -616,10 +639,10 @@ static int gdb_handle_packet(GDBState *s
         put_packet(s, "OK");
         break;
     case 'm':
-        addr = strtoul(p, (char **)&p, 16);
+        addr = strtoull(p, (char **)&p, 16);
         if (*p == ',')
             p++;
-        len = strtoul(p, NULL, 16);
+        len = strtoull(p, NULL, 16);
         if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {
             put_packet (s, "E14");
         } else {
@@ -628,10 +651,10 @@ static int gdb_handle_packet(GDBState *s
         }
         break;
     case 'M':
-        addr = strtoul(p, (char **)&p, 16);
+        addr = strtoull(p, (char **)&p, 16);
         if (*p == ',')
             p++;
-        len = strtoul(p, (char **)&p, 16);
+        len = strtoull(p, (char **)&p, 16);
         if (*p == ':')
             p++;
         hextomem(mem_buf, p, len);
@@ -644,10 +667,10 @@ static int gdb_handle_packet(GDBState *s
         type = strtoul(p, (char **)&p, 16);
         if (*p == ',')
             p++;
-        addr = strtoul(p, (char **)&p, 16);
+        addr = strtoull(p, (char **)&p, 16);
         if (*p == ',')
             p++;
-        len = strtoul(p, (char **)&p, 16);
+        len = strtoull(p, (char **)&p, 16);
         if (type == 0 || type == 1) {
             if (cpu_breakpoint_insert(env, addr) < 0)
                 goto breakpoint_error;
@@ -661,10 +684,10 @@ static int gdb_handle_packet(GDBState *s
         type = strtoul(p, (char **)&p, 16);
         if (*p == ',')
             p++;
-        addr = strtoul(p, (char **)&p, 16);
+        addr = strtoull(p, (char **)&p, 16);
         if (*p == ',')
             p++;
-        len = strtoul(p, (char **)&p, 16);
+        len = strtoull(p, (char **)&p, 16);
         if (type == 0 || type == 1) {
             cpu_breakpoint_remove(env, addr);
             put_packet(s, "OK");
@@ -672,6 +695,18 @@ static int gdb_handle_packet(GDBState *s
             goto breakpoint_error;
         }
         break;
+#ifdef CONFIG_USER_ONLY
+    case 'q':
+        if (strncmp(p, "Offsets", 7) == 0) {
+            TaskState *ts = env->opaque;
+
+            sprintf(buf, "Text=%x;Data=%x;Bss=%x", ts->info->code_offset,
+                ts->info->data_offset, ts->info->data_offset);
+            put_packet(s, buf);
+            break;
+        }
+        /* Fall through.  */
+#endif
     default:
         //        unknown_command:
         /* put empty packet */
@@ -829,7 +864,7 @@ static void gdb_read(void *opaque)
     int i, size;
     uint8_t buf[4096];
 
-    size = read(s->fd, buf, sizeof(buf));
+    size = recv(s->fd, buf, sizeof(buf), 0);
     if (size < 0)
         return;
     if (size == 0) {
@@ -866,7 +901,7 @@ static void gdb_accept(void *opaque)
 
     /* set short latency */
     val = 1;
-    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
     
 #ifdef CONFIG_USER_ONLY
     s = &gdbserver_state;
@@ -881,9 +916,11 @@ static void gdb_accept(void *opaque)
     s->env = first_cpu; /* XXX: allow to change CPU */
     s->fd = fd;
 
+#ifdef CONFIG_USER_ONLY
     fcntl(fd, F_SETFL, O_NONBLOCK);
-
-#ifndef CONFIG_USER_ONLY
+#else
+    socket_set_nonblock(fd);
+
     /* stop the VM */
     vm_stop(EXCP_INTERRUPT);
 
@@ -907,7 +944,7 @@ static int gdbserver_open(int port)
 
     /* allow fast reuse */
     val = 1;
-    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
 
     sockaddr.sin_family = AF_INET;
     sockaddr.sin_port = htons(port);
@@ -923,7 +960,7 @@ static int gdbserver_open(int port)
         return -1;
     }
 #ifndef CONFIG_USER_ONLY
-    fcntl(fd, F_SETFL, O_NONBLOCK);
+    socket_set_nonblock(fd);
 #endif
     return fd;
 }
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/hw/adlib.c
--- a/tools/ioemu/hw/adlib.c    Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/hw/adlib.c    Mon Aug 07 18:00:22 2006 -0500
@@ -301,6 +301,7 @@ int Adlib_init (AudioState *audio)
     as.freq = conf.freq;
     as.nchannels = SHIFT;
     as.fmt = AUD_FMT_S16;
+    as.endianness = AUDIO_HOST_ENDIANNESS;
 
     AUD_register_card (audio, "adlib", &s->card);
 
@@ -310,8 +311,7 @@ int Adlib_init (AudioState *audio)
         "adlib",
         s,
         adlib_callback,
-        &as,
-        0                       /* XXX: little endian? */
+        &as
         );
     if (!s->voice) {
         Adlib_fini (s);
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/hw/apic.c
--- a/tools/ioemu/hw/apic.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/hw/apic.c     Mon Aug 07 18:00:22 2006 -0500
@@ -239,7 +239,7 @@ void cpu_set_apic_base(CPUState *env, ui
 {
     APICState *s = env->apic_state;
 #ifdef DEBUG_APIC
-    printf("cpu_set_apic_base: %016llx\n", val);
+    printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
 #endif
     s->apicbase = (val & 0xfffff000) | 
         (s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
@@ -255,7 +255,7 @@ uint64_t cpu_get_apic_base(CPUState *env
 {
     APICState *s = env->apic_state;
 #ifdef DEBUG_APIC
-    printf("cpu_get_apic_base: %016llx\n", (uint64_t)s->apicbase);
+    printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
 #endif
     return s->apicbase;
 }
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/hw/cuda.c
--- a/tools/ioemu/hw/cuda.c     Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/hw/cuda.c     Mon Aug 07 18:00:22 2006 -0500
@@ -209,7 +209,7 @@ static int64_t get_next_irq_time(CUDATim
     }
 #if 0
 #ifdef DEBUG_CUDA
-    printf("latch=%d counter=%lld delta_next=%lld\n", 
+    printf("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n", 
            s->latch, d, next_time - d);
 #endif
 #endif
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/hw/es1370.c
--- a/tools/ioemu/hw/es1370.c   Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/hw/es1370.c   Mon Aug 07 18:00:22 2006 -0500
@@ -423,6 +423,7 @@ static void es1370_update_voices (ES1370
                 as.freq = new_freq;
                 as.nchannels = 1 << (new_fmt & 1);
                 as.fmt = (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8;
+                as.endianness = 0;
 
                 if (i == ADC_CHANNEL) {
                     s->adc_voice =
@@ -432,8 +433,7 @@ static void es1370_update_voices (ES1370
                             "es1370.adc",
                             s,
                             es1370_adc_callback,
-                            &as,
-                            0   /* little endian */
+                            &as
                             );
                 }
                 else {
@@ -444,8 +444,7 @@ static void es1370_update_voices (ES1370
                             i ? "es1370.dac2" : "es1370.dac1",
                             s,
                             i ? es1370_dac2_callback : es1370_dac1_callback,
-                            &as,
-                            0   /* litle endian */
+                            &as
                             );
                 }
             }
@@ -479,8 +478,9 @@ IO_WRITE_PROTO (es1370_writeb)
 IO_WRITE_PROTO (es1370_writeb)
 {
     ES1370State *s = opaque;
+    uint32_t shift, mask;
+
     addr = es1370_fixup (s, addr);
-    uint32_t shift, mask;
 
     switch (addr) {
     case ES1370_REG_CONTROL:
diff -r 61204c1d740e -r 87cefa5f7c5e tools/ioemu/hw/esp.c
--- a/tools/ioemu/hw/esp.c      Thu Jul 27 20:07:02 2006 -0400
+++ b/tools/ioemu/hw/esp.c      Mon Aug 07 18:00:22 2006 -0500
@@ -38,16 +38,13 @@ do { printf("ESP: set_irq(%d): %d\n", (i
 #define ESPDMA_REGS 4
 #define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1)
 #define ESP_MAXREG 0x3f
-#define TI_BUFSZ 1024*1024 // XXX
+#define TI_BUFSZ 32
 #define DMA_VER 0xa0000000
 #define DMA_INTR 1
 #define DMA_INTREN 0x10
+#define DMA_WRITE_MEM 0x100
 #define DMA_LOADED 0x04000000
 typedef struct ESPState ESPState;
-
-typedef int ESPDMAFunc(ESPState *s, 
-                       target_phys_addr_t phys_addr, 
-                       int transfer_size1);
 
 struct ESPState {
     BlockDriverState **bd;
@@ -57,12 +54,14 @@ struct ESPState {
     uint32_t espdmaregs[ESPDMA_REGS];
     uint32_t ti_size;
     uint32_t ti_rptr, ti_wptr;
-    int ti_dir;
     uint8_t ti_buf[TI_BUFSZ];
+    int sense;
     int dma;
-    ESPDMAFunc *dma_cb;
-    int64_t offset, len;
-    int target;
+    SCSIDevice *scsi_dev[MAX_DISKS];
+    SCSIDevice *current_dev;
+    uint8_t cmdbuf[TI_BUFSZ];
+    int cmdlen;
+    int do_cmd;
 };
 
 #define STAT_DO 0x00
@@ -83,394 +82,200 @@ struct ESPState {
 #define SEQ_0 0x0
 #define SEQ_CD 0x4
 
-/* XXX: stolen from ide.c, move to common ATAPI/SCSI library */
-static void lba_to_msf(uint8_t *buf, int lba)
-{
-    lba += 150;
-    buf[0] = (lba / 75) / 60;
-    buf[1] = (lba / 75) % 60;
-    buf[2] = lba % 75;
-}
-
-static inline void cpu_to_ube16(uint8_t *buf, int val)
-{
-    buf[0] = val >> 8;
-    buf[1] = val;
-}
-
-static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
-{
-    buf[0] = val >> 24;
-    buf[1] = val >> 16;
-    buf[2] = val >> 8;
-    buf[3] = val;
-}
-
-/* same toc as bochs. Return -1 if error or the toc length */
-/* XXX: check this */
-static int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int 
start_track)
-{
-    uint8_t *q;
-    int len;
-    
-    if (start_track > 1 && start_track != 0xaa)
-        return -1;
-    q = buf + 2;
-    *q++ = 1; /* first session */
-    *q++ = 1; /* last session */
-    if (start_track <= 1) {
-        *q++ = 0; /* reserved */
-        *q++ = 0x14; /* ADR, control */
-        *q++ = 1;    /* track number */
-        *q++ = 0; /* reserved */
-        if (msf) {
-            *q++ = 0; /* reserved */
-            lba_to_msf(q, 0);
-            q += 3;
-        } else {
-            /* sector 0 */
-            cpu_to_ube32(q, 0);
-            q += 4;
-        }
-    }
-    /* lead out track */
-    *q++ = 0; /* reserved */
-    *q++ = 0x16; /* ADR, control */
-    *q++ = 0xaa; /* track number */
-    *q++ = 0; /* reserved */
-    if (msf) {
-        *q++ = 0; /* reserved */
-        lba_to_msf(q, nb_sectors);
-        q += 3;
-    } else {
-        cpu_to_ube32(q, nb_sectors);
-        q += 4;
-    }
-    len = q - buf;
-    cpu_to_ube16(buf, len - 2);
-    return len;
-}
-
-/* mostly same info as PearPc */
-static int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, 
-                              int session_num)
-{
-    uint8_t *q;
-    int len;
-    
-    q = buf + 2;
-    *q++ = 1; /* first session */
-    *q++ = 1; /* last session */
-
-    *q++ = 1; /* session number */
-    *q++ = 0x14; /* data track */
-    *q++ = 0; /* track number */
-    *q++ = 0xa0; /* lead-in */
-    *q++ = 0; /* min */
-    *q++ = 0; /* sec */
-    *q++ = 0; /* frame */
-    *q++ = 0;
-    *q++ = 1; /* first track */
-    *q++ = 0x00; /* disk type */
-    *q++ = 0x00;
-    
-    *q++ = 1; /* session number */
-    *q++ = 0x14; /* data track */
-    *q++ = 0; /* track number */
-    *q++ = 0xa1;
-    *q++ = 0; /* min */
-    *q++ = 0; /* sec */
-    *q++ = 0; /* frame */
-    *q++ = 0;
-    *q++ = 1; /* last track */
-    *q++ = 0x00;
-    *q++ = 0x00;
-    
-    *q++ = 1; /* session number */
-    *q++ = 0x14; /* data track */
-    *q++ = 0; /* track number */
-    *q++ = 0xa2; /* lead-out */
-    *q++ = 0; /* min */
-    *q++ = 0; /* sec */
-    *q++ = 0; /* frame */
-    if (msf) {
-        *q++ = 0; /* reserved */
-        lba_to_msf(q, nb_sectors);
-        q += 3;
-    } else {
-        cpu_to_ube32(q, nb_sectors);
-        q += 4;
-    }
-
-    *q++ = 1; /* session number */
-    *q++ = 0x14; /* ADR, control */
-    *q++ = 0;    /* track number */
-    *q++ = 1;    /* point */
-    *q++ = 0; /* min */
-    *q++ = 0; /* sec */
-    *q++ = 0; /* frame */
-    if (msf) {
-        *q++ = 0; 
-        lba_to_msf(q, 0);
-        q += 3;
-    } else {
-        *q++ = 0; 
-        *q++ = 0; 
-        *q++ = 0; 
-        *q++ = 0; 
-    }
-
-    len = q - buf;
-    cpu_to_ube16(buf, len - 2);
-    return len;
-}
-
-static int esp_write_dma_cb(ESPState *s, 
-                            target_phys_addr_t phys_addr, 
-                            int transfer_size1)
-{
-    DPRINTF("Write callback (offset %lld len %lld size %d trans_size %d)\n",
-            s->offset, s->len, s->ti_size, transfer_size1);
-    bdrv_write(s->bd[s->target], s->offset, s->ti_buf, s->len);
-    s->offset = 0;
-    s->len = 0;
-    s->target = 0;
-    return 0;
-}
-
-static void handle_satn(ESPState *s)
-{
-    uint8_t buf[32];
+static int get_cmd(ESPState *s, uint8_t *buf)
+{
     uint32_t dmaptr, dmalen;
-    unsigned int i;
-    int64_t nb_sectors;
     int target;
 
     dmalen = s->wregs[0] | (s->wregs[1] << 8);
     target = s->wregs[4] & 7;
-    DPRINTF("Select with ATN len %d target %d\n", dmalen, target);
+    DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
     if (s->dma) {
        dmaptr = iommu_translate(s->espdmaregs[1]);
-       DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 
'w': 'r', dmaptr);
+       DPRINTF("DMA Direction: %c, addr 0x%8.8x\n",
+                s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', dmaptr);
        cpu_physical_memory_read(dmaptr, buf, dmalen);
     } else {
        buf[0] = 0;
        memcpy(&buf[1], s->ti_buf, dmalen);
        dmalen++;
     }
-    for (i = 0; i < dmalen; i++) {
-       DPRINTF("Command %2.2x\n", buf[i]);
-    }
-    s->ti_dir = 0;
+
     s->ti_size = 0;
     s->ti_rptr = 0;
     s->ti_wptr = 0;
 
-    if (target >= 4 || !s->bd[target]) { // No such drive
+    if (target >= 4 || !s->scsi_dev[target]) {
+        // No such drive
        s->rregs[4] = STAT_IN;
        s->rregs[5] = INTR_DC;
        s->rregs[6] = SEQ_0;
        s->espdmaregs[0] |= DMA_INTR;
        pic_set_irq(s->irq, 1);
-       return;
-    }
-    switch (buf[1]) {
-    case 0x0:
-       DPRINTF("Test Unit Ready (len %d)\n", buf[5]);
-       break;
-    case 0x12:
-       DPRINTF("Inquiry (len %d)\n", buf[5]);
-       memset(s->ti_buf, 0, 36);
-       if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
-           s->ti_buf[0] = 5;
-           memcpy(&s->ti_buf[16], "QEMU CDROM     ", 16);
-       } else {
-           s->ti_buf[0] = 0;
-           memcpy(&s->ti_buf[16], "QEMU HARDDISK  ", 16);
-       }
-       memcpy(&s->ti_buf[8], "QEMU   ", 8);
-       s->ti_buf[2] = 1;
-       s->ti_buf[3] = 2;
-       s->ti_buf[4] = 32;
-       s->ti_dir = 1;
-       s->ti_size = 36;
-       break;
-    case 0x1a:
-       DPRINTF("Mode Sense(6) (page %d, len %d)\n", buf[3], buf[5]);
-       break;
-    case 0x25:
-       DPRINTF("Read Capacity (len %d)\n", buf[5]);
-       memset(s->ti_buf, 0, 8);
-       bdrv_get_geometry(s->bd[target], &nb_sectors);
-       s->ti_buf[0] = (nb_sectors >> 24) & 0xff;
-       s->ti_buf[1] = (nb_sectors >> 16) & 0xff;
-       s->ti_buf[2] = (nb_sectors >> 8) & 0xff;
-       s->ti_buf[3] = nb_sectors & 0xff;
-       s->ti_buf[4] = 0;
-       s->ti_buf[5] = 0;
-       if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM)
-           s->ti_buf[6] = 8; // sector size 2048
-       else
-           s->ti_buf[6] = 2; // sector size 512
-       s->ti_buf[7] = 0;
-       s->ti_dir = 1;
-       s->ti_size = 8;
-       break;
-    case 0x28:
-       {
-           int64_t offset, len;
-
-           if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
-               offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | 
buf[6]) * 4;
-               len = ((buf[8] << 8) | buf[9]) * 4;
-               s->ti_size = len * 2048;
-           } else {
-               offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | 
buf[6];
-               len = (buf[8] << 8) | buf[9];
-               s->ti_size = len * 512;
-           }
-           DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len);
-            if (s->ti_size > TI_BUFSZ) {
-                DPRINTF("size too large %d\n", s->ti_size);
-            }
-           bdrv_read(s->bd[target], offset, s->ti_buf, len);
-           // XXX error handling
-           s->ti_dir = 1;
-           break;
-       }
-    case 0x2a:
-       {
-           int64_t offset, len;
-
-           if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
-               offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | 
buf[6]) * 4;
-               len = ((buf[8] << 8) | buf[9]) * 4;
-               s->ti_size = len * 2048;
-           } else {
-               offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | 
buf[6];
-               len = (buf[8] << 8) | buf[9];
-               s->ti_size = len * 512;
-           }
-           DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len);
-            if (s->ti_size > TI_BUFSZ) {
-                DPRINTF("size too large %d\n", s->ti_size);
-            }
-            s->dma_cb = esp_write_dma_cb;
-            s->offset = offset;
-            s->len = len;
-            s->target = target;
-           // XXX error handling
-           s->ti_dir = 0;
-           break;
-       }
-    case 0x43:
-        {
-            int start_track, format, msf, len;
-
-            msf = buf[2] & 2;
-            format = buf[3] & 0xf;
-            start_track = buf[7];
-            bdrv_get_geometry(s->bd[target], &nb_sectors);
-            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, 
format, msf >> 1);
-            switch(format) {
-            case 0:
-                len = cdrom_read_toc(nb_sectors, buf, msf, start_track);
-                if (len < 0)
-                    goto error_cmd;
-                s->ti_size = len;
-                break;
-            case 1:
-                /* multi session : only a single session defined */
-                memset(buf, 0, 12);
-                buf[1] = 0x0a;
-                buf[2] = 0x01;
-                buf[3] = 0x01;
-                s->ti_size = 12;
-                break;
-            case 2:
-                len = cdrom_read_toc_raw(nb_sectors, buf, msf, start_track);
-                if (len < 0)
-                    goto error_cmd;
-                s->ti_size = len;
-                break;
-            default:
-            error_cmd:
-                DPRINTF("Read TOC error\n");
-                // XXX error handling
-                break;
-            }
-           s->ti_dir = 1;
-            break;
-        }
-    default:
-       DPRINTF("Unknown SCSI command (%2.2x)\n", buf[1]);
-       break;
-    }
-    s->rregs[4] = STAT_IN | STAT_TC | STAT_DI;
+       return 0;
+    }
+    s->current_dev = s->scsi_dev[target];
+    return dmalen;
+}
+
+static void do_cmd(ESPState *s, uint8_t *buf)
+{
+    int32_t datalen;
+    int lun;
+
+    DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
+    lun = buf[0] & 7;
+    datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun);
+    if (datalen == 0) {
+        s->ti_size = 0;
+    } else {
+        s->rregs[4] = STAT_IN | STAT_TC;
+        if (datalen > 0) {
+            s->rregs[4] |= STAT_DI;
+            s->ti_size = datalen;
+        } else {
+            s->rregs[4] |= STAT_DO;
+            s->ti_size = -datalen;
+        }
+    }
     s->rregs[5] = INTR_BS | INTR_FC;
     s->rregs[6] = SEQ_CD;
     s->espdmaregs[0] |= DMA_INTR;
     pic_set_irq(s->irq, 1);
 }
 
-static void dma_write(ESPState *s, const uint8_t *buf, uint32_t len)
-{
-    uint32_t dmaptr, dmalen;
-
-    dmalen = s->wregs[0] | (s->wregs[1] << 8);
-    DPRINTF("Transfer status len %d\n", dmalen);
+static void handle_satn(ESPState *s)
+{
+    uint8_t buf[32];
+    int len;
+
+    len = get_cmd(s, buf);
+    if (len)
+        do_cmd(s, buf);
+}
+
+static void handle_satn_stop(ESPState *s)
+{
+    s->cmdlen = get_cmd(s, s->cmdbuf);
+    if (s->cmdlen) {
+        DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen);
+        s->do_cmd = 1;
+        s->espdmaregs[1] += s->cmdlen;
+        s->rregs[4] = STAT_IN | STAT_TC | STAT_CD;
+        s->rregs[5] = INTR_BS | INTR_FC;
+        s->rregs[6] = SEQ_CD;
+        s->espdmaregs[0] |= DMA_INTR;
+        pic_set_irq(s->irq, 1);
+    }
+}
+
+static void write_response(ESPState *s)
+{
+    uint32_t dmaptr;
+
+    DPRINTF("Transfer status (sense=%d)\n", s->sense);
+    s->ti_buf[0] = s->sense;
+    s->ti_buf[1] = 0;
     if (s->dma) {
        dmaptr = iommu_translate(s->espdmaregs[1]);
-       DPRINTF("DMA Direction: %c\n", s->espdmaregs[0] & 0x100? 'w': 'r');
-       cpu_physical_memory_write(dmaptr, buf, len);
+       DPRINTF("DMA Direction: %c\n",
+                s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r');
+       cpu_physical_memory_write(dmaptr, s->ti_buf, 2);
        s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
        s->rregs[5] = INTR_BS | INTR_FC;
        s->rregs[6] = SEQ_CD;
     } else {
-       memcpy(s->ti_buf, buf, len);
-       s->ti_size = dmalen;
+       s->ti_size = 2;
        s->ti_rptr = 0;
        s->ti_wptr = 0;
-       s->rregs[7] = dmalen;
+       s->rregs[7] = 2;
     }
     s->espdmaregs[0] |= DMA_INTR;
     pic_set_irq(s->irq, 1);
 
 }
 
-static const uint8_t okbuf[] = {0, 0};
+static void esp_command_complete(void *opaque, uint32_t tag, int sense)
+{
+    ESPState *s = (ESPState *)opaque;
+
+    DPRINTF("SCSI Command complete\n");
+    if (s->ti_size != 0)
+        DPRINTF("SCSI command completed unexpectedly\n");
+    s->ti_size = 0;
+    if (sense)
+        DPRINTF("Command failed\n");
+    s->sense = sense;
+    s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
+}
 
 static void handle_ti(ESPState *s)
 {
-    uint32_t dmaptr, dmalen;
+    uint32_t dmaptr, dmalen, minlen, len, from, to;
     unsigned int i;
+    int to_device;
+    uint8_t buf[TARGET_PAGE_SIZE];
 
     dmalen = s->wregs[0] | (s->wregs[1] << 8);
-    DPRINTF("Transfer Information len %d\n", dmalen);
+    if (dmalen==0) {
+      dmalen=0x10000;
+    }
+
+    if (s->do_cmd)
+        minlen = (dmalen < 32) ? dmalen : 32;
+    else
+        minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
+    DPRINTF("Transfer Information len %d\n", minlen);
     if (s->dma) {
        dmaptr = iommu_translate(s->espdmaregs[1]);
-       DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 
'w': 'r', dmaptr);
-       for (i = 0; i < s->ti_size; i++) {
+        /* Check if the transfer writes to to reads from the device.  */
+        to_device = (s->espdmaregs[0] & DMA_WRITE_MEM) == 0;
+       DPRINTF("DMA Direction: %c, addr 0x%8.8x %08x\n",
+                to_device ? 'r': 'w', dmaptr, s->ti_size);
+       from = s->espdmaregs[1];
+       to = from + minlen;
+       for (i = 0; i < minlen; i += len, from += len) {
            dmaptr = iommu_translate(s->espdmaregs[1] + i);
-           if (s->ti_dir)
-               cpu_physical_memory_write(dmaptr, &s->ti_buf[i], 1);
-           else
-               cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1);
-       }
-        if (s->dma_cb) {
-            s->dma_cb(s, s->espdmaregs[1], dmalen);
-            s->dma_cb = NULL;
-        }
-       s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
-       s->rregs[5] = INTR_BS;
+           if ((from & TARGET_PAGE_MASK) != (to & TARGET_PAGE_MASK)) {
+               len = TARGET_PAGE_SIZE - (from & ~TARGET_PAGE_MASK);
+            } else {
+              len = to - from;
+            }
+            DPRINTF("DMA address p %08x v %08x len %08x, from %08x, to 
%08x\n", dmaptr, s->espdmaregs[1] + i, len, from, to);
+            s->ti_size -= len;
+            if (s->do_cmd) {
+                DPRINTF("command len %d + %d\n", s->cmdlen, len);
+                cpu_physical_memory_read(dmaptr, &s->cmdbuf[s->cmdlen], len);
+                s->ti_size = 0;
+                s->cmdlen = 0;
+                s->do_cmd = 0;
+                do_cmd(s, s->cmdbuf);
+                return;
+            } else {
+                if (to_device) {
+                    cpu_physical_memory_read(dmaptr, buf, len);
+                    scsi_write_data(s->current_dev, buf, len);
+                } else {
+                    scsi_read_data(s->current_dev, buf, len);
+                    cpu_physical_memory_write(dmaptr, buf, len);
+                }
+            }
+        }
+        if (s->ti_size) {
+           s->rregs[4] = STAT_IN | STAT_TC | (to_device ? STAT_DO : STAT_DI);
+        }
+        s->rregs[5] = INTR_BS;
        s->rregs[6] = 0;
+       s->rregs[7] = 0;
        s->espdmaregs[0] |= DMA_INTR;
-    } else {
-       s->ti_size = dmalen;
-       s->ti_rptr = 0;
-       s->ti_wptr = 0;
-       s->rregs[7] = dmalen;
-    }  
+    } else if (s->do_cmd) {
+        DPRINTF("command len %d\n", s->cmdlen);
+        s->ti_size = 0;
+        s->cmdlen = 0;
+        s->do_cmd = 0;
+        do_cmd(s, s->cmdbuf);
+        return;
+    }
     pic_set_irq(s->irq, 1);
 }
 
@@ -484,9 +289,8 @@ static void esp_reset(void *opaque)
     s->ti_size = 0;
     s->ti_rptr = 0;
     s->ti_wptr = 0;
-    s->ti_dir = 0;
     s->dma = 0;
-    s->dma_cb = NULL;
+    s->do_cmd = 0;
 }
 
 static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
@@ -501,7 +305,12 @@ static uint32_t esp_mem_readb(void *opaq
        // FIFO
        if (s->ti_size > 0) {
            s->ti_size--;
-           s->rregs[saddr] = s->ti_buf[s->ti_rptr++];
+            if ((s->rregs[4] & 6) == 0) {
+                /* Data in/out.  */
+                scsi_read_data(s->current_dev, &s->rregs[2], 0);
+            } else {
+                s->rregs[2] = s->ti_buf[s->ti_rptr++];
+            }
            pic_set_irq(s->irq, 1);
        }
        if (s->ti_size == 0) {
@@ -536,8 +345,17 @@ static void esp_mem_writeb(void *opaque,
         break;
     case 2:
        // FIFO
-       s->ti_size++;
-       s->ti_buf[s->ti_wptr++] = val & 0xff;
+        if (s->do_cmd) {
+            s->cmdbuf[s->cmdlen++] = val & 0xff;
+        } else if ((s->rregs[4] & 6) == 0) {
+            uint8_t buf;
+            buf = val & 0xff;
+            s->ti_size--;
+            scsi_write_data(s->current_dev, &buf, 0);
+        } else {
+            s->ti_size++;
+            s->ti_buf[s->ti_wptr++] = val & 0xff;
+        }
        break;
     case 3:
         s->rregs[saddr] = val;
@@ -574,11 +392,11 @@ static void esp_mem_writeb(void *opaque,
            break;
        case 0x11:
            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
-           dma_write(s, okbuf, 2);
+           write_response(s);
            break;
        case 0x12:
            DPRINTF("Message Accepted (%2.2x)\n", val);
-           dma_write(s, okbuf, 2);
+           write_response(s);
            s->rregs[5] = INTR_DC;
            s->rregs[6] = 0;
            break;
@@ -586,11 +404,12 @@ static void esp_mem_writeb(void *opaque,
            DPRINTF("Set ATN (%2.2x)\n", val);
            break;
        case 0x42:
+           DPRINTF("Set ATN (%2.2x)\n", val);
            handle_satn(s);
            break;
        case 0x43:
            DPRINTF("Set ATN & stop (%2.2x)\n", val);
-           handle_satn(s);
+           handle_satn_stop(s);
            break;
        default:
            DPRINTF("Unhandled ESP command (%2.2x)\n", val);

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

<Prev in Thread] Current Thread [Next in Thread>