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

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



# HG changeset patch
# User 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


 


Rackspace

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