# HG changeset patch
# User chris@xxxxxxxxxxxxxxxxxxxxxxxx
# Node ID b450f21472a0574fbc382f2f84ea0a8295aa6423
# Parent bd68ce5a3f0cb22e12a860fb20846c35cce68bf2
Add qemu 0.8.1 based ioemu.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxxx>
---
.hgignore | 18
tools/ioemu/.cvsignore | 29
tools/ioemu/COPYING | 339 +
tools/ioemu/COPYING.LIB | 504 ++
tools/ioemu/CVS/Entries | 109
tools/ioemu/CVS/Repository | 1
tools/ioemu/CVS/Root | 1
tools/ioemu/CVS/Tag | 1
tools/ioemu/Changelog | 376 +
tools/ioemu/LICENSE | 12
tools/ioemu/Makefile | 149
tools/ioemu/Makefile.target | 531 ++
tools/ioemu/README | 3
tools/ioemu/README.distrib | 16
tools/ioemu/TODO | 61
tools/ioemu/VERSION | 1
tools/ioemu/a.out.h | 431 +
tools/ioemu/aes.c | 1317 +++++
tools/ioemu/aes.h | 26
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/audio/alsaaudio.c | 981 ++++
tools/ioemu/audio/audio.c | 1481 ++++++
tools/ioemu/audio/audio.h | 133
tools/ioemu/audio/audio_int.h | 268 +
tools/ioemu/audio/audio_template.h | 565 ++
tools/ioemu/audio/coreaudio.c | 564 ++
tools/ioemu/audio/dsound_template.h | 282 +
tools/ioemu/audio/dsoundaudio.c | 1076 ++++
tools/ioemu/audio/fmodaudio.c | 683 ++
tools/ioemu/audio/mixeng.c | 277 +
tools/ioemu/audio/mixeng.h | 51
tools/ioemu/audio/mixeng_template.h | 177
tools/ioemu/audio/noaudio.c | 170
tools/ioemu/audio/ossaudio.c | 762 +++
tools/ioemu/audio/rate_template.h | 111
tools/ioemu/audio/sdlaudio.c | 437 +
tools/ioemu/audio/sys-queue.h | 241 +
tools/ioemu/audio/wavaudio.c | 255 +
tools/ioemu/block-bochs.c | 224
tools/ioemu/block-cloop.c | 169
tools/ioemu/block-cow.c | 264 +
tools/ioemu/block-dmg.c | 297 +
tools/ioemu/block-qcow.c | 710 ++
tools/ioemu/block-vmdk.c | 439 +
tools/ioemu/block-vpc.c | 242 +
tools/ioemu/block-vvfat.c | 2807 +++++++++++
tools/ioemu/block.c | 797 +++
tools/ioemu/block_int.h | 80
tools/ioemu/bswap.h | 202
tools/ioemu/cocoa.m | 911 +++
tools/ioemu/configure | 896 +++
tools/ioemu/console.c | 1008 ++++
tools/ioemu/cpu-all.h | 944 +++
tools/ioemu/cpu-defs.h | 125
tools/ioemu/cpu-exec.c | 1480 ++++++
tools/ioemu/dis-asm.h | 455 +
tools/ioemu/disas.c | 413 +
tools/ioemu/disas.h | 23
tools/ioemu/dyngen-exec.h | 257 +
tools/ioemu/dyngen-op.h | 9
tools/ioemu/dyngen.c | 2550 ++++++++++
tools/ioemu/dyngen.h | 429 +
tools/ioemu/elf.h | 1160 ++++
tools/ioemu/elf_ops.h | 205
tools/ioemu/exec-all.h | 605 ++
tools/ioemu/exec.c | 2379 +++++++++
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-macros.h | 720 +++
tools/ioemu/fpu/softfloat-native.c | 363 +
tools/ioemu/fpu/softfloat-native.h | 359 +
tools/ioemu/fpu/softfloat-specialize.h | 464 +
tools/ioemu/fpu/softfloat.c | 5320 ++++++++++++++++++++++
tools/ioemu/fpu/softfloat.h | 398 +
tools/ioemu/gdbstub.c | 943 +++
tools/ioemu/gdbstub.h | 12
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/hw/adb.c | 410 +
tools/ioemu/hw/adlib.c | 341 +
tools/ioemu/hw/apic.c | 1042 ++++
tools/ioemu/hw/arm_boot.c | 105
tools/ioemu/hw/arm_pic.c | 73
tools/ioemu/hw/arm_pic.h | 27
tools/ioemu/hw/arm_timer.c | 383 +
tools/ioemu/hw/cirrus_vga.c | 3311 +++++++++++++
tools/ioemu/hw/cirrus_vga_rop.h | 78
tools/ioemu/hw/cirrus_vga_rop2.h | 281 +
tools/ioemu/hw/cuda.c | 656 ++
tools/ioemu/hw/dma.c | 537 ++
tools/ioemu/hw/es1370.c | 1062 ++++
tools/ioemu/hw/esp.c | 747 +++
tools/ioemu/hw/fdc.c | 1757 +++++++
tools/ioemu/hw/fmopl.c | 1390 +++++
tools/ioemu/hw/fmopl.h | 174
tools/ioemu/hw/heathrow_pic.c | 168
tools/ioemu/hw/i8254.c | 482 ++
tools/ioemu/hw/i8259.c | 561 ++
tools/ioemu/hw/ide.c | 2726 +++++++++++
tools/ioemu/hw/integratorcp.c | 546 ++
tools/ioemu/hw/iommu.c | 258 +
tools/ioemu/hw/lance.c | 462 +
tools/ioemu/hw/m48t59.c | 608 ++
tools/ioemu/hw/m48t59.h | 13
tools/ioemu/hw/mc146818rtc.c | 486 ++
tools/ioemu/hw/mips_r4k.c | 295 +
tools/ioemu/hw/ne2000.c | 816 +++
tools/ioemu/hw/openpic.c | 1027 ++++
tools/ioemu/hw/parallel.c | 183
tools/ioemu/hw/pc.c | 927 +++
tools/ioemu/hw/pci.c | 1872 +++++++
tools/ioemu/hw/pckbd.c | 370 +
tools/ioemu/hw/pcspk.c | 147
tools/ioemu/hw/piix4acpi.c | 484 ++
tools/ioemu/hw/pl011.c | 251 +
tools/ioemu/hw/pl050.c | 127
tools/ioemu/hw/pl080.c | 328 +
tools/ioemu/hw/pl110.c | 420 +
tools/ioemu/hw/pl110_template.h | 252 +
tools/ioemu/hw/pl190.c | 252 +
tools/ioemu/hw/ppc.c | 428 +
tools/ioemu/hw/ppc_chrp.c | 564 ++
tools/ioemu/hw/ppc_prep.c | 690 ++
tools/ioemu/hw/ps2.c | 566 ++
tools/ioemu/hw/rtl8139.c | 2875 ++++++++++++
tools/ioemu/hw/sb16.c | 1415 +++++
tools/ioemu/hw/serial.c | 456 +
tools/ioemu/hw/sh7750.c | 836 +++
tools/ioemu/hw/sh7750_regnames.c | 128
tools/ioemu/hw/sh7750_regnames.h | 6
tools/ioemu/hw/sh7750_regs.h | 1623 ++++++
tools/ioemu/hw/shix.c | 111
tools/ioemu/hw/slavio_intctl.c | 400 +
tools/ioemu/hw/slavio_misc.c | 244 +
tools/ioemu/hw/slavio_serial.c | 545 ++
tools/ioemu/hw/slavio_timer.c | 288 +
tools/ioemu/hw/smc91c111.c | 714 ++
tools/ioemu/hw/sun4m.c | 324 +
tools/ioemu/hw/sun4u.c | 376 +
tools/ioemu/hw/tc58128.c | 181
tools/ioemu/hw/tcx.c | 330 +
tools/ioemu/hw/usb-hid.c | 537 ++
tools/ioemu/hw/usb-hub.c | 549 ++
tools/ioemu/hw/usb-uhci.c | 680 ++
tools/ioemu/hw/usb.c | 193
tools/ioemu/hw/usb.h | 166
tools/ioemu/hw/versatilepb.c | 271 +
tools/ioemu/hw/vga.c | 2029 ++++++++
tools/ioemu/hw/vga_int.h | 172
tools/ioemu/hw/vga_template.h | 519 ++
tools/ioemu/i386-dis.c | 4143 +++++++++++++++++
tools/ioemu/i386-vl.ld | 140
tools/ioemu/i386.ld | 140
tools/ioemu/ia64.ld | 211
tools/ioemu/keymaps.c | 145
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/keymaps/ar | 98
tools/ioemu/keymaps/common | 157
tools/ioemu/keymaps/da | 120
tools/ioemu/keymaps/de | 114
tools/ioemu/keymaps/de-ch | 169
tools/ioemu/keymaps/en-gb | 119
tools/ioemu/keymaps/en-us | 35
tools/ioemu/keymaps/es | 105
tools/ioemu/keymaps/et | 86
tools/ioemu/keymaps/fi | 124
tools/ioemu/keymaps/fo | 77
tools/ioemu/keymaps/fr | 181
tools/ioemu/keymaps/fr-be | 140
tools/ioemu/keymaps/fr-ca | 50
tools/ioemu/keymaps/fr-ch | 114
tools/ioemu/keymaps/hr | 125
tools/ioemu/keymaps/hu | 115
tools/ioemu/keymaps/is | 140
tools/ioemu/keymaps/it | 115
tools/ioemu/keymaps/ja | 104
tools/ioemu/keymaps/lt | 57
tools/ioemu/keymaps/lv | 128
tools/ioemu/keymaps/mk | 101
tools/ioemu/keymaps/modifiers | 17
tools/ioemu/keymaps/nl | 60
tools/ioemu/keymaps/nl-be | 3
tools/ioemu/keymaps/no | 119
tools/ioemu/keymaps/pl | 122
tools/ioemu/keymaps/pt | 113
tools/ioemu/keymaps/pt-br | 69
tools/ioemu/keymaps/ru | 109
tools/ioemu/keymaps/sl | 110
tools/ioemu/keymaps/sv | 82
tools/ioemu/keymaps/th | 131
tools/ioemu/keymaps/tr | 123
tools/ioemu/kqemu.c | 900 +++
tools/ioemu/kqemu.h | 132
tools/ioemu/loader.c | 235
tools/ioemu/monitor.c | 2335 +++++++++
tools/ioemu/osdep.c | 628 ++
tools/ioemu/osdep.h | 53
tools/ioemu/patches/acpi-poweroff-support | 26
tools/ioemu/patches/acpi-support | 58
tools/ioemu/patches/acpi-timer-support | 43
tools/ioemu/patches/domain-destroy | 24
tools/ioemu/patches/domain-reset | 45
tools/ioemu/patches/domain-timeoffset | 138
tools/ioemu/patches/hypervisor-pit | 48
tools/ioemu/patches/ide-hd-multithread | 75
tools/ioemu/patches/qemu-64bit | 80
tools/ioemu/patches/qemu-bugfixes | 19
tools/ioemu/patches/qemu-cleanup | 66
tools/ioemu/patches/qemu-dm | 385 +
tools/ioemu/patches/qemu-hvm-banner | 19
tools/ioemu/patches/qemu-infrastructure | 9
tools/ioemu/patches/qemu-logging | 57
tools/ioemu/patches/qemu-no-apic | 42
tools/ioemu/patches/qemu-nobios | 48
tools/ioemu/patches/qemu-smp | 38
tools/ioemu/patches/qemu-target-i386-dm | 115
tools/ioemu/patches/qemu-timer | 37
tools/ioemu/patches/sdl-mouse-invisible-wall | 17
tools/ioemu/patches/serial-non-block | 23
tools/ioemu/patches/series | 32
tools/ioemu/patches/shadow-vram | 32
tools/ioemu/patches/shared-vram | 123
tools/ioemu/patches/support-xm-console | 37
tools/ioemu/patches/vnc-cleanup | 63
tools/ioemu/patches/vnc-fixes | 317 +
tools/ioemu/patches/xen-build | 171
tools/ioemu/patches/xen-domain-name | 64
tools/ioemu/patches/xen-domid | 37
tools/ioemu/patches/xen-mm | 61
tools/ioemu/patches/xen-network | 52
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/Makefile | 24
tools/ioemu/pc-bios/README | 17
tools/ioemu/pc-bios/bios.diff | 87
tools/ioemu/pc-bios/linux_boot.S | 29
tools/ioemu/pc-bios/ohw.diff | 1153 ++++
tools/ioemu/pc-bios/proll.patch | 939 +++
tools/ioemu/pc-bios/vgabios.diff | 318 +
tools/ioemu/qemu-binfmt-conf.sh | 39
tools/ioemu/qemu-doc.texi | 1748 +++++++
tools/ioemu/qemu-img.c | 699 ++
tools/ioemu/qemu-img.texi | 126
tools/ioemu/qemu-tech.texi | 595 ++
tools/ioemu/qemu_socket.h | 30
tools/ioemu/readline.c | 425 +
tools/ioemu/sdl.c | 556 ++
tools/ioemu/sdl_keysym.h | 278 +
tools/ioemu/softmmu_exec.h | 65
tools/ioemu/softmmu_header.h | 385 +
tools/ioemu/softmmu_template.h | 313 +
tools/ioemu/tap-win32.c | 680 ++
tools/ioemu/target-i386-dm/cpu.h | 86
tools/ioemu/target-i386-dm/exec-dm.c | 512 ++
tools/ioemu/target-i386-dm/helper2.c | 507 ++
tools/ioemu/target-i386-dm/i8259-dm.c | 107
tools/ioemu/target-i386-dm/qemu-dm.debug | 5
tools/ioemu/target-i386-dm/qemu-ifup | 10
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/cpu.h | 653 ++
tools/ioemu/target-i386/exec.h | 572 ++
tools/ioemu/target-i386/helper.c | 3505 ++++++++++++++
tools/ioemu/target-i386/helper2.c | 1028 ++++
tools/ioemu/target-i386/op.c | 2437 ++++++++++
tools/ioemu/target-i386/opreg_template.h | 190
tools/ioemu/target-i386/ops_mem.h | 156
tools/ioemu/target-i386/ops_sse.h | 1374 +++++
tools/ioemu/target-i386/ops_template.h | 597 ++
tools/ioemu/target-i386/ops_template_mem.h | 483 ++
tools/ioemu/target-i386/translate-copy.c | 1323 +++++
tools/ioemu/target-i386/translate.c | 6468 +++++++++++++++++++++++++++
tools/ioemu/tests/.cvsignore | 23
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 | 92
tools/ioemu/tests/hello-arm.c | 113
tools/ioemu/tests/hello-i386.c | 26
tools/ioemu/tests/linux-test.c | 536 ++
tools/ioemu/tests/qruncom.c | 327 +
tools/ioemu/tests/runcom.c | 195
tools/ioemu/tests/sha1.c | 242 +
tools/ioemu/tests/test-i386-code16.S | 79
tools/ioemu/tests/test-i386-muldiv.h | 76
tools/ioemu/tests/test-i386-shift.h | 187
tools/ioemu/tests/test-i386-vm86.S | 104
tools/ioemu/tests/test-i386.c | 2611 ++++++++++
tools/ioemu/tests/test-i386.h | 152
tools/ioemu/tests/test_path.c | 152
tools/ioemu/tests/testthread.c | 51
tools/ioemu/texi2pod.pl | 428 +
tools/ioemu/thunk.c | 243 +
tools/ioemu/thunk.h | 158
tools/ioemu/translate-all.c | 311 +
tools/ioemu/translate-op.c | 37
tools/ioemu/usb-linux.c | 488 ++
tools/ioemu/vgafont.h | 4611 +++++++++++++++++++
tools/ioemu/vl.c | 6001 +++++++++++++++++++++++++
tools/ioemu/vl.h | 1111 ++++
tools/ioemu/vnc.c | 1001 ++++
tools/ioemu/vnc_keysym.h | 275 +
tools/ioemu/vnchextile.h | 189
tools/ioemu/x86_64.ld | 171
319 files changed, 149548 insertions(+), 6 deletions(-)
diff -r bd68ce5a3f0c -r b450f21472a0 .hgignore
--- a/.hgignore Wed Jul 12 19:16:07 2006 +0100
+++ b/.hgignore Wed Jul 12 19:16:10 2006 +0100
@@ -123,12 +123,18 @@
^tools/firmware/vmxassist/roms\.h$
^tools/firmware/vmxassist/vmxassist$
^tools/firmware/vmxassist/vmxloader$
-^tools/ioemu/config-host\..*$
-^tools/ioemu/keysym_adapter_sdl\.h$
-^tools/ioemu/keysym_adapter_vnc\.h$
-^tools/ioemu/target-.*/Makefile$
-^tools/ioemu/target-.*/config\..*$
-^tools/ioemu/target-.*/qemu-dm$
+^tools/ioemu/\.pc/.*$
+^tools/ioemu/config-host\.h$
+^tools/ioemu/config-host\.mak$
+^tools/ioemu/i386-dm/config\.h$
+^tools/ioemu/i386-dm/config\.mak$
+^tools/ioemu/i386-dm/qemu-dm$
+^tools/ioemu/qemu-doc\.html$
+^tools/ioemu/qemu-img\.1$
+^tools/ioemu/qemu-img\.pod$
+^tools/ioemu/qemu-tech\.html$
+^tools/ioemu/qemu\.1$
+^tools/ioemu/qemu\.pod$
^tools/libxc/xen/.*$
^tools/misc/cpuperf/cpuperf-perfcntr$
^tools/misc/cpuperf/cpuperf-xen$
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/.cvsignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/.cvsignore Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,29 @@
+arm-user
+arm-softmmu
+armeb-user
+config-host.*
+dyngen
+i386
+i386-softmmu
+i386-user
+ppc-softmmu
+ppc64-softmmu
+ppc-user
+qemu-doc.html
+qemu-tech.html
+qemu.1
+qemu.pod
+qemu-img.1
+qemu-img.pod
+sparc-user
+qemu-img
+sparc-softmmu
+x86_64-softmmu
+sparc64-user
+sparc64-softmmu
+mips-softmmu
+mipsel-softmmu
+mips-user
+mipsel-user
+sh4-user
+sh4-softmmu
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/COPYING
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/COPYING Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/COPYING.LIB
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/COPYING.LIB Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/CVS/Entries
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/CVS/Entries Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,109 @@
+D/audio////
+D/hw////
+D/linux-user////
+D/pc-bios////
+D/slirp////
+D/target-arm////
+D/target-i386////
+D/target-ppc////
+D/target-sparc////
+D/tests////
+D/fpu////
+D/keymaps////
+D/target-mips////
+/.cvsignore/1.13/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/COPYING/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/COPYING.LIB/1.2/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/Changelog/1.116/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/LICENSE/1.2/Sat Feb 12 14:45:23 2005//Trelease_0_8_1
+/Makefile/1.99/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/Makefile.target/1.107/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/README/1.12/Wed May 24 10:40:08 2006//Trelease_0_8_1
+/README.distrib/1.2/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/TODO/1.38/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/VERSION/1.28/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/a.out.h/1.2/Wed May 24 10:40:08 2006//Trelease_0_8_1
+/aes.c/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/aes.h/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/alpha-dis.c/1.3/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/alpha.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/arm-dis.c/1.3/Wed May 24 10:40:08 2006//Trelease_0_8_1
+/arm.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/block-bochs.c/1.1/Tue Apr 26 21:34:00 2005//Trelease_0_8_1
+/block-cloop.c/1.3/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/block-cow.c/1.5/Thu May 25 12:38:49 2006//Trelease_0_8_1
+/block-dmg.c/1.4/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/block-qcow.c/1.6/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/block-vmdk.c/1.7/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/block-vpc.c/1.2/Thu May 25 12:38:49 2006//Trelease_0_8_1
+/block-vvfat.c/1.5/Thu May 25 18:22:25 2006//Trelease_0_8_1
+/block.c/1.26/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/block_int.h/1.4/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/bswap.h/1.5/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/cocoa.m/1.8/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/configure/1.100/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/console.c/1.5/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/cpu-all.h/1.54/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/cpu-defs.h/1.15/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/cpu-exec.c/1.78/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/dis-asm.h/1.11/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/disas.c/1.30/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/disas.h/1.7/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/dyngen-exec.h/1.27/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/dyngen-op.h/1.1/Mon Jan 3 23:40:55 2005//Trelease_0_8_1
+/dyngen.c/1.42/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/dyngen.h/1.10/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/elf.h/1.6/Thu May 25 12:38:50 2006//Trelease_0_8_1
+/elf_ops.h/1.3/Tue May 2 20:54:12 2006//Trelease_0_8_1
+/exec-all.h/1.47/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/exec.c/1.79/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/gdbstub.c/1.36/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/gdbstub.h/1.2/Tue Apr 26 20:42:36 2005//Trelease_0_8_1
+/i386-dis.c/1.5/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/i386-vl.ld/1.3/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/i386.ld/1.2/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/ia64.ld/1.1/Thu Apr 7 22:20:28 2005//Trelease_0_8_1
+/keymaps.c/1.2/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/kqemu.c/1.10/Thu May 25 18:22:26 2006//Trelease_0_8_1
+/kqemu.h/1.1/Wed Feb 8 22:39:17 2006//Trelease_0_8_1
+/linux-2.6.9-qemu-fast.patch/1.1/Wed Dec 8 23:48:11 2004//Trelease_0_8_1
+/loader.c/1.2/Wed Apr 26 22:05:26 2006//Trelease_0_8_1
+/m68k-dis.c/1.1/Sun Nov 6 16:52:11 2005//Trelease_0_8_1
+/m68k.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/mips-dis.c/1.3/Thu May 25 18:22:28 2006//Trelease_0_8_1
+/monitor.c/1.48/Thu May 25 18:22:28 2006//Trelease_0_8_1
+/osdep.c/1.10/Wed May 24 10:40:10 2006//Trelease_0_8_1
+/osdep.h/1.5/Wed May 24 10:40:10 2006//Trelease_0_8_1
+/ppc-dis.c/1.7/Thu May 25 12:38:51 2006//Trelease_0_8_1
+/ppc.ld/1.2/Thu May 25 12:38:51 2006//Trelease_0_8_1
+/qemu-binfmt-conf.sh/1.4/Thu May 25 18:22:28 2006//Trelease_0_8_1
+/qemu-doc.texi/1.87/Thu May 25 18:22:29 2006//Trelease_0_8_1
+/qemu-img.c/1.8/Thu May 25 12:38:51 2006//Trelease_0_8_1
+/qemu-img.texi/1.2/Thu May 25 12:38:51 2006//Trelease_0_8_1
+/qemu-tech.texi/1.9/Thu May 25 18:22:29 2006//Trelease_0_8_1
+/qemu_socket.h/1.1/Sun Apr 30 22:53:25 2006//Trelease_0_8_1
+/readline.c/1.1/Tue May 23 19:16:56 2006//Trelease_0_8_1
+/s390.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/sdl.c/1.26/Thu May 25 18:22:29 2006//Trelease_0_8_1
+/sdl_keysym.h/1.3/Tue Mar 1 21:43:41 2005//Trelease_0_8_1
+/sh4-dis.c/1.1/Thu Apr 27 21:05:14 2006//Trelease_0_8_1
+/softmmu_exec.h/1.1/Sun Oct 30 18:16:26 2005//Trelease_0_8_1
+/softmmu_header.h/1.13/Thu May 25 18:22:29 2006//Trelease_0_8_1
+/softmmu_template.h/1.16/Thu May 25 18:22:29 2006//Trelease_0_8_1
+/sparc-dis.c/1.2/Thu May 25 18:22:29 2006//Trelease_0_8_1
+/sparc.ld/1.1/Wed May 17 14:47:01 2006//Trelease_0_8_1
+/tap-win32.c/1.2/Sun Feb 19 12:40:00 2006//Trelease_0_8_1
+/texi2pod.pl/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1
+/thunk.c/1.6/Wed May 24 10:40:10 2006//Trelease_0_8_1
+/thunk.h/1.13/Wed May 17 14:47:02 2006//Trelease_0_8_1
+/translate-all.c/1.14/Thu May 25 18:22:29 2006//Trelease_0_8_1
+/translate-op.c/1.1/Sun Mar 13 16:53:06 2005//Trelease_0_8_1
+/usb-linux.c/1.4/Sat Mar 11 18:03:38 2006//Trelease_0_8_1
+/vgafont.h/1.1/Wed May 17 14:47:02 2006//Trelease_0_8_1
+/vl.c/1.184/Thu May 25 18:22:30 2006//Trelease_0_8_1
+/vl.h/1.116/Thu May 25 18:22:30 2006//Trelease_0_8_1
+/vnc.c/1.4/Mon May 1 21:44:22 2006//Trelease_0_8_1
+/vnc_keysym.h/1.1/Sun Apr 30 21:28:36 2006//Trelease_0_8_1
+/vnchextile.h/1.1/Sun Apr 30 21:28:36 2006//Trelease_0_8_1
+/x86_64.ld/1.1/Thu Jan 6 20:50:00 2005//Trelease_0_8_1
+D/target-sh4////
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/CVS/Repository
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/CVS/Repository Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1 @@
+qemu
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/CVS/Root
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/CVS/Root Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1 @@
+:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/CVS/Tag
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/CVS/Tag Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1 @@
+Nrelease_0_8_1
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/Changelog
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/Changelog Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,376 @@
+version 0.8.1:
+
+ - USB tablet support (Brad Campbell, Anthony Liguori)
+ - win32 host serial support (Kazu)
+ - PC speaker support (Joachim Henke)
+ - IDE LBA48 support (Jens Axboe)
+ - SSE3 support
+ - Solaris port (Ben Taylor)
+ - Preliminary SH4 target (Samuel Tardieu)
+ - VNC server (Anthony Liguori)
+ - slirp fixes (Ed Swierk et al.)
+ - USB fixes
+ - ARM Versatile Platform Baseboard emulation (Paul Brook)
+
+version 0.8.0:
+
+ - ARM system emulation: Arm Integrator/CP board with an arm1026ej-s
+ cpu (Paul Brook)
+ - SMP support
+ - Mac OS X cocoa improvements (Mike Kronenberg)
+ - Mac OS X CoreAudio driver (Mike Kronenberg)
+ - DirectSound driver (malc)
+ - ALSA audio driver (malc)
+ - new audio options: '-soundhw' and '-audio-help' (malc)
+ - ES1370 PCI audio device (malc)
+ - Initial USB support
+ - Linux host serial port access
+ - Linux host low level parallel port access
+ - New network emulation code supporting VLANs.
+ - MIPS and MIPSel User Linux emulation
+ - MIPS fixes to boot Linux (Daniel Jacobowitz)
+ - NX bit support
+ - Initial SPARC SMP support (Blue Swirl)
+ - Major overhaul of the virtual FAT driver for read/write support
+ (Johannes Schindelin)
+
+version 0.7.2:
+
+ - x86_64 fixes (Win2000 and Linux 2.6 boot in 32 bit)
+ - merge self modifying code handling in dirty ram page mecanism.
+ - MIPS fixes (Ralf Baechle)
+ - better user net performances
+
+version 0.7.1:
+
+ - read-only Virtual FAT support (Johannes Schindelin)
+ - Windows 2000 install disk full hack (original idea from Vladimir
+ N. Oleynik)
+ - VMDK disk image creation (Filip Navara)
+ - SPARC64 progress (Blue Swirl)
+ - initial MIPS support (Jocelyn mayer)
+ - MIPS improvements (Ralf Baechle)
+ - 64 bit fixes in user networking (initial patch by Gwenole Beauchesne)
+ - IOAPIC support (Filip Navara)
+
+version 0.7.0:
+
+ - better BIOS translation and HDD geometry auto-detection
+ - user mode networking bug fix
+ - undocumented FPU ops support
+ - Cirrus VGA: support for 1280x1024x[8,15,16] modes
+ - 'pidfile' option
+ - .dmg disk image format support (Johannes Schindelin)
+ - keymaps support (initial patch by Johannes Schindelin)
+ - big endian ARM support (Lennert Buytenhek)
+ - added generic 64 bit target support
+ - x86_64 target support
+ - initial APIC support
+ - MMX/SSE/SSE2/PNI support
+ - PC parallel port support (Mark Jonckheere)
+ - initial SPARC64 support (Blue Swirl)
+ - SPARC target boots Linux (Blue Swirl)
+ - armv5te user mode support (Paul Brook)
+ - ARM VFP support (Paul Brook)
+ - ARM "Angel" semihosting syscalls (Paul Brook)
+ - user mode gdb stub support (Paul Brook)
+ - Samba 3 support
+ - initial Cocoa support (Pierre d'Herbemont)
+ - generic FPU emulation code
+ - Virtual PC read-only disk image support (Alex Beregszaszi)
+
+version 0.6.1:
+
+ - Mac OS X port (Pierre d'Herbemont)
+ - Virtual console support
+ - Better monitor line edition
+ - New block device layer
+ - New 'qcow' growable disk image support with AES encryption and
+ transparent decompression
+ - VMware 3 and 4 read-only disk image support (untested)
+ - Support for up to 4 serial ports
+ - TFTP server support (Magnus Damm)
+ - Port redirection support in user mode networking
+ - Support for not executable data sections
+ - Compressed loop disk image support (Johannes Schindelin)
+ - Level triggered IRQ fix (aka NE2000 PCI performance fix) (Steve
+ Wormley)
+ - Fixed Fedora Core 2 problems (now you can run qemu without any
+ LD_ASSUME_KERNEL tricks on FC2)
+ - DHCP fix for Windows (accept DHCPREQUEST alone)
+ - SPARC system emulation (Blue Swirl)
+ - Automatic Samba configuration for host file access from Windows.
+ - '-loadvm' and '-full-screen' options
+ - ne2000 savevm support (Johannes Schindelin)
+ - Ctrl-Alt is now the default grab key. Ctrl-Alt-[0-9] switches to
+ the virtual consoles.
+ - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert)
+ - Floppy fixes for NT4 and NT5 (Mike Nordell)
+ - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
+ - SDL Audio support and SB16 fixes (malc)
+ - ENTER instruction bug fix (initial patch by Stefan Kisdaroczi)
+ - VGA font change fix
+ - VGA read-only CRTC register fix
+
+version 0.6.0:
+
+ - minimalist FPU exception support (NetBSD FPU probe fix)
+ - cr0.ET fix (Win95 boot)
+ - *BSD port (Markus Niemisto)
+ - I/O access fix (signaled by Mark Jonckheere)
+ - IDE drives serial number fix (Mike Nordell)
+ - int13 CDROM BIOS fix (aka Solaris x86 install CD fix)
+ - int15, ah=86 BIOS fix (aka Solaris x86 hardware probe hang up fix)
+ - BSR/BSF "undefined behaviour" fix
+ - vmdk2raw: convert VMware disk images to raw images
+ - PCI support
+ - NE2K PCI support
+ - dummy VGA PCI support
+ - VGA font selection fix (Daniel Serpell)
+ - PIC reset fix (Hidemi KAWAI)
+ - PIC spurious irq support (aka Solaris install bug)
+ - added '-localtime' option
+ - Cirrus CL-GD54xx VGA support (initial patch by Makoto Suzuki (suzu))
+ - APM and system shutdown support
+ - Fixed system reset
+ - Support for other PC BIOSes
+ - Initial PowerMac hardware emulation
+ - PowerMac/PREP OpenFirmware compatible BIOS (Jocelyn Mayer)
+ - initial IDE BMDMA support (needed for Darwin x86)
+ - Set the default memory size for PC emulation to 128 MB
+
+version 0.5.5:
+
+ - SDL full screen support (initial patch by malc)
+ - VGA support on PowerPC PREP
+ - VBE fixes (Matthew Mastracci)
+ - PIT fixes (aka Win98 hardware probe and "VGA slowness" bug)
+ - IDE master only fixes (aka Win98 CD-ROM probe bug)
+ - ARM load/store half word fix (Ulrich Hecht)
+ - FDC fixes for Win98
+
+version 0.5.4:
+
+ - qemu-fast fixes
+ - BIOS area protection fix (aka EMM386.EXE fix) (Mike Nordell)
+ - keyboard/mouse fix (Mike Nordell)
+ - IDE fixes (Linux did not recognized slave drivers)
+ - VM86 EIP masking fix (aka NT5 install fix) (Mike Nordell)
+ - QEMU can now boot a PowerPC Linux kernel (Jocelyn Mayer)
+ - User mode network stack
+ - imul imm8 fix + 0x82 opcode support (Hidemi KAWAI)
+ - precise self modifying code (aka BeOS install bug)
+
+version 0.5.3:
+
+ - added Bochs VESA VBE support
+ - VGA memory map mode 3 access fix (OS/2 install fix)
+ - IDE fixes (Jens Axboe)
+ - CPU interrupt fixes
+ - fixed various TLB invalidation cases (NT install)
+ - fixed cr0.WP semantics (XP install)
+ - direct chaining support for SPARC and PowerPC (faster)
+ - ARM NWFPE support (initial patch by Ulrich Hecht)
+ - added specific x86 to x86 translator (close to native performance
+ in qemu-i386 and qemu-fast)
+ - shm syscalls support (Paul McKerras)
+ - added accurate CR0.MP/ME/TS emulation
+ - fixed DMA memory write access (Win95 boot floppy fix)
+ - graphical x86 linux loader
+ - command line monitor
+ - generic removable device support
+ - support of CD-ROM change
+ - multiple network interface support
+ - initial x86-64 host support (Gwenole Beauchesne)
+ - lret to outer priviledge fix (OS/2 install fix)
+ - task switch fixes (SkyOS boot)
+ - VM save/restore commands
+ - new timer API
+ - more precise RTC emulation (periodic timers + time updates)
+ - Win32 port (initial patch by Kazu)
+
+version 0.5.2:
+
+ - improved soft MMU speed (assembly functions and specializing)
+ - improved multitasking speed by avoiding flushing TBs when
+ switching tasks
+ - improved qemu-fast speed
+ - improved self modifying code handling (big performance gain in
+ softmmu mode).
+ - fixed IO checking
+ - fixed CD-ROM detection (win98 install CD)
+ - fixed addseg real mode bug (GRUB boot fix)
+ - added ROM memory support (win98 boot)
+ - fixed 'call Ev' in case of paging exception
+ - updated the script 'qemu-binfmt-conf.sh' to use QEMU automagically
+ when launching executables for the supported target CPUs.
+ - PowerPC system emulation update (Jocelyn Mayer)
+ - PC floppy emulation and DMA fixes (Jocelyn Mayer)
+ - polled mode for PIC (Jocelyn Mayer)
+ - fixed PTE dirty bit handling
+ - fixed xadd same reg bug
+ - fixed cmpxchg exception safeness
+ - access to virtual memory in gdb stub
+ - task gate and NT flag fixes
+ - eflags optimisation fix for string operations
+
+version 0.5.1:
+
+ - float access fixes when using soft mmu
+ - PC emulation support on PowerPC
+ - A20 support
+ - IDE CD-ROM emulation
+ - ARM fixes (Ulrich Hecht)
+ - SB16 emulation (malc)
+ - IRET and INT fixes in VM86 mode with IOPL=3
+ - Port I/Os use TSS io map
+ - Full task switching/task gate support
+ - added verr, verw, arpl, fcmovxx
+ - PowerPC target support (Jocelyn Mayer)
+ - Major SPARC target fixes (dynamically linked programs begin to work)
+
+version 0.5.0:
+
+ - full hardware level VGA emulation
+ - graphical display with SDL
+ - added PS/2 mouse and keyboard emulation
+ - popw (%esp) fix
+ - mov to/from segment data width fix
+ - added real mode support
+ - added Bochs BIOS and LGPL'ed VGA BIOS loader in qemu
+ - m68k host port (Richard Zidlicky)
+ - partial soft MMU support for memory mapped I/Os
+ - multi-target build
+ - fixed: no error code in hardware interrupts
+ - fixed: pop ss, mov ss, x and sti disable hardware irqs for the next insn
+ - correct single stepping thru string operations
+ - preliminary SPARC target support (Thomas M. Ogrisegg)
+ - tun-fd option (Rusty Russell)
+ - automatic IDE geometry detection
+ - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}.
+ - added man page
+ - added full soft mmu mode to launch unpatched OSes.
+
+version 0.4.3:
+
+ - x86 exception fix in case of nop instruction.
+ - gcc 3.2.2 bug workaround (RedHat 9 fix)
+ - sparc and Alpha host fixes
+ - many ARM target fixes: 'ls' and 'bash' can be launched.
+
+version 0.4.2:
+
+ - many exception handling fixes (can compile a Linux kernel inside vl)
+ - IDE emulation support
+ - initial GDB stub support
+ - deferred update support for disk images (Rusty Russell)
+ - accept User Mode Linux Copy On Write disk images
+ - SMP kernels can at least be booted
+
+version 0.4.1:
+
+ - more accurate timer support in vl.
+ - more reliable NE2000 probe in vl.
+ - added 2.5.66 kernel in vl-test.
+ - added VLTMPDIR environment variable in vl.
+
+version 0.4:
+
+ - initial support for ring 0 x86 processor emulation
+ - fixed signal handling for correct dosemu DPMI emulation
+ - fast x86 MMU emulation with mmap()
+ - fixed popl (%esp) case
+ - Linux kernel can be executed by QEMU with the 'vl' command.
+
+version 0.3:
+
+ - initial support for ARM emulation
+ - added fnsave, frstor, fnstenv, fldenv FPU instructions
+ - added FPU register save in signal emulation
+ - initial ARM port
+ - Sparc and Alpha ports work on the regression test
+ - generic ioctl number conversion
+ - fixed ioctl type conversion
+
+version 0.2:
+
+ - PowerPC disassembly and ELF symbols output (Rusty Russell)
+ - flock support (Rusty Russell)
+ - ugetrlimit support (Rusty Russell)
+ - fstat64 fix (Rusty Russell)
+ - initial Alpha port (Falk Hueffner)
+ - initial IA64 port (Matt Wilson)
+ - initial Sparc and Sparc64 port (David S. Miller)
+ - added HLT instruction
+ - LRET instruction fix.
+ - added GPF generation for I/Os.
+ - added INT3 and TF flag support.
+ - SHL instruction C flag fix.
+ - mmap emulation for host page size > 4KB
+ - self-modifying code support
+ - better VM86 support (dosemu works on non trivial programs)
+ - precise exception support (EIP is computed correctly in most cases)
+ - more precise LDT/GDT/IDT emulation
+ - faster segment load in vm86 mode
+ - direct chaining of basic blocks (faster emulation)
+
+version 0.1.6:
+
+ - automatic library search system. QEMU can now work with unpatched
+ ELF dynamic loader and libc (Rusty Russell).
+ - ISO C warning fixes (Alistair Strachan)
+ - first self-virtualizable version (works only as long as the
+ translation cache is not flushed)
+ - RH9 fixes
+
+version 0.1.5:
+
+ - ppc64 support + personality() patch (Rusty Russell)
+ - first Alpha CPU patches (Falk Hueffner)
+ - removed bfd.h dependancy
+ - fixed shrd, shld, idivl and divl on PowerPC.
+ - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
+
+version 0.1.4:
+
+ - more accurate VM86 emulation (can launch small DOS 16 bit
+ executables in wine).
+ - fixed push/pop fs/gs
+ - added iret instruction.
+ - added times() syscall and SIOCATMARK ioctl.
+
+version 0.1.3:
+
+ - S390 support (Ulrich Weigand)
+ - glibc 2.3.x compile fix (Ulrich Weigand)
+ - socketcall endian fix (Ulrich Weigand)
+ - struct sockaddr endian fix (Ulrich Weigand)
+ - sendmsg/recvmsg endian fix (Ulrich Weigand)
+ - execve endian fix (Ulrich Weigand)
+ - fdset endian fix (Ulrich Weigand)
+ - partial setsockopt syscall support (Ulrich Weigand)
+ - more accurate pushf/popf emulation
+ - first partial vm86() syscall support (can be used with runcom example).
+ - added bound, cmpxchg8b, cpuid instructions
+ - added 16 bit addressing support/override for string operations
+ - poll() fix
+
+version 0.1.2:
+
+ - compile fixes
+ - xlat instruction
+ - xchg instruction memory lock
+ - added simple vm86 example (not working with QEMU yet). The 54 byte
+ DOS executable 'pi_10.com' program was released by Bertram
+ Felgenhauer (more information at http://www.boo.net/~jasonp/pipage.html).
+
+version 0.1.1:
+
+ - glibc 2.2 compilation fixes
+ - added -s and -L options
+ - binary distribution of x86 glibc and wine
+ - big endian fixes in ELF loader and getdents.
+
+version 0.1:
+
+ - initial public release.
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/LICENSE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/LICENSE Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,12 @@
+The following points clarify the QEMU licenses:
+
+1) The QEMU virtual CPU core library (libqemu.a) and the QEMU PC
+ system emulator are released under the GNU Lesser General Public
+ License.
+
+2) The Linux user mode QEMU emulator is released under the GNU General
+ Public License.
+
+3) QEMU is a trademark of Fabrice Bellard.
+
+Fabrice Bellard.
\ No newline at end of file
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/Makefile Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,149 @@
+XEN_ROOT=../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+include config-host.mak
+
+CFLAGS+=-Wall -O2 -g -fno-strict-aliasing -I.
+ifdef CONFIG_DARWIN
+CFLAGS+= -mdynamic-no-pic
+endif
+LDFLAGS=-g
+LIBS=
+DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+TOOLS=qemu-img$(EXESUF)
+ifdef CONFIG_STATIC
+LDFLAGS+=-static
+endif
+ifdef BUILD_DOCS
+DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1
+else
+DOCS=
+endif
+
+all: $(DOCS)
+ for d in $(TARGET_DIRS); do \
+ $(MAKE) -C $$d $@ || exit 1 ; \
+ done
+
+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)
+
+dyngen$(EXESUF): dyngen.c
+ $(HOST_CC) $(CFLAGS) $(DEFINES) -o $@ $^
+
+clean:
+# avoid old build problems by removing potentially incorrect old files
+ rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h
opc-arm.h gen-op-arm.h
+ rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
+ $(MAKE) -C tests clean
+ for d in $(TARGET_DIRS); do \
+ $(MAKE) -C $$d $@ || exit 1 ; \
+ done
+
+distclean: clean
+ rm -f config-host.mak config-host.h $(DOCS)
+ for d in $(TARGET_DIRS); do \
+ rm -rf $$d || exit 1 ; \
+ done
+
+KEYMAPS=da en-gb et fr fr-ch is lt modifiers no pt-br sv \
+ar de en-us fi fr-be hr it lv nl pl ru th \
+common de-ch es fo fr-ca hu ja mk nl-be pt sl tr
+
+install-doc: $(DOCS)
+ mkdir -p "$(DESTDIR)$(docdir)"
+ $(INSTALL) -m 644 qemu-doc.html qemu-tech.html "$(DESTDIR)$(docdir)"
+ifndef CONFIG_WIN32
+ mkdir -p "$(DESTDIR)$(mandir)/man1"
+ $(INSTALL) qemu.1 qemu-img.1 "$(DESTDIR)$(mandir)/man1"
+endif
+
+install: all $(if $(BUILD_DOCS),install-doc)
+ mkdir -p "$(DESTDIR)$(bindir)"
+# $(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 \
+# $(INSTALL) -m 644 $(SRC_PATH)/pc-bios/$$x
"$(DESTDIR)$(datadir)"; \
+# done
+ifndef CONFIG_WIN32
+ mkdir -p "$(DESTDIR)$(datadir)/keymaps"
+ for x in $(KEYMAPS); do \
+ $(INSTALL) -m 644 $(SRC_PATH)/keymaps/$$x
"$(DESTDIR)$(datadir)/keymaps"; \
+ done
+endif
+ for d in $(TARGET_DIRS); do \
+ $(MAKE) -C $$d $@ || exit 1 ; \
+ done
+
+# various test targets
+test speed test2: all
+ $(MAKE) -C tests $@
+
+TAGS:
+ etags *.[ch] tests/*.[ch]
+
+cscope:
+ rm -f ./cscope.*
+ find . -name "*.[ch]" -print > ./cscope.files
+ cscope -b
+
+# documentation
+%.html: %.texi
+ texi2html -monolithic -number $<
+
+%.info: %.texi
+ makeinfo $< -o $@
+
+%.dvi: %.texi
+ texi2dvi $<
+
+qemu.1: qemu-doc.texi
+ perl -w $(SRC_PATH)/texi2pod.pl $< qemu.pod
+ pod2man --section=1 --center=" " --release=" " qemu.pod > $@
+
+qemu-img.1: qemu-img.texi
+ perl -w $(SRC_PATH)/texi2pod.pl $< qemu-img.pod
+ pod2man --section=1 --center=" " --release=" " qemu-img.pod > $@
+
+FILE=qemu-$(shell cat VERSION)
+
+# tar release (use 'make -k tar' on a checkouted tree)
+tar:
+ rm -rf /tmp/$(FILE)
+ cp -r . /tmp/$(FILE)
+ ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS )
+ rm -rf /tmp/$(FILE)
+
+# generate a binary distribution
+tarbin:
+ ( cd / ; tar zcvf ~/qemu-$(VERSION)-i386.tar.gz \
+ $(bindir)/qemu \
+ $(bindir)/qemu-system-ppc \
+ $(bindir)/qemu-system-sparc \
+ $(bindir)/qemu-system-x86_64 \
+ $(bindir)/qemu-system-mips \
+ $(bindir)/qemu-system-mipsel \
+ $(bindir)/qemu-system-arm \
+ $(bindir)/qemu-i386 \
+ $(bindir)/qemu-arm \
+ $(bindir)/qemu-armeb \
+ $(bindir)/qemu-sparc \
+ $(bindir)/qemu-ppc \
+ $(bindir)/qemu-mips \
+ $(bindir)/qemu-mipsel \
+ $(bindir)/qemu-img \
+ $(datadir)/bios.bin \
+ $(datadir)/vgabios.bin \
+ $(datadir)/vgabios-cirrus.bin \
+ $(datadir)/ppc_rom.bin \
+ $(datadir)/video.x \
+ $(datadir)/proll.elf \
+ $(datadir)/linux_boot.bin \
+ $(docdir)/qemu-doc.html \
+ $(docdir)/qemu-tech.html \
+ $(mandir)/man1/qemu.1 $(mandir)/man1/qemu-img.1 )
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/Makefile.target
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/Makefile.target Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,531 @@
+include config.mak
+
+XEN_ROOT=../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+TARGET_BASE_ARCH:=$(TARGET_ARCH)
+ifeq ($(TARGET_ARCH), x86_64)
+TARGET_BASE_ARCH:=i386
+endif
+ifeq ($(TARGET_ARCH), ppc64)
+TARGET_BASE_ARCH:=ppc
+endif
+ifeq ($(TARGET_ARCH), sparc64)
+TARGET_BASE_ARCH:=sparc
+endif
+TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)$(TARGET_SUB)
+VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
+DEFINES=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
+DEFINES+= -I$(XEN_ROOT)/tools/libxc
+DEFINES+= -I$(XEN_ROOT)/tools/xenstore
+ifdef CONFIG_USER_ONLY
+VPATH+=:$(SRC_PATH)/linux-user
+DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
+endif
+CFLAGS+=-Wall -O2 -g -fno-strict-aliasing
+SSE2 := $(call test-gcc-flag,$(CC),-msse2)
+ifeq ($(SSE2),-msse2)
+CFLAGS += -DUSE_SSE2=1 -msse2
+endif
+CFLAGS+= $(LOCAL_CFLAGS)
+#CFLAGS+=-Werror
+LDFLAGS=-g
+LIBS=
+HELPER_CFLAGS=$(CFLAGS)
+DYNGEN=../dyngen$(EXESUF)
+# user emulator name
+TARGET_ARCH2=$(TARGET_ARCH)
+ifeq ($(TARGET_ARCH),arm)
+ ifeq ($(TARGET_WORDS_BIGENDIAN),yes)
+ TARGET_ARCH2=armeb
+ endif
+endif
+ifeq ($(TARGET_ARCH),mips)
+ ifneq ($(TARGET_WORDS_BIGENDIAN),yes)
+ TARGET_ARCH2=mipsel
+ endif
+endif
+QEMU_USER=qemu-$(TARGET_ARCH2)
+# system emulator name
+ifdef CONFIG_SOFTMMU
+ifeq ($(TARGET_ARCH), i386)
+QEMU_SYSTEM=qemu$(EXESUF)
+else
+QEMU_SYSTEM=qemu-system-$(TARGET_ARCH2)$(EXESUF)
+endif
+else
+QEMU_SYSTEM=qemu-fast
+endif
+
+QEMU_SYSTEM=qemu-dm
+
+ifdef CONFIG_USER_ONLY
+PROGS=$(QEMU_USER)
+else
+PROGS+=$(QEMU_SYSTEM)
+ifndef CONFIG_SOFTMMU
+CONFIG_STATIC=y
+endif
+endif # !CONFIG_USER_ONLY
+
+ifdef CONFIG_STATIC
+LDFLAGS+=-static
+endif
+
+ifeq ($(ARCH),i386)
+CFLAGS+=-fomit-frame-pointer
+OP_CFLAGS=$(CFLAGS) -mpreferred-stack-boundary=2
+ifeq ($(HAVE_GCC3_OPTIONS),yes)
+OP_CFLAGS+= -falign-functions=0 -fno-gcse
+else
+OP_CFLAGS+= -malign-functions=0
+endif
+
+ifdef TARGET_GPROF
+USE_I386_LD=y
+endif
+ifdef CONFIG_STATIC
+USE_I386_LD=y
+endif
+ifdef USE_I386_LD
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386.ld
+else
+# WARNING: this LDFLAGS is _very_ tricky : qemu is an ELF shared object
+# that the kernel ELF loader considers as an executable. I think this
+# is the simplest way to make it self virtualizable!
+LDFLAGS+=-Wl,-shared
+endif
+endif
+
+ifeq ($(ARCH),x86_64)
+OP_CFLAGS=$(CFLAGS) -falign-functions=0
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/x86_64.ld
+endif
+
+ifeq ($(ARCH),ppc)
+CFLAGS+= -D__powerpc__
+OP_CFLAGS=$(CFLAGS)
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld
+endif
+
+ifeq ($(ARCH),s390)
+OP_CFLAGS=$(CFLAGS)
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/s390.ld
+endif
+
+ifeq ($(ARCH),sparc)
+CFLAGS+=-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
+
+ifeq ($(ARCH),sparc64)
+CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
+LDFLAGS+=-m64
+OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
+endif
+
+ifeq ($(ARCH),alpha)
+# -msmall-data is not used because we want two-instruction relocations
+# for the constant constructions
+OP_CFLAGS=-Wall -O2 -g
+# Ensure there's only a single GP
+CFLAGS += -msmall-data
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/alpha.ld
+endif
+
+ifeq ($(ARCH),ia64)
+CFLAGS += -mno-sdata
+OP_CFLAGS=$(CFLAGS)
+LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld
+endif
+
+ifeq ($(ARCH),arm)
+OP_CFLAGS=$(CFLAGS) -mno-sched-prolog -fno-omit-frame-pointer
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/arm.ld
+endif
+
+ifeq ($(ARCH),m68k)
+OP_CFLAGS=$(CFLAGS) -fomit-frame-pointer
+LDFLAGS+=-Wl,-T,m68k.ld
+endif
+
+ifeq ($(HAVE_GCC3_OPTIONS),yes)
+# very important to generate a return at the end of every operation
+OP_CFLAGS+=-fno-reorder-blocks -fno-optimize-sibling-calls
+endif
+
+ifeq ($(CONFIG_DARWIN),yes)
+OP_CFLAGS+= -mdynamic-no-pic
+LIBS+=-lmx
+endif
+
+#########################################################
+
+DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+LIBS+=-lm
+LIBS+=-L../../libxc -lxenctrl -lxenguest
+LIBS+=-L../../xenstore -lxenstore
+LIBS+=-lpthread
+ifndef CONFIG_USER_ONLY
+LIBS+=-lz
+endif
+ifdef CONFIG_WIN32
+LIBS+=-lwinmm -lws2_32 -liphlpapi
+endif
+ifdef CONFIG_SOLARIS
+LIBS+=-lsocket -lnsl -lresolv
+endif
+
+# profiling code
+ifdef TARGET_GPROF
+LDFLAGS+=-p
+main.o: CFLAGS+=-p
+endif
+
+OBJS= elfload.o main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o
+ifeq ($(TARGET_ARCH), i386)
+OBJS+= vm86.o
+endif
+ifeq ($(TARGET_ARCH), arm)
+OBJS+=nwfpe/fpa11.o nwfpe/fpa11_cpdo.o \
+nwfpe/fpa11_cpdt.o nwfpe/fpa11_cprt.o nwfpe/fpopcode.o nwfpe/single_cpdo.o \
+ nwfpe/double_cpdo.o nwfpe/extended_cpdo.o arm-semi.o
+endif
+SRCS:= $(OBJS:.o=.c)
+OBJS+= libqemu.a
+
+# cpu emulator library
+LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
+ translate.o op.o
+ifdef CONFIG_SOFTFLOAT
+LIBOBJS+=fpu/softfloat.o
+else
+LIBOBJS+=fpu/softfloat-native.o
+endif
+DEFINES+=-I$(SRC_PATH)/fpu
+
+ifeq ($(TARGET_ARCH), i386)
+LIBOBJS+=helper.o helper2.o
+ifeq ($(ARCH), i386)
+LIBOBJS+=translate-copy.o
+endif
+endif
+
+ifeq ($(TARGET_ARCH), x86_64)
+LIBOBJS+=helper.o helper2.o
+endif
+
+ifeq ($(TARGET_BASE_ARCH), ppc)
+LIBOBJS+= op_helper.o helper.o
+endif
+
+ifeq ($(TARGET_ARCH), mips)
+LIBOBJS+= op_helper.o helper.o
+endif
+
+ifeq ($(TARGET_BASE_ARCH), sparc)
+LIBOBJS+= op_helper.o helper.o
+endif
+
+ifeq ($(TARGET_BASE_ARCH), arm)
+LIBOBJS+= op_helper.o helper.o
+endif
+
+ifeq ($(TARGET_BASE_ARCH), sh4)
+LIBOBJS+= op_helper.o helper.o
+endif
+
+# NOTE: the disassembler code is only needed for debugging
+LIBOBJS+=disas.o
+ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
+USE_I386_DIS=y
+endif
+ifeq ($(findstring x86_64, $(TARGET_ARCH) $(ARCH)),x86_64)
+USE_I386_DIS=y
+endif
+ifdef USE_I386_DIS
+LIBOBJS+=i386-dis.o
+endif
+ifeq ($(findstring alpha, $(TARGET_ARCH) $(ARCH)),alpha)
+LIBOBJS+=alpha-dis.o
+endif
+ifeq ($(findstring ppc, $(TARGET_BASE_ARCH) $(ARCH)),ppc)
+LIBOBJS+=ppc-dis.o
+endif
+ifeq ($(findstring mips, $(TARGET_ARCH) $(ARCH)),mips)
+LIBOBJS+=mips-dis.o
+endif
+ifeq ($(findstring sparc, $(TARGET_BASE_ARCH) $(ARCH)),sparc)
+LIBOBJS+=sparc-dis.o
+endif
+ifeq ($(findstring arm, $(TARGET_ARCH) $(ARCH)),arm)
+LIBOBJS+=arm-dis.o
+endif
+ifeq ($(findstring m68k, $(TARGET_ARCH) $(ARCH)),m68k)
+LIBOBJS+=m68k-dis.o
+endif
+ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4)
+LIBOBJS+=sh4-dis.o
+endif
+
+ifdef CONFIG_GDBSTUB
+OBJS+=gdbstub.o
+endif
+
+# qemu-dm objects
+LIBOBJS=helper2.o exec-dm.o i8259-dm.o
+
+all: $(PROGS)
+
+$(QEMU_USER): $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+ifeq ($(ARCH),alpha)
+# Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
+# the address space (31 bit so sign extending doesn't matter)
+ echo -ne '\001\000\000\000' | dd of=qemu bs=1 seek=48 count=4
conv=notrunc
+endif
+
+# must use static linking to avoid leaving stuff in virtual address space
+VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o
+VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o
block-bochs.o block-vpc.o block-vvfat.o
+ifdef CONFIG_WIN32
+VL_OBJS+=tap-win32.o
+endif
+
+SOUND_HW = sb16.o es1370.o
+AUDIODRV = audio.o noaudio.o wavaudio.o
+ifdef CONFIG_SDL
+AUDIODRV += sdlaudio.o
+endif
+ifdef CONFIG_OSS
+AUDIODRV += ossaudio.o
+endif
+ifdef CONFIG_COREAUDIO
+AUDIODRV += coreaudio.o
+endif
+ifdef CONFIG_ALSA
+AUDIODRV += alsaaudio.o
+LIBS += -lasound
+endif
+ifdef CONFIG_DSOUND
+AUDIODRV += dsoundaudio.o
+LIBS += -lole32 -ldxguid
+endif
+ifdef CONFIG_FMOD
+AUDIODRV += fmodaudio.o
+audio.o fmodaudio.o: DEFINES := -I$(CONFIG_FMOD_INC) $(DEFINES)
+LIBS += $(CONFIG_FMOD_LIB)
+endif
+ifdef CONFIG_ADLIB
+SOUND_HW += fmopl.o adlib.o
+endif
+
+# USB layer
+VL_OBJS+= usb.o usb-hub.o usb-uhci.o usb-linux.o usb-hid.o
+
+# PCI network cards
+VL_OBJS+= ne2000.o rtl8139.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+= piix4acpi.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
+DEFINES += -DHAS_AUDIO
+endif
+ifeq ($(TARGET_ARCH), mips)
+VL_OBJS+= mips_r4k.o dma.o vga.o serial.o i8254.o i8259.o
+#VL_OBJS+= #ide.o pckbd.o fdc.o m48t59.o
+endif
+ifeq ($(TARGET_BASE_ARCH), sparc)
+ifeq ($(TARGET_ARCH), sparc64)
+VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o
+VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o
+VL_OBJS+= cirrus_vga.o parallel.o
+else
+VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t59.o slavio_intctl.o
+VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o
+endif
+endif
+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
+endif
+ifeq ($(TARGET_BASE_ARCH), sh4)
+VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
+endif
+ifdef CONFIG_GDBSTUB
+VL_OBJS+=gdbstub.o
+endif
+ifdef CONFIG_SDL
+VL_OBJS+=sdl.o
+endif
+VL_OBJS+=vnc.o
+ifdef CONFIG_COCOA
+VL_OBJS+=cocoa.o
+COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework IOKit
+ifdef CONFIG_COREAUDIO
+COCOA_LIBS+=-framework CoreAudio
+endif
+endif
+ifdef CONFIG_SLIRP
+DEFINES+=-I$(SRC_PATH)/slirp
+SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
+slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o \
+tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
+VL_OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
+endif
+
+VL_LDFLAGS=
+# specific flags are needed for non soft mmu emulator
+ifdef CONFIG_STATIC
+VL_LDFLAGS+=-static
+endif
+ifndef CONFIG_SOFTMMU
+VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386-vl.ld
+endif
+ifndef CONFIG_DARWIN
+ifndef CONFIG_WIN32
+ifndef CONFIG_SOLARIS
+VL_LIBS=-lutil
+endif
+endif
+endif
+ifdef TARGET_GPROF
+vl.o: CFLAGS+=-p
+VL_LDFLAGS+=-p
+endif
+
+ifeq ($(ARCH),ia64)
+VL_LDFLAGS+=-Wl,-G0 -Wl,-T,$(SRC_PATH)/ia64.ld
+endif
+
+ifdef CONFIG_WIN32
+SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole
+endif
+
+$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
+ $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS)
$(VL_LIBS)
+
+cocoa.o: cocoa.m
+ $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
+
+sdl.o: sdl.c keymaps.c sdl_keysym.h
+ $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
+
+vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h
+ $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
+
+sdlaudio.o: sdlaudio.c
+ $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
+
+depend: $(SRCS)
+ $(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend
+
+vldepend: $(VL_OBJS:.o=.c)
+ $(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend
+
+# libqemu
+
+libqemu.a: $(LIBOBJS)
+ rm -f $@
+ $(AR) rcs $@ $(LIBOBJS)
+
+translate.o: translate.c gen-op.h opc.h cpu.h
+
+translate-all.o: translate-all.c opc.h cpu.h
+
+translate-op.o: translate-all.c op.h opc.h cpu.h
+
+op.h: op.o $(DYNGEN)
+ $(DYNGEN) -o $@ $<
+
+opc.h: op.o $(DYNGEN)
+ $(DYNGEN) -c -o $@ $<
+
+gen-op.h: op.o $(DYNGEN)
+ $(DYNGEN) -g -o $@ $<
+
+op.o: op.c
+ $(CC) $(OP_CFLAGS) $(DEFINES) -c -o $@ $<
+
+helper.o: helper.c
+ $(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
+
+ifeq ($(TARGET_BASE_ARCH), i386)
+op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h
ops_sse.h
+endif
+
+ifeq ($(TARGET_ARCH), arm)
+op.o: op.c op_template.h
+pl110.o: pl110_template.h
+endif
+
+ifeq ($(TARGET_BASE_ARCH), sparc)
+op.o: op.c op_template.h op_mem.h fop_template.h fbranch_template.h
+magic_load.o: elf_op.h
+endif
+
+ifeq ($(TARGET_BASE_ARCH), ppc)
+op.o: op.c op_template.h op_mem.h
+op_helper.o: op_helper_mem.h
+translate.o: translate.c translate_init.c
+endif
+
+ifeq ($(TARGET_ARCH), mips)
+op.o: op.c op_template.c op_mem.c
+op_helper.o: op_helper_mem.c
+endif
+
+loader.o: loader.c elf_ops.h
+
+ifeq ($(TARGET_ARCH), sh4)
+op.o: op.c op_mem.c cpu.h
+op_helper.o: op_helper.c exec.h cpu.h
+helper.o: helper.c exec.h cpu.h
+sh7750.o: sh7750.c sh7750_regs.h sh7750_regnames.h cpu.h
+shix.o: shix.c sh7750_regs.h sh7750_regnames.h
+sh7750_regnames.o: sh7750_regnames.c sh7750_regnames.h sh7750_regs.h
+tc58128.o: tc58128.c
+endif
+
+%.o: %.c
+ $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
+
+%.o: %.S
+ $(CC) $(DEFINES) -c -o $@ $<
+
+clean:
+ rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o slirp/*.o
fpu/*.o
+
+distclean: clean
+ rm -rf config.mak config.h
+
+install: all
+ mkdir -p "$(DESTDIR)$(bindir)" "$(DESTDIR)$(configdir)"
+ifneq ($(PROGS),)
+ $(INSTALL) -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)"
+endif
+ install -m 755 $(TARGET_PATH)/qemu-dm.debug "$(DESTDIR)$(bindir)"
+ install -m 755 $(TARGET_PATH)/qemu-ifup "$(DESTDIR)$(configdir)"
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
+
+ifeq (1, 0)
+audio.o sdlaudio.o dsoundaudio.o ossaudio.o wavaudio.o noaudio.o \
+fmodaudio.o alsaaudio.o mixeng.o sb16.o es1370.o gus.o adlib.o: \
+CFLAGS := $(CFLAGS) -Wall -Werror -W -Wsign-compare
+endif
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/README
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/README Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,3 @@
+Read the documentation in qemu-doc.html.
+
+Fabrice Bellard.
\ No newline at end of file
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/README.distrib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/README.distrib Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,16 @@
+Information about the various packages used to build the current qemu
+x86 binary distribution:
+
+* gcc 2.95.2 was used for the build. A glibc 2.1.3 Debian distribution
+ was used to get most of the binary packages.
+
+* wine-20020411 tarball
+
+ ./configure --prefix=/usr/local/wine-i386
+
+ All exe and libs were stripped. Some compile time tools and the
+ includes were deleted.
+
+* ldconfig was launched to build the library links:
+
+ qemu-i386 /usr/gnemul/qemu-i386/bin/ldconfig-i386 -C
/usr/gnemul/qemu-i386/etc/ld.so.cache
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/TODO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/TODO Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,61 @@
+short term:
+----------
+- 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)
+- see undefined flags for BTx insn
+- user/kernel PUSHL/POPL in helper.c
+- keyboard output buffer filling timing emulation
+- return UD exception if LOCK prefix incorrectly used
+- test ldt limit < 7 ?
+- tests for each target CPU
+- 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:
+-------------------
+- add IPC syscalls
+- handle rare page fault cases (in particular if page fault in helpers or
+ in syscall emulation code).
+- more syscalls (in particular all 64 bit ones, IPCs, fix 64 bit
+ issues, fix 16 bit uid issues)
+- use page_unprotect_range in every suitable syscall to handle all
+ cases of self modifying code.
+- fix thread stack freeing (use kernel 2.5.x CLONE_CHILD_CLEARTID)
+- use kernel traps for unaligned accesses on ARM ?
+
+
+lower priority:
+--------------
+- int15 ah=86: use better timing
+- suppress shift_mem ops
+- fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret)
+- optimize FPU operations (evaluate x87 stack pointer statically)
+- use -msoft-float on ARM
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/VERSION
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/VERSION Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1 @@
+0.8.1
\ No newline at end of file
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/a.out.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/a.out.h Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,431 @@
+/* a.out.h
+
+ Copyright 1997, 1998, 1999, 2001 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#ifndef _A_OUT_H_
+#define _A_OUT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define COFF_IMAGE_WITH_PE
+#define COFF_LONG_SECTION_NAMES
+
+/*** coff information for Intel 386/486. */
+
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ short f_magic; /* magic number */
+ short f_nscns; /* number of sections */
+ unsigned long f_timdat; /* time & date stamp */
+ unsigned long f_symptr; /* file pointer to symtab */
+ unsigned long f_nsyms; /* number of symtab entries */
+ short f_opthdr; /* sizeof(optional hdr) */
+ short f_flags; /* flags */
+};
+
+/* Bits for f_flags:
+ * F_RELFLG relocation info stripped from file
+ * F_EXEC file is executable (no unresolved external references)
+ * F_LNNO line numbers stripped from file
+ * F_LSYMS local symbols stripped from file
+ * F_AR32WR file has byte ordering of an AR32WR machine (e.g. vax)
+ */
+
+#define F_RELFLG (0x0001)
+#define F_EXEC (0x0002)
+#define F_LNNO (0x0004)
+#define F_LSYMS (0x0008)
+
+
+
+#define I386MAGIC 0x14c
+#define I386PTXMAGIC 0x154
+#define I386AIXMAGIC 0x175
+
+/* This is Lynx's all-platform magic number for executables. */
+
+#define LYNXCOFFMAGIC 0415
+
+#define I386BADMAG(x) (((x).f_magic != I386MAGIC) \
+ && (x).f_magic != I386AIXMAGIC \
+ && (x).f_magic != I386PTXMAGIC \
+ && (x).f_magic != LYNXCOFFMAGIC)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER"=
+ **********************/
+
+
+typedef struct
+{
+ unsigned short magic; /* type of file
*/
+ unsigned short vstamp; /* version stamp */
+ unsigned long tsize; /* text size in bytes, padded to FW
bdry*/
+ unsigned long dsize; /* initialized data " "
*/
+ unsigned long bsize; /* uninitialized data " "
*/
+ unsigned long entry; /* entry pt.
*/
+ unsigned long text_start; /* base of text used for this file */
+ unsigned long data_start; /* base of data used for this file=
+ */
+}
+AOUTHDR;
+
+#define AOUTSZ 28
+#define AOUTHDRSZ 28
+
+#define OMAGIC 0404 /* object files, eg as output */
+#define ZMAGIC 0413 /* demand load format, eg normal ld output */
+#define STMAGIC 0401 /* target shlib */
+#define SHMAGIC 0443 /* host shlib */
+
+
+/* define some NT default values */
+/* #define NT_IMAGE_BASE 0x400000 moved to internal.h */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT 0x200
+#define NT_DEF_RESERVE 0x100000
+#define NT_DEF_COMMIT 0x1000
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ unsigned long s_paddr; /* physical address, offset
+ of last addr in scn */
+ unsigned long s_vaddr; /* virtual address */
+ unsigned long s_size; /* section size */
+ unsigned long s_scnptr; /* file ptr to raw data for section */
+ unsigned long s_relptr; /* file ptr to relocation */
+ unsigned long s_lnnoptr; /* file ptr to line numbers */
+ unsigned short s_nreloc; /* number of relocation entries */
+ unsigned short s_nlnno; /* number of line number entries*/
+ unsigned long s_flags; /* flags */
+};
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _COMMENT ".comment"
+#define _LIB ".lib"
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ unsigned long l_symndx; /* function name symbol index, iff l_lnno 0 */
+ unsigned long l_paddr; /* (physical) address of line number */
+ } l_addr;
+ unsigned short l_lnno; /* line number */
+};
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct __attribute__((packed)) external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ unsigned long e_zeroes;
+ unsigned long e_offset;
+ } e;
+ } e;
+ unsigned long e_value;
+ unsigned short e_scnum;
+ unsigned short e_type;
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+#define N_BTMASK (0xf)
+#define N_TMASK (0x30)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+union external_auxent {
+ struct {
+ unsigned long x_tagndx; /* str, un, or enum tag indx */
+ union {
+ struct {
+ unsigned short x_lnno; /* declaration line number */
+ unsigned short x_size; /* str/union/array size */
+ } x_lnsz;
+ unsigned long x_fsize; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ unsigned long x_lnnoptr;/* ptr to fcn line # */
+ unsigned long x_endndx; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ unsigned short x_tvndx; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ unsigned long x_zeroes;
+ unsigned long x_offset;
+ } x_n;
+ } x_file;
+
+ struct {
+ unsigned long x_scnlen; /* section length */
+ unsigned short x_nreloc; /* # relocation entries */
+ unsigned short x_nlinno; /* # line numbers */
+ unsigned long x_checksum; /* section COMDAT checksum */
+ unsigned short x_associated;/* COMDAT associated section index */
+ char x_comdat[1]; /* COMDAT selection number */
+ } x_scn;
+
+ struct {
+ unsigned long x_tvfill; /* tv fill value */
+ unsigned short x_tvlen; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+
+#define _ETEXT "etext"
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_type[2];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+/* end of coff/i386.h */
+
+/* PE COFF header information */
+
+#ifndef _PE_H
+#define _PE_H
+
+/* NT specific file attributes */
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+/* additional flags to be set for section headers to allow the NT loader to
+ read and write to the section data (to replace the addresses of data in
+ dlls for one thing); also to execute the section in .text's case=
+ */
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+/*
+ * Section characteristics added for ppc-nt
+ */
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved. */
+
+#define IMAGE_SCN_CNT_CODE 0x00000020 /* Section contains
code. */
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* Section contains
initialized data. */
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* Section contains
uninitialized data. */
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100 /* Reserved. */
+#define IMAGE_SCN_LNK_INFO 0x00000200 /* Section contains
comments or some other type of information. */
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* Section contents
will not become part of image. */
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* Section contents
comdat. */
+
+#define IMAGE_SCN_MEM_FARDATA 0x00008000
+
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default alignment
if no others are specified. */
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+
+
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* Section contains
extended relocations. */
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* Section is not
cachable. */
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* Section is not
pageable. */
+#define IMAGE_SCN_MEM_SHARED 0x10000000 /* Section is
shareable. */
+
+/* COMDAT selection codes. */
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES (1) /* Warn if duplicates. */
+#define IMAGE_COMDAT_SELECT_ANY (2) /* No warning. */
+#define IMAGE_COMDAT_SELECT_SAME_SIZE (3) /* Warn if different size. */
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH (4) /* Warn if different.
*/
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE (5) /* Base on other
section. */
+
+/* Magic values that are true for all dos/nt implementations */
+#define DOSMAGIC 0x5a4d
+#define NT_SIGNATURE 0x00004550
+
+/* NT allows long filenames, we want to accommodate this. This may break
+ some of the bfd functions */
+#undef FILNMLEN
+#define FILNMLEN 18 /* # characters in a file name */
+
+
+#ifdef COFF_IMAGE_WITH_PE
+/* The filehdr is only weired in images */
+
+#undef FILHDR
+struct external_PE_filehdr
+{
+ /* DOS header fields */
+ unsigned short e_magic; /* Magic number, 0x5a4d */
+ unsigned short e_cblp; /* Bytes on last page of file, 0x90 */
+ unsigned short e_cp; /* Pages in file, 0x3 */
+ unsigned short e_crlc; /* Relocations, 0x0 */
+ unsigned short e_cparhdr; /* Size of header in paragraphs, 0x4 */
+ unsigned short e_minalloc; /* Minimum extra paragraphs needed, 0x0 */
+ unsigned short e_maxalloc; /* Maximum extra paragraphs needed, 0xFFFF */
+ unsigned short e_ss; /* Initial (relative) SS value, 0x0 */
+ unsigned short e_sp; /* Initial SP value, 0xb8 */
+ unsigned short e_csum; /* Checksum, 0x0 */
+ unsigned short e_ip; /* Initial IP value, 0x0 */
+ unsigned short e_cs; /* Initial (relative) CS value, 0x0 */
+ unsigned short e_lfarlc; /* File address of relocation table, 0x40 */
+ unsigned short e_ovno; /* Overlay number, 0x0 */
+ char e_res[4][2]; /* Reserved words, all 0x0 */
+ unsigned short e_oemid; /* OEM identifier (for e_oeminfo), 0x0 */
+ unsigned short e_oeminfo; /* OEM information; e_oemid specific, 0x0 */
+ char e_res2[10][2]; /* Reserved words, all 0x0 */
+ unsigned long e_lfanew; /* File address of new exe header, 0x80 */
+ char dos_message[16][4]; /* other stuff, always follow DOS header */
+ unsigned int nt_signature; /* required NT signature, 0x4550 */
+
+ /* From standard header */
+
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ unsigned long f_timdat; /* time & date stamp */
+ unsigned long f_symptr; /* file pointer to symtab */
+ unsigned long f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+};
+
+
+#define FILHDR struct external_PE_filehdr
+#undef FILHSZ
+#define FILHSZ 152
+
+#endif
+
+typedef struct
+{
+ unsigned short magic; /* type of file
*/
+ unsigned short vstamp; /* version stamp */
+ unsigned long tsize; /* text size in bytes, padded to FW
bdry*/
+ unsigned long dsize; /* initialized data " "
*/
+ unsigned long bsize; /* uninitialized data " "
*/
+ unsigned long entry; /* entry pt.
*/
+ unsigned long text_start; /* base of text used for this file */
+ unsigned long data_start; /* base of all data used for this file */
+
+ /* NT extra fields; see internal.h for descriptions */
+ unsigned long ImageBase;
+ unsigned long SectionAlignment;
+ unsigned long FileAlignment;
+ unsigned short MajorOperatingSystemVersion;
+ unsigned short MinorOperatingSystemVersion;
+ unsigned short MajorImageVersion;
+ unsigned short MinorImageVersion;
+ unsigned short MajorSubsystemVersion;
+ unsigned short MinorSubsystemVersion;
+ char Reserved1[4];
+ unsigned long SizeOfImage;
+ unsigned long SizeOfHeaders;
+ unsigned long CheckSum;
+ unsigned short Subsystem;
+ unsigned short DllCharacteristics;
+ unsigned long SizeOfStackReserve;
+ unsigned long SizeOfStackCommit;
+ unsigned long SizeOfHeapReserve;
+ unsigned long SizeOfHeapCommit;
+ unsigned long LoaderFlags;
+ unsigned long NumberOfRvaAndSizes;
+ /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
+ char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars */
+
+} PEAOUTHDR;
+
+
+#undef AOUTSZ
+#define AOUTSZ (AOUTHDRSZ + 196)
+
+#undef E_FILNMLEN
+#define E_FILNMLEN 18 /* # characters in a file name */
+#endif
+
+/* end of coff/pe.h */
+
+#define DT_NON (0) /* no derived type */
+#define DT_PTR (1) /* pointer */
+#define DT_FCN (2) /* function */
+#define DT_ARY (3) /* array */
+
+#define ISPTR(x) (((x) & N_TMASK) == (DT_PTR << N_BTSHFT))
+#define ISFCN(x) (((x) & N_TMASK) == (DT_FCN << N_BTSHFT))
+#define ISARY(x) (((x) & N_TMASK) == (DT_ARY << N_BTSHFT))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _A_OUT_H_ */
+
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/aes.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/aes.c Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1317 @@
+/**
+ *
+ * aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project.
+ */
+/*
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@xxxxxxxxxxxxxxxxxxx>
+ * @author Antoon Bosselaers <antoon.bosselaers@xxxxxxxxxxxxxxxxxxx>
+ * @author Paulo Barreto <paulo.barreto@xxxxxxxxxxxx>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "vl.h"
+#include "aes.h"
+
+#define NDEBUG
+#include <assert.h>
+
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+
+#define MAXKC (256/32)
+#define MAXKB (256/8)
+#define MAXNR 14
+
+/* This controls loop-unrolling in aes_core.c */
+#undef FULL_UNROLL
+# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^
((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
+# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >>
16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+static const u32 Te0[256] = {
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+static const u32 Td0[256] = {
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u32 Td4[256] = {
+ 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+ 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+ 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+ 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+ 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+ 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+ 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+ 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+ 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+ 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+ 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+ 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+ 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+ 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+ 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+ 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+ 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+ 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+ 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+ 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+ 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+ 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+ 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+ 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+ 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+ 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+ 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+ 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+ 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+ 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+ 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+ 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+ 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+ 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+ 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+ 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+ 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+ 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+ 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+ 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+ 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+ 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+ 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+ 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+ 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+ 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+ 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+ 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+ 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+ 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+ 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+ 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+ 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+ 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+ 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+ 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+ 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+ 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+ 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+ 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+ 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+ 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+ 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+ 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+static const u32 rcon[] = {
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more
than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key) {
+
+ u32 *rk;
+ int i = 0;
+ u32 temp;
+
+ if (!userKey || !key)
+ return -1;
+ if (bits != 128 && bits != 192 && bits != 256)
+ return -2;
+
+ rk = key->rd_key;
+
+ if (bits==128)
+ key->rounds = 10;
+ else if (bits==192)
+ key->rounds = 12;
+ else
+ key->rounds = 14;
+
+ rk[0] = GETU32(userKey );
+ rk[1] = GETU32(userKey + 4);
+ rk[2] = GETU32(userKey + 8);
+ rk[3] = GETU32(userKey + 12);
+ if (bits == 128) {
+ while (1) {
+ temp = rk[3];
+ rk[4] = rk[0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ if (++i == 10) {
+ return 0;
+ }
+ rk += 4;
+ }
+ }
+ rk[4] = GETU32(userKey + 16);
+ rk[5] = GETU32(userKey + 20);
+ if (bits == 192) {
+ while (1) {
+ temp = rk[ 5];
+ rk[ 6] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 7] = rk[ 1] ^ rk[ 6];
+ rk[ 8] = rk[ 2] ^ rk[ 7];
+ rk[ 9] = rk[ 3] ^ rk[ 8];
+ if (++i == 8) {
+ return 0;
+ }
+ rk[10] = rk[ 4] ^ rk[ 9];
+ rk[11] = rk[ 5] ^ rk[10];
+ rk += 6;
+ }
+ }
+ rk[6] = GETU32(userKey + 24);
+ rk[7] = GETU32(userKey + 28);
+ if (bits == 256) {
+ while (1) {
+ temp = rk[ 7];
+ rk[ 8] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 9] = rk[ 1] ^ rk[ 8];
+ rk[10] = rk[ 2] ^ rk[ 9];
+ rk[11] = rk[ 3] ^ rk[10];
+ if (++i == 7) {
+ return 0;
+ }
+ temp = rk[11];
+ rk[12] = rk[ 4] ^
+ (Te4[(temp >> 24) ] & 0xff000000) ^
+ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp ) & 0xff] & 0x000000ff);
+ rk[13] = rk[ 5] ^ rk[12];
+ rk[14] = rk[ 6] ^ rk[13];
+ rk[15] = rk[ 7] ^ rk[14];
+
+ rk += 8;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key) {
+
+ u32 *rk;
+ int i, j, status;
+ u32 temp;
+
+ /* first, start with an encryption schedule */
+ status = AES_set_encrypt_key(userKey, bits, key);
+ if (status < 0)
+ return status;
+
+ rk = key->rd_key;
+
+ /* invert the order of the round keys: */
+ for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+ temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
+ temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+ temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+ temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+ }
+ /* apply the inverse MixColumn transform to all round keys but the
first and the last: */
+ for (i = 1; i < (key->rounds); i++) {
+ rk += 4;
+ rk[0] =
+ Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[0] ) & 0xff] & 0xff];
+ rk[1] =
+ Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[1] ) & 0xff] & 0xff];
+ rk[2] =
+ Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[2] ) & 0xff] & 0xff];
+ rk[3] =
+ Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[3] ) & 0xff] & 0xff];
+ }
+ return 0;
+}
+
+#ifndef AES_ASM
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key) {
+
+ const u32 *rk;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ assert(in && out && key);
+ rk = key->rd_key;
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(in ) ^ rk[0];
+ s1 = GETU32(in + 4) ^ rk[1];
+ s2 = GETU32(in + 8) ^ rk[2];
+ s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^
Te3[s3 & 0xff] ^ rk[ 4];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^
Te3[s0 & 0xff] ^ rk[ 5];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^
Te3[s1 & 0xff] ^ rk[ 6];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^
Te3[s2 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^
Te3[t3 & 0xff] ^ rk[ 8];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^
Te3[t0 & 0xff] ^ rk[ 9];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^
Te3[t1 & 0xff] ^ rk[10];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^
Te3[t2 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^
Te3[s3 & 0xff] ^ rk[12];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^
Te3[s0 & 0xff] ^ rk[13];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^
Te3[s1 & 0xff] ^ rk[14];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^
Te3[s2 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^
Te3[t3 & 0xff] ^ rk[16];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^
Te3[t0 & 0xff] ^ rk[17];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^
Te3[t1 & 0xff] ^ rk[18];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^
Te3[t2 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^
Te3[s3 & 0xff] ^ rk[20];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^
Te3[s0 & 0xff] ^ rk[21];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^
Te3[s1 & 0xff] ^ rk[22];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^
Te3[s2 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^
Te3[t3 & 0xff] ^ rk[24];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^
Te3[t0 & 0xff] ^ rk[25];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^
Te3[t1 & 0xff] ^ rk[26];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^
Te3[t2 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^
Te3[s3 & 0xff] ^ rk[28];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^
Te3[s0 & 0xff] ^ rk[29];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^
Te3[s1 & 0xff] ^ rk[30];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^
Te3[s2 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^
Te3[t3 & 0xff] ^ rk[32];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^
Te3[t0 & 0xff] ^ rk[33];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^
Te3[t1 & 0xff] ^ rk[34];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^
Te3[t2 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^
Te3[s3 & 0xff] ^ rk[36];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^
Te3[s0 & 0xff] ^ rk[37];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^
Te3[s1 & 0xff] ^ rk[38];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^
Te3[s2 & 0xff] ^ rk[39];
+ if (key->rounds > 10) {
+ /* round 10: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^
Te3[t3 & 0xff] ^ rk[40];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^
Te3[t0 & 0xff] ^ rk[41];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^
Te3[t1 & 0xff] ^ rk[42];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^
Te3[t2 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^
Te3[s3 & 0xff] ^ rk[44];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^
Te3[s0 & 0xff] ^ rk[45];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^
Te3[s1 & 0xff] ^ rk[46];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^
Te3[s2 & 0xff] ^ rk[47];
+ if (key->rounds > 12) {
+ /* round 12: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) &
0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) &
0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) &
0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) &
0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) &
0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) &
0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) &
0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) &
0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+ }
+ }
+ rk += key->rounds << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = key->rounds >> 1;
+ for (;;) {
+ t0 =
+ Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
+ }
+
+ s0 =
+ Te0[(t0 >> 24) ] ^
+ Te1[(t1 >> 16) & 0xff] ^
+ Te2[(t2 >> 8) & 0xff] ^
+ Te3[(t3 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Te0[(t1 >> 24) ] ^
+ Te1[(t2 >> 16) & 0xff] ^
+ Te2[(t3 >> 8) & 0xff] ^
+ Te3[(t0 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Te0[(t2 >> 24) ] ^
+ Te1[(t3 >> 16) & 0xff] ^
+ Te2[(t0 >> 8) & 0xff] ^
+ Te3[(t1 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Te0[(t3 >> 24) ] ^
+ Te1[(t0 >> 16) & 0xff] ^
+ Te2[(t1 >> 8) & 0xff] ^
+ Te3[(t2 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Te4[(t0 >> 24) ] & 0xff000000) ^
+ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(out , s0);
+ s1 =
+ (Te4[(t1 >> 24) ] & 0xff000000) ^
+ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(out + 4, s1);
+ s2 =
+ (Te4[(t2 >> 24) ] & 0xff000000) ^
+ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(out + 8, s2);
+ s3 =
+ (Te4[(t3 >> 24) ] & 0xff000000) ^
+ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(out + 12, s3);
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key) {
+
+ const u32 *rk;
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ assert(in && out && key);
+ rk = key->rd_key;
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(in ) ^ rk[0];
+ s1 = GETU32(in + 4) ^ rk[1];
+ s2 = GETU32(in + 8) ^ rk[2];
+ s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^
Td3[s1 & 0xff] ^ rk[ 4];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^
Td3[s2 & 0xff] ^ rk[ 5];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^
Td3[s3 & 0xff] ^ rk[ 6];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^
Td3[s0 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^
Td3[t1 & 0xff] ^ rk[ 8];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^
Td3[t2 & 0xff] ^ rk[ 9];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^
Td3[t3 & 0xff] ^ rk[10];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^
Td3[t0 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^
Td3[s1 & 0xff] ^ rk[12];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^
Td3[s2 & 0xff] ^ rk[13];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^
Td3[s3 & 0xff] ^ rk[14];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^
Td3[s0 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^
Td3[t1 & 0xff] ^ rk[16];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^
Td3[t2 & 0xff] ^ rk[17];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^
Td3[t3 & 0xff] ^ rk[18];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^
Td3[t0 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^
Td3[s1 & 0xff] ^ rk[20];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^
Td3[s2 & 0xff] ^ rk[21];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^
Td3[s3 & 0xff] ^ rk[22];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^
Td3[s0 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^
Td3[t1 & 0xff] ^ rk[24];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^
Td3[t2 & 0xff] ^ rk[25];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^
Td3[t3 & 0xff] ^ rk[26];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^
Td3[t0 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^
Td3[s1 & 0xff] ^ rk[28];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^
Td3[s2 & 0xff] ^ rk[29];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^
Td3[s3 & 0xff] ^ rk[30];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^
Td3[s0 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^
Td3[t1 & 0xff] ^ rk[32];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^
Td3[t2 & 0xff] ^ rk[33];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^
Td3[t3 & 0xff] ^ rk[34];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^
Td3[t0 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^
Td3[s1 & 0xff] ^ rk[36];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^
Td3[s2 & 0xff] ^ rk[37];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^
Td3[s3 & 0xff] ^ rk[38];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^
Td3[s0 & 0xff] ^ rk[39];
+ if (key->rounds > 10) {
+ /* round 10: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^
Td3[t1 & 0xff] ^ rk[40];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^
Td3[t2 & 0xff] ^ rk[41];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^
Td3[t3 & 0xff] ^ rk[42];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^
Td3[t0 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^
Td3[s1 & 0xff] ^ rk[44];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^
Td3[s2 & 0xff] ^ rk[45];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^
Td3[s3 & 0xff] ^ rk[46];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^
Td3[s0 & 0xff] ^ rk[47];
+ if (key->rounds > 12) {
+ /* round 12: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) &
0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) &
0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) &
0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) &
0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) &
0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) &
0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) &
0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) &
0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+ }
+ }
+ rk += key->rounds << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = key->rounds >> 1;
+ for (;;) {
+ t0 =
+ Td0[(s0 >> 24) ] ^
+ Td1[(s3 >> 16) & 0xff] ^
+ Td2[(s2 >> 8) & 0xff] ^
+ Td3[(s1 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Td0[(s1 >> 24) ] ^
+ Td1[(s0 >> 16) & 0xff] ^
+ Td2[(s3 >> 8) & 0xff] ^
+ Td3[(s2 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Td0[(s2 >> 24) ] ^
+ Td1[(s1 >> 16) & 0xff] ^
+ Td2[(s0 >> 8) & 0xff] ^
+ Td3[(s3 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Td0[(s3 >> 24) ] ^
+ Td1[(s2 >> 16) & 0xff] ^
+ Td2[(s1 >> 8) & 0xff] ^
+ Td3[(s0 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
+ }
+
+ s0 =
+ Td0[(t0 >> 24) ] ^
+ Td1[(t3 >> 16) & 0xff] ^
+ Td2[(t2 >> 8) & 0xff] ^
+ Td3[(t1 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Td0[(t1 >> 24) ] ^
+ Td1[(t0 >> 16) & 0xff] ^
+ Td2[(t3 >> 8) & 0xff] ^
+ Td3[(t2 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Td0[(t2 >> 24) ] ^
+ Td1[(t1 >> 16) & 0xff] ^
+ Td2[(t0 >> 8) & 0xff] ^
+ Td3[(t3 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Td0[(t3 >> 24) ] ^
+ Td1[(t2 >> 16) & 0xff] ^
+ Td2[(t1 >> 8) & 0xff] ^
+ Td3[(t0 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Td4[(t0 >> 24) ] & 0xff000000) ^
+ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(out , s0);
+ s1 =
+ (Td4[(t1 >> 24) ] & 0xff000000) ^
+ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(out + 4, s1);
+ s2 =
+ (Td4[(t2 >> 24) ] & 0xff000000) ^
+ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(out + 8, s2);
+ s3 =
+ (Td4[(t3 >> 24) ] & 0xff000000) ^
+ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(out + 12, s3);
+}
+
+#endif /* AES_ASM */
+
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ const unsigned long length, const AES_KEY *key,
+ unsigned char *ivec, const int enc)
+{
+
+ unsigned long n;
+ unsigned long len = length;
+ unsigned char tmp[AES_BLOCK_SIZE];
+
+ assert(in && out && key && ivec);
+
+ if (enc) {
+ while (len >= AES_BLOCK_SIZE) {
+ for(n=0; n < AES_BLOCK_SIZE; ++n)
+ tmp[n] = in[n] ^ ivec[n];
+ AES_encrypt(tmp, out, key);
+ memcpy(ivec, out, AES_BLOCK_SIZE);
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ if (len) {
+ for(n=0; n < len; ++n)
+ tmp[n] = in[n] ^ ivec[n];
+ for(n=len; n < AES_BLOCK_SIZE; ++n)
+ tmp[n] = ivec[n];
+ AES_encrypt(tmp, tmp, key);
+ memcpy(out, tmp, AES_BLOCK_SIZE);
+ memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ }
+ } else {
+ while (len >= AES_BLOCK_SIZE) {
+ memcpy(tmp, in, AES_BLOCK_SIZE);
+ AES_decrypt(in, out, key);
+ for(n=0; n < AES_BLOCK_SIZE; ++n)
+ out[n] ^= ivec[n];
+ memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ len -= AES_BLOCK_SIZE;
+ in += AES_BLOCK_SIZE;
+ out += AES_BLOCK_SIZE;
+ }
+ if (len) {
+ memcpy(tmp, in, AES_BLOCK_SIZE);
+ AES_decrypt(tmp, tmp, key);
+ for(n=0; n < len; ++n)
+ out[n] = tmp[n] ^ ivec[n];
+ memcpy(ivec, tmp, AES_BLOCK_SIZE);
+ }
+ }
+}
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/aes.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/aes.h Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,26 @@
+#ifndef QEMU_AES_H
+#define QEMU_AES_H
+
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+struct aes_key_st {
+ uint32_t rd_key[4 *(AES_MAXNR + 1)];
+ int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ const unsigned long length, const AES_KEY *key,
+ unsigned char *ivec, const int enc);
+
+#endif
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/CVS/Entries
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/CVS/Entries Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,19 @@
+/alsaaudio.c/1.5/Sun Nov 20 18:53:05 2005//Trelease_0_8_1
+/audio.c/1.9/Thu May 25 18:22:31 2006//Trelease_0_8_1
+/audio.h/1.5/Thu May 25 18:22:31 2006//Trelease_0_8_1
+/audio_int.h/1.7/Thu May 25 18:22:31 2006//Trelease_0_8_1
+/audio_template.h/1.4/Sun Nov 20 16:24:34 2005//Trelease_0_8_1
+/coreaudio.c/1.5/Sun Nov 20 18:53:42 2005//Trelease_0_8_1
+/dsound_template.h/1.2/Sat Nov 5 18:55:27 2005//Trelease_0_8_1
+/dsoundaudio.c/1.2/Sat Nov 5 18:55:27 2005//Trelease_0_8_1
+/fmodaudio.c/1.5/Thu May 25 18:22:32 2006//Trelease_0_8_1
+/mixeng.c/1.4/Thu May 25 18:22:32 2006//Trelease_0_8_1
+/mixeng.h/1.2/Thu May 25 18:22:32 2006//Trelease_0_8_1
+/mixeng_template.h/1.2/Thu May 25 18:22:32 2006//Trelease_0_8_1
+/noaudio.c/1.4/Thu May 25 18:22:32 2006//Trelease_0_8_1
+/ossaudio.c/1.9/Thu May 25 18:22:32 2006//Trelease_0_8_1
+/rate_template.h/1.2/Sat Nov 5 18:55:27 2005//Trelease_0_8_1
+/sdlaudio.c/1.6/Thu May 25 18:22:32 2006//Trelease_0_8_1
+/sys-queue.h/1.1/Sun Oct 30 18:58:22 2005//Trelease_0_8_1
+/wavaudio.c/1.6/Thu May 25 18:22:32 2006//Trelease_0_8_1
+D
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/CVS/Repository
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/CVS/Repository Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1 @@
+qemu/audio
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/CVS/Root
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/CVS/Root Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1 @@
+:pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/qemu
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/CVS/Tag
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/CVS/Tag Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1 @@
+Nrelease_0_8_1
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/alsaaudio.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/alsaaudio.c Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,981 @@
+/*
+ * QEMU ALSA audio driver
+ *
+ * Copyright (c) 2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include <alsa/asoundlib.h>
+#include "vl.h"
+
+#define AUDIO_CAP "alsa"
+#include "audio_int.h"
+
+typedef struct ALSAVoiceOut {
+ HWVoiceOut hw;
+ void *pcm_buf;
+ snd_pcm_t *handle;
+} ALSAVoiceOut;
+
+typedef struct ALSAVoiceIn {
+ HWVoiceIn hw;
+ snd_pcm_t *handle;
+ void *pcm_buf;
+} ALSAVoiceIn;
+
+static struct {
+ int size_in_usec_in;
+ int size_in_usec_out;
+ const char *pcm_name_in;
+ const char *pcm_name_out;
+ unsigned int buffer_size_in;
+ unsigned int period_size_in;
+ unsigned int buffer_size_out;
+ unsigned int period_size_out;
+ unsigned int threshold;
+
+ int buffer_size_in_overriden;
+ int period_size_in_overriden;
+
+ int buffer_size_out_overriden;
+ int period_size_out_overriden;
+ int verbose;
+} conf = {
+#ifdef HIGH_LATENCY
+ .size_in_usec_in = 1,
+ .size_in_usec_out = 1,
+#endif
+ .pcm_name_out = "hw:0,0",
+ .pcm_name_in = "hw:0,0",
+#ifdef HIGH_LATENCY
+ .buffer_size_in = 400000,
+ .period_size_in = 400000 / 4,
+ .buffer_size_out = 400000,
+ .period_size_out = 400000 / 4,
+#else
+#define DEFAULT_BUFFER_SIZE 1024
+#define DEFAULT_PERIOD_SIZE 256
+ .buffer_size_in = DEFAULT_BUFFER_SIZE * 4,
+ .period_size_in = DEFAULT_PERIOD_SIZE * 4,
+ .buffer_size_out = DEFAULT_BUFFER_SIZE,
+ .period_size_out = DEFAULT_PERIOD_SIZE,
+ .buffer_size_in_overriden = 0,
+ .buffer_size_out_overriden = 0,
+ .period_size_in_overriden = 0,
+ .period_size_out_overriden = 0,
+#endif
+ .threshold = 0,
+ .verbose = 0
+};
+
+struct alsa_params_req {
+ int freq;
+ audfmt_e fmt;
+ int nchannels;
+ unsigned int buffer_size;
+ unsigned int period_size;
+};
+
+struct alsa_params_obt {
+ int freq;
+ audfmt_e fmt;
+ int nchannels;
+ snd_pcm_uframes_t samples;
+};
+
+static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
+}
+
+static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
+ int err,
+ const char *typ,
+ const char *fmt,
+ ...
+ )
+{
+ va_list ap;
+
+ AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
+}
+
+static void alsa_anal_close (snd_pcm_t **handlep)
+{
+ int err = snd_pcm_close (*handlep);
+ if (err) {
+ alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
+ }
+ *handlep = NULL;
+}
+
+static int alsa_write (SWVoiceOut *sw, void *buf, int len)
+{
+ return audio_pcm_sw_write (sw, buf, len);
+}
+
+static int aud_to_alsafmt (audfmt_e fmt)
+{
+ switch (fmt) {
+ case AUD_FMT_S8:
+ return SND_PCM_FORMAT_S8;
+
+ case AUD_FMT_U8:
+ return SND_PCM_FORMAT_U8;
+
+ case AUD_FMT_S16:
+ return SND_PCM_FORMAT_S16_LE;
+
+ case AUD_FMT_U16:
+ return SND_PCM_FORMAT_U16_LE;
+
+ default:
+ dolog ("Internal logic error: Bad audio format %d\n", fmt);
+#ifdef DEBUG_AUDIO
+ abort ();
+#endif
+ return SND_PCM_FORMAT_U8;
+ }
+}
+
+static int alsa_to_audfmt (int alsafmt, audfmt_e *fmt, int *endianness)
+{
+ switch (alsafmt) {
+ case SND_PCM_FORMAT_S8:
+ *endianness = 0;
+ *fmt = AUD_FMT_S8;
+ break;
+
+ case SND_PCM_FORMAT_U8:
+ *endianness = 0;
+ *fmt = AUD_FMT_U8;
+ break;
+
+ case SND_PCM_FORMAT_S16_LE:
+ *endianness = 0;
+ *fmt = AUD_FMT_S16;
+ break;
+
+ case SND_PCM_FORMAT_U16_LE:
+ *endianness = 0;
+ *fmt = AUD_FMT_U16;
+ break;
+
+ case SND_PCM_FORMAT_S16_BE:
+ *endianness = 1;
+ *fmt = AUD_FMT_S16;
+ break;
+
+ case SND_PCM_FORMAT_U16_BE:
+ *endianness = 1;
+ *fmt = AUD_FMT_U16;
+ break;
+
+ default:
+ dolog ("Unrecognized audio format %d\n", alsafmt);
+ return -1;
+ }
+
+ return 0;
+}
+
+#if defined DEBUG_MISMATCHES || defined DEBUG
+static void alsa_dump_info (struct alsa_params_req *req,
+ struct alsa_params_obt *obt)
+{
+ dolog ("parameter | requested value | obtained value\n");
+ dolog ("format | %10d | %10d\n", req->fmt, obt->fmt);
+ dolog ("channels | %10d | %10d\n",
+ req->nchannels, obt->nchannels);
+ dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
+ dolog ("============================================\n");
+ dolog ("requested: buffer size %d period size %d\n",
+ req->buffer_size, req->period_size);
+ dolog ("obtained: samples %ld\n", obt->samples);
+}
+#endif
+
+static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
+{
+ int err;
+ snd_pcm_sw_params_t *sw_params;
+
+ snd_pcm_sw_params_alloca (&sw_params);
+
+ err = snd_pcm_sw_params_current (handle, sw_params);
+ if (err < 0) {
+ dolog ("Could not fully initialize DAC\n");
+ alsa_logerr (err, "Failed to get current software parameters\n");
+ return;
+ }
+
+ err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
+ if (err < 0) {
+ dolog ("Could not fully initialize DAC\n");
+ alsa_logerr (err, "Failed to set software threshold to %ld\n",
+ threshold);
+ return;
+ }
+
+ err = snd_pcm_sw_params (handle, sw_params);
+ if (err < 0) {
+ dolog ("Could not fully initialize DAC\n");
+ alsa_logerr (err, "Failed to set software parameters\n");
+ return;
+ }
+}
+
+static int alsa_open (int in, struct alsa_params_req *req,
+ struct alsa_params_obt *obt, snd_pcm_t **handlep)
+{
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *hw_params;
+ int err, freq, nchannels;
+ const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out;
+ unsigned int period_size, buffer_size;
+ snd_pcm_uframes_t obt_buffer_size;
+ const char *typ = in ? "ADC" : "DAC";
+
+ freq = req->freq;
+ period_size = req->period_size;
+ buffer_size = req->buffer_size;
+ nchannels = req->nchannels;
+
+ snd_pcm_hw_params_alloca (&hw_params);
+
+ err = snd_pcm_open (
+ &handle,
+ pcm_name,
+ in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
+ SND_PCM_NONBLOCK
+ );
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
+ return -1;
+ }
+
+ err = snd_pcm_hw_params_any (handle, hw_params);
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
+ goto err;
+ }
+
+ err = snd_pcm_hw_params_set_access (
+ handle,
+ hw_params,
+ SND_PCM_ACCESS_RW_INTERLEAVED
+ );
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set access type\n");
+ goto err;
+ }
+
+ err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
+ goto err;
+ }
+
+ err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
+ goto err;
+ }
+
+ err = snd_pcm_hw_params_set_channels_near (
+ handle,
+ hw_params,
+ &nchannels
+ );
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
+ req->nchannels);
+ goto err;
+ }
+
+ if (nchannels != 1 && nchannels != 2) {
+ alsa_logerr2 (err, typ,
+ "Can not handle obtained number of channels %d\n",
+ nchannels);
+ goto err;
+ }
+
+ if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) {
+ if (!buffer_size) {
+ buffer_size = DEFAULT_BUFFER_SIZE;
+ period_size= DEFAULT_PERIOD_SIZE;
+ }
+ }
+
+ if (buffer_size) {
+ if ((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out)) {
+ if (period_size) {
+ err = snd_pcm_hw_params_set_period_time_near (
+ handle,
+ hw_params,
+ &period_size,
+ 0
+ );
+ if (err < 0) {
+ alsa_logerr2 (err, typ,
+ "Failed to set period time %d\n",
+ req->period_size);
+ goto err;
+ }
+ }
+
+ err = snd_pcm_hw_params_set_buffer_time_near (
+ handle,
+ hw_params,
+ &buffer_size,
+ 0
+ );
+
+ if (err < 0) {
+ alsa_logerr2 (err, typ,
+ "Failed to set buffer time %d\n",
+ req->buffer_size);
+ goto err;
+ }
+ }
+ else {
+ int dir;
+ snd_pcm_uframes_t minval;
+
+ if (period_size) {
+ minval = period_size;
+ dir = 0;
+
+ err = snd_pcm_hw_params_get_period_size_min (
+ hw_params,
+ &minval,
+ &dir
+ );
+ if (err < 0) {
+ alsa_logerr (
+ err,
+ "Could not get minmal period size for %s\n",
+ typ
+ );
+ }
+ else {
+ if (period_size < minval) {
+ if ((in && conf.period_size_in_overriden)
+ || (!in && conf.period_size_out_overriden)) {
+ dolog ("%s period size(%d) is less "
+ "than minmal period size(%ld)\n",
+ typ,
+ period_size,
+ minval);
+ }
+ period_size = minval;
+ }
+ }
+
+ err = snd_pcm_hw_params_set_period_size (
+ handle,
+ hw_params,
+ period_size,
+ 0
+ );
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set period size %d\n",
+ req->period_size);
+ goto err;
+ }
+ }
+
+ minval = buffer_size;
+ err = snd_pcm_hw_params_get_buffer_size_min (
+ hw_params,
+ &minval
+ );
+ if (err < 0) {
+ alsa_logerr (err, "Could not get minmal buffer size for %s\n",
+ typ);
+ }
+ else {
+ if (buffer_size < minval) {
+ if ((in && conf.buffer_size_in_overriden)
+ || (!in && conf.buffer_size_out_overriden)) {
+ dolog (
+ "%s buffer size(%d) is less "
+ "than minimal buffer size(%ld)\n",
+ typ,
+ buffer_size,
+ minval
+ );
+ }
+ buffer_size = minval;
+ }
+ }
+
+ err = snd_pcm_hw_params_set_buffer_size (
+ handle,
+ hw_params,
+ buffer_size
+ );
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to set buffer size %d\n",
+ req->buffer_size);
+ goto err;
+ }
+ }
+ }
+ else {
+ dolog ("warning: Buffer size is not set\n");
+ }
+
+ err = snd_pcm_hw_params (handle, hw_params);
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
+ goto err;
+ }
+
+ err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Failed to get buffer size\n");
+ goto err;
+ }
+
+ err = snd_pcm_prepare (handle);
+ if (err < 0) {
+ alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
+ goto err;
+ }
+
+ if (!in && conf.threshold) {
+ snd_pcm_uframes_t threshold;
+ int bytes_per_sec;
+
+ bytes_per_sec = freq
+ << (nchannels == 2)
+ << (req->fmt == AUD_FMT_S16 || req->fmt == AUD_FMT_U16);
+
+ threshold = (conf.threshold * bytes_per_sec) / 1000;
+ alsa_set_threshold (handle, threshold);
+ }
+
+ obt->fmt = req->fmt;
+ obt->nchannels = nchannels;
+ obt->freq = freq;
+ obt->samples = obt_buffer_size;
+ *handlep = handle;
+
+#if defined DEBUG_MISMATCHES || defined DEBUG
+ if (obt->fmt != req->fmt ||
+ obt->nchannels != req->nchannels ||
+ obt->freq != req->freq) {
+ dolog ("Audio paramters mismatch for %s\n", typ);
+ alsa_dump_info (req, obt);
+ }
+#endif
+
+#ifdef DEBUG
+ alsa_dump_info (req, obt);
+#endif
+ return 0;
+
+ err:
+ alsa_anal_close (&handle);
+ return -1;
+}
+
+static int alsa_recover (snd_pcm_t *handle)
+{
+ int err = snd_pcm_prepare (handle);
+ if (err < 0) {
+ alsa_logerr (err, "Failed to prepare handle %p\n", handle);
+ return -1;
+ }
+ return 0;
+}
+
+static snd_pcm_sframes_t alsa_get_avail (snd_pcm_t *handle)
+{
+ snd_pcm_sframes_t avail;
+
+ avail = snd_pcm_avail_update (handle);
+ if (avail < 0) {
+ if (avail == -EPIPE) {
+ if (!alsa_recover (handle)) {
+ avail = snd_pcm_avail_update (handle);
+ }
+ }
+
+ if (avail < 0) {
+ alsa_logerr (avail,
+ "Could not obtain number of available frames\n");
+ return -1;
+ }
+ }
+
+ return avail;
+}
+
+static int alsa_run_out (HWVoiceOut *hw)
+{
+ ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
+ int rpos, live, decr;
+ int samples;
+ uint8_t *dst;
+ st_sample_t *src;
+ snd_pcm_sframes_t avail;
+
+ live = audio_pcm_hw_get_live_out (hw);
+ if (!live) {
+ return 0;
+ }
+
+ avail = alsa_get_avail (alsa->handle);
+ if (avail < 0) {
+ dolog ("Could not get number of available playback frames\n");
+ return 0;
+ }
+
+ decr = audio_MIN (live, avail);
+ samples = decr;
+ rpos = hw->rpos;
+ while (samples) {
+ int left_till_end_samples = hw->samples - rpos;
+ int len = audio_MIN (samples, left_till_end_samples);
+ snd_pcm_sframes_t written;
+
+ src = hw->mix_buf + rpos;
+ dst = advance (alsa->pcm_buf, rpos << hw->info.shift);
+
+ hw->clip (dst, src, len);
+
+ while (len) {
+ written = snd_pcm_writei (alsa->handle, dst, len);
+
+ if (written <= 0) {
+ switch (written) {
+ case 0:
+ if (conf.verbose) {
+ dolog ("Failed to write %d frames (wrote zero)\n",
len);
+ }
+ goto exit;
+
+ case -EPIPE:
+ if (alsa_recover (alsa->handle)) {
+ alsa_logerr (written, "Failed to write %d frames\n",
+ len);
+ goto exit;
+ }
+ if (conf.verbose) {
+ dolog ("Recovering from playback xrun\n");
+ }
+ continue;
+
+ case -EAGAIN:
+ goto exit;
+
+ default:
+ alsa_logerr (written, "Failed to write %d frames to %p\n",
+ len, dst);
+ goto exit;
+ }
+ }
+
+ mixeng_clear (src, written);
+ rpos = (rpos + written) % hw->samples;
+ samples -= written;
+ len -= written;
+ dst = advance (dst, written << hw->info.shift);
+ src += written;
+ }
+ }
+
+ exit:
+ hw->rpos = rpos;
+ return decr;
+}
+
+static void alsa_fini_out (HWVoiceOut *hw)
+{
+ ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
+
+ ldebug ("alsa_fini\n");
+ alsa_anal_close (&alsa->handle);
+
+ if (alsa->pcm_buf) {
+ qemu_free (alsa->pcm_buf);
+ alsa->pcm_buf = NULL;
+ }
+}
+
+static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as)
+{
+ ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
+ struct alsa_params_req req;
+ struct alsa_params_obt obt;
+ audfmt_e effective_fmt;
+ int endianness;
+ int err;
+ snd_pcm_t *handle;
+ audsettings_t obt_as;
+
+ req.fmt = aud_to_alsafmt (as->fmt);
+ req.freq = as->freq;
+ req.nchannels = as->nchannels;
+ req.period_size = conf.period_size_out;
+ req.buffer_size = conf.buffer_size_out;
+
+ if (alsa_open (0, &req, &obt, &handle)) {
+ return -1;
+ }
+
+ err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness);
+ if (err) {
+ alsa_anal_close (&handle);
+ return -1;
+ }
+
+ 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)
+ );
+ hw->samples = obt.samples;
+
+ alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 <<
hw->info.shift);
+ if (!alsa->pcm_buf) {
+ dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",
+ hw->samples, 1 << hw->info.shift);
+ alsa_anal_close (&handle);
+ return -1;
+ }
+
+ alsa->handle = handle;
+ return 0;
+}
+
+static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
+{
+ int err;
+
+ if (pause) {
+ err = snd_pcm_drop (handle);
+ if (err < 0) {
+ alsa_logerr (err, "Could not stop %s\n", typ);
+ return -1;
+ }
+ }
+ else {
+ err = snd_pcm_prepare (handle);
+ if (err < 0) {
+ alsa_logerr (err, "Could not prepare handle for %s\n", typ);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
+{
+ ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
+
+ switch (cmd) {
+ case VOICE_ENABLE:
+ ldebug ("enabling voice\n");
+ return alsa_voice_ctl (alsa->handle, "playback", 0);
+
+ case VOICE_DISABLE:
+ ldebug ("disabling voice\n");
+ return alsa_voice_ctl (alsa->handle, "playback", 1);
+ }
+
+ return -1;
+}
+
+static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as)
+{
+ ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
+ struct alsa_params_req req;
+ struct alsa_params_obt obt;
+ int endianness;
+ int err;
+ audfmt_e effective_fmt;
+ snd_pcm_t *handle;
+ audsettings_t obt_as;
+
+ req.fmt = aud_to_alsafmt (as->fmt);
+ req.freq = as->freq;
+ req.nchannels = as->nchannels;
+ req.period_size = conf.period_size_in;
+ req.buffer_size = conf.buffer_size_in;
+
+ if (alsa_open (1, &req, &obt, &handle)) {
+ return -1;
+ }
+
+ err = alsa_to_audfmt (obt.fmt, &effective_fmt, &endianness);
+ if (err) {
+ alsa_anal_close (&handle);
+ return -1;
+ }
+
+ 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)
+ );
+ hw->samples = obt.samples;
+
+ alsa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 <<
hw->info.shift);
+ if (!alsa->pcm_buf) {
+ dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
+ hw->samples, 1 << hw->info.shift);
+ alsa_anal_close (&handle);
+ return -1;
+ }
+
+ alsa->handle = handle;
+ return 0;
+}
+
+static void alsa_fini_in (HWVoiceIn *hw)
+{
+ ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
+
+ alsa_anal_close (&alsa->handle);
+
+ if (alsa->pcm_buf) {
+ qemu_free (alsa->pcm_buf);
+ alsa->pcm_buf = NULL;
+ }
+}
+
+static int alsa_run_in (HWVoiceIn *hw)
+{
+ ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
+ int hwshift = hw->info.shift;
+ int i;
+ int live = audio_pcm_hw_get_live_in (hw);
+ int dead = hw->samples - live;
+ int decr;
+ struct {
+ int add;
+ int len;
+ } bufs[2] = {
+ { hw->wpos, 0 },
+ { 0, 0 }
+ };
+ snd_pcm_sframes_t avail;
+ snd_pcm_uframes_t read_samples = 0;
+
+ if (!dead) {
+ return 0;
+ }
+
+ avail = alsa_get_avail (alsa->handle);
+ if (avail < 0) {
+ dolog ("Could not get number of captured frames\n");
+ return 0;
+ }
+
+ if (!avail && (snd_pcm_state (alsa->handle) == SND_PCM_STATE_PREPARED)) {
+ avail = hw->samples;
+ }
+
+ decr = audio_MIN (dead, avail);
+ if (!decr) {
+ return 0;
+ }
+
+ if (hw->wpos + decr > hw->samples) {
+ bufs[0].len = (hw->samples - hw->wpos);
+ bufs[1].len = (decr - (hw->samples - hw->wpos));
+ }
+ else {
+ bufs[0].len = decr;
+ }
+
+ for (i = 0; i < 2; ++i) {
+ void *src;
+ st_sample_t *dst;
+ snd_pcm_sframes_t nread;
+ snd_pcm_uframes_t len;
+
+ len = bufs[i].len;
+
+ src = advance (alsa->pcm_buf, bufs[i].add << hwshift);
+ dst = hw->conv_buf + bufs[i].add;
+
+ while (len) {
+ nread = snd_pcm_readi (alsa->handle, src, len);
+
+ if (nread <= 0) {
+ switch (nread) {
+ case 0:
+ if (conf.verbose) {
+ dolog ("Failed to read %ld frames (read zero)\n", len);
+ }
+ goto exit;
+
+ case -EPIPE:
+ if (alsa_recover (alsa->handle)) {
+ alsa_logerr (nread, "Failed to read %ld frames\n",
len);
+ goto exit;
+ }
+ if (conf.verbose) {
+ dolog ("Recovering from capture xrun\n");
+ }
+ continue;
+
+ case -EAGAIN:
+ goto exit;
+
+ default:
+ alsa_logerr (
+ nread,
+ "Failed to read %ld frames from %p\n",
+ len,
+ src
+ );
+ goto exit;
+ }
+ }
+
+ hw->conv (dst, src, nread, &nominal_volume);
+
+ src = advance (src, nread << hwshift);
+ dst += nread;
+
+ read_samples += nread;
+ len -= nread;
+ }
+ }
+
+ exit:
+ hw->wpos = (hw->wpos + read_samples) % hw->samples;
+ return read_samples;
+}
+
+static int alsa_read (SWVoiceIn *sw, void *buf, int size)
+{
+ return audio_pcm_sw_read (sw, buf, size);
+}
+
+static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
+{
+ ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
+
+ switch (cmd) {
+ case VOICE_ENABLE:
+ ldebug ("enabling voice\n");
+ return alsa_voice_ctl (alsa->handle, "capture", 0);
+
+ case VOICE_DISABLE:
+ ldebug ("disabling voice\n");
+ return alsa_voice_ctl (alsa->handle, "capture", 1);
+ }
+
+ return -1;
+}
+
+static void *alsa_audio_init (void)
+{
+ return &conf;
+}
+
+static void alsa_audio_fini (void *opaque)
+{
+ (void) opaque;
+}
+
+static struct audio_option alsa_options[] = {
+ {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out,
+ "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
+ {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out,
+ "DAC period size", &conf.period_size_out_overriden, 0},
+ {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out,
+ "DAC buffer size", &conf.buffer_size_out_overriden, 0},
+
+ {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in,
+ "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0},
+ {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in,
+ "ADC period size", &conf.period_size_in_overriden, 0},
+ {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in,
+ "ADC buffer size", &conf.buffer_size_in_overriden, 0},
+
+ {"THRESHOLD", AUD_OPT_INT, &conf.threshold,
+ "(undocumented)", NULL, 0},
+
+ {"DAC_DEV", AUD_OPT_STR, &conf.pcm_name_out,
+ "DAC device name (for instance dmix)", NULL, 0},
+
+ {"ADC_DEV", AUD_OPT_STR, &conf.pcm_name_in,
+ "ADC device name", NULL, 0},
+
+ {"VERBOSE", AUD_OPT_BOOL, &conf.verbose,
+ "Behave in a more verbose way", NULL, 0},
+
+ {NULL, 0, NULL, NULL, NULL, 0}
+};
+
+static struct audio_pcm_ops alsa_pcm_ops = {
+ alsa_init_out,
+ alsa_fini_out,
+ alsa_run_out,
+ alsa_write,
+ alsa_ctl_out,
+
+ alsa_init_in,
+ alsa_fini_in,
+ alsa_run_in,
+ alsa_read,
+ alsa_ctl_in
+};
+
+struct audio_driver alsa_audio_driver = {
+ INIT_FIELD (name = ) "alsa",
+ INIT_FIELD (descr = ) "ALSA http://www.alsa-project.org",
+ INIT_FIELD (options = ) alsa_options,
+ INIT_FIELD (init = ) alsa_audio_init,
+ INIT_FIELD (fini = ) alsa_audio_fini,
+ INIT_FIELD (pcm_ops = ) &alsa_pcm_ops,
+ INIT_FIELD (can_be_default = ) 1,
+ INIT_FIELD (max_voices_out = ) INT_MAX,
+ INIT_FIELD (max_voices_in = ) INT_MAX,
+ INIT_FIELD (voice_size_out = ) sizeof (ALSAVoiceOut),
+ INIT_FIELD (voice_size_in = ) sizeof (ALSAVoiceIn)
+};
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/audio.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/audio.c Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1481 @@
+/*
+ * QEMU Audio subsystem
+ *
+ * Copyright (c) 2003-2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#define AUDIO_CAP "audio"
+#include "audio_int.h"
+
+/* #define DEBUG_PLIVE */
+/* #define DEBUG_LIVE */
+/* #define DEBUG_OUT */
+
+#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"
+
+static struct audio_driver *drvtab[] = {
+#ifdef CONFIG_OSS
+ &oss_audio_driver,
+#endif
+#ifdef CONFIG_ALSA
+ &alsa_audio_driver,
+#endif
+#ifdef CONFIG_COREAUDIO
+ &coreaudio_audio_driver,
+#endif
+#ifdef CONFIG_DSOUND
+ &dsound_audio_driver,
+#endif
+#ifdef CONFIG_FMOD
+ &fmod_audio_driver,
+#endif
+#ifdef CONFIG_SDL
+ &sdl_audio_driver,
+#endif
+ &no_audio_driver,
+ &wav_audio_driver
+};
+
+struct fixed_settings {
+ int enabled;
+ int nb_voices;
+ int greedy;
+ audsettings_t settings;
+};
+
+static struct {
+ struct fixed_settings fixed_out;
+ struct fixed_settings fixed_in;
+ union {
+ int hz;
+ int64_t ticks;
+ } period;
+ int plive;
+ int log_to_monitor;
+} conf = {
+ { /* DAC fixed settings */
+ 1, /* enabled */
+ 1, /* nb_voices */
+ 1, /* greedy */
+ {
+ 44100, /* freq */
+ 2, /* nchannels */
+ AUD_FMT_S16 /* fmt */
+ }
+ },
+
+ { /* ADC fixed settings */
+ 1, /* enabled */
+ 1, /* nb_voices */
+ 1, /* greedy */
+ {
+ 44100, /* freq */
+ 2, /* nchannels */
+ AUD_FMT_S16 /* fmt */
+ }
+ },
+
+ { 0 }, /* period */
+ 0, /* plive */
+ 0 /* log_to_monitor */
+};
+
+static AudioState glob_audio_state;
+
+volume_t nominal_volume = {
+ 0,
+#ifdef FLOAT_MIXENG
+ 1.0,
+ 1.0
+#else
+ UINT_MAX,
+ UINT_MAX
+#endif
+};
+
+/* http://www.df.lth.se/~john_e/gems/gem002d.html */
+/* http://www.multi-platforms.com/Tips/PopCount.htm */
+uint32_t popcount (uint32_t u)
+{
+ u = ((u&0x55555555) + ((u>>1)&0x55555555));
+ u = ((u&0x33333333) + ((u>>2)&0x33333333));
+ u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
+ u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
+ u = ( u&0x0000ffff) + (u>>16);
+ return u;
+}
+
+inline uint32_t lsbindex (uint32_t u)
+{
+ return popcount ((u&-u)-1);
+}
+
+#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED
+#error No its not
+#else
+int audio_bug (const char *funcname, int cond)
+{
+ if (cond) {
+ static int shown;
+
+ AUD_log (NULL, "Error a bug that was just triggered in %s\n",
funcname);
+ if (!shown) {
+ shown = 1;
+ AUD_log (NULL, "Save all your work and restart without audio\n");
+ AUD_log (NULL, "Please send bug report to malc@xxxxxxxxxxxxx\n");
+ AUD_log (NULL, "I am sorry\n");
+ }
+ AUD_log (NULL, "Context:\n");
+
+#if defined AUDIO_BREAKPOINT_ON_BUG
+# if defined HOST_I386
+# if defined __GNUC__
+ __asm__ ("int3");
+# elif defined _MSC_VER
+ _asm _emit 0xcc;
+# else
+ abort ();
+# endif
+# else
+ abort ();
+# endif
+#endif
+ }
+
+ return cond;
+}
+#endif
+
+void *audio_calloc (const char *funcname, int nmemb, size_t size)
+{
+ int cond;
+ size_t len;
+
+ len = nmemb * size;
+ cond = !nmemb || !size;
+ cond |= nmemb < 0;
+ cond |= len < size;
+
+ if (audio_bug ("audio_calloc", cond)) {
+ AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
+ funcname);
+ AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
+ return NULL;
+ }
+
+ return qemu_mallocz (len);
+}
+
+static char *audio_alloc_prefix (const char *s)
+{
+ const char qemu_prefix[] = "QEMU_";
+ size_t len;
+ char *r;
+
+ if (!s) {
+ return NULL;
+ }
+
+ len = strlen (s);
+ r = qemu_malloc (len + sizeof (qemu_prefix));
+
+ if (r) {
+ size_t i;
+ char *u = r + sizeof (qemu_prefix) - 1;
+
+ strcpy (r, qemu_prefix);
+ strcat (r, s);
+
+ for (i = 0; i < len; ++i) {
+ u[i] = toupper (u[i]);
+ }
+ }
+ return r;
+}
+
+const char *audio_audfmt_to_string (audfmt_e fmt)
+{
+ switch (fmt) {
+ case AUD_FMT_U8:
+ return "U8";
+
+ case AUD_FMT_U16:
+ return "U16";
+
+ case AUD_FMT_S8:
+ return "S8";
+
+ case AUD_FMT_S16:
+ return "S16";
+ }
+
+ dolog ("Bogus audfmt %d returning S16\n", fmt);
+ return "S16";
+}
+
+audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp)
+{
+ if (!strcasecmp (s, "u8")) {
+ *defaultp = 0;
+ return AUD_FMT_U8;
+ }
+ else if (!strcasecmp (s, "u16")) {
+ *defaultp = 0;
+ return AUD_FMT_U16;
+ }
+ else if (!strcasecmp (s, "s8")) {
+ *defaultp = 0;
+ return AUD_FMT_S8;
+ }
+ else if (!strcasecmp (s, "s16")) {
+ *defaultp = 0;
+ return AUD_FMT_S16;
+ }
+ else {
+ dolog ("Bogus audio format `%s' using %s\n",
+ s, audio_audfmt_to_string (defval));
+ *defaultp = 1;
+ return defval;
+ }
+}
+
+static audfmt_e audio_get_conf_fmt (const char *envname,
+ audfmt_e defval,
+ int *defaultp)
+{
+ const char *var = getenv (envname);
+ if (!var) {
+ *defaultp = 1;
+ return defval;
+ }
+ return audio_string_to_audfmt (var, defval, defaultp);
+}
+
+static int audio_get_conf_int (const char *key, int defval, int *defaultp)
+{
+ int val;
+ char *strval;
+
+ strval = getenv (key);
+ if (strval) {
+ *defaultp = 0;
+ val = atoi (strval);
+ return val;
+ }
+ else {
+ *defaultp = 1;
+ return defval;
+ }
+}
+
+static const char *audio_get_conf_str (const char *key,
+ const char *defval,
+ int *defaultp)
+{
+ const char *val = getenv (key);
+ if (!val) {
+ *defaultp = 1;
+ return defval;
+ }
+ else {
+ *defaultp = 0;
+ return val;
+ }
+}
+
+void AUD_vlog (const char *cap, const char *fmt, va_list ap)
+{
+ if (conf.log_to_monitor) {
+ if (cap) {
+ term_printf ("%s: ", cap);
+ }
+
+ term_vprintf (fmt, ap);
+ }
+ else {
+ if (cap) {
+ fprintf (stderr, "%s: ", cap);
+ }
+
+ vfprintf (stderr, fmt, ap);
+ }
+}
+
+void AUD_log (const char *cap, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ AUD_vlog (cap, fmt, ap);
+ va_end (ap);
+}
+
+static void audio_print_options (const char *prefix,
+ struct audio_option *opt)
+{
+ char *uprefix;
+
+ if (!prefix) {
+ dolog ("No prefix specified\n");
+ return;
+ }
+
+ if (!opt) {
+ dolog ("No options\n");
+ return;
+ }
+
+ uprefix = audio_alloc_prefix (prefix);
+
+ for (; opt->name; opt++) {
+ const char *state = "default";
+ printf (" %s_%s: ", uprefix, opt->name);
+
+ if (opt->overridenp && *opt->overridenp) {
+ state = "current";
+ }
+
+ switch (opt->tag) {
+ case AUD_OPT_BOOL:
+ {
+ int *intp = opt->valp;
+ printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);
+ }
+ break;
+
+ case AUD_OPT_INT:
+ {
+ int *intp = opt->valp;
+ printf ("integer, %s = %d\n", state, *intp);
+ }
+ break;
+
+ case AUD_OPT_FMT:
+ {
+ audfmt_e *fmtp = opt->valp;
+ printf (
+ "format, %s = %s, (one of: U8 S8 U16 S16)\n",
+ state,
+ audio_audfmt_to_string (*fmtp)
+ );
+ }
+ break;
+
+ case AUD_OPT_STR:
+ {
+ const char **strp = opt->valp;
+ printf ("string, %s = %s\n",
+ state,
+ *strp ? *strp : "(not set)");
+ }
+ break;
+
+ default:
+ printf ("???\n");
+ dolog ("Bad value tag for option %s_%s %d\n",
+ uprefix, opt->name, opt->tag);
+ break;
+ }
+ printf (" %s\n", opt->descr);
+ }
+
+ qemu_free (uprefix);
+}
+
+static void audio_process_options (const char *prefix,
+ struct audio_option *opt)
+{
+ char *optname;
+ const char qemu_prefix[] = "QEMU_";
+ size_t preflen;
+
+ if (audio_bug (AUDIO_FUNC, !prefix)) {
+ dolog ("prefix = NULL\n");
+ return;
+ }
+
+ if (audio_bug (AUDIO_FUNC, !opt)) {
+ dolog ("opt = NULL\n");
+ return;
+ }
+
+ preflen = strlen (prefix);
+
+ for (; opt->name; opt++) {
+ size_t len, i;
+ int def;
+
+ if (!opt->valp) {
+ dolog ("Option value pointer for `%s' is not set\n",
+ opt->name);
+ continue;
+ }
+
+ len = strlen (opt->name);
+ /* len of opt->name + len of prefix + size of qemu_prefix
+ * (includes trailing zero) + zero + underscore (on behalf of
+ * sizeof) */
+ optname = qemu_malloc (len + preflen + sizeof (qemu_prefix) + 1);
+ if (!optname) {
+ dolog ("Could not allocate memory for option name `%s'\n",
+ opt->name);
+ continue;
+ }
+
+ strcpy (optname, qemu_prefix);
+
+ /* copy while upper-casing, including trailing zero */
+ for (i = 0; i <= preflen; ++i) {
+ optname[i + sizeof (qemu_prefix) - 1] = toupper (prefix[i]);
+ }
+ strcat (optname, "_");
+ strcat (optname, opt->name);
+
+ def = 1;
+ switch (opt->tag) {
+ case AUD_OPT_BOOL:
+ case AUD_OPT_INT:
+ {
+ int *intp = opt->valp;
+ *intp = audio_get_conf_int (optname, *intp, &def);
+ }
+ break;
+
+ case AUD_OPT_FMT:
+ {
+ audfmt_e *fmtp = opt->valp;
+ *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);
+ }
+ break;
+
+ case AUD_OPT_STR:
+ {
+ const char **strp = opt->valp;
+ *strp = audio_get_conf_str (optname, *strp, &def);
+ }
+ break;
+
+ default:
+ dolog ("Bad value tag for option `%s' - %d\n",
+ optname, opt->tag);
+ break;
+ }
+
+ if (!opt->overridenp) {
+ opt->overridenp = &opt->overriden;
+ }
+ *opt->overridenp = !def;
+ qemu_free (optname);
+ }
+}
+
+static void audio_print_settings (audsettings_t *as)
+{
+ dolog ("frequency=%d nchannels=%d fmt=", as->freq, as->nchannels);
+
+ switch (as->fmt) {
+ case AUD_FMT_S8:
+ AUD_log (NULL, "S8");
+ break;
+ case AUD_FMT_U8:
+ AUD_log (NULL, "U8");
+ break;
+ case AUD_FMT_S16:
+ AUD_log (NULL, "S16");
+ break;
+ case AUD_FMT_U16:
+ AUD_log (NULL, "U16");
+ break;
+ default:
+ AUD_log (NULL, "invalid(%d)", as->fmt);
+ break;
+ }
+ AUD_log (NULL, "\n");
+}
+
+static int audio_validate_settigs (audsettings_t *as)
+{
+ int invalid;
+
+ invalid = as->nchannels != 1 && as->nchannels != 2;
+
+ switch (as->fmt) {
+ case AUD_FMT_S8:
+ case AUD_FMT_U8:
+ case AUD_FMT_S16:
+ case AUD_FMT_U16:
+ break;
+ default:
+ invalid = 1;
+ break;
+ }
+
+ invalid |= as->freq <= 0;
+
+ if (invalid) {
+ return -1;
+ }
+ return 0;
+}
+
+static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
+{
+ int bits = 8, sign = 0;
+
+ switch (as->fmt) {
+ case AUD_FMT_S8:
+ sign = 1;
+ case AUD_FMT_U8:
+ break;
+
+ case AUD_FMT_S16:
+ sign = 1;
+ case AUD_FMT_U16:
+ bits = 16;
+ break;
+ }
+ 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
+ )
+{
+ int bits = 8, sign = 0;
+
+ switch (as->fmt) {
+ case AUD_FMT_S8:
+ sign = 1;
+ case AUD_FMT_U8:
+ break;
+
+ case AUD_FMT_S16:
+ sign = 1;
+ case AUD_FMT_U16:
+ bits = 16;
+ break;
+ }
+
+ info->freq = as->freq;
+ info->bits = bits;
+ info->sign = sign;
+ info->nchannels = as->nchannels;
+ 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;
+}
+
+void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len)
+{
+ if (!len) {
+ return;
+ }
+
+ if (info->sign) {
+ memset (buf, len << info->shift, 0x00);
+ }
+ else {
+ if (info->bits == 8) {
+ memset (buf, len << info->shift, 0x80);
+ }
+ else {
+ int i;
+ uint16_t *p = buf;
+ int shift = info->nchannels - 1;
+ short s = INT16_MAX;
+
+ if (info->swap_endian) {
+ s = bswap16 (s);
+ }
+
+ for (i = 0; i < len << shift; i++) {
+ p[i] = s;
+ }
+ }
+ }
+}
+
+/*
+ * Hard voice (capture)
+ */
+static int audio_pcm_hw_find_min_in (HWVoiceIn *hw)
+{
+ SWVoiceIn *sw;
+ int m = hw->total_samples_captured;
+
+ for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+ if (sw->active) {
+ m = audio_MIN (m, sw->total_hw_samples_acquired);
+ }
+ }
+ return m;
+}
+
+int audio_pcm_hw_get_live_in (HWVoiceIn *hw)
+{
+ int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
+ dolog ("live=%d hw->samples=%d\n", live, hw->samples);
+ return 0;
+ }
+ return live;
+}
+
+/*
+ * Soft voice (capture)
+ */
+static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw)
+{
+ HWVoiceIn *hw = sw->hw;
+ int live = hw->total_samples_captured - sw->total_hw_samples_acquired;
+ int rpos;
+
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
+ dolog ("live=%d hw->samples=%d\n", live, hw->samples);
+ return 0;
+ }
+
+ rpos = hw->wpos - live;
+ if (rpos >= 0) {
+ return rpos;
+ }
+ else {
+ return hw->samples + rpos;
+ }
+}
+
+int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
+{
+ HWVoiceIn *hw = sw->hw;
+ int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
+ st_sample_t *src, *dst = sw->buf;
+
+ rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;
+
+ live = hw->total_samples_captured - sw->total_hw_samples_acquired;
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
+ dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);
+ return 0;
+ }
+
+ samples = size >> sw->info.shift;
+ if (!live) {
+ return 0;
+ }
+
+ swlim = (live * sw->ratio) >> 32;
+ swlim = audio_MIN (swlim, samples);
+
+ while (swlim) {
+ src = hw->conv_buf + rpos;
+ isamp = hw->wpos - rpos;
+ /* XXX: <= ? */
+ if (isamp <= 0) {
+ isamp = hw->samples - rpos;
+ }
+
+ if (!isamp) {
+ break;
+ }
+ osamp = swlim;
+
+ if (audio_bug (AUDIO_FUNC, osamp < 0)) {
+ dolog ("osamp=%d\n", osamp);
+ return 0;
+ }
+
+ st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
+ swlim -= osamp;
+ rpos = (rpos + isamp) % hw->samples;
+ dst += osamp;
+ ret += osamp;
+ total += isamp;
+ }
+
+ sw->clip (buf, sw->buf, ret);
+ sw->total_hw_samples_acquired += total;
+ return ret << sw->info.shift;
+}
+
+/*
+ * Hard voice (playback)
+ */
+static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep)
+{
+ SWVoiceOut *sw;
+ int m = INT_MAX;
+ int nb_live = 0;
+
+ for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+ if (sw->active || !sw->empty) {
+ m = audio_MIN (m, sw->total_hw_samples_mixed);
+ nb_live += 1;
+ }
+ }
+
+ *nb_livep = nb_live;
+ return m;
+}
+
+int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live)
+{
+ int smin;
+
+ smin = audio_pcm_hw_find_min_out (hw, nb_live);
+
+ if (!*nb_live) {
+ return 0;
+ }
+ else {
+ int live = smin;
+
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
+ dolog ("live=%d hw->samples=%d\n", live, hw->samples);
+ return 0;
+ }
+ return live;
+ }
+}
+
+int audio_pcm_hw_get_live_out (HWVoiceOut *hw)
+{
+ int nb_live;
+ int live;
+
+ live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
+ dolog ("live=%d hw->samples=%d\n", live, hw->samples);
+ return 0;
+ }
+ return live;
+}
+
+/*
+ * Soft voice (playback)
+ */
+int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size)
+{
+ int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
+ int ret = 0, pos = 0, total = 0;
+
+ if (!sw) {
+ return size;
+ }
+
+ hwsamples = sw->hw->samples;
+
+ live = sw->total_hw_samples_mixed;
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){
+ dolog ("live=%d hw->samples=%d\n", live, hwsamples);
+ return 0;
+ }
+
+ if (live == hwsamples) {
+ return 0;
+ }
+
+ wpos = (sw->hw->rpos + live) % hwsamples;
+ samples = size >> sw->info.shift;
+
+ dead = hwsamples - live;
+ swlim = ((int64_t) dead << 32) / sw->ratio;
+ swlim = audio_MIN (swlim, samples);
+ if (swlim) {
+ sw->conv (sw->buf, buf, swlim, &sw->vol);
+ }
+
+ while (swlim) {
+ dead = hwsamples - live;
+ left = hwsamples - wpos;
+ blck = audio_MIN (dead, left);
+ if (!blck) {
+ break;
+ }
+ isamp = swlim;
+ osamp = blck;
+ st_rate_flow_mix (
+ sw->rate,
+ sw->buf + pos,
+ sw->hw->mix_buf + wpos,
+ &isamp,
+ &osamp
+ );
+ ret += isamp;
+ swlim -= isamp;
+ pos += isamp;
+ live += osamp;
+ wpos = (wpos + osamp) % hwsamples;
+ total += osamp;
+ }
+
+ sw->total_hw_samples_mixed += total;
+ sw->empty = sw->total_hw_samples_mixed == 0;
+
+#ifdef DEBUG_OUT
+ dolog (
+ "%s: write size %d ret %d total sw %d\n",
+ SW_NAME (sw),
+ size >> sw->info.shift,
+ ret,
+ sw->total_hw_samples_mixed
+ );
+#endif
+
+ return ret << sw->info.shift;
+}
+
+#ifdef DEBUG_AUDIO
+static void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info)
+{
+ dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",
+ cap, info->bits, info->sign, info->freq, info->nchannels);
+}
+#endif
+
+#define DAC
+#include "audio_template.h"
+#undef DAC
+#include "audio_template.h"
+
+int AUD_write (SWVoiceOut *sw, void *buf, int size)
+{
+ int bytes;
+
+ if (!sw) {
+ /* XXX: Consider options */
+ return size;
+ }
+
+ if (!sw->hw->enabled) {
+ dolog ("Writing to disabled voice %s\n", SW_NAME (sw));
+ return 0;
+ }
+
+ bytes = sw->hw->pcm_ops->write (sw, buf, size);
+ return bytes;
+}
+
+int AUD_read (SWVoiceIn *sw, void *buf, int size)
+{
+ int bytes;
+
+ if (!sw) {
+ /* XXX: Consider options */
+ return size;
+ }
+
+ if (!sw->hw->enabled) {
+ dolog ("Reading from disabled voice %s\n", SW_NAME (sw));
+ return 0;
+ }
+
+ bytes = sw->hw->pcm_ops->read (sw, buf, size);
+ return bytes;
+}
+
+int AUD_get_buffer_size_out (SWVoiceOut *sw)
+{
+ return sw->hw->samples << sw->hw->info.shift;
+}
+
+void AUD_set_active_out (SWVoiceOut *sw, int on)
+{
+ HWVoiceOut *hw;
+
+ if (!sw) {
+ return;
+ }
+
+ hw = sw->hw;
+ if (sw->active != on) {
+ SWVoiceOut *temp_sw;
+
+ 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) {
+ int nb_active = 0;
+
+ for (temp_sw = hw->sw_head.lh_first; temp_sw;
+ temp_sw = temp_sw->entries.le_next) {
+ nb_active += temp_sw->active != 0;
+ }
+
+ hw->pending_disable = nb_active == 1;
+ }
+ }
+ sw->active = on;
+ }
+}
+
+void AUD_set_active_in (SWVoiceIn *sw, int on)
+{
+ HWVoiceIn *hw;
+
+ if (!sw) {
+ return;
+ }
+
+ hw = sw->hw;
+ if (sw->active != on) {
+ SWVoiceIn *temp_sw;
+
+ if (on) {
+ if (!hw->enabled) {
+ hw->enabled = 1;
+ hw->pcm_ops->ctl_in (hw, VOICE_ENABLE);
+ }
+ sw->total_hw_samples_acquired = hw->total_samples_captured;
+ }
+ else {
+ if (hw->enabled) {
+ int nb_active = 0;
+
+ for (temp_sw = hw->sw_head.lh_first; temp_sw;
+ temp_sw = temp_sw->entries.le_next) {
+ nb_active += temp_sw->active != 0;
+ }
+
+ if (nb_active == 1) {
+ hw->enabled = 0;
+ hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
+ }
+ }
+ }
+ sw->active = on;
+ }
+}
+
+static int audio_get_avail (SWVoiceIn *sw)
+{
+ int live;
+
+ if (!sw) {
+ return 0;
+ }
+
+ live = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
+ dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
+ return 0;
+ }
+
+ ldebug (
+ "%s: get_avail live %d ret %lld\n",
+ SW_NAME (sw),
+ live, (((int64_t) live << 32) / sw->ratio) << sw->info.shift
+ );
+
+ return (((int64_t) live << 32) / sw->ratio) << sw->info.shift;
+}
+
+static int audio_get_free (SWVoiceOut *sw)
+{
+ int live, dead;
+
+ if (!sw) {
+ return 0;
+ }
+
+ live = sw->total_hw_samples_mixed;
+
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > sw->hw->samples)) {
+ dolog ("live=%d sw->hw->samples=%d\n", live, sw->hw->samples);
+ return 0;
+ }
+
+ dead = sw->hw->samples - live;
+
+#ifdef DEBUG_OUT
+ dolog ("%s: get_free live %d dead %d ret %lld\n",
+ SW_NAME (sw),
+ live, dead, (((int64_t) dead << 32) / sw->ratio) << sw->info.shift);
+#endif
+
+ return (((int64_t) dead << 32) / sw->ratio) << sw->info.shift;
+}
+
+static void audio_run_out (AudioState *s)
+{
+ HWVoiceOut *hw = NULL;
+ SWVoiceOut *sw;
+
+ while ((hw = audio_pcm_hw_find_any_enabled_out (s, hw))) {
+ int played;
+ int live, free, nb_live, cleanup_required;
+
+ live = audio_pcm_hw_get_live_out2 (hw, &nb_live);
+ if (!nb_live) {
+ live = 0;
+ }
+
+ if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {
+ dolog ("live=%d hw->samples=%d\n", live, hw->samples);
+ continue;
+ }
+
+ if (hw->pending_disable && !nb_live) {
+#ifdef DEBUG_OUT
+ dolog ("Disabling voice\n");
+#endif
+ hw->enabled = 0;
+ hw->pending_disable = 0;
+ hw->pcm_ops->ctl_out (hw, VOICE_DISABLE);
+ continue;
+ }
+
+ if (!live) {
+ for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+ if (sw->active) {
+ free = audio_get_free (sw);
+ if (free > 0) {
+ sw->callback.fn (sw->callback.opaque, free);
+ }
+ }
+ }
+ continue;
+ }
+
+ 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",
+ hw->rpos, hw->samples, played);
+ hw->rpos = 0;
+ }
+
+#ifdef DEBUG_OUT
+ dolog ("played=%d\n", played);
+#endif
+
+ if (played) {
+ hw->ts_helper += played;
+ }
+
+ cleanup_required = 0;
+ for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+ if (!sw->active && sw->empty) {
+ continue;
+ }
+
+ if (audio_bug (AUDIO_FUNC, played > sw->total_hw_samples_mixed)) {
+ dolog ("played=%d sw->total_hw_samples_mixed=%d\n",
+ played, sw->total_hw_samples_mixed);
+ played = sw->total_hw_samples_mixed;
+ }
+
+ sw->total_hw_samples_mixed -= played;
+
+ if (!sw->total_hw_samples_mixed) {
+ sw->empty = 1;
+ cleanup_required |= !sw->active && !sw->callback.fn;
+ }
+
+ if (sw->active) {
+ free = audio_get_free (sw);
+ if (free > 0) {
+ sw->callback.fn (sw->callback.opaque, free);
+ }
+ }
+ }
+
+ if (cleanup_required) {
+ restart:
+ for (sw = hw->sw_head.lh_first; sw; sw = 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 */
+ }
+ }
+ }
+ }
+}
+
+static void audio_run_in (AudioState *s)
+{
+ HWVoiceIn *hw = NULL;
+
+ while ((hw = audio_pcm_hw_find_any_enabled_in (s, hw))) {
+ SWVoiceIn *sw;
+ int captured, min;
+
+ captured = hw->pcm_ops->run_in (hw);
+
+ min = audio_pcm_hw_find_min_in (hw);
+ hw->total_samples_captured += captured - min;
+ hw->ts_helper += captured;
+
+ for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {
+ sw->total_hw_samples_acquired -= min;
+
+ if (sw->active) {
+ int avail;
+
+ avail = audio_get_avail (sw);
+ if (avail > 0) {
+ sw->callback.fn (sw->callback.opaque, avail);
+ }
+ }
+ }
+ }
+}
+
+static void audio_timer (void *opaque)
+{
+ AudioState *s = opaque;
+
+ audio_run_out (s);
+ audio_run_in (s);
+
+ qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
+}
+
+static struct audio_option audio_options[] = {
+ /* DAC */
+ {"DAC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_out.enabled,
+ "Use fixed settings for host DAC", NULL, 0},
+
+ {"DAC_FIXED_FREQ", AUD_OPT_INT, &conf.fixed_out.settings.freq,
+ "Frequency for fixed host DAC", NULL, 0},
+
+ {"DAC_FIXED_FMT", AUD_OPT_FMT, &conf.fixed_out.settings.fmt,
+ "Format for fixed host DAC", NULL, 0},
+
+ {"DAC_FIXED_CHANNELS", AUD_OPT_INT, &conf.fixed_out.settings.nchannels,
+ "Number of channels for fixed DAC (1 - mono, 2 - stereo)", NULL, 0},
+
+ {"DAC_VOICES", AUD_OPT_INT, &conf.fixed_out.nb_voices,
+ "Number of voices for DAC", NULL, 0},
+
+ /* ADC */
+ {"ADC_FIXED_SETTINGS", AUD_OPT_BOOL, &conf.fixed_in.enabled,
+ "Use fixed settings for host ADC", NULL, 0},
+
+ {"ADC_FIXED_FREQ", AUD_OPT_INT, &conf.fixed_in.settings.freq,
+ "Frequency for fixed host ADC", NULL, 0},
+
+ {"ADC_FIXED_FMT", AUD_OPT_FMT, &conf.fixed_in.settings.fmt,
+ "Format for fixed host ADC", NULL, 0},
+
+ {"ADC_FIXED_CHANNELS", AUD_OPT_INT, &conf.fixed_in.settings.nchannels,
+ "Number of channels for fixed ADC (1 - mono, 2 - stereo)", NULL, 0},
+
+ {"ADC_VOICES", AUD_OPT_INT, &conf.fixed_in.nb_voices,
+ "Number of voices for ADC", NULL, 0},
+
+ /* Misc */
+ {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hz,
+ "Timer period in HZ (0 - use lowest possible)", NULL, 0},
+
+ {"PLIVE", AUD_OPT_BOOL, &conf.plive,
+ "(undocumented)", NULL, 0},
+
+ {"LOG_TO_MONITOR", AUD_OPT_BOOL, &conf.log_to_monitor,
+ "print logging messages to montior instead of stderr", NULL, 0},
+
+ {NULL, 0, NULL, NULL, NULL, 0}
+};
+
+static void audio_pp_nb_voices (const char *typ, int nb)
+{
+ switch (nb) {
+ case 0:
+ printf ("Does not support %s\n", typ);
+ break;
+ case 1:
+ printf ("One %s voice\n", typ);
+ break;
+ case INT_MAX:
+ printf ("Theoretically supports many %s voices\n", typ);
+ break;
+ default:
+ printf ("Theoretically supports upto %d %s voices\n", nb, typ);
+ break;
+ }
+
+}
+
+void AUD_help (void)
+{
+ size_t i;
+
+ audio_process_options ("AUDIO", audio_options);
+ for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
+ struct audio_driver *d = drvtab[i];
+ if (d->options) {
+ audio_process_options (d->name, d->options);
+ }
+ }
+
+ printf ("Audio options:\n");
+ audio_print_options ("AUDIO", audio_options);
+ printf ("\n");
+
+ printf ("Available drivers:\n");
+
+ for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
+ struct audio_driver *d = drvtab[i];
+
+ printf ("Name: %s\n", d->name);
+ printf ("Description: %s\n", d->descr);
+
+ audio_pp_nb_voices ("playback", d->max_voices_out);
+ audio_pp_nb_voices ("capture", d->max_voices_in);
+
+ if (d->options) {
+ printf ("Options:\n");
+ audio_print_options (d->name, d->options);
+ }
+ else {
+ printf ("No options\n");
+ }
+ printf ("\n");
+ }
+
+ printf (
+ "Options are settable through environment variables.\n"
+ "Example:\n"
+#ifdef _WIN32
+ " set QEMU_AUDIO_DRV=wav\n"
+ " set QEMU_WAV_PATH=c:\\tune.wav\n"
+#else
+ " export QEMU_AUDIO_DRV=wav\n"
+ " export QEMU_WAV_PATH=$HOME/tune.wav\n"
+ "(for csh replace export with setenv in the above)\n"
+#endif
+ " qemu ...\n\n"
+ );
+}
+
+static int audio_driver_init (AudioState *s, struct audio_driver *drv)
+{
+ if (drv->options) {
+ audio_process_options (drv->name, drv->options);
+ }
+ s->drv_opaque = drv->init ();
+
+ if (s->drv_opaque) {
+ audio_init_nb_voices_out (s, drv);
+ audio_init_nb_voices_in (s, drv);
+ s->drv = drv;
+ return 0;
+ }
+ else {
+ dolog ("Could not init `%s' audio driver\n", drv->name);
+ return -1;
+ }
+}
+
+static void audio_vm_change_state_handler (void *opaque, int running)
+{
+ AudioState *s = opaque;
+ HWVoiceOut *hwo = NULL;
+ HWVoiceIn *hwi = NULL;
+ int op = running ? VOICE_ENABLE : VOICE_DISABLE;
+
+ while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
+ hwo->pcm_ops->ctl_out (hwo, op);
+ }
+
+ while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
+ hwi->pcm_ops->ctl_in (hwi, op);
+ }
+}
+
+static void audio_atexit (void)
+{
+ AudioState *s = &glob_audio_state;
+ HWVoiceOut *hwo = NULL;
+ HWVoiceIn *hwi = NULL;
+
+ while ((hwo = audio_pcm_hw_find_any_enabled_out (s, hwo))) {
+ hwo->pcm_ops->ctl_out (hwo, VOICE_DISABLE);
+ hwo->pcm_ops->fini_out (hwo);
+ }
+
+ while ((hwi = audio_pcm_hw_find_any_enabled_in (s, hwi))) {
+ hwi->pcm_ops->ctl_in (hwi, VOICE_DISABLE);
+ hwi->pcm_ops->fini_in (hwi);
+ }
+
+ if (s->drv) {
+ s->drv->fini (s->drv_opaque);
+ }
+}
+
+static void audio_save (QEMUFile *f, void *opaque)
+{
+ (void) f;
+ (void) opaque;
+}
+
+static int audio_load (QEMUFile *f, void *opaque, int version_id)
+{
+ (void) f;
+ (void) opaque;
+
+ if (version_id != 1) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card)
+{
+ card->audio = s;
+ card->name = qemu_strdup (name);
+ memset (&card->entries, 0, sizeof (card->entries));
+ LIST_INSERT_HEAD (&s->card_head, card, entries);
+}
+
+void AUD_remove_card (QEMUSoundCard *card)
+{
+ LIST_REMOVE (card, entries);
+ card->audio = NULL;
+ qemu_free (card->name);
+}
+
+AudioState *AUD_init (void)
+{
+ size_t i;
+ int done = 0;
+ const char *drvname;
+ AudioState *s = &glob_audio_state;
+
+ LIST_INIT (&s->hw_head_out);
+ LIST_INIT (&s->hw_head_in);
+ atexit (audio_atexit);
+
+ s->ts = qemu_new_timer (vm_clock, audio_timer, s);
+ if (!s->ts) {
+ dolog ("Could not create audio timer\n");
+ return NULL;
+ }
+
+ audio_process_options ("AUDIO", audio_options);
+
+ s->nb_hw_voices_out = conf.fixed_out.nb_voices;
+ s->nb_hw_voices_in = conf.fixed_in.nb_voices;
+
+ if (s->nb_hw_voices_out <= 0) {
+ dolog ("Bogus number of playback voices %d, setting to 1\n",
+ s->nb_hw_voices_out);
+ s->nb_hw_voices_out = 1;
+ }
+
+ if (s->nb_hw_voices_in <= 0) {
+ dolog ("Bogus number of capture voices %d, setting to 0\n",
+ s->nb_hw_voices_in);
+ s->nb_hw_voices_in = 0;
+ }
+
+ {
+ int def;
+ drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);
+ }
+
+ if (drvname) {
+ int found = 0;
+
+ for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
+ if (!strcmp (drvname, drvtab[i]->name)) {
+ done = !audio_driver_init (s, drvtab[i]);
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ dolog ("Unknown audio driver `%s'\n", drvname);
+ dolog ("Run with -audio-help to list available drivers\n");
+ }
+ }
+
+ if (!done) {
+ for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
+ if (drvtab[i]->can_be_default) {
+ done = !audio_driver_init (s, drvtab[i]);
+ }
+ }
+ }
+
+ if (!done) {
+ done = !audio_driver_init (s, &no_audio_driver);
+ if (!done) {
+ dolog ("Could not initialize audio subsystem\n");
+ }
+ else {
+ dolog ("warning: Using timer based audio emulation\n");
+ }
+ }
+
+ if (done) {
+ VMChangeStateEntry *e;
+
+ if (conf.period.hz <= 0) {
+ if (conf.period.hz < 0) {
+ dolog ("warning: Timer period is negative - %d "
+ "treating as zero\n",
+ conf.period.hz);
+ }
+ conf.period.ticks = 1;
+ }
+ else {
+ conf.period.ticks = ticks_per_sec / conf.period.hz;
+ }
+
+ e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler,
s);
+ if (!e) {
+ dolog ("warning: Could not register change state handler\n"
+ "(Audio can continue looping even after stopping the
VM)\n");
+ }
+ }
+ else {
+ qemu_del_timer (s->ts);
+ return NULL;
+ }
+
+ LIST_INIT (&s->card_head);
+ register_savevm ("audio", 0, 1, audio_save, audio_load, s);
+ qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + conf.period.ticks);
+ return s;
+}
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/audio.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/audio.h Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,133 @@
+/*
+ * QEMU Audio subsystem header
+ *
+ * Copyright (c) 2003-2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef QEMU_AUDIO_H
+#define QEMU_AUDIO_H
+
+#include "sys-queue.h"
+
+typedef void (*audio_callback_fn_t) (void *opaque, int avail);
+
+typedef enum {
+ AUD_FMT_U8,
+ AUD_FMT_S8,
+ AUD_FMT_U16,
+ AUD_FMT_S16
+} audfmt_e;
+
+typedef struct {
+ int freq;
+ int nchannels;
+ audfmt_e fmt;
+} audsettings_t;
+
+typedef struct AudioState AudioState;
+typedef struct SWVoiceOut SWVoiceOut;
+typedef struct SWVoiceIn SWVoiceIn;
+
+typedef struct QEMUSoundCard {
+ AudioState *audio;
+ char *name;
+ LIST_ENTRY (QEMUSoundCard) entries;
+} QEMUSoundCard;
+
+typedef struct QEMUAudioTimeStamp {
+ uint64_t old_ts;
+} QEMUAudioTimeStamp;
+
+void AUD_vlog (const char *cap, const char *fmt, va_list ap);
+void AUD_log (const char *cap, const char *fmt, ...)
+#ifdef __GNUC__
+ __attribute__ ((__format__ (__printf__, 2, 3)))
+#endif
+ ;
+
+AudioState *AUD_init (void);
+void AUD_help (void);
+void AUD_register_card (AudioState *s, const char *name, QEMUSoundCard *card);
+void AUD_remove_card (QEMUSoundCard *card);
+
+SWVoiceOut *AUD_open_out (
+ QEMUSoundCard *card,
+ SWVoiceOut *sw,
+ const char *name,
+ void *callback_opaque,
+ audio_callback_fn_t callback_fn,
+ audsettings_t *settings,
+ int sw_endian
+ );
+
+void AUD_close_out (QEMUSoundCard *card, SWVoiceOut *sw);
+int AUD_write (SWVoiceOut *sw, void *pcm_buf, int size);
+int AUD_get_buffer_size_out (SWVoiceOut *sw);
+void AUD_set_active_out (SWVoiceOut *sw, int on);
+int AUD_is_active_out (SWVoiceOut *sw);
+
+void AUD_init_time_stamp_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
+uint64_t AUD_get_elapsed_usec_out (SWVoiceOut *sw, QEMUAudioTimeStamp *ts);
+
+SWVoiceIn *AUD_open_in (
+ QEMUSoundCard *card,
+ SWVoiceIn *sw,
+ const char *name,
+ void *callback_opaque,
+ audio_callback_fn_t callback_fn,
+ audsettings_t *settings,
+ int sw_endian
+ );
+
+void AUD_close_in (QEMUSoundCard *card, SWVoiceIn *sw);
+int AUD_read (SWVoiceIn *sw, void *pcm_buf, int size);
+void AUD_set_active_in (SWVoiceIn *sw, int on);
+int AUD_is_active_in (SWVoiceIn *sw);
+
+void AUD_init_time_stamp_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
+uint64_t AUD_get_elapsed_usec_in (SWVoiceIn *sw, QEMUAudioTimeStamp *ts);
+
+static inline void *advance (void *p, int incr)
+{
+ uint8_t *d = p;
+ return (d + incr);
+}
+
+uint32_t popcount (uint32_t u);
+inline uint32_t lsbindex (uint32_t u);
+
+#ifdef __GNUC__
+#define audio_MIN(a, b) ( __extension__ ({ \
+ __typeof (a) ta = a; \
+ __typeof (b) tb = b; \
+ ((ta)>(tb)?(tb):(ta)); \
+}))
+
+#define audio_MAX(a, b) ( __extension__ ({ \
+ __typeof (a) ta = a; \
+ __typeof (b) tb = b; \
+ ((ta)<(tb)?(tb):(ta)); \
+}))
+#else
+#define audio_MIN(a, b) ((a)>(b)?(b):(a))
+#define audio_MAX(a, b) ((a)<(b)?(b):(a))
+#endif
+
+#endif /* audio.h */
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/audio_int.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/audio_int.h Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,268 @@
+/*
+ * QEMU Audio subsystem header
+ *
+ * Copyright (c) 2003-2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef QEMU_AUDIO_INT_H
+#define QEMU_AUDIO_INT_H
+
+#ifdef CONFIG_COREAUDIO
+#define FLOAT_MIXENG
+/* #define RECIPROCAL */
+#endif
+#include "mixeng.h"
+
+struct audio_pcm_ops;
+
+typedef enum {
+ AUD_OPT_INT,
+ AUD_OPT_FMT,
+ AUD_OPT_STR,
+ AUD_OPT_BOOL
+} audio_option_tag_e;
+
+struct audio_option {
+ const char *name;
+ audio_option_tag_e tag;
+ void *valp;
+ const char *descr;
+ int *overridenp;
+ int overriden;
+};
+
+struct audio_callback {
+ void *opaque;
+ audio_callback_fn_t fn;
+};
+
+struct audio_pcm_info {
+ int bits;
+ int sign;
+ int freq;
+ int nchannels;
+ int align;
+ int shift;
+ int bytes_per_second;
+ int swap_endian;
+};
+
+typedef struct HWVoiceOut {
+ int enabled;
+ int pending_disable;
+ int valid;
+ struct audio_pcm_info info;
+
+ f_sample *clip;
+
+ int rpos;
+ uint64_t ts_helper;
+
+ st_sample_t *mix_buf;
+
+ int samples;
+ LIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
+ struct audio_pcm_ops *pcm_ops;
+ LIST_ENTRY (HWVoiceOut) entries;
+} HWVoiceOut;
+
+typedef struct HWVoiceIn {
+ int enabled;
+ struct audio_pcm_info info;
+
+ t_sample *conv;
+
+ int wpos;
+ int total_samples_captured;
+ uint64_t ts_helper;
+
+ st_sample_t *conv_buf;
+
+ int samples;
+ LIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
+ struct audio_pcm_ops *pcm_ops;
+ LIST_ENTRY (HWVoiceIn) entries;
+} HWVoiceIn;
+
+struct SWVoiceOut {
+ struct audio_pcm_info info;
+ t_sample *conv;
+ int64_t ratio;
+ st_sample_t *buf;
+ void *rate;
+ int total_hw_samples_mixed;
+ int active;
+ int empty;
+ HWVoiceOut *hw;
+ char *name;
+ volume_t vol;
+ struct audio_callback callback;
+ LIST_ENTRY (SWVoiceOut) entries;
+};
+
+struct SWVoiceIn {
+ int active;
+ struct audio_pcm_info info;
+ int64_t ratio;
+ void *rate;
+ int total_hw_samples_acquired;
+ st_sample_t *buf;
+ f_sample *clip;
+ HWVoiceIn *hw;
+ char *name;
+ volume_t vol;
+ struct audio_callback callback;
+ LIST_ENTRY (SWVoiceIn) entries;
+};
+
+struct audio_driver {
+ const char *name;
+ const char *descr;
+ struct audio_option *options;
+ void *(*init) (void);
+ void (*fini) (void *);
+ struct audio_pcm_ops *pcm_ops;
+ int can_be_default;
+ int max_voices_out;
+ int max_voices_in;
+ int voice_size_out;
+ int voice_size_in;
+};
+
+struct audio_pcm_ops {
+ int (*init_out)(HWVoiceOut *hw, audsettings_t *as);
+ void (*fini_out)(HWVoiceOut *hw);
+ int (*run_out) (HWVoiceOut *hw);
+ int (*write) (SWVoiceOut *sw, void *buf, int size);
+ int (*ctl_out) (HWVoiceOut *hw, int cmd, ...);
+
+ int (*init_in) (HWVoiceIn *hw, audsettings_t *as);
+ void (*fini_in) (HWVoiceIn *hw);
+ int (*run_in) (HWVoiceIn *hw);
+ int (*read) (SWVoiceIn *sw, void *buf, int size);
+ int (*ctl_in) (HWVoiceIn *hw, int cmd, ...);
+};
+
+struct AudioState {
+ struct audio_driver *drv;
+ void *drv_opaque;
+
+ QEMUTimer *ts;
+ LIST_HEAD (card_head, QEMUSoundCard) card_head;
+ LIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
+ LIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
+ int nb_hw_voices_out;
+ int nb_hw_voices_in;
+};
+
+extern struct audio_driver no_audio_driver;
+extern struct audio_driver oss_audio_driver;
+extern struct audio_driver sdl_audio_driver;
+extern struct audio_driver wav_audio_driver;
+extern struct audio_driver fmod_audio_driver;
+extern struct audio_driver alsa_audio_driver;
+extern struct audio_driver coreaudio_audio_driver;
+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_info_clear_buf (struct audio_pcm_info *info, void *buf, int
len);
+
+int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int len);
+int audio_pcm_hw_get_live_in (HWVoiceIn *hw);
+
+int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int len);
+int audio_pcm_hw_get_live_out (HWVoiceOut *hw);
+int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live);
+
+int audio_bug (const char *funcname, int cond);
+void *audio_calloc (const char *funcname, int nmemb, size_t size);
+
+#define VOICE_ENABLE 1
+#define VOICE_DISABLE 2
+
+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__
+#define GCC_ATTR __attribute__ ((__unused__, __format__ (__printf__, 1, 2)))
+#define INIT_FIELD(f) . f
+#define GCC_FMT_ATTR(n, m) __attribute__ ((__format__ (__printf__, n, m)))
+#else
+#define GCC_ATTR /**/
+#define INIT_FIELD(f) /**/
+#define GCC_FMT_ATTR(n, m)
+#endif
+
+static void GCC_ATTR dolog (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+}
+
+#ifdef DEBUG
+static void GCC_ATTR ldebug (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+}
+#else
+#if defined NDEBUG && defined __GNUC__
+#define ldebug(...)
+#elif defined NDEBUG && defined _MSC_VER
+#define ldebug __noop
+#else
+static void GCC_ATTR ldebug (const char *fmt, ...)
+{
+ (void) fmt;
+}
+#endif
+#endif
+
+#undef GCC_ATTR
+
+#define AUDIO_STRINGIFY_(n) #n
+#define AUDIO_STRINGIFY(n) AUDIO_STRINGIFY_(n)
+
+#if defined _MSC_VER || defined __GNUC__
+#define AUDIO_FUNC __FUNCTION__
+#else
+#define AUDIO_FUNC __FILE__ ":" AUDIO_STRINGIFY (__LINE__)
+#endif
+
+#endif /* audio_int.h */
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/audio_template.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/audio_template.h Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,565 @@
+/*
+ * QEMU Audio subsystem header
+ *
+ * Copyright (c) 2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef DAC
+#define NAME "playback"
+#define HWBUF hw->mix_buf
+#define TYPE out
+#define HW HWVoiceOut
+#define SW SWVoiceOut
+#else
+#define NAME "capture"
+#define TYPE in
+#define HW HWVoiceIn
+#define SW SWVoiceIn
+#define HWBUF hw->conv_buf
+#endif
+
+static void glue (audio_init_nb_voices_, TYPE) (
+ AudioState *s,
+ struct audio_driver *drv
+ )
+{
+ int max_voices = glue (drv->max_voices_, TYPE);
+ int voice_size = glue (drv->voice_size_, TYPE);
+
+ if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
+ if (!max_voices) {
+#ifdef DAC
+ dolog ("Driver `%s' does not support " NAME "\n", drv->name);
+#endif
+ }
+ else {
+ dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n",
+ drv->name,
+ glue (s->nb_hw_voices_, TYPE),
+ max_voices);
+ }
+ glue (s->nb_hw_voices_, TYPE) = max_voices;
+ }
+
+ if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) {
+ dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
+ drv->name, max_voices);
+ glue (s->nb_hw_voices_, TYPE) = 0;
+ }
+
+ if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) {
+ dolog ("drv=`%s' voice_size=%d max_voices=0\n",
+ drv->name, voice_size);
+ }
+}
+
+static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
+{
+ if (HWBUF) {
+ qemu_free (HWBUF);
+ }
+
+ HWBUF = NULL;
+}
+
+static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
+{
+ HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (st_sample_t));
+ if (!HWBUF) {
+ dolog ("Could not allocate " NAME " buffer (%d samples)\n",
+ hw->samples);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
+{
+ if (sw->buf) {
+ qemu_free (sw->buf);
+ }
+
+ if (sw->rate) {
+ st_rate_stop (sw->rate);
+ }
+
+ sw->buf = NULL;
+ sw->rate = NULL;
+}
+
+static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
+{
+ int samples;
+
+#ifdef DAC
+ samples = sw->hw->samples;
+#else
+ samples = ((int64_t) sw->hw->samples << 32) / sw->ratio;
+#endif
+
+ sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (st_sample_t));
+ if (!sw->buf) {
+ dolog ("Could not allocate buffer for `%s' (%d samples)\n",
+ SW_NAME (sw), samples);
+ return -1;
+ }
+
+#ifdef DAC
+ sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq);
+#else
+ sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
+#endif
+ if (!sw->rate) {
+ qemu_free (sw->buf);
+ sw->buf = NULL;
+ return -1;
+ }
+ return 0;
+}
+
+static int glue (audio_pcm_sw_init_, TYPE) (
+ SW *sw,
+ HW *hw,
+ const char *name,
+ audsettings_t *as,
+ int endian
+ )
+{
+ int err;
+
+ audio_pcm_init_info (&sw->info, as, audio_need_to_swap_endian (endian));
+ sw->hw = hw;
+ sw->active = 0;
+#ifdef DAC
+ sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
+ sw->total_hw_samples_mixed = 0;
+ sw->empty = 1;
+#else
+ sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
+#endif
+
+#ifdef DAC
+ sw->conv = mixeng_conv
+#else
+ sw->clip = mixeng_clip
+#endif
+ [sw->info.nchannels == 2]
+ [sw->info.sign]
+ [sw->info.swap_endian]
+ [sw->info.bits == 16];
+
+ sw->name = qemu_strdup (name);
+ err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
+ if (err) {
+ qemu_free (sw->name);
+ sw->name = NULL;
+ }
+ return err;
+}
+
+static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
+{
+ glue (audio_pcm_sw_free_resources_, TYPE) (sw);
+ if (sw->name) {
+ qemu_free (sw->name);
+ sw->name = NULL;
+ }
+}
+
+static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
+{
+ LIST_INSERT_HEAD (&hw->sw_head, sw, entries);
+}
+
+static void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw)
+{
+ LIST_REMOVE (sw, entries);
+}
+
+static void glue (audio_pcm_hw_gc_, TYPE) (AudioState *s, HW **hwp)
+{
+ HW *hw = *hwp;
+
+ if (!hw->sw_head.lh_first) {
+ LIST_REMOVE (hw, entries);
+ glue (s->nb_hw_voices_, TYPE) += 1;
+ glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
+ glue (hw->pcm_ops->fini_, TYPE) (hw);
+ qemu_free (hw);
+ *hwp = NULL;
+ }
+}
+
+static HW *glue (audio_pcm_hw_find_any_, TYPE) (AudioState *s, HW *hw)
+{
+ return hw ? hw->entries.le_next : s->glue (hw_head_, TYPE).lh_first;
+}
+
+static HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (AudioState *s, HW *hw)
+{
+ while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
+ if (hw->enabled) {
+ return hw;
+ }
+ }
+ return NULL;
+}
+
+static HW *glue (audio_pcm_hw_find_specific_, TYPE) (
+ AudioState *s,
+ HW *hw,
+ audsettings_t *as
+ )
+{
+ while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (s, hw))) {
+ if (audio_pcm_info_eq (&hw->info, as)) {
+ return hw;
+ }
+ }
+ return NULL;
+}
+
+static HW *glue (audio_pcm_hw_add_new_, TYPE) (AudioState *s, audsettings_t
*as)
+{
+ HW *hw;
+ struct audio_driver *drv = s->drv;
+
+ if (!glue (s->nb_hw_voices_, TYPE)) {
+ return NULL;
+ }
+
+ if (audio_bug (AUDIO_FUNC, !drv)) {
+ dolog ("No host audio driver\n");
+ return NULL;
+ }
+
+ if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) {
+ dolog ("Host audio driver without pcm_ops\n");
+ return NULL;
+ }
+
+ hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE));
+ if (!hw) {
+ dolog ("Can not allocate voice `%s' size %d\n",
+ drv->name, glue (drv->voice_size_, TYPE));
+ return NULL;
+ }
+
+ hw->pcm_ops = drv->pcm_ops;
+ LIST_INIT (&hw->sw_head);
+
+ if (glue (hw->pcm_ops->init_, TYPE) (hw, as)) {
+ goto err0;
+ }
+
+ if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) {
+ dolog ("hw->samples=%d\n", hw->samples);
+ goto err1;
+ }
+
+#ifdef DAC
+ hw->clip = mixeng_clip
+#else
+ hw->conv = mixeng_conv
+#endif
+ [hw->info.nchannels == 2]
+ [hw->info.sign]
+ [hw->info.swap_endian]
+ [hw->info.bits == 16];
+
+ if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) {
+ goto err1;
+ }
+
+ LIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries);
+ glue (s->nb_hw_voices_, TYPE) -= 1;
+ return hw;
+
+ err1:
+ glue (hw->pcm_ops->fini_, TYPE) (hw);
+ err0:
+ qemu_free (hw);
+ return NULL;
+}
+
+static HW *glue (audio_pcm_hw_add_, TYPE) (AudioState *s, audsettings_t *as)
+{
+ HW *hw;
+
+ if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) {
+ hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
+ if (hw) {
+ return hw;
+ }
+ }
+
+ hw = glue (audio_pcm_hw_find_specific_, TYPE) (s, NULL, as);
+ if (hw) {
+ return hw;
+ }
+
+ hw = glue (audio_pcm_hw_add_new_, TYPE) (s, as);
+ if (hw) {
+ return hw;
+ }
+
+ return glue (audio_pcm_hw_find_any_, TYPE) (s, NULL);
+}
+
+static SW *glue (audio_pcm_create_voice_pair_, TYPE) (
+ AudioState *s,
+ const char *sw_name,
+ audsettings_t *as,
+ int sw_endian
+ )
+{
+ SW *sw;
+ HW *hw;
+ audsettings_t hw_as;
+
+ if (glue (conf.fixed_, TYPE).enabled) {
+ hw_as = glue (conf.fixed_, TYPE).settings;
+ }
+ else {
+ hw_as = *as;
+ }
+
+ sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw));
+ if (!sw) {
+ dolog ("Could not allocate soft voice `%s' (%zu bytes)\n",
+ sw_name ? sw_name : "unknown", sizeof (*sw));
+ goto err1;
+ }
+
+ hw = glue (audio_pcm_hw_add_, TYPE) (s, &hw_as);
+ if (!hw) {
+ goto err2;
+ }
+
+ glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw);
+
+ if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as, sw_endian)) {
+ goto err3;
+ }
+
+ return sw;
+
+err3:
+ glue (audio_pcm_hw_del_sw_, TYPE) (sw);
+ glue (audio_pcm_hw_gc_, TYPE) (s, &hw);
+err2:
+ qemu_free (sw);
+err1:
+ return NULL;
+}
+
+static void glue (audio_close_, TYPE) (AudioState *s, SW *sw)
+{
+ glue (audio_pcm_sw_fini_, TYPE) (sw);
+ glue (audio_pcm_hw_del_sw_, TYPE) (sw);
+ glue (audio_pcm_hw_gc_, TYPE) (s, &sw->hw);
+ qemu_free (sw);
+}
+
+void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
+{
+ if (sw) {
+ if (audio_bug (AUDIO_FUNC, !card || !card->audio)) {
+ dolog ("card=%p card->audio=%p\n",
+ card, card ? card->audio : NULL);
+ return;
+ }
+
+ glue (audio_close_, TYPE) (card->audio, sw);
+ }
+}
+
+SW *glue (AUD_open_, TYPE) (
+ QEMUSoundCard *card,
+ SW *sw,
+ const char *name,
+ void *callback_opaque ,
+ audio_callback_fn_t callback_fn,
+ audsettings_t *as,
+ int sw_endian
+ )
+{
+ AudioState *s;
+#ifdef DAC
+ int live = 0;
+ SW *old_sw = NULL;
+#endif
+
+ ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
+ name, as->freq, as->nchannels, as->fmt);
+
+ if (audio_bug (AUDIO_FUNC,
+ !card || !card->audio || !name || !callback_fn || !as)) {
+ dolog ("card=%p card->audio=%p name=%p callback_fn=%p as=%p\n",
+ card, card ? card->audio : NULL, name, callback_fn, as);
+ goto fail;
+ }
+
+ s = card->audio;
+
+ if (audio_bug (AUDIO_FUNC, audio_validate_settigs (as))) {
+ audio_print_settings (as);
+ goto fail;
+ }
+
+ if (audio_bug (AUDIO_FUNC, !s->drv)) {
+ dolog ("Can not open `%s' (no host audio driver)\n", name);
+ goto fail;
+ }
+
+ if (sw && audio_pcm_info_eq (&sw->info, as)) {
+ return sw;
+ }
+
+#ifdef DAC
+ if (conf.plive && sw && (!sw->active && !sw->empty)) {
+ live = sw->total_hw_samples_mixed;
+
+#ifdef DEBUG_PLIVE
+ dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw),
live);
+ dolog ("Old %s freq %d, bits %d, channels %d\n",
+ SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels);
+ dolog ("New %s freq %d, bits %d, channels %d\n",
+ name,
+ freq,
+ (fmt == AUD_FMT_S16 || fmt == AUD_FMT_U16) ? 16 : 8,
+ nchannels);
+#endif
+
+ if (live) {
+ old_sw = sw;
+ old_sw->callback.fn = NULL;
+ sw = NULL;
+ }
+ }
+#endif
+
+ if (!glue (conf.fixed_, TYPE).enabled && sw) {
+ glue (AUD_close_, TYPE) (card, sw);
+ sw = NULL;
+ }
+
+ if (sw) {
+ HW *hw = sw->hw;
+
+ if (!hw) {
+ dolog ("Internal logic error voice `%s' has no hardware store\n",
+ SW_NAME (sw));
+ goto fail;
+ }
+
+ glue (audio_pcm_sw_fini_, TYPE) (sw);
+ if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as, sw_endian)) {
+ goto fail;
+ }
+ }
+ else {
+ sw = glue (audio_pcm_create_voice_pair_, TYPE) (s, name, as,
sw_endian);
+ if (!sw) {
+ dolog ("Failed to create voice `%s'\n", name);
+ return NULL;
+ }
+ }
+
+ if (sw) {
+ sw->vol = nominal_volume;
+ sw->callback.fn = callback_fn;
+ sw->callback.opaque = callback_opaque;
+
+#ifdef DAC
+ if (live) {
+ int mixed =
+ (live << old_sw->info.shift)
+ * old_sw->info.bytes_per_second
+ / sw->info.bytes_per_second;
+
+#ifdef DEBUG_PLIVE
+ dolog ("Silence will be mixed %d\n", mixed);
+#endif
+ sw->total_hw_samples_mixed += mixed;
+ }
+#endif
+
+#ifdef DEBUG_AUDIO
+ dolog ("%s\n", name);
+ audio_pcm_print_info ("hw", &sw->hw->info);
+ audio_pcm_print_info ("sw", &sw->info);
+#endif
+ }
+
+ return sw;
+
+ fail:
+ glue (AUD_close_, TYPE) (card, sw);
+ return NULL;
+}
+
+int glue (AUD_is_active_, TYPE) (SW *sw)
+{
+ return sw ? sw->active : 0;
+}
+
+void glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
+{
+ if (!sw) {
+ return;
+ }
+
+ ts->old_ts = sw->hw->ts_helper;
+}
+
+uint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts)
+{
+ uint64_t delta, cur_ts, old_ts;
+
+ if (!sw) {
+ return 0;
+ }
+
+ cur_ts = sw->hw->ts_helper;
+ old_ts = ts->old_ts;
+ /* dolog ("cur %lld old %lld\n", cur_ts, old_ts); */
+
+ if (cur_ts >= old_ts) {
+ delta = cur_ts - old_ts;
+ }
+ else {
+ delta = UINT64_MAX - old_ts + cur_ts;
+ }
+
+ if (!delta) {
+ return 0;
+ }
+
+ return (delta * sw->hw->info.freq) / 1000000;
+}
+
+#undef TYPE
+#undef HW
+#undef SW
+#undef HWBUF
+#undef NAME
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/coreaudio.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/coreaudio.c Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,564 @@
+/*
+ * QEMU OS X CoreAudio audio driver
+ *
+ * Copyright (c) 2005 Mike Kronenberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <CoreAudio/CoreAudio.h>
+#include <string.h> /* strerror */
+#include <pthread.h> /* pthread_X */
+
+#include "vl.h"
+
+#define AUDIO_CAP "coreaudio"
+#include "audio_int.h"
+
+struct {
+ int buffer_frames;
+ int nbuffers;
+ int isAtexit;
+} conf = {
+ .buffer_frames = 512,
+ .nbuffers = 4,
+ .isAtexit = 0
+};
+
+typedef struct coreaudioVoiceOut {
+ HWVoiceOut hw;
+ pthread_mutex_t mutex;
+ int isAtexit;
+ AudioDeviceID outputDeviceID;
+ UInt32 audioDevicePropertyBufferFrameSize;
+ AudioStreamBasicDescription outputStreamBasicDescription;
+ int live;
+ int decr;
+ int rpos;
+} coreaudioVoiceOut;
+
+static void coreaudio_logstatus (OSStatus status)
+{
+ char *str = "BUG";
+
+ switch(status) {
+ case kAudioHardwareNoError:
+ str = "kAudioHardwareNoError";
+ break;
+
+ case kAudioHardwareNotRunningError:
+ str = "kAudioHardwareNotRunningError";
+ break;
+
+ case kAudioHardwareUnspecifiedError:
+ str = "kAudioHardwareUnspecifiedError";
+ break;
+
+ case kAudioHardwareUnknownPropertyError:
+ str = "kAudioHardwareUnknownPropertyError";
+ break;
+
+ case kAudioHardwareBadPropertySizeError:
+ str = "kAudioHardwareBadPropertySizeError";
+ break;
+
+ case kAudioHardwareIllegalOperationError:
+ str = "kAudioHardwareIllegalOperationError";
+ break;
+
+ case kAudioHardwareBadDeviceError:
+ str = "kAudioHardwareBadDeviceError";
+ break;
+
+ case kAudioHardwareBadStreamError:
+ str = "kAudioHardwareBadStreamError";
+ break;
+
+ case kAudioHardwareUnsupportedOperationError:
+ str = "kAudioHardwareUnsupportedOperationError";
+ break;
+
+ case kAudioDeviceUnsupportedFormatError:
+ str = "kAudioDeviceUnsupportedFormatError";
+ break;
+
+ case kAudioDevicePermissionsError:
+ str = "kAudioDevicePermissionsError";
+ break;
+
+ default:
+ AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);
+ return;
+ }
+
+ AUD_log (AUDIO_CAP, "Reason: %s\n", str);
+}
+
+static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (
+ OSStatus status,
+ const char *fmt,
+ ...
+ )
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ AUD_log (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ coreaudio_logstatus (status);
+}
+
+static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (
+ OSStatus status,
+ const char *typ,
+ const char *fmt,
+ ...
+ )
+{
+ va_list ap;
+
+ AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ coreaudio_logstatus (status);
+}
+
+static inline UInt32 isPlaying (AudioDeviceID outputDeviceID)
+{
+ OSStatus status;
+ UInt32 result = 0;
+ UInt32 propertySize = sizeof(outputDeviceID);
+ status = AudioDeviceGetProperty(
+ outputDeviceID, 0, 0,
+ kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr(status,
+ "Could not determine whether Device is playing\n");
+ }
+ return result;
+}
+
+static void coreaudio_atexit (void)
+{
+ conf.isAtexit = 1;
+}
+
+static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name)
+{
+ int err;
+
+ err = pthread_mutex_lock (&core->mutex);
+ if (err) {
+ dolog ("Could not lock voice for %s\nReason: %s\n",
+ fn_name, strerror (err));
+ return -1;
+ }
+ return 0;
+}
+
+static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name)
+{
+ int err;
+
+ err = pthread_mutex_unlock (&core->mutex);
+ if (err) {
+ dolog ("Could not unlock voice for %s\nReason: %s\n",
+ fn_name, strerror (err));
+ return -1;
+ }
+ return 0;
+}
+
+static int coreaudio_run_out (HWVoiceOut *hw)
+{
+ int live, decr;
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
+
+ if (coreaudio_lock (core, "coreaudio_run_out")) {
+ return 0;
+ }
+
+ live = audio_pcm_hw_get_live_out (hw);
+
+ if (core->decr > live) {
+ ldebug ("core->decr %d live %d core->live %d\n",
+ core->decr,
+ live,
+ core->live);
+ }
+
+ decr = audio_MIN (core->decr, live);
+ core->decr -= decr;
+
+ core->live = live - decr;
+ hw->rpos = core->rpos;
+
+ coreaudio_unlock (core, "coreaudio_run_out");
+ return decr;
+}
+
+/* callback to feed audiooutput buffer */
+static OSStatus audioDeviceIOProc(
+ AudioDeviceID inDevice,
+ const AudioTimeStamp* inNow,
+ const AudioBufferList* inInputData,
+ const AudioTimeStamp* inInputTime,
+ AudioBufferList* outOutputData,
+ const AudioTimeStamp* inOutputTime,
+ void* hwptr)
+{
+ UInt32 frame, frameCount;
+ float *out = outOutputData->mBuffers[0].mData;
+ HWVoiceOut *hw = hwptr;
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
+ int rpos, live;
+ st_sample_t *src;
+#ifndef FLOAT_MIXENG
+#ifdef RECIPROCAL
+ const float scale = 1.f / UINT_MAX;
+#else
+ const float scale = UINT_MAX;
+#endif
+#endif
+
+ if (coreaudio_lock (core, "audioDeviceIOProc")) {
+ inInputTime = 0;
+ return 0;
+ }
+
+ frameCount = core->audioDevicePropertyBufferFrameSize;
+ live = core->live;
+
+ /* if there are not enough samples, set signal and return */
+ if (live < frameCount) {
+ inInputTime = 0;
+ coreaudio_unlock (core, "audioDeviceIOProc(empty)");
+ return 0;
+ }
+
+ rpos = core->rpos;
+ src = hw->mix_buf + rpos;
+
+ /* fill buffer */
+ for (frame = 0; frame < frameCount; frame++) {
+#ifdef FLOAT_MIXENG
+ *out++ = src[frame].l; /* left channel */
+ *out++ = src[frame].r; /* right channel */
+#else
+#ifdef RECIPROCAL
+ *out++ = src[frame].l * scale; /* left channel */
+ *out++ = src[frame].r * scale; /* right channel */
+#else
+ *out++ = src[frame].l / scale; /* left channel */
+ *out++ = src[frame].r / scale; /* right channel */
+#endif
+#endif
+ }
+
+ /* cleanup */
+ mixeng_clear (src, frameCount);
+ rpos = (rpos + frameCount) % hw->samples;
+ core->decr += frameCount;
+ core->rpos = rpos;
+
+ coreaudio_unlock (core, "audioDeviceIOProc");
+ return 0;
+}
+
+static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
+{
+ return audio_pcm_sw_write (sw, buf, len);
+}
+
+static int coreaudio_init_out (HWVoiceOut *hw, audsettings_t *as)
+{
+ OSStatus status;
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
+ UInt32 propertySize;
+ int err;
+ int bits = 8;
+ int endianess = 0;
+ const char *typ = "playback";
+ AudioValueRange frameRange;
+
+ /* create mutex */
+ err = pthread_mutex_init(&core->mutex, NULL);
+ if (err) {
+ dolog("Could not create mutex\nReason: %s\n", strerror (err));
+ return -1;
+ }
+
+ 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)
+ );
+
+ /* open default output device */
+ propertySize = sizeof(core->outputDeviceID);
+ status = AudioHardwareGetProperty(
+ kAudioHardwarePropertyDefaultOutputDevice,
+ &propertySize,
+ &core->outputDeviceID);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ,
+ "Could not get default output Device\n");
+ return -1;
+ }
+ if (core->outputDeviceID == kAudioDeviceUnknown) {
+ dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
+ return -1;
+ }
+
+ /* get minimum and maximum buffer frame sizes */
+ propertySize = sizeof(frameRange);
+ status = AudioDeviceGetProperty(
+ core->outputDeviceID,
+ 0,
+ 0,
+ kAudioDevicePropertyBufferFrameSizeRange,
+ &propertySize,
+ &frameRange);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ,
+ "Could not get device buffer frame range\n");
+ return -1;
+ }
+
+ if (frameRange.mMinimum > conf.buffer_frames) {
+ core->audioDevicePropertyBufferFrameSize = (UInt32)
frameRange.mMinimum;
+ dolog ("warning: Upsizing Buffer Frames to %f\n", frameRange.mMinimum);
+ }
+ else if (frameRange.mMaximum < conf.buffer_frames) {
+ core->audioDevicePropertyBufferFrameSize = (UInt32)
frameRange.mMaximum;
+ dolog ("warning: Downsizing Buffer Frames to %f\n",
frameRange.mMaximum);
+ }
+ else {
+ core->audioDevicePropertyBufferFrameSize = conf.buffer_frames;
+ }
+
+ /* set Buffer Frame Size */
+ propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
+ status = AudioDeviceSetProperty(
+ core->outputDeviceID,
+ NULL,
+ 0,
+ false,
+ kAudioDevicePropertyBufferFrameSize,
+ propertySize,
+ &core->audioDevicePropertyBufferFrameSize);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ,
+ "Could not set device buffer frame size %ld\n",
+ core->audioDevicePropertyBufferFrameSize);
+ return -1;
+ }
+
+ /* get Buffer Frame Size */
+ propertySize = sizeof(core->audioDevicePropertyBufferFrameSize);
+ status = AudioDeviceGetProperty(
+ core->outputDeviceID,
+ 0,
+ false,
+ kAudioDevicePropertyBufferFrameSize,
+ &propertySize,
+ &core->audioDevicePropertyBufferFrameSize);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ,
+ "Could not get device buffer frame size\n");
+ return -1;
+ }
+ hw->samples = conf.nbuffers * core->audioDevicePropertyBufferFrameSize;
+
+ /* get StreamFormat */
+ propertySize = sizeof(core->outputStreamBasicDescription);
+ status = AudioDeviceGetProperty(
+ core->outputDeviceID,
+ 0,
+ false,
+ kAudioDevicePropertyStreamFormat,
+ &propertySize,
+ &core->outputStreamBasicDescription);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ,
+ "Could not get Device Stream properties\n");
+ core->outputDeviceID = kAudioDeviceUnknown;
+ return -1;
+ }
+
+ /* set Samplerate */
+ core->outputStreamBasicDescription.mSampleRate = (Float64) as->freq;
+ propertySize = sizeof(core->outputStreamBasicDescription);
+ status = AudioDeviceSetProperty(
+ core->outputDeviceID,
+ 0,
+ 0,
+ 0,
+ kAudioDevicePropertyStreamFormat,
+ propertySize,
+ &core->outputStreamBasicDescription);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
+ as->freq);
+ core->outputDeviceID = kAudioDeviceUnknown;
+ return -1;
+ }
+
+ /* set Callback */
+ status = AudioDeviceAddIOProc(core->outputDeviceID, audioDeviceIOProc, hw);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
+ core->outputDeviceID = kAudioDeviceUnknown;
+ return -1;
+ }
+
+ /* start Playback */
+ if (!isPlaying(core->outputDeviceID)) {
+ status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr2 (status, typ, "Could not start playback\n");
+ AudioDeviceRemoveIOProc(core->outputDeviceID, audioDeviceIOProc);
+ core->outputDeviceID = kAudioDeviceUnknown;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void coreaudio_fini_out (HWVoiceOut *hw)
+{
+ OSStatus status;
+ int err;
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
+
+ if (!conf.isAtexit) {
+ /* stop playback */
+ if (isPlaying(core->outputDeviceID)) {
+ status = AudioDeviceStop(core->outputDeviceID, audioDeviceIOProc);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr (status, "Could not stop playback\n");
+ }
+ }
+
+ /* remove callback */
+ status = AudioDeviceRemoveIOProc(core->outputDeviceID,
+ audioDeviceIOProc);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr (status, "Could not remove IOProc\n");
+ }
+ }
+ core->outputDeviceID = kAudioDeviceUnknown;
+
+ /* destroy mutex */
+ err = pthread_mutex_destroy(&core->mutex);
+ if (err) {
+ dolog("Could not destroy mutex\nReason: %s\n", strerror (err));
+ }
+}
+
+static int coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
+{
+ OSStatus status;
+ coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
+
+ switch (cmd) {
+ case VOICE_ENABLE:
+ /* start playback */
+ if (!isPlaying(core->outputDeviceID)) {
+ status = AudioDeviceStart(core->outputDeviceID, audioDeviceIOProc);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr (status, "Could not resume playback\n");
+ }
+ }
+ break;
+
+ case VOICE_DISABLE:
+ /* stop playback */
+ if (!conf.isAtexit) {
+ if (isPlaying(core->outputDeviceID)) {
+ status = AudioDeviceStop(core->outputDeviceID,
audioDeviceIOProc);
+ if (status != kAudioHardwareNoError) {
+ coreaudio_logerr (status, "Could not pause playback\n");
+ }
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+static void *coreaudio_audio_init (void)
+{
+ atexit(coreaudio_atexit);
+ return &coreaudio_audio_init;
+}
+
+static void coreaudio_audio_fini (void *opaque)
+{
+ (void) opaque;
+}
+
+static struct audio_option coreaudio_options[] = {
+ {"BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_frames,
+ "Size of the buffer in frames", NULL, 0},
+ {"BUFFER_COUNT", AUD_OPT_INT, &conf.nbuffers,
+ "Number of buffers", NULL, 0},
+ {NULL, 0, NULL, NULL, NULL, 0}
+};
+
+static struct audio_pcm_ops coreaudio_pcm_ops = {
+ coreaudio_init_out,
+ coreaudio_fini_out,
+ coreaudio_run_out,
+ coreaudio_write,
+ coreaudio_ctl_out,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+struct audio_driver coreaudio_audio_driver = {
+ INIT_FIELD (name = ) "coreaudio",
+ INIT_FIELD (descr = )
+ "CoreAudio http://developer.apple.com/audio/coreaudio.html",
+ INIT_FIELD (options = ) coreaudio_options,
+ INIT_FIELD (init = ) coreaudio_audio_init,
+ INIT_FIELD (fini = ) coreaudio_audio_fini,
+ INIT_FIELD (pcm_ops = ) &coreaudio_pcm_ops,
+ INIT_FIELD (can_be_default = ) 1,
+ INIT_FIELD (max_voices_out = ) 1,
+ INIT_FIELD (max_voices_in = ) 0,
+ INIT_FIELD (voice_size_out = ) sizeof (coreaudioVoiceOut),
+ INIT_FIELD (voice_size_in = ) 0
+};
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/dsound_template.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/dsound_template.h Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,282 @@
+/*
+ * QEMU DirectSound audio driver header
+ *
+ * Copyright (c) 2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifdef DSBTYPE_IN
+#define NAME "capture buffer"
+#define TYPE in
+#define IFACE IDirectSoundCaptureBuffer
+#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
+#define FIELD dsound_capture_buffer
+#else
+#define NAME "playback buffer"
+#define TYPE out
+#define IFACE IDirectSoundBuffer
+#define BUFPTR LPDIRECTSOUNDBUFFER
+#define FIELD dsound_buffer
+#endif
+
+static int glue (dsound_unlock_, TYPE) (
+ BUFPTR buf,
+ LPVOID p1,
+ LPVOID p2,
+ DWORD blen1,
+ DWORD blen2
+ )
+{
+ HRESULT hr;
+
+ hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not unlock " NAME "\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int glue (dsound_lock_, TYPE) (
+ BUFPTR buf,
+ struct audio_pcm_info *info,
+ DWORD pos,
+ DWORD len,
+ LPVOID *p1p,
+ LPVOID *p2p,
+ DWORD *blen1p,
+ DWORD *blen2p,
+ int entire
+ )
+{
+ HRESULT hr;
+ int i;
+ LPVOID p1 = NULL, p2 = NULL;
+ DWORD blen1 = 0, blen2 = 0;
+
+ for (i = 0; i < conf.lock_retries; ++i) {
+ hr = glue (IFACE, _Lock) (
+ buf,
+ pos,
+ len,
+ &p1,
+ &blen1,
+ &p2,
+ &blen2,
+ (entire
+#ifdef DSBTYPE_IN
+ ? DSCBLOCK_ENTIREBUFFER
+#else
+ ? DSBLOCK_ENTIREBUFFER
+#endif
+ : 0)
+ );
+
+ if (FAILED (hr)) {
+#ifndef DSBTYPE_IN
+ if (hr == DSERR_BUFFERLOST) {
+ if (glue (dsound_restore_, TYPE) (buf)) {
+ dsound_logerr (hr, "Could not lock " NAME "\n");
+ goto fail;
+ }
+ continue;
+ }
+#endif
+ dsound_logerr (hr, "Could not lock " NAME "\n");
+ goto fail;
+ }
+
+ break;
+ }
+
+ if (i == conf.lock_retries) {
+ dolog ("%d attempts to lock " NAME " failed\n", i);
+ goto fail;
+ }
+
+ if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
+ dolog ("DirectSound returned misaligned buffer %ld %ld\n",
+ blen1, blen2);
+ glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
+ goto fail;
+ }
+
+ if (!p1 && blen1) {
+ dolog ("warning: !p1 && blen1=%ld\n", blen1);
+ blen1 = 0;
+ }
+
+ if (!p2 && blen2) {
+ dolog ("warning: !p2 && blen2=%ld\n", blen2);
+ blen2 = 0;
+ }
+
+ *p1p = p1;
+ *p2p = p2;
+ *blen1p = blen1;
+ *blen2p = blen2;
+ return 0;
+
+ fail:
+ *p1p = NULL - 1;
+ *p2p = NULL - 1;
+ *blen1p = -1;
+ *blen2p = -1;
+ return -1;
+}
+
+#ifdef DSBTYPE_IN
+static void dsound_fini_in (HWVoiceIn *hw)
+#else
+static void dsound_fini_out (HWVoiceOut *hw)
+#endif
+{
+ HRESULT hr;
+#ifdef DSBTYPE_IN
+ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
+#else
+ DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
+#endif
+
+ if (ds->FIELD) {
+ hr = glue (IFACE, _Stop) (ds->FIELD);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not stop " NAME "\n");
+ }
+
+ hr = glue (IFACE, _Release) (ds->FIELD);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not release " NAME "\n");
+ }
+ ds->FIELD = NULL;
+ }
+}
+
+#ifdef DSBTYPE_IN
+static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
+#else
+static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
+#endif
+{
+ int err;
+ HRESULT hr;
+ dsound *s = &glob_dsound;
+ WAVEFORMATEX wfx;
+ audsettings_t obt_as;
+#ifdef DSBTYPE_IN
+ const char *typ = "ADC";
+ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
+ DSCBUFFERDESC bd;
+ DSCBCAPS bc;
+#else
+ const char *typ = "DAC";
+ DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
+ DSBUFFERDESC bd;
+ DSBCAPS bc;
+#endif
+
+ err = waveformat_from_audio_settings (&wfx, as);
+ if (err) {
+ return -1;
+ }
+
+ memset (&bd, 0, sizeof (bd));
+ bd.dwSize = sizeof (bd);
+ bd.lpwfxFormat = &wfx;
+#ifdef DSBTYPE_IN
+ bd.dwBufferBytes = conf.bufsize_in;
+ hr = IDirectSoundCapture_CreateCaptureBuffer (
+ s->dsound_capture,
+ &bd,
+ &ds->dsound_capture_buffer,
+ NULL
+ );
+#else
+ bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
+ bd.dwBufferBytes = conf.bufsize_out;
+ hr = IDirectSound_CreateSoundBuffer (
+ s->dsound,
+ &bd,
+ &ds->dsound_buffer,
+ NULL
+ );
+#endif
+
+ if (FAILED (hr)) {
+ dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
+ return -1;
+ }
+
+ hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
+ if (FAILED (hr)) {
+ dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
+ goto fail0;
+ }
+
+#ifdef DEBUG_DSOUND
+ dolog (NAME "\n");
+ print_wave_format (&wfx);
+#endif
+
+ memset (&bc, 0, sizeof (bc));
+ bc.dwSize = sizeof (bc);
+
+ hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
+ if (FAILED (hr)) {
+ dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
+ goto fail0;
+ }
+
+ err = waveformat_to_audio_settings (&wfx, &obt_as);
+ if (err) {
+ goto fail0;
+ }
+
+ ds->first_time = 1;
+
+ audio_pcm_init_info (&hw->info, &obt_as, audio_need_to_swap_endian (0));
+
+ if (bc.dwBufferBytes & hw->info.align) {
+ dolog (
+ "GetCaps returned misaligned buffer size %ld, alignment %d\n",
+ bc.dwBufferBytes, hw->info.align + 1
+ );
+ }
+ hw->samples = bc.dwBufferBytes >> hw->info.shift;
+
+#ifdef DEBUG_DSOUND
+ dolog ("caps %ld, desc %ld\n",
+ bc.dwBufferBytes, bd.dwBufferBytes);
+
+ dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
+ hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
+#endif
+ return 0;
+
+ fail0:
+ glue (dsound_fini_, TYPE) (hw);
+ return -1;
+}
+
+#undef NAME
+#undef TYPE
+#undef IFACE
+#undef BUFPTR
+#undef FIELD
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/dsoundaudio.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/dsoundaudio.c Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,1076 @@
+/*
+ * QEMU DirectSound audio driver
+ *
+ * Copyright (c) 2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * SEAL 1.07 by Carlos 'pel' Hasan was used as documentation
+ */
+
+#include "vl.h"
+
+#define AUDIO_CAP "dsound"
+#include "audio_int.h"
+
+#include <windows.h>
+#include <objbase.h>
+#include <dsound.h>
+
+/* #define DEBUG_DSOUND */
+
+static struct {
+ int lock_retries;
+ int restore_retries;
+ int getstatus_retries;
+ int set_primary;
+ int bufsize_in;
+ int bufsize_out;
+ audsettings_t settings;
+ int latency_millis;
+} conf = {
+ 1,
+ 1,
+ 1,
+ 0,
+ 16384,
+ 16384,
+ {
+ 44100,
+ 2,
+ AUD_FMT_S16
+ },
+ 10
+};
+
+typedef struct {
+ LPDIRECTSOUND dsound;
+ LPDIRECTSOUNDCAPTURE dsound_capture;
+ LPDIRECTSOUNDBUFFER dsound_primary_buffer;
+ audsettings_t settings;
+} dsound;
+
+static dsound glob_dsound;
+
+typedef struct {
+ HWVoiceOut hw;
+ LPDIRECTSOUNDBUFFER dsound_buffer;
+ DWORD old_pos;
+ int first_time;
+#ifdef DEBUG_DSOUND
+ DWORD old_ppos;
+ DWORD played;
+ DWORD mixed;
+#endif
+} DSoundVoiceOut;
+
+typedef struct {
+ HWVoiceIn hw;
+ int first_time;
+ LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
+} DSoundVoiceIn;
+
+static void dsound_log_hresult (HRESULT hr)
+{
+ const char *str = "BUG";
+
+ switch (hr) {
+ case DS_OK:
+ str = "The method succeeded";
+ break;
+#ifdef DS_NO_VIRTUALIZATION
+ case DS_NO_VIRTUALIZATION:
+ str = "The buffer was created, but another 3D algorithm was
substituted";
+ break;
+#endif
+#ifdef DS_INCOMPLETE
+ case DS_INCOMPLETE:
+ str = "The method succeeded, but not all the optional effects were
obtained";
+ break;
+#endif
+#ifdef DSERR_ACCESSDENIED
+ case DSERR_ACCESSDENIED:
+ str = "The request failed because access was denied";
+ break;
+#endif
+#ifdef DSERR_ALLOCATED
+ case DSERR_ALLOCATED:
+ str = "The request failed because resources, such as a priority level,
were already in use by another caller";
+ break;
+#endif
+#ifdef DSERR_ALREADYINITIALIZED
+ case DSERR_ALREADYINITIALIZED:
+ str = "The object is already initialized";
+ break;
+#endif
+#ifdef DSERR_BADFORMAT
+ case DSERR_BADFORMAT:
+ str = "The specified wave format is not supported";
+ break;
+#endif
+#ifdef DSERR_BADSENDBUFFERGUID
+ case DSERR_BADSENDBUFFERGUID:
+ str = "The GUID specified in an audiopath file does not match a valid
mix-in buffer";
+ break;
+#endif
+#ifdef DSERR_BUFFERLOST
+ case DSERR_BUFFERLOST:
+ str = "The buffer memory has been lost and must be restored";
+ break;
+#endif
+#ifdef DSERR_BUFFERTOOSMALL
+ case DSERR_BUFFERTOOSMALL:
+ str = "The buffer size is not great enough to enable effects
processing";
+ break;
+#endif
+#ifdef DSERR_CONTROLUNAVAIL
+ case DSERR_CONTROLUNAVAIL:
+ str = "The buffer control (volume, pan, and so on) requested by the
caller is not available. Controls must be specified when the buffer is created,
using the dwFlags member of DSBUFFERDESC";
+ break;
+#endif
+#ifdef DSERR_DS8_REQUIRED
+ case DSERR_DS8_REQUIRED:
+ str = "A DirectSound object of class CLSID_DirectSound8 or later is
required for the requested functionality. For more information, see
IDirectSound8 Interface";
+ break;
+#endif
+#ifdef DSERR_FXUNAVAILABLE
+ case DSERR_FXUNAVAILABLE:
+ str = "The effects requested could not be found on the system, or they
are in the wrong order or in the wrong location; for example, an effect
expected in hardware was found in software";
+ break;
+#endif
+#ifdef DSERR_GENERIC
+ case DSERR_GENERIC :
+ str = "An undetermined error occurred inside the DirectSound
subsystem";
+ break;
+#endif
+#ifdef DSERR_INVALIDCALL
+ case DSERR_INVALIDCALL:
+ str = "This function is not valid for the current state of this
object";
+ break;
+#endif
+#ifdef DSERR_INVALIDPARAM
+ case DSERR_INVALIDPARAM:
+ str = "An invalid parameter was passed to the returning function";
+ break;
+#endif
+#ifdef DSERR_NOAGGREGATION
+ case DSERR_NOAGGREGATION:
+ str = "The object does not support aggregation";
+ break;
+#endif
+#ifdef DSERR_NODRIVER
+ case DSERR_NODRIVER:
+ str = "No sound driver is available for use, or the given GUID is not
a valid DirectSound device ID";
+ break;
+#endif
+#ifdef DSERR_NOINTERFACE
+ case DSERR_NOINTERFACE:
+ str = "The requested COM interface is not available";
+ break;
+#endif
+#ifdef DSERR_OBJECTNOTFOUND
+ case DSERR_OBJECTNOTFOUND:
+ str = "The requested object was not found";
+ break;
+#endif
+#ifdef DSERR_OTHERAPPHASPRIO
+ case DSERR_OTHERAPPHASPRIO:
+ str = "Another application has a higher priority level, preventing
this call from succeeding";
+ break;
+#endif
+#ifdef DSERR_OUTOFMEMORY
+ case DSERR_OUTOFMEMORY:
+ str = "The DirectSound subsystem could not allocate sufficient memory
to complete the caller's request";
+ break;
+#endif
+#ifdef DSERR_PRIOLEVELNEEDED
+ case DSERR_PRIOLEVELNEEDED:
+ str = "A cooperative level of DSSCL_PRIORITY or higher is required";
+ break;
+#endif
+#ifdef DSERR_SENDLOOP
+ case DSERR_SENDLOOP:
+ str = "A circular loop of send effects was detected";
+ break;
+#endif
+#ifdef DSERR_UNINITIALIZED
+ case DSERR_UNINITIALIZED:
+ str = "The Initialize method has not been called or has not been
called successfully before other methods were called";
+ break;
+#endif
+#ifdef DSERR_UNSUPPORTED
+ case DSERR_UNSUPPORTED:
+ str = "The function called is not supported at this time";
+ break;
+#endif
+ default:
+ AUD_log (AUDIO_CAP, "Reason: Unknown (HRESULT %#lx)\n", hr);
+ return;
+ }
+
+ AUD_log (AUDIO_CAP, "Reason: %s\n", str);
+}
+
+static void GCC_FMT_ATTR (2, 3) dsound_logerr (
+ HRESULT hr,
+ const char *fmt,
+ ...
+ )
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ dsound_log_hresult (hr);
+}
+
+static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
+ HRESULT hr,
+ const char *typ,
+ const char *fmt,
+ ...
+ )
+{
+ va_list ap;
+
+ AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ dsound_log_hresult (hr);
+}
+
+static DWORD millis_to_bytes (struct audio_pcm_info *info, DWORD millis)
+{
+ return (millis * info->bytes_per_second) / 1000;
+}
+
+#ifdef DEBUG_DSOUND
+static void print_wave_format (WAVEFORMATEX *wfx)
+{
+ dolog ("tag = %d\n", wfx->wFormatTag);
+ dolog ("nChannels = %d\n", wfx->nChannels);
+ dolog ("nSamplesPerSec = %ld\n", wfx->nSamplesPerSec);
+ dolog ("nAvgBytesPerSec = %ld\n", wfx->nAvgBytesPerSec);
+ dolog ("nBlockAlign = %d\n", wfx->nBlockAlign);
+ dolog ("wBitsPerSample = %d\n", wfx->wBitsPerSample);
+ dolog ("cbSize = %d\n", wfx->cbSize);
+}
+#endif
+
+static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
+{
+ HRESULT hr;
+ int i;
+
+ for (i = 0; i < conf.restore_retries; ++i) {
+ hr = IDirectSoundBuffer_Restore (dsb);
+
+ switch (hr) {
+ case DS_OK:
+ return 0;
+
+ case DSERR_BUFFERLOST:
+ continue;
+
+ default:
+ dsound_logerr (hr, "Could not restore playback buffer\n");
+ return -1;
+ }
+ }
+
+ dolog ("%d attempts to restore playback buffer failed\n", i);
+ return -1;
+}
+
+static int waveformat_from_audio_settings (WAVEFORMATEX *wfx, audsettings_t
*as)
+{
+ memset (wfx, 0, sizeof (*wfx));
+
+ wfx->wFormatTag = WAVE_FORMAT_PCM;
+ wfx->nChannels = as->nchannels;
+ wfx->nSamplesPerSec = as->freq;
+ wfx->nAvgBytesPerSec = as->freq << (as->nchannels == 2);
+ wfx->nBlockAlign = 1 << (as->nchannels == 2);
+ wfx->cbSize = 0;
+
+ switch (as->fmt) {
+ case AUD_FMT_S8:
+ wfx->wBitsPerSample = 8;
+ break;
+
+ case AUD_FMT_U8:
+ wfx->wBitsPerSample = 8;
+ break;
+
+ case AUD_FMT_S16:
+ wfx->wBitsPerSample = 16;
+ wfx->nAvgBytesPerSec <<= 1;
+ wfx->nBlockAlign <<= 1;
+ break;
+
+ case AUD_FMT_U16:
+ wfx->wBitsPerSample = 16;
+ wfx->nAvgBytesPerSec <<= 1;
+ wfx->nBlockAlign <<= 1;
+ break;
+
+ default:
+ dolog ("Internal logic error: Bad audio format %d\n", as->freq);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int waveformat_to_audio_settings (WAVEFORMATEX *wfx, audsettings_t *as)
+{
+ if (wfx->wFormatTag != WAVE_FORMAT_PCM) {
+ dolog ("Invalid wave format, tag is not PCM, but %d\n",
+ wfx->wFormatTag);
+ return -1;
+ }
+
+ if (!wfx->nSamplesPerSec) {
+ dolog ("Invalid wave format, frequency is zero\n");
+ return -1;
+ }
+ as->freq = wfx->nSamplesPerSec;
+
+ switch (wfx->nChannels) {
+ case 1:
+ as->nchannels = 1;
+ break;
+
+ case 2:
+ as->nchannels = 2;
+ break;
+
+ default:
+ dolog (
+ "Invalid wave format, number of channels is not 1 or 2, but %d\n",
+ wfx->nChannels
+ );
+ return -1;
+ }
+
+ switch (wfx->wBitsPerSample) {
+ case 8:
+ as->fmt = AUD_FMT_U8;
+ break;
+
+ case 16:
+ as->fmt = AUD_FMT_S16;
+ break;
+
+ default:
+ dolog ("Invalid wave format, bits per sample is not 8 or 16, but %d\n",
+ wfx->wBitsPerSample);
+ return -1;
+ }
+
+ return 0;
+}
+
+#include "dsound_template.h"
+#define DSBTYPE_IN
+#include "dsound_template.h"
+#undef DSBTYPE_IN
+
+static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
+{
+ HRESULT hr;
+ int i;
+
+ for (i = 0; i < conf.getstatus_retries; ++i) {
+ hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not get playback buffer status\n");
+ return -1;
+ }
+
+ if (*statusp & DSERR_BUFFERLOST) {
+ if (dsound_restore_out (dsb)) {
+ return -1;
+ }
+ continue;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
+ DWORD *statusp)
+{
+ HRESULT hr;
+
+ hr = IDirectSoundCaptureBuffer_GetStatus (dscb, statusp);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not get capture buffer status\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
+{
+ int src_len1 = dst_len;
+ int src_len2 = 0;
+ int pos = hw->rpos + dst_len;
+ st_sample_t *src1 = hw->mix_buf + hw->rpos;
+ st_sample_t *src2 = NULL;
+
+ if (pos > hw->samples) {
+ src_len1 = hw->samples - hw->rpos;
+ src2 = hw->mix_buf;
+ src_len2 = dst_len - src_len1;
+ pos = src_len2;
+ }
+
+ 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;
+}
+
+static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb)
+{
+ int err;
+ LPVOID p1, p2;
+ DWORD blen1, blen2, len1, len2;
+
+ err = dsound_lock_out (
+ dsb,
+ &hw->info,
+ 0,
+ hw->samples << hw->info.shift,
+ &p1, &p2,
+ &blen1, &blen2,
+ 1
+ );
+ if (err) {
+ return;
+ }
+
+ len1 = blen1 >> hw->info.shift;
+ len2 = blen2 >> hw->info.shift;
+
+#ifdef DEBUG_DSOUND
+ dolog ("clear %p,%ld,%ld %p,%ld,%ld\n",
+ p1, blen1, len1,
+ p2, blen2, len2);
+#endif
+
+ if (p1 && len1) {
+ audio_pcm_info_clear_buf (&hw->info, p1, len1);
+ }
+
+ if (p2 && len2) {
+ audio_pcm_info_clear_buf (&hw->info, p2, len2);
+ }
+
+ dsound_unlock_out (dsb, p1, p2, blen1, blen2);
+}
+
+static void dsound_close (dsound *s)
+{
+ HRESULT hr;
+
+ if (s->dsound_primary_buffer) {
+ hr = IDirectSoundBuffer_Release (s->dsound_primary_buffer);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not release primary buffer\n");
+ }
+ s->dsound_primary_buffer = NULL;
+ }
+}
+
+static int dsound_open (dsound *s)
+{
+ int err;
+ HRESULT hr;
+ WAVEFORMATEX wfx;
+ DSBUFFERDESC dsbd;
+ HWND hwnd;
+
+ hwnd = GetForegroundWindow ();
+ hr = IDirectSound_SetCooperativeLevel (
+ s->dsound,
+ hwnd,
+ DSSCL_PRIORITY
+ );
+
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not set cooperative level for window %p\n",
+ hwnd);
+ return -1;
+ }
+
+ if (!conf.set_primary) {
+ return 0;
+ }
+
+ err = waveformat_from_audio_settings (&wfx, &conf.settings);
+ if (err) {
+ return -1;
+ }
+
+ memset (&dsbd, 0, sizeof (dsbd));
+ dsbd.dwSize = sizeof (dsbd);
+ dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
+ dsbd.dwBufferBytes = 0;
+ dsbd.lpwfxFormat = NULL;
+
+ hr = IDirectSound_CreateSoundBuffer (
+ s->dsound,
+ &dsbd,
+ &s->dsound_primary_buffer,
+ NULL
+ );
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not create primary playback buffer\n");
+ return -1;
+ }
+
+ hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not set primary playback buffer format\n");
+ }
+
+ hr = IDirectSoundBuffer_GetFormat (
+ s->dsound_primary_buffer,
+ &wfx,
+ sizeof (wfx),
+ NULL
+ );
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not get primary playback buffer format\n");
+ goto fail0;
+ }
+
+#ifdef DEBUG_DSOUND
+ dolog ("Primary\n");
+ print_wave_format (&wfx);
+#endif
+
+ err = waveformat_to_audio_settings (&wfx, &s->settings);
+ if (err) {
+ goto fail0;
+ }
+
+ return 0;
+
+ fail0:
+ dsound_close (s);
+ return -1;
+}
+
+static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
+{
+ HRESULT hr;
+ DWORD status;
+ DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
+ LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
+
+ if (!dsb) {
+ dolog ("Attempt to control voice without a buffer\n");
+ return 0;
+ }
+
+ switch (cmd) {
+ case VOICE_ENABLE:
+ if (dsound_get_status_out (dsb, &status)) {
+ return -1;
+ }
+
+ if (status & DSBSTATUS_PLAYING) {
+ dolog ("warning: Voice is already playing\n");
+ return 0;
+ }
+
+ dsound_clear_sample (hw, dsb);
+
+ hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not start playing buffer\n");
+ return -1;
+ }
+ break;
+
+ case VOICE_DISABLE:
+ if (dsound_get_status_out (dsb, &status)) {
+ return -1;
+ }
+
+ if (status & DSBSTATUS_PLAYING) {
+ hr = IDirectSoundBuffer_Stop (dsb);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not stop playing buffer\n");
+ return -1;
+ }
+ }
+ else {
+ dolog ("warning: Voice is not playing\n");
+ }
+ break;
+ }
+ return 0;
+}
+
+static int dsound_write (SWVoiceOut *sw, void *buf, int len)
+{
+ return audio_pcm_sw_write (sw, buf, len);
+}
+
+static int dsound_run_out (HWVoiceOut *hw)
+{
+ int err;
+ HRESULT hr;
+ DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
+ LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
+ int live, len, hwshift;
+ DWORD blen1, blen2;
+ DWORD len1, len2;
+ DWORD decr;
+ DWORD wpos, ppos, old_pos;
+ LPVOID p1, p2;
+ int bufsize;
+
+ if (!dsb) {
+ dolog ("Attempt to run empty with playback buffer\n");
+ return 0;
+ }
+
+ hwshift = hw->info.shift;
+ bufsize = hw->samples << hwshift;
+
+ live = audio_pcm_hw_get_live_out (hw);
+
+ hr = IDirectSoundBuffer_GetCurrentPosition (
+ dsb,
+ &ppos,
+ ds->first_time ? &wpos : NULL
+ );
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not get playback buffer position\n");
+ return 0;
+ }
+
+ len = live << hwshift;
+
+ if (ds->first_time) {
+ if (conf.latency_millis) {
+ DWORD cur_blat;
+
+ cur_blat = audio_ring_dist (wpos, ppos, bufsize);
+ ds->first_time = 0;
+ old_pos = wpos;
+ old_pos +=
+ millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat;
+ old_pos %= bufsize;
+ old_pos &= ~hw->info.align;
+ }
+ else {
+ old_pos = wpos;
+ }
+#ifdef DEBUG_DSOUND
+ ds->played = 0;
+ ds->mixed = 0;
+#endif
+ }
+ else {
+ if (ds->old_pos == ppos) {
+#ifdef DEBUG_DSOUND
+ dolog ("old_pos == ppos\n");
+#endif
+ return 0;
+ }
+
+#ifdef DEBUG_DSOUND
+ ds->played += audio_ring_dist (ds->old_pos, ppos, hw->bufsize);
+#endif
+ old_pos = ds->old_pos;
+ }
+
+ if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
+ len = ppos - old_pos;
+ }
+ else {
+ if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
+ len = bufsize - old_pos + ppos;
+ }
+ }
+
+ if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
+ dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
+ len, bufsize, old_pos, ppos);
+ return 0;
+ }
+
+ len &= ~hw->info.align;
+ if (!len) {
+ return 0;
+ }
+
+#ifdef DEBUG_DSOUND
+ ds->old_ppos = ppos;
+#endif
+ err = dsound_lock_out (
+ dsb,
+ &hw->info,
+ old_pos,
+ len,
+ &p1, &p2,
+ &blen1, &blen2,
+ 0
+ );
+ if (err) {
+ return 0;
+ }
+
+ len1 = blen1 >> hwshift;
+ len2 = blen2 >> hwshift;
+ decr = len1 + len2;
+
+ if (p1 && len1) {
+ dsound_write_sample (hw, p1, len1);
+ }
+
+ if (p2 && len2) {
+ dsound_write_sample (hw, p2, len2);
+ }
+
+ dsound_unlock_out (dsb, p1, p2, blen1, blen2);
+ ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;
+
+#ifdef DEBUG_DSOUND
+ ds->mixed += decr << hwshift;
+
+ dolog ("played %lu mixed %lu diff %ld sec %f\n",
+ ds->played,
+ ds->mixed,
+ ds->mixed - ds->played,
+ abs (ds->mixed - ds->played) / (double) hw->info.bytes_per_second);
+#endif
+ return decr;
+}
+
+static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
+{
+ HRESULT hr;
+ DWORD status;
+ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
+ LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
+
+ if (!dscb) {
+ dolog ("Attempt to control capture voice without a buffer\n");
+ return -1;
+ }
+
+ switch (cmd) {
+ case VOICE_ENABLE:
+ if (dsound_get_status_in (dscb, &status)) {
+ return -1;
+ }
+
+ if (status & DSCBSTATUS_CAPTURING) {
+ dolog ("warning: Voice is already capturing\n");
+ return 0;
+ }
+
+ /* clear ?? */
+
+ hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not start capturing\n");
+ return -1;
+ }
+ break;
+
+ case VOICE_DISABLE:
+ if (dsound_get_status_in (dscb, &status)) {
+ return -1;
+ }
+
+ if (status & DSCBSTATUS_CAPTURING) {
+ hr = IDirectSoundCaptureBuffer_Stop (dscb);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not stop capturing\n");
+ return -1;
+ }
+ }
+ else {
+ dolog ("warning: Voice is not capturing\n");
+ }
+ break;
+ }
+ return 0;
+}
+
+static int dsound_read (SWVoiceIn *sw, void *buf, int len)
+{
+ return audio_pcm_sw_read (sw, buf, len);
+}
+
+static int dsound_run_in (HWVoiceIn *hw)
+{
+ int err;
+ HRESULT hr;
+ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
+ LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
+ int live, len, dead;
+ DWORD blen1, blen2;
+ DWORD len1, len2;
+ DWORD decr;
+ DWORD cpos, rpos;
+ LPVOID p1, p2;
+ int hwshift;
+
+ if (!dscb) {
+ dolog ("Attempt to run without capture buffer\n");
+ return 0;
+ }
+
+ hwshift = hw->info.shift;
+
+ live = audio_pcm_hw_get_live_in (hw);
+ dead = hw->samples - live;
+ if (!dead) {
+ return 0;
+ }
+
+ hr = IDirectSoundCaptureBuffer_GetCurrentPosition (
+ dscb,
+ &cpos,
+ ds->first_time ? &rpos : NULL
+ );
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not get capture buffer position\n");
+ return 0;
+ }
+
+ if (ds->first_time) {
+ ds->first_time = 0;
+ if (rpos & hw->info.align) {
+ ldebug ("warning: Misaligned capture read position %ld(%d)\n",
+ rpos, hw->info.align);
+ }
+ hw->wpos = rpos >> hwshift;
+ }
+
+ if (cpos & hw->info.align) {
+ ldebug ("warning: Misaligned capture position %ld(%d)\n",
+ cpos, hw->info.align);
+ }
+ cpos >>= hwshift;
+
+ len = audio_ring_dist (cpos, hw->wpos, hw->samples);
+ if (!len) {
+ return 0;
+ }
+ len = audio_MIN (len, dead);
+
+ err = dsound_lock_in (
+ dscb,
+ &hw->info,
+ hw->wpos << hwshift,
+ len << hwshift,
+ &p1,
+ &p2,
+ &blen1,
+ &blen2,
+ 0
+ );
+ if (err) {
+ return 0;
+ }
+
+ len1 = blen1 >> hwshift;
+ len2 = blen2 >> hwshift;
+ decr = len1 + len2;
+
+ if (p1 && len1) {
+ hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);
+ }
+
+ if (p2 && len2) {
+ hw->conv (hw->conv_buf, p2, len2, &nominal_volume);
+ }
+
+ dsound_unlock_in (dscb, p1, p2, blen1, blen2);
+ hw->wpos = (hw->wpos + decr) % hw->samples;
+ return decr;
+}
+
+static void dsound_audio_fini (void *opaque)
+{
+ HRESULT hr;
+ dsound *s = opaque;
+
+ if (!s->dsound) {
+ return;
+ }
+
+ hr = IDirectSound_Release (s->dsound);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not release DirectSound\n");
+ }
+ s->dsound = NULL;
+
+ if (!s->dsound_capture) {
+ return;
+ }
+
+ hr = IDirectSoundCapture_Release (s->dsound_capture);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not release DirectSoundCapture\n");
+ }
+ s->dsound_capture = NULL;
+}
+
+static void *dsound_audio_init (void)
+{
+ int err;
+ HRESULT hr;
+ dsound *s = &glob_dsound;
+
+ hr = CoInitialize (NULL);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not initialize COM\n");
+ return NULL;
+ }
+
+ hr = CoCreateInstance (
+ &CLSID_DirectSound,
+ NULL,
+ CLSCTX_ALL,
+ &IID_IDirectSound,
+ (void **) &s->dsound
+ );
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not create DirectSound instance\n");
+ return NULL;
+ }
+
+ hr = IDirectSound_Initialize (s->dsound, NULL);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not initialize DirectSound\n");
+ return NULL;
+ }
+
+ hr = CoCreateInstance (
+ &CLSID_DirectSoundCapture,
+ NULL,
+ CLSCTX_ALL,
+ &IID_IDirectSoundCapture,
+ (void **) &s->dsound_capture
+ );
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");
+ }
+ else {
+ hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");
+
+ hr = IDirectSoundCapture_Release (s->dsound_capture);
+ if (FAILED (hr)) {
+ dsound_logerr (hr, "Could not release DirectSoundCapture\n");
+ }
+ s->dsound_capture = NULL;
+ }
+ }
+
+ err = dsound_open (s);
+ if (err) {
+ dsound_audio_fini (s);
+ return NULL;
+ }
+
+ return s;
+}
+
+static struct audio_option dsound_options[] = {
+ {"LOCK_RETRIES", AUD_OPT_INT, &conf.lock_retries,
+ "Number of times to attempt locking the buffer", NULL, 0},
+ {"RESTOURE_RETRIES", AUD_OPT_INT, &conf.restore_retries,
+ "Number of times to attempt restoring the buffer", NULL, 0},
+ {"GETSTATUS_RETRIES", AUD_OPT_INT, &conf.getstatus_retries,
+ "Number of times to attempt getting status of the buffer", NULL, 0},
+ {"SET_PRIMARY", AUD_OPT_BOOL, &conf.set_primary,
+ "Set the parameters of primary buffer", NULL, 0},
+ {"LATENCY_MILLIS", AUD_OPT_INT, &conf.latency_millis,
+ "(undocumented)", NULL, 0},
+ {"PRIMARY_FREQ", AUD_OPT_INT, &conf.settings.freq,
+ "Primary buffer frequency", NULL, 0},
+ {"PRIMARY_CHANNELS", AUD_OPT_INT, &conf.settings.nchannels,
+ "Primary buffer number of channels (1 - mono, 2 - stereo)", NULL, 0},
+ {"PRIMARY_FMT", AUD_OPT_FMT, &conf.settings.fmt,
+ "Primary buffer format", NULL, 0},
+ {"BUFSIZE_OUT", AUD_OPT_INT, &conf.bufsize_out,
+ "(undocumented)", NULL, 0},
+ {"BUFSIZE_IN", AUD_OPT_INT, &conf.bufsize_in,
+ "(undocumented)", NULL, 0},
+ {NULL, 0, NULL, NULL, NULL, 0}
+};
+
+static struct audio_pcm_ops dsound_pcm_ops = {
+ dsound_init_out,
+ dsound_fini_out,
+ dsound_run_out,
+ dsound_write,
+ dsound_ctl_out,
+
+ dsound_init_in,
+ dsound_fini_in,
+ dsound_run_in,
+ dsound_read,
+ dsound_ctl_in
+};
+
+struct audio_driver dsound_audio_driver = {
+ INIT_FIELD (name = ) "dsound",
+ INIT_FIELD (descr = )
+ "DirectSound http://wikipedia.org/wiki/DirectSound",
+ INIT_FIELD (options = ) dsound_options,
+ INIT_FIELD (init = ) dsound_audio_init,
+ INIT_FIELD (fini = ) dsound_audio_fini,
+ INIT_FIELD (pcm_ops = ) &dsound_pcm_ops,
+ INIT_FIELD (can_be_default = ) 1,
+ INIT_FIELD (max_voices_out = ) INT_MAX,
+ INIT_FIELD (max_voices_in = ) 1,
+ INIT_FIELD (voice_size_out = ) sizeof (DSoundVoiceOut),
+ INIT_FIELD (voice_size_in = ) sizeof (DSoundVoiceIn)
+};
diff -r bd68ce5a3f0c -r b450f21472a0 tools/ioemu/audio/fmodaudio.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/audio/fmodaudio.c Wed Jul 12 19:16:10 2006 +0100
@@ -0,0 +1,683 @@
+/*
+ * QEMU FMOD audio driver
+ *
+ * Copyright (c) 2004-2005 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include <fmod.h>
+#include <fmod_errors.h>
+#include "vl.h"
+
+#define AUDIO_CAP "fmod"
+#include "audio_int.h"
+
+typedef struct FMODVoiceOut {
+ HWVoiceOut hw;
+ unsigned int old_pos;
+ FSOUND_SAMPLE *fmod_sample;
+ int channel;
+} FMODVoiceOut;
+
+typedef struct FMODVoiceIn {
+ HWVoiceIn hw;
+ FSOUND_SAMPLE *fmod_sample;
+} FMODVoiceIn;
+
+static struct {
+ const char *drvname;
+ int nb_samples;
+ int freq;
+ int nb_channels;
+ int bufsize;
+ int threshold;
+ int broken_adc;
+} conf = {
+ NULL,
+ 2048 * 2,
+ 44100,
+ 2,
+ 0,
+ 0,
+ 0
+};
+
+static void GCC_FMT_ATTR (1, 2) fmod_logerr (const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ AUD_log (AUDIO_CAP, "Reason: %s\n",
+ FMOD_ErrorString (FSOUND_GetError ()));
+}
+
+static void GCC_FMT_ATTR (2, 3) fmod_logerr2 (
+ const char *typ,
+ const char *fmt,
+ ...
+ )
+{
+ va_list ap;
+
+ AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);
+
+ va_start (ap, fmt);
+ AUD_vlog (AUDIO_CAP, fmt, ap);
+ va_end (ap);
+
+ AUD_log (AUDIO_CAP, "Reason: %s\n",
+ FMOD_ErrorString (FSOUND_GetError ()));
+}
+
+static int fmod_write (SWVoiceOut *sw, void *buf, int len)
+{
+ return audio_pcm_sw_write (sw, buf, len);
+}
+
+static void fmod_clear_sample (FMODVoiceOut *fmd)
+{
+ HWVoiceOut *hw = &fmd->hw;
+ int status;
+ void *p1 = 0, *p2 = 0;
+ unsigned int len1 = 0, len2 = 0;
+
+ status = FSOUND_Sample_Lock (
+ fmd->fmod_sample,
+ 0,
+ hw->samples << hw->info.shift,
+ &p1,
+ &p2,
+ &len1,
+ &len2
+ );
+
+ if (!status) {
+ fmod_logerr ("Failed to lock sample\n");
+ return;
+ }
+
+ if ((len1 & hw->info.align) || (len2 & hw->info.align)) {
+ dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
+ len1, len2, hw->info.align + 1);
+ goto fail;
+ }
+
+ if ((len1 + len2) - (hw->samples << hw->info.shift)) {
+ dolog ("Lock returned incomplete length %d, %d\n",
+ len1 + len2, hw->samples << hw->info.shift);
+ goto fail;
+ }
+
+ audio_pcm_info_clear_buf (&hw->info, p1, hw->samples);
+
+ fail:
+ status = FSOUND_Sample_Unlock (fmd->fmod_sample, p1, p2, len1, len2);
+ if (!status) {
+ fmod_logerr ("Failed to unlock sample\n");
+ }
+}
+
+static void fmod_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
+{
+ int src_len1 = dst_len;
+ int src_len2 = 0;
+ int pos = hw->rpos + dst_len;
+ st_sample_t *src1 = hw->mix_buf + hw->rpos;
+ st_sample_t *src2 = NULL;
+
+ if (pos > hw->samples) {
+ src_len1 = hw->samples - hw->rpos;
+ src2 = hw->mix_buf;
+ src_len2 = dst_len - src_len1;
+ pos = src_len2;
+ }
+
+ 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;
+}
+
+static int fmod_unlock_sample (FSOUND_SAMPLE *sample, void *p1, void *p2,
+ unsigned int blen1, unsigned int blen2)
+{
+ int status = FSOUND_Sample_Unlock (sample, p1, p2, blen1, blen2);
+ if (!status) {
+ fmod_logerr ("Failed to unlock sample\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int fmod_lock_sample (
+ FSOUND_SAMPLE *sample,
+ struct audio_pcm_info *info,
+ int pos,
+ int len,
+ void **p1,
+ void **p2,
+ unsigned int *blen1,
+ unsigned int *blen2
+ )
+{
+ int status;
+
+ status = FSOUND_Sample_Lock (
+ sample,
+ pos << info->shift,
+ len << info->shift,
+ p1,
+ p2,
+ blen1,
+ blen2
+ );
+
+ if (!status) {
+ fmod_logerr ("Failed to lock sample\n");
+ return -1;
+ }
+
+ if ((*blen1 & info->align) || (*blen2 & info->align)) {
+ dolog ("Lock returned misaligned length %d, %d, alignment %d\n",
+ *blen1, *blen2, info->align + 1);
+
+ fmod_unlock_sample (sample, *p1, *p2, *blen1, *blen2);
+
+ *p1 = NULL - 1;
+ *p2 = NULL - 1;
+ *blen1 = ~0U;
+ *blen2 = ~0U;
+ return -1;
+ }
+
+ if (!*p1 && *blen1) {
+ dolog ("warning: !p1 && blen1=%d\n", *blen1);
+ *blen1 = 0;
+ }
+
+ if (!p2 && *blen2) {
+ dolog ("warning: !p2 && blen2=%d\n", *blen2);
+ *blen2 = 0;
+ }
+
+ return 0;
+}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|