# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID f7b43e5c42b981fa16ad9bfc5339ff8496dd2288
# Parent 2db50529223e20a3d48d96e8cbfe3eaf7998b58c
# Parent d71e72d8532cfdf5896f560d98d45262841c8b83
merge with xen-unstable.hg
---
patches/linux-2.6.16.13/net-gso.patch | 2516
---
tools/examples/vtpm-addtodb | 10
tools/ioemu/cpu.h | 76
tools/ioemu/create_keysym_header.sh | 77
tools/ioemu/hw/acpi.c | 178
tools/ioemu/hw/i8259_stub.c | 81
tools/ioemu/hw/m48t08.c | 391
tools/ioemu/hw/m48t08.h | 12
tools/ioemu/hw/magic-load.c | 324
tools/ioemu/hw/pcnet.c | 1154
-
tools/ioemu/hw/pcnet.h | 537
tools/ioemu/hw/port-e9.c | 47
tools/ioemu/hw/sched.c | 268
tools/ioemu/hw/timer.c | 97
tools/ioemu/ia64_intrinsic.h | 276
tools/ioemu/keyboard_rdesktop.c | 165
tools/ioemu/keymaps/convert-map | 63
tools/ioemu/main.c | 250
tools/ioemu/path.c | 147
tools/ioemu/target-i386-dm/Makefile | 406
tools/ioemu/x86_32.ld | 140
tools/vtpm/tpm_emulator-0.3-x86_64.patch | 657
-
.hgignore | 51
Config.mk | 4
buildconfigs/Rules.mk | 14
buildconfigs/conf.linux-native/00_xen_to_native | 84
buildconfigs/create_config.sh | 50
buildconfigs/linux-defconfig_xen0_ia64 | 1
buildconfigs/linux-defconfig_xen0_x86_32 | 1
buildconfigs/linux-defconfig_xen0_x86_64 | 1
buildconfigs/linux-defconfig_xen_ia64 | 1
buildconfigs/linux-defconfig_xen_x86_32 | 1
buildconfigs/linux-defconfig_xen_x86_64 | 1
buildconfigs/mk.linux-2.6-native | 4
buildconfigs/mk.linux-2.6-xen | 17
config/ia64.mk | 1
config/powerpc64.mk | 4
config/x86_32.mk | 2
config/x86_64.mk | 2
extras/mini-os/mm.c | 2
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c | 23
linux-2.6-xen-sparse/drivers/xen/Kconfig | 104
linux-2.6-xen-sparse/drivers/xen/Makefile | 1
linux-2.6-xen-sparse/drivers/xen/blktap/Makefile | 3
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 1439
++
linux-2.6-xen-sparse/drivers/xen/blktap/common.h | 120
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c | 165
linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c | 354
linux-2.6-xen-sparse/drivers/xen/console/console.c | 33
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 4
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h | 2
linux-2.6-xen-sparse/include/linux/skbuff.h | 5
linux-2.6-xen-sparse/net/core/dev.c | 36
patches/linux-2.6.16.13/blktap-aio-16_03_06.patch | 164
patches/linux-2.6.16.13/net-csum.patch | 15
patches/linux-2.6.16.13/net-gso-0-base.patch | 1974
+++
patches/linux-2.6.16.13/net-gso-1-check-dodgy.patch | 16
patches/linux-2.6.16.13/net-gso-2-checksum-fix.patch | 311
patches/linux-2.6.16.13/net-gso-3-fix-errorcheck.patch | 13
patches/linux-2.6.16.13/xenoprof-generic.patch | 144
tools/Makefile | 15
tools/blktap/Makefile | 28
tools/blktap/README | 122
tools/blktap/drivers/Makefile | 76
tools/blktap/drivers/aes.c | 1319
++
tools/blktap/drivers/aes.h | 26
tools/blktap/drivers/blktapctrl.c | 704
+
tools/blktap/drivers/blktapctrl.h | 55
tools/blktap/drivers/block-aio.c | 327
tools/blktap/drivers/block-qcow.c | 1369
++
tools/blktap/drivers/block-ram.c | 296
tools/blktap/drivers/block-sync.c | 242
tools/blktap/drivers/block-vmdk.c | 415
tools/blktap/drivers/bswap.h | 202
tools/blktap/drivers/img2qcow.c | 289
tools/blktap/drivers/qcow-create.c | 80
tools/blktap/drivers/qcow2raw.c | 346
tools/blktap/drivers/tapdisk.c | 674
+
tools/blktap/drivers/tapdisk.h | 211
tools/blktap/lib/Makefile | 68
tools/blktap/lib/blkif.c | 185
tools/blktap/lib/blktaplib.h | 223
tools/blktap/lib/list.h | 55
tools/blktap/lib/xenbus.c | 387
tools/blktap/lib/xs_api.c | 364
tools/blktap/lib/xs_api.h | 50
tools/examples/Makefile | 3
tools/examples/README | 1
tools/examples/blktap | 15
tools/examples/vtpm-common.sh | 48
tools/examples/vtpm-impl | 58
tools/examples/xen-backend.agent | 3
tools/examples/xen-backend.rules | 1
tools/examples/xmexample.hvm | 15
tools/firmware/vmxassist/vmxassist.ld | 3
tools/ioemu/.cvsignore | 29
tools/ioemu/CVS/Entries | 109
tools/ioemu/CVS/Repository | 1
tools/ioemu/CVS/Root | 1
tools/ioemu/CVS/Tag | 1
tools/ioemu/Changelog | 81
tools/ioemu/LICENSE | 12
tools/ioemu/Makefile | 135
tools/ioemu/Makefile.target | 531
tools/ioemu/README | 53
tools/ioemu/README.distrib | 16
tools/ioemu/TODO | 21
tools/ioemu/VERSION | 2
tools/ioemu/a.out.h | 431
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 | 2047
++-
tools/ioemu/audio/audio.h | 114
tools/ioemu/audio/audio_int.h | 340
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 | 298
tools/ioemu/audio/mixeng.h | 26
tools/ioemu/audio/mixeng_template.h | 140
tools/ioemu/audio/noaudio.c | 170
tools/ioemu/audio/ossaudio.c | 707
-
tools/ioemu/audio/rate_template.h | 111
tools/ioemu/audio/sdlaudio.c | 423
tools/ioemu/audio/sys-queue.h | 241
tools/ioemu/audio/wavaudio.c | 208
tools/ioemu/block-bochs.c | 224
tools/ioemu/block-cloop.c | 12
tools/ioemu/block-cow.c | 7
tools/ioemu/block-dmg.c | 297
tools/ioemu/block-qcow.c | 53
tools/ioemu/block-vmdk.c | 200
tools/ioemu/block-vpc.c | 242
tools/ioemu/block-vvfat.c | 2807
++++
tools/ioemu/block.c | 272
tools/ioemu/block_int.h | 5
tools/ioemu/cocoa.m | 911
+
tools/ioemu/configure | 673
-
tools/ioemu/console.c | 389
tools/ioemu/cpu-all.h | 503
tools/ioemu/cpu-defs.h | 54
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 | 251
tools/ioemu/exec.c | 2117
+++
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 | 36
tools/ioemu/hw/adlib.c | 390
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 | 226
tools/ioemu/hw/cuda.c | 104
tools/ioemu/hw/dma.c | 4
tools/ioemu/hw/es1370.c | 1062
+
tools/ioemu/hw/esp.c | 747
+
tools/ioemu/hw/fdc.c | 58
tools/ioemu/hw/heathrow_pic.c | 168
tools/ioemu/hw/i8254.c | 63
tools/ioemu/hw/i8259.c | 212
tools/ioemu/hw/ide.c | 617
tools/ioemu/hw/integratorcp.c | 546
tools/ioemu/hw/iommu.c | 208
tools/ioemu/hw/lance.c | 292
tools/ioemu/hw/m48t59.c | 204
tools/ioemu/hw/m48t59.h | 10
tools/ioemu/hw/mips_r4k.c | 295
tools/ioemu/hw/ne2000.c | 219
tools/ioemu/hw/openpic.c | 22
tools/ioemu/hw/parallel.c | 183
tools/ioemu/hw/pc.c | 506
tools/ioemu/hw/pci.c | 721
-
tools/ioemu/hw/pckbd.c | 628
tools/ioemu/hw/pcspk.c | 147
tools/ioemu/hw/piix4acpi.c | 27
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 | 84
tools/ioemu/hw/ppc_chrp.c | 473
tools/ioemu/hw/ppc_prep.c | 216
tools/ioemu/hw/ps2.c | 566
tools/ioemu/hw/rtl8139.c | 2875
++++
tools/ioemu/hw/sb16.c | 333
tools/ioemu/hw/serial.c | 228
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 | 339
tools/ioemu/hw/sun4u.c | 376
tools/ioemu/hw/tc58128.c | 181
tools/ioemu/hw/tcx.c | 407
tools/ioemu/hw/versatilepb.c | 271
tools/ioemu/hw/vga.c | 274
tools/ioemu/hw/vga_int.h | 2
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/kqemu.c | 900
+
tools/ioemu/kqemu.h | 132
tools/ioemu/loader.c | 235
tools/ioemu/monitor.c | 1773
++
tools/ioemu/osdep.c | 129
tools/ioemu/osdep.h | 3
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 | 399
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 | 33
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 | 321
tools/ioemu/patches/vnc-start-vncviewer | 69
tools/ioemu/patches/xen-build | 179
tools/ioemu/patches/xen-domain-name | 64
tools/ioemu/patches/xen-domid | 37
tools/ioemu/patches/xen-mm | 63
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 | 15
tools/ioemu/qemu-doc.texi | 1748
++
tools/ioemu/qemu-img.c | 17
tools/ioemu/qemu-img.texi | 126
tools/ioemu/qemu-tech.texi | 595
tools/ioemu/qemu_socket.h | 30
tools/ioemu/readline.c | 1
tools/ioemu/sdl.c | 239
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 | 270
tools/ioemu/target-i386-dm/i8259-dm.c | 107
tools/ioemu/target-i386-dm/qemu-ifup | 2
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 | 2
tools/ioemu/translate-all.c | 311
tools/ioemu/translate-op.c | 37
tools/ioemu/vl.c | 4464
+++++-
tools/ioemu/vl.h | 539
tools/ioemu/vnc.c | 1576
+-
tools/ioemu/vnc_keysym.h | 275
tools/ioemu/vnchextile.h | 189
tools/libaio/COPYING | 515
tools/libaio/ChangeLog | 43
tools/libaio/INSTALL | 18
tools/libaio/Makefile | 40
tools/libaio/TODO | 4
tools/libaio/harness/Makefile | 37
tools/libaio/harness/README | 19
tools/libaio/harness/attic/0.t | 9
tools/libaio/harness/attic/1.t | 9
tools/libaio/harness/cases/10.t | 53
tools/libaio/harness/cases/11.t | 39
tools/libaio/harness/cases/12.t | 49
tools/libaio/harness/cases/13.t | 66
tools/libaio/harness/cases/14.t | 90
tools/libaio/harness/cases/2.t | 41
tools/libaio/harness/cases/3.t | 25
tools/libaio/harness/cases/4.t | 72
tools/libaio/harness/cases/5.t | 47
tools/libaio/harness/cases/6.t | 57
tools/libaio/harness/cases/7.t | 27
tools/libaio/harness/cases/8.t | 49
tools/libaio/harness/cases/aio_setup.h | 98
tools/libaio/harness/cases/common-7-8.h | 37
tools/libaio/harness/main.c | 39
tools/libaio/harness/runtests.sh | 19
tools/libaio/libaio.spec | 187
tools/libaio/man/aio.3 | 315
tools/libaio/man/aio_cancel.3 | 137
tools/libaio/man/aio_cancel64.3 | 50
tools/libaio/man/aio_error.3 | 81
tools/libaio/man/aio_error64.3 | 64
tools/libaio/man/aio_fsync.3 | 139
tools/libaio/man/aio_fsync64.3 | 51
tools/libaio/man/aio_init.3 | 96
tools/libaio/man/aio_read.3 | 146
tools/libaio/man/aio_read64.3 | 60
tools/libaio/man/aio_return.3 | 71
tools/libaio/man/aio_return64.3 | 51
tools/libaio/man/aio_suspend.3 | 123
tools/libaio/man/aio_suspend64.3 | 51
tools/libaio/man/aio_write.3 | 176
tools/libaio/man/aio_write64.3 | 61
tools/libaio/man/io.3 | 351
tools/libaio/man/io_cancel.1 | 21
tools/libaio/man/io_cancel.3 | 65
tools/libaio/man/io_destroy.1 | 17
tools/libaio/man/io_fsync.3 | 82
tools/libaio/man/io_getevents.1 | 29
tools/libaio/man/io_getevents.3 | 79
tools/libaio/man/io_prep_fsync.3 | 89
tools/libaio/man/io_prep_pread.3 | 79
tools/libaio/man/io_prep_pwrite.3 | 77
tools/libaio/man/io_queue_init.3 | 63
tools/libaio/man/io_queue_release.3 | 48
tools/libaio/man/io_queue_run.3 | 50
tools/libaio/man/io_queue_wait.3 | 56
tools/libaio/man/io_set_callback.3 | 44
tools/libaio/man/io_setup.1 | 15
tools/libaio/man/io_submit.1 | 109
tools/libaio/man/io_submit.3 | 135
tools/libaio/man/lio_listio.3 | 229
tools/libaio/man/lio_listio64.3 | 39
tools/libaio/src/Makefile | 64
tools/libaio/src/compat-0_1.c | 62
tools/libaio/src/io_cancel.c | 23
tools/libaio/src/io_destroy.c | 23
tools/libaio/src/io_getevents.c | 57
tools/libaio/src/io_queue_init.c | 33
tools/libaio/src/io_queue_release.c | 27
tools/libaio/src/io_queue_run.c | 39
tools/libaio/src/io_queue_wait.c | 31
tools/libaio/src/io_setup.c | 23
tools/libaio/src/io_submit.c | 23
tools/libaio/src/libaio.h | 222
tools/libaio/src/libaio.map | 22
tools/libaio/src/raw_syscall.c | 19
tools/libaio/src/syscall-alpha.h | 209
tools/libaio/src/syscall-i386.h | 72
tools/libaio/src/syscall-ia64.h | 45
tools/libaio/src/syscall-ppc.h | 94
tools/libaio/src/syscall-s390.h | 131
tools/libaio/src/syscall-x86_64.h | 63
tools/libaio/src/syscall.h | 27
tools/libaio/src/vsys_def.h | 24
tools/libxc/Makefile | 3
tools/libxc/xc_load_elf.c | 4
tools/libxc/xc_ppc_linux_build.c | 408
tools/libxc/xenctrl.h | 5
tools/misc/lomount/lomount.c | 430
tools/misc/xend | 7
tools/pygrub/README | 2
tools/python/xen/util/dictio.py | 50
tools/python/xen/util/security.py | 98
tools/python/xen/xend/XendDomain.py | 30
tools/python/xen/xend/XendDomainInfo.py | 14
tools/python/xen/xend/XendLogging.py | 2
tools/python/xen/xend/image.py | 54
tools/python/xen/xend/server/BlktapController.py | 14
tools/python/xen/xend/server/DevController.py | 7
tools/python/xen/xend/server/SrvDaemon.py | 2
tools/python/xen/xend/server/blkif.py | 12
tools/python/xen/xm/addlabel.py | 154
tools/python/xen/xm/create.py | 172
tools/python/xen/xm/dry-run.py | 56
tools/python/xen/xm/getlabel.py | 114
tools/python/xen/xm/main.py | 38
tools/python/xen/xm/resources.py | 56
tools/python/xen/xm/rmlabel.py | 118
tools/vtpm/Makefile | 43
tools/vtpm/tpm_emulator.patch | 1284
-
tools/vtpm/vtpm.patch | 1134
-
tools/vtpm_manager/Makefile | 14
tools/vtpm_manager/Rules.mk | 1
tools/vtpm_manager/crypto/sym_crypto.c | 17
tools/vtpm_manager/manager/dmictl.c | 114
tools/vtpm_manager/manager/migration.c | 307
tools/vtpm_manager/manager/securestorage.c | 85
tools/vtpm_manager/manager/vtpm_ipc.c | 2
tools/vtpm_manager/manager/vtpm_manager.c | 4
tools/vtpm_manager/manager/vtpm_manager.h | 16
tools/vtpm_manager/manager/vtpm_manager_handler.c | 21
tools/vtpm_manager/manager/vtpmd.c | 3
tools/vtpm_manager/manager/vtpmpriv.h | 39
tools/vtpm_manager/manager/vtsp.c | 68
tools/vtpm_manager/manager/vtsp.h | 3
tools/vtpm_manager/migration/Makefile | 39
tools/vtpm_manager/migration/vtpm_manager_if.c | 186
tools/vtpm_manager/migration/vtpm_migrator.h | 104
tools/vtpm_manager/migration/vtpm_migrator_if.c | 219
tools/vtpm_manager/migration/vtpm_migratorc.c | 211
tools/vtpm_manager/migration/vtpm_migratord.c | 202
tools/vtpm_manager/migration/vtpm_migratord_handler.c | 171
tools/vtpm_manager/tcs/tcs.c | 3
tools/vtpm_manager/tcs/transmit.c | 4
tools/vtpm_manager/util/buffer.c | 23
tools/vtpm_manager/util/buffer.h | 4
tools/vtpm_manager/util/log.h | 4
tools/vtpm_manager/util/tcg.h | 18
tools/xenmon/xenbaked.c | 269
tools/xenmon/xenmon.py | 52
tools/xenstore/Makefile | 24
tools/xm-test/configure.ac | 8
tools/xm-test/ramdisk/Makefile.am | 9
tools/xm-test/ramdisk/bin/create_disk_image | 33
tools/xm-test/tests/enforce_dom0_cpus/01_enforce_dom0_cpus_basic_pos.py | 8
xen/Makefile | 2
xen/Rules.mk | 6
xen/arch/powerpc/0opt.c | 28
xen/arch/powerpc/Makefile | 117
xen/arch/powerpc/Rules.mk | 51
xen/arch/powerpc/audit.c | 45
xen/arch/powerpc/bitops.c | 94
xen/arch/powerpc/boot/boot32.S | 75
xen/arch/powerpc/boot/start.S | 51
xen/arch/powerpc/boot_of.c | 1016
+
xen/arch/powerpc/dart.c | 299
xen/arch/powerpc/dart.h | 36
xen/arch/powerpc/dart_u3.c | 108
xen/arch/powerpc/dart_u4.c | 177
xen/arch/powerpc/delay.c | 37
xen/arch/powerpc/dom0_ops.c | 87
xen/arch/powerpc/domain.c | 251
xen/arch/powerpc/domain_build.c | 285
xen/arch/powerpc/elf32.c | 5
xen/arch/powerpc/exceptions.c | 87
xen/arch/powerpc/exceptions.h | 57
xen/arch/powerpc/external.c | 247
xen/arch/powerpc/float.S | 243
xen/arch/powerpc/gdbstub.c | 207
xen/arch/powerpc/hcalls.c | 172
xen/arch/powerpc/htab.c | 69
xen/arch/powerpc/iommu.c | 79
xen/arch/powerpc/iommu.h | 28
xen/arch/powerpc/irq.c | 22
xen/arch/powerpc/mambo.S | 64
xen/arch/powerpc/mm.c | 141
xen/arch/powerpc/mpic.c | 1109
+
xen/arch/powerpc/mpic_init.c | 390
xen/arch/powerpc/mpic_init.h | 29
xen/arch/powerpc/of-devtree.c | 1088
+
xen/arch/powerpc/of-devtree.h | 139
xen/arch/powerpc/of-devwalk.c | 135
xen/arch/powerpc/of_handler/Makefile | 31
xen/arch/powerpc/of_handler/console.c | 233
xen/arch/powerpc/of_handler/control.c | 90
xen/arch/powerpc/of_handler/cpu.c | 82
xen/arch/powerpc/of_handler/devtree.c | 266
xen/arch/powerpc/of_handler/head.S | 152
xen/arch/powerpc/of_handler/io.c | 160
xen/arch/powerpc/of_handler/leap.S | 38
xen/arch/powerpc/of_handler/memcmp.c | 39
xen/arch/powerpc/of_handler/memory.c | 129
xen/arch/powerpc/of_handler/memset.c | 67
xen/arch/powerpc/of_handler/ofh.c | 454
xen/arch/powerpc/of_handler/ofh.h | 164
xen/arch/powerpc/of_handler/papr.S | 97
xen/arch/powerpc/of_handler/papr.h | 69
xen/arch/powerpc/of_handler/services.c | 96
xen/arch/powerpc/of_handler/snprintf.c | 332
xen/arch/powerpc/of_handler/strcmp.c | 36
xen/arch/powerpc/of_handler/strlen.c | 30
xen/arch/powerpc/of_handler/strncmp.c | 39
xen/arch/powerpc/of_handler/strncpy.c | 54
xen/arch/powerpc/of_handler/strnlen.c | 30
xen/arch/powerpc/of_handler/vdevice.c | 74
xen/arch/powerpc/of_handler/xen_hvcall.S | 28
xen/arch/powerpc/of_handler/xencomm.c | 84
xen/arch/powerpc/ofd_fixup.c | 509
xen/arch/powerpc/oftree.h | 33
xen/arch/powerpc/papr/Makefile | 10
xen/arch/powerpc/papr/debug.c | 84
xen/arch/powerpc/papr/tce.c | 84
xen/arch/powerpc/papr/vtce.c | 158
xen/arch/powerpc/papr/vterm.c | 70
xen/arch/powerpc/papr/xlate.c | 499
xen/arch/powerpc/physdev.c | 24
xen/arch/powerpc/powerpc64/Makefile | 11
xen/arch/powerpc/powerpc64/asm-offsets.c | 65
xen/arch/powerpc/powerpc64/domain.c | 143
xen/arch/powerpc/powerpc64/exceptions.S | 519
xen/arch/powerpc/powerpc64/hypercall_table.S | 83
xen/arch/powerpc/powerpc64/io.S | 142
xen/arch/powerpc/powerpc64/memcpy.S | 171
xen/arch/powerpc/powerpc64/ppc970.c | 164
xen/arch/powerpc/powerpc64/prom_call.S | 116
xen/arch/powerpc/powerpc64/string.S | 286
xen/arch/powerpc/powerpc64/traps.c | 50
xen/arch/powerpc/ppc32/prom_call.c | 41
xen/arch/powerpc/rtas.c | 24
xen/arch/powerpc/setup.c | 370
xen/arch/powerpc/smp.c | 60
xen/arch/powerpc/tce.h | 71
xen/arch/powerpc/time.c | 131
xen/arch/powerpc/usercopy.c | 232
xen/arch/powerpc/xen.lds | 226
xen/arch/x86/hvm/i8254.c | 10
xen/arch/x86/hvm/intercept.c | 4
xen/arch/x86/hvm/io.c | 66
xen/arch/x86/hvm/platform.c | 19
xen/arch/x86/hvm/svm/intr.c | 1
xen/arch/x86/hvm/svm/svm.c | 29
xen/arch/x86/hvm/vmx/io.c | 1
xen/arch/x86/hvm/vmx/vmcs.c | 20
xen/arch/x86/hvm/vmx/vmx.c | 29
xen/arch/x86/irq.c | 15
xen/arch/x86/mm.c | 12
xen/arch/x86/shadow.c | 19
xen/arch/x86/traps.c | 87
xen/arch/x86/x86_emulate.c | 19
xen/common/grant_table.c | 6
xen/common/memory.c | 4
xen/common/trace.c | 24
xen/include/asm-powerpc/asm_defns.h | 28
xen/include/asm-powerpc/atomic.h | 211
xen/include/asm-powerpc/bitops.h | 309
xen/include/asm-powerpc/cache.h | 60
xen/include/asm-powerpc/config.h | 77
xen/include/asm-powerpc/current.h | 79
xen/include/asm-powerpc/debugger.h | 44
xen/include/asm-powerpc/delay.h | 28
xen/include/asm-powerpc/desc.h | 25
xen/include/asm-powerpc/div64.h | 33
xen/include/asm-powerpc/domain.h | 114
xen/include/asm-powerpc/event.h | 99
xen/include/asm-powerpc/flushtlb.h | 108
xen/include/asm-powerpc/grant_table.h | 64
xen/include/asm-powerpc/guest_access.h | 99
xen/include/asm-powerpc/hardirq.h | 21
xen/include/asm-powerpc/hcalls.h | 34
xen/include/asm-powerpc/htab.h | 142
xen/include/asm-powerpc/hypercall.h | 26
xen/include/asm-powerpc/init.h | 59
xen/include/asm-powerpc/io.h | 67
xen/include/asm-powerpc/iocap.h | 26
xen/include/asm-powerpc/irq.h | 31
xen/include/asm-powerpc/mach-default/irq_vectors.h | 105
xen/include/asm-powerpc/memory.h | 39
xen/include/asm-powerpc/misc.h | 33
xen/include/asm-powerpc/mm.h | 224
xen/include/asm-powerpc/mpic.h | 294
xen/include/asm-powerpc/msr.h | 66
xen/include/asm-powerpc/multicall.h | 27
xen/include/asm-powerpc/page.h | 116
xen/include/asm-powerpc/papr.h | 218
xen/include/asm-powerpc/pci.h | 35
xen/include/asm-powerpc/powerpc64/config.h | 45
xen/include/asm-powerpc/powerpc64/ppc970-hid.h | 107
xen/include/asm-powerpc/powerpc64/ppc970.h | 31
xen/include/asm-powerpc/powerpc64/procarea.h | 36
xen/include/asm-powerpc/powerpc64/processor.h | 193
xen/include/asm-powerpc/powerpc64/string.h | 40
xen/include/asm-powerpc/processor.h | 202
xen/include/asm-powerpc/reg_defs.h | 180
xen/include/asm-powerpc/regs.h | 25
xen/include/asm-powerpc/shadow.h | 45
xen/include/asm-powerpc/smp.h | 36
xen/include/asm-powerpc/smpboot.h | 21
xen/include/asm-powerpc/spinlock.h | 221
xen/include/asm-powerpc/string.h | 26
xen/include/asm-powerpc/system.h | 243
xen/include/asm-powerpc/time.h | 42
xen/include/asm-powerpc/types.h | 69
xen/include/asm-powerpc/uaccess.h | 38
xen/include/asm-x86/hvm/io.h | 4
xen/include/asm-x86/hvm/vcpu.h | 18
xen/include/asm-x86/hvm/vpit.h | 4
xen/include/public/arch-powerpc.h | 119
xen/include/public/grant_table.h | 4
xen/include/public/trace.h | 1
xen/include/public/xen.h | 2
xen/include/public/xencomm.h | 37
xen/include/xen/irq.h | 1
xen/include/xen/perfc_defn.h | 2
671 files changed, 143820 insertions(+), 17596 deletions(-)
diff -r 2db50529223e -r f7b43e5c42b9 .hgignore
--- a/.hgignore Tue Jul 25 09:51:50 2006 -0600
+++ b/.hgignore Tue Jul 25 12:19:05 2006 -0600
@@ -54,6 +54,7 @@
^extras/mini-os/h/xen-public$
^extras/mini-os/mini-os\..*$
^install/.*$
+^linux-[^/]*-native/.*$
^linux-[^/]*-xen/.*$
^linux-[^/]*-xen0/.*$
^linux-[^/]*-xenU/.*$
@@ -73,27 +74,11 @@
^tools/.*/TAGS$
^tools/.*/build/lib.*/.*\.py$
^tools/blktap/Makefile\.smh$
-^tools/blktap/blkcow$
-^tools/blktap/blkcowgnbd$
-^tools/blktap/blkcowimg$
-^tools/blktap/blkdump$
-^tools/blktap/blkgnbd$
-^tools/blktap/blkimg$
-^tools/blktap/bstest$
-^tools/blktap/parallax/blockstored$
-^tools/blktap/parallax/parallax$
-^tools/blktap/parallax/vdi_create$
-^tools/blktap/parallax/vdi_fill$
-^tools/blktap/parallax/vdi_list$
-^tools/blktap/parallax/vdi_snap$
-^tools/blktap/parallax/vdi_snap_delete$
-^tools/blktap/parallax/vdi_snap_list$
-^tools/blktap/parallax/vdi_tree$
-^tools/blktap/parallax/vdi_validate$
-^tools/blktap/ublkback/ublkback$
-^tools/blktap/vdi\.dot$
-^tools/blktap/vdi\.ps$
-^tools/blktap/xen/.*$
+^tools/blktap/drivers/blktapctrl$
+^tools/blktap/drivers/img2qcow$
+^tools/blktap/drivers/qcow-create$
+^tools/blktap/drivers/qcow2raw$
+^tools/blktap/drivers/tapdisk$
^tools/check/\..*$
^tools/console/xenconsole$
^tools/console/xenconsoled$
@@ -122,13 +107,21 @@
^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/libaio/src/.*\.ol$
+^tools/libaio/src/.*\.os$
^tools/misc/cpuperf/cpuperf-perfcntr$
^tools/misc/cpuperf/cpuperf-xen$
^tools/misc/lomount/lomount$
@@ -203,3 +196,7 @@
^xen/xen$
^xen/xen-syms$
^xen/xen\..*$
+^xen/arch/ppc/dom0\.bin$
+^xen/arch/ppc/asm-offsets\.s$
+^xen/arch/ppc/firmware
+^xen/arch/ppc/firmware_image
diff -r 2db50529223e -r f7b43e5c42b9 Config.mk
--- a/Config.mk Tue Jul 25 09:51:50 2006 -0600
+++ b/Config.mk Tue Jul 25 12:19:05 2006 -0600
@@ -3,8 +3,8 @@
# A debug build of Xen and tools?
debug ?= n
-# Currently supported architectures: x86_32, x86_64
-XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
+XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/ \
+ -e s/ppc/powerpc/)
XEN_TARGET_ARCH ?= $(XEN_COMPILE_ARCH)
XEN_TARGET_X86_PAE ?= n
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/Rules.mk
--- a/buildconfigs/Rules.mk Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/Rules.mk Tue Jul 25 12:19:05 2006 -0600
@@ -69,9 +69,6 @@ ref-%/.valid-ref: pristine-%/.valid-pris
touch $@ # update timestamp to avoid rebuild
endif
-%-prep:
- $(MAKE) -f buildconfigs/mk.$* prep
-
%-install:
$(MAKE) -f buildconfigs/mk.$* build
@@ -83,14 +80,19 @@ endif
%-build: %-dist
@: # do nothing
+%-prep: DESTDIR=$(DISTDIR)/install
+%-prep:
+ $(MAKE) -f buildconfigs/mk.$* prep
+
+%-config: DESTDIR=$(DISTDIR)/install
+%-config:
+ $(MAKE) -f buildconfigs/mk.$* config
+
%-delete:
$(MAKE) -f buildconfigs/mk.$* delete
%-clean:
$(MAKE) -f buildconfigs/mk.$* clean
-
-%-config:
- $(MAKE) -f buildconfigs/mk.$* config
linux-2.6-xen.patch: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf tmp-$@
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/linux-defconfig_xen0_ia64
--- a/buildconfigs/linux-defconfig_xen0_ia64 Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_ia64 Tue Jul 25 12:19:05 2006 -0600
@@ -1527,6 +1527,7 @@ CONFIG_XEN_BACKEND=y
# CONFIG_XEN_PCIDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_XENBUS_DEV=y
+# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
# CONFIG_XEN_TPMDEV_BACKEND is not set
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32 Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_32 Tue Jul 25 12:19:05 2006 -0600
@@ -1322,6 +1322,7 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y
CONFIG_XEN_PCIDEV_BACKEND_PASS=y
# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
CONFIG_XEN_NETDEV_BACKEND=y
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64 Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen0_x86_64 Tue Jul 25 12:19:05 2006 -0600
@@ -1263,6 +1263,7 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y
CONFIG_XEN_PCIDEV_BACKEND_PASS=y
# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
CONFIG_XEN_NETDEV_BACKEND=y
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/linux-defconfig_xen_ia64
--- a/buildconfigs/linux-defconfig_xen_ia64 Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_ia64 Tue Jul 25 12:19:05 2006 -0600
@@ -1533,6 +1533,7 @@ CONFIG_XEN_BACKEND=y
# CONFIG_XEN_PCIDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_XENBUS_DEV=y
+# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
# CONFIG_XEN_TPMDEV_BACKEND is not set
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32 Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_32 Tue Jul 25 12:19:05 2006 -0600
@@ -3023,6 +3023,7 @@ CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
CONFIG_XEN_NETDEV_BACKEND=y
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64 Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/linux-defconfig_xen_x86_64 Tue Jul 25 12:19:05 2006 -0600
@@ -2855,6 +2855,7 @@ CONFIG_XEN_PCIDEV_BACKEND_PASS=y
CONFIG_XEN_PCIDEV_BACKEND_PASS=y
# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
CONFIG_XEN_BLKDEV_BACKEND=y
+CONFIG_XEN_BLKDEV_TAP=y
CONFIG_XEN_NETDEV_BACKEND=y
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=y
diff -r 2db50529223e -r f7b43e5c42b9 buildconfigs/mk.linux-2.6-xen
--- a/buildconfigs/mk.linux-2.6-xen Tue Jul 25 09:51:50 2006 -0600
+++ b/buildconfigs/mk.linux-2.6-xen Tue Jul 25 12:19:05 2006 -0600
@@ -4,6 +4,11 @@ EXTRAVERSION ?= xen
EXTRAVERSION ?= xen
LINUX_DIR = linux-$(LINUX_VER)-$(EXTRAVERSION)
+
+IMAGE_TARGET ?= vmlinuz
+INSTALL_BOOT_PATH ?= $(DESTDIR)
+
+LINUX_VER3 := $(LINUX_SERIES).$(word 3, $(subst ., ,$(LINUX_VER)))
include buildconfigs/Rules.mk
@@ -14,8 +19,9 @@ build: $(LINUX_DIR)/include/linux/autoco
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH)
INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \
fi
- $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR)
vmlinuz
- $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR)
install
+ $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR)
$(IMAGE_TARGET)
+ mkdir -p $(INSTALL_BOOT_PATH)
+ $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH)
INSTALL_PATH=$(INSTALL_BOOT_PATH) install
$(LINUX_DIR)/include/linux/autoconf.h: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf $(LINUX_DIR)
@@ -25,10 +31,9 @@ build: $(LINUX_DIR)/include/linux/autoco
LINUX_ARCH=$(LINUX_ARCH) bash ./mkbuildtree ../$(LINUX_DIR) )
# Re-use config from install dir if one exits else use default config
CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p'
$(LINUX_DIR)/Makefile); \
- [ -r
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
- cp
$(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION)
$(LINUX_DIR)/.config \
- || cp
buildconfigs/linux-defconfig_$(EXTRAVERSION)_$(XEN_TARGET_ARCH)$(XEN_SYSTYPE) \
- $(LINUX_DIR)/.config
+ [ -r
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
+ cp
$(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION-$(EXTRAVERSION)
$(LINUX_DIR)/.config \
+ || sh buildconfigs/create_config.sh $(LINUX_DIR)/.config
$(EXTRAVERSION) $(XEN_TARGET_ARCH) $(XEN_SYSTYPE)
# See if we need to munge config to enable PAE
$(MAKE) CONFIG_FILE=$(LINUX_DIR)/.config -f buildconfigs/Rules.mk
config-update-pae
# Patch kernel Makefile to set EXTRAVERSION
diff -r 2db50529223e -r f7b43e5c42b9 config/ia64.mk
--- a/config/ia64.mk Tue Jul 25 09:51:50 2006 -0600
+++ b/config/ia64.mk Tue Jul 25 12:19:05 2006 -0600
@@ -1,4 +1,5 @@ CONFIG_IA64 := y
CONFIG_IA64 := y
CONFIG_IOEMU := y
+CONFIG_XCUTILS := y
LIBDIR := lib
diff -r 2db50529223e -r f7b43e5c42b9 config/x86_32.mk
--- a/config/x86_32.mk Tue Jul 25 09:51:50 2006 -0600
+++ b/config/x86_32.mk Tue Jul 25 12:19:05 2006 -0600
@@ -1,7 +1,7 @@ CONFIG_X86 := y
CONFIG_X86 := y
-CONFIG_PLAN9 := y
CONFIG_HVM := y
CONFIG_MIGRATE := y
+CONFIG_XCUTILS := y
CONFIG_IOEMU := y
CONFIG_MBOOTPACK := y
diff -r 2db50529223e -r f7b43e5c42b9 config/x86_64.mk
--- a/config/x86_64.mk Tue Jul 25 09:51:50 2006 -0600
+++ b/config/x86_64.mk Tue Jul 25 12:19:05 2006 -0600
@@ -1,7 +1,7 @@ CONFIG_X86 := y
CONFIG_X86 := y
-CONFIG_PLAN9 := y
CONFIG_HVM := y
CONFIG_MIGRATE := y
+CONFIG_XCUTILS := y
CONFIG_IOEMU := y
CONFIG_MBOOTPACK := y
diff -r 2db50529223e -r f7b43e5c42b9 extras/mini-os/mm.c
--- a/extras/mini-os/mm.c Tue Jul 25 09:51:50 2006 -0600
+++ b/extras/mini-os/mm.c Tue Jul 25 12:19:05 2006 -0600
@@ -687,7 +687,7 @@ void *map_frames(unsigned long *f, unsig
/* Find a run of n contiguous frames */
for (x = 0; x <= 1024 - n; x += y + 1) {
for (y = 0; y < n; y++)
- if (demand_map_pgt[y] & _PAGE_PRESENT)
+ if (demand_map_pgt[x+y] & _PAGE_PRESENT)
break;
if (y == n)
break;
diff -r 2db50529223e -r f7b43e5c42b9
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Tue Jul 25
09:51:50 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Tue Jul 25
12:19:05 2006 -0600
@@ -29,6 +29,7 @@
#include <xen/interface/xen.h>
#include <xen/interface/xenoprof.h>
#include <../../../drivers/oprofile/cpu_buffer.h>
+#include <../../../drivers/oprofile/event_buffer.h>
static int xenoprof_start(void);
static void xenoprof_stop(void);
@@ -151,16 +152,27 @@ static void xenoprof_handle_passive(void
static void xenoprof_handle_passive(void)
{
int i, j;
-
- for (i = 0; i < pdomains; i++)
+ int flag_domain, flag_switch = 0;
+
+ for (i = 0; i < pdomains; i++) {
+ flag_domain = 0;
for (j = 0; j < passive_domains[i].nbuf; j++) {
xenoprof_buf_t *buf = p_xenoprof_buf[i][j];
if (buf->event_head == buf->event_tail)
continue;
- oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_START,
passive_domains[i].domain_id);
+ if (!flag_domain) {
+ if
(!oprofile_add_domain_switch(passive_domains[i].
+ domain_id))
+ goto done;
+ flag_domain = 1;
+ }
xenoprof_add_pc(buf, 1);
- oprofile_add_pc(IGNORED_PC, CPU_MODE_PASSIVE_STOP,
passive_domains[i].domain_id);
- }
+ flag_switch = 1;
+ }
+ }
+done:
+ if (flag_switch)
+ oprofile_add_domain_switch(COORDINATOR_DOMAIN);
}
static irqreturn_t
@@ -177,6 +189,7 @@ xenoprof_ovf_interrupt(int irq, void * d
if (is_primary && !test_and_set_bit(0, &flag)) {
xenoprof_handle_passive();
+ smp_mb__before_clear_bit();
clear_bit(0, &flag);
}
diff -r 2db50529223e -r f7b43e5c42b9 linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Jul 25 09:51:50 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Tue Jul 25 12:19:05 2006 -0600
@@ -29,6 +29,11 @@ config XEN_UNPRIVILEGED_GUEST
default !XEN_PRIVILEGED_GUEST
config XEN_PRIVCMD
+ bool
+ depends on PROC_FS
+ default y
+
+config XEN_XENBUS_DEV
bool
depends on PROC_FS
default y
@@ -40,8 +45,59 @@ config XEN_BACKEND
Support for backend device drivers that provide I/O services
to other virtual machines.
+config XEN_BLKDEV_BACKEND
+ tristate "Block-device backend driver"
+ depends on XEN_BACKEND
+ default y
+ help
+ The block-device backend driver allows the kernel to export its
+ block devices to other guests via a high-performance shared-memory
+ interface.
+
+config XEN_BLKDEV_TAP
+ tristate "Block-device tap backend driver"
+ depends on XEN_BACKEND
+ default XEN_PRIVILEGED_GUEST
+ help
+ The block tap driver is an alternative to the block back driver
+ and allows VM block requests to be redirected to userspace through
+ a device interface. The tap allows user-space development of
+ high-performance block backends, where disk images may be implemented
+ as files, in memory, or on other hosts across the network. This
+ driver can safely coexist with the existing blockback driver.
+
+config XEN_NETDEV_BACKEND
+ tristate "Network-device backend driver"
+ depends on XEN_BACKEND && NET
+ default y
+ help
+ The network-device backend driver allows the kernel to export its
+ network devices to other guests via a high-performance shared-memory
+ interface.
+
+config XEN_NETDEV_PIPELINED_TRANSMITTER
+ bool "Pipelined transmitter (DANGEROUS)"
+ depends on XEN_NETDEV_BACKEND
+ default n
+ help
+ If the net backend is a dumb domain, such as a transparent Ethernet
+ bridge with no local IP interface, it is safe to say Y here to get
+ slightly lower network overhead.
+ If the backend has a local IP interface; or may be doing smart things
+ like reassembling packets to perform firewall filtering; or if you
+ are unsure; or if you experience network hangs when this option is
+ enabled; then you must say N here.
+
+config XEN_NETDEV_LOOPBACK
+ tristate "Network-device loopback driver"
+ depends on XEN_NETDEV_BACKEND
+ default y
+ help
+ A two-interface loopback device to emulate a local netfront-netback
+ connection.
+
config XEN_PCIDEV_BACKEND
- tristate "PCI device backend driver"
+ tristate "PCI-device backend driver"
depends on PCI && XEN_BACKEND
default XEN_PRIVILEGED_GUEST
help
@@ -80,50 +136,6 @@ config XEN_PCIDEV_BE_DEBUG
depends on XEN_PCIDEV_BACKEND
default n
-config XEN_BLKDEV_BACKEND
- tristate "Block-device backend driver"
- depends on XEN_BACKEND
- default y
- help
- The block-device backend driver allows the kernel to export its
- block devices to other guests via a high-performance shared-memory
- interface.
-
-config XEN_XENBUS_DEV
- bool
- depends on PROC_FS
- default y
-
-config XEN_NETDEV_BACKEND
- tristate "Network-device backend driver"
- depends on XEN_BACKEND && NET
- default y
- help
- The network-device backend driver allows the kernel to export its
- network devices to other guests via a high-performance shared-memory
- interface.
-
-config XEN_NETDEV_PIPELINED_TRANSMITTER
- bool "Pipelined transmitter (DANGEROUS)"
- depends on XEN_NETDEV_BACKEND
- default n
- help
- If the net backend is a dumb domain, such as a transparent Ethernet
- bridge with no local IP interface, it is safe to say Y here to get
- slightly lower network overhead.
- If the backend has a local IP interface; or may be doing smart things
- like reassembling packets to perform firewall filtering; or if you
- are unsure; or if you experience network hangs when this option is
- enabled; then you must say N here.
-
-config XEN_NETDEV_LOOPBACK
- tristate "Network-device loopback driver"
- depends on XEN_NETDEV_BACKEND
- default y
- help
- A two-interface loopback device to emulate a local netfront-netback
- connection.
-
config XEN_TPMDEV_BACKEND
tristate "TPM-device backend driver"
depends on XEN_BACKEND
@@ -183,7 +195,7 @@ config XEN_SYSFS
depends on SYSFS
default y
help
- Xen hypervisor attributes will show up under /sys/hypervisor/.
+ Xen hypervisor attributes will show up under /sys/hypervisor/.
choice
prompt "Xen version compatibility"
diff -r 2db50529223e -r f7b43e5c42b9 linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Tue Jul 25 09:51:50 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Tue Jul 25 12:19:05 2006 -0600
@@ -8,6 +8,7 @@ obj-$(CONFIG_XEN_BALLOON) += balloon/
obj-$(CONFIG_XEN_BALLOON) += balloon/
obj-$(CONFIG_XEN_DEVMEM) += char/
obj-$(CONFIG_XEN_BLKDEV_BACKEND) += blkback/
+obj-$(CONFIG_XEN_BLKDEV_TAP) += blktap/
obj-$(CONFIG_XEN_NETDEV_BACKEND) += netback/
obj-$(CONFIG_XEN_TPMDEV_BACKEND) += tpmback/
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/
diff -r 2db50529223e -r f7b43e5c42b9
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Jul 25
09:51:50 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Jul 25
12:19:05 2006 -0600
@@ -536,18 +536,27 @@ static void xencons_close(struct tty_str
if (DUMMY_TTY(tty))
return;
- if (tty->count == 1) {
- tty->closing = 1;
- tty_wait_until_sent(tty, 0);
- if (DRV(tty->driver)->flush_buffer != NULL)
- DRV(tty->driver)->flush_buffer(tty);
- if (tty->ldisc.flush_buffer != NULL)
- tty->ldisc.flush_buffer(tty);
- tty->closing = 0;
- spin_lock_irqsave(&xencons_lock, flags);
- xencons_tty = NULL;
- spin_unlock_irqrestore(&xencons_lock, flags);
- }
+ down(&tty_sem);
+
+ if (tty->count != 1) {
+ up(&tty_sem);
+ return;
+ }
+
+ /* Prevent other threads from re-opening this tty. */
+ set_bit(TTY_CLOSING, &tty->flags);
+ up(&tty_sem);
+
+ tty->closing = 1;
+ tty_wait_until_sent(tty, 0);
+ if (DRV(tty->driver)->flush_buffer != NULL)
+ DRV(tty->driver)->flush_buffer(tty);
+ if (tty->ldisc.flush_buffer != NULL)
+ tty->ldisc.flush_buffer(tty);
+ tty->closing = 0;
+ spin_lock_irqsave(&xencons_lock, flags);
+ xencons_tty = NULL;
+ spin_unlock_irqrestore(&xencons_lock, flags);
}
static struct tty_operations xencons_ops = {
diff -r 2db50529223e -r f7b43e5c42b9
linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Tue Jul 25
09:51:50 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c Tue Jul 25
12:19:05 2006 -0600
@@ -852,11 +852,11 @@ static void processing_timeout(unsigned
*/
if (pak == packet_find_packet(&dataex.pending_pak, pak) ||
pak == packet_find_packet(&dataex.current_pak, pak)) {
- list_del(&pak->next);
if ((pak->flags & PACKET_FLAG_DISCARD_RESPONSE) == 0) {
tpm_send_fail_message(pak, pak->req_tag);
}
- packet_free(pak);
+ /* discard future responses */
+ pak->flags |= PACKET_FLAG_DISCARD_RESPONSE;
}
write_unlock_irqrestore(&dataex.pak_lock, flags);
diff -r 2db50529223e -r f7b43e5c42b9
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h Tue Jul
25 09:51:50 2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h Tue Jul
25 12:19:05 2006 -0600
@@ -120,7 +120,6 @@ dma_set_mask(struct device *dev, u64 mas
return 0;
}
-#ifdef __i386__
static inline int
dma_get_cache_alignment(void)
{
@@ -128,7 +127,6 @@ dma_get_cache_alignment(void)
* maximum possible, to be safe */
return (1 << INTERNODE_CACHE_SHIFT);
}
-#endif
#define dma_is_consistent(d) (1)
diff -r 2db50529223e -r f7b43e5c42b9 linux-2.6-xen-sparse/include/linux/skbuff.h
--- a/linux-2.6-xen-sparse/include/linux/skbuff.h Tue Jul 25 09:51:50
2006 -0600
+++ b/linux-2.6-xen-sparse/include/linux/skbuff.h Tue Jul 25 12:19:05
2006 -0600
@@ -1412,5 +1412,10 @@ static inline void nf_reset(struct sk_bu
static inline void nf_reset(struct sk_buff *skb) {}
#endif /* CONFIG_NETFILTER */
+static inline int skb_is_gso(const struct sk_buff *skb)
+{
+ return skb_shinfo(skb)->gso_size;
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff -r 2db50529223e -r f7b43e5c42b9 linux-2.6-xen-sparse/net/core/dev.c
--- a/linux-2.6-xen-sparse/net/core/dev.c Tue Jul 25 09:51:50 2006 -0600
+++ b/linux-2.6-xen-sparse/net/core/dev.c Tue Jul 25 12:19:05 2006 -0600
@@ -1089,9 +1089,17 @@ int skb_checksum_help(struct sk_buff *sk
unsigned int csum;
int ret = 0, offset = skb->h.raw - skb->data;
- if (inward) {
- skb->ip_summed = CHECKSUM_NONE;
- goto out;
+ if (inward)
+ goto out_set_summed;
+
+ if (unlikely(skb_shinfo(skb)->gso_size)) {
+ static int warned;
+
+ WARN_ON(!warned);
+ warned = 1;
+
+ /* Let GSO fix up the checksum. */
+ goto out_set_summed;
}
if (skb_cloned(skb)) {
@@ -1108,6 +1116,8 @@ int skb_checksum_help(struct sk_buff *sk
BUG_ON(skb->csum + 2 > offset);
*(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
+
+out_set_summed:
skb->ip_summed = CHECKSUM_NONE;
out:
return ret;
@@ -1128,17 +1138,35 @@ struct sk_buff *skb_gso_segment(struct s
struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
struct packet_type *ptype;
int type = skb->protocol;
+ int err;
BUG_ON(skb_shinfo(skb)->frag_list);
- BUG_ON(skb->ip_summed != CHECKSUM_HW);
skb->mac.raw = skb->data;
skb->mac_len = skb->nh.raw - skb->data;
__skb_pull(skb, skb->mac_len);
+ if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
+ static int warned;
+
+ WARN_ON(!warned);
+ warned = 1;
+
+ if (skb_header_cloned(skb) &&
+ (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+ return ERR_PTR(err);
+ }
+
rcu_read_lock();
list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
+ if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
+ err = ptype->gso_send_check(skb);
+ segs = ERR_PTR(err);
+ if (err || skb_gso_ok(skb, features))
+ break;
+ __skb_push(skb, skb->data - skb->nh.raw);
+ }
segs = ptype->gso_segment(skb, features);
break;
}
diff -r 2db50529223e -r f7b43e5c42b9 patches/linux-2.6.16.13/net-csum.patch
--- a/patches/linux-2.6.16.13/net-csum.patch Tue Jul 25 09:51:50 2006 -0600
+++ b/patches/linux-2.6.16.13/net-csum.patch Tue Jul 25 12:19:05 2006 -0600
@@ -1,40 +1,39 @@ diff -pruN ../pristine-linux-2.6.16.13/n
diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c
./net/ipv4/netfilter/ip_nat_proto_tcp.c
--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_tcp.c
2006-05-02 22:38:44.000000000 +0100
-+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-05-04 17:41:37.000000000
+0100
-@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-05-16 13:28:19.000000000
+0100
+@@ -129,7 +129,12 @@ tcp_manip_pkt(struct sk_buff **pskb,
if (hdrsize < sizeof(*hdr))
return 1;
- hdr->check = ip_nat_cheat_check(~oldip, newip,
-+ if ((*pskb)->proto_csum_blank) {
++#ifdef CONFIG_XEN
++ if ((*pskb)->proto_csum_blank)
+ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
-+ } else {
++ else
++#endif
+ hdr->check = ip_nat_cheat_check(~oldip, newip,
ip_nat_cheat_check(oldport ^ 0xFFFF,
newport,
hdr->check));
-+ }
- return 1;
- }
-
diff -pruN ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c
./net/ipv4/netfilter/ip_nat_proto_udp.c
--- ../pristine-linux-2.6.16.13/net/ipv4/netfilter/ip_nat_proto_udp.c
2006-05-02 22:38:44.000000000 +0100
-+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-05-04 17:41:37.000000000
+0100
-@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb,
++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-05-16 13:30:14.000000000
+0100
+@@ -113,11 +113,17 @@ udp_manip_pkt(struct sk_buff **pskb,
newport = tuple->dst.u.udp.port;
portptr = &hdr->dest;
}
- if (hdr->check) /* 0 is a special case meaning no checksum */
- hdr->check = ip_nat_cheat_check(~oldip, newip,
+ if (hdr->check) { /* 0 is a special case meaning no checksum */
-+ if ((*pskb)->proto_csum_blank) {
++#ifdef CONFIG_XEN
++ if ((*pskb)->proto_csum_blank)
+ hdr->check = ip_nat_cheat_check(oldip, ~newip,
hdr->check);
-+ } else {
++ else
++#endif
+ hdr->check = ip_nat_cheat_check(~oldip, newip,
ip_nat_cheat_check(*portptr ^ 0xFFFF,
newport,
hdr->check));
-+ }
+ }
*portptr = newport;
return 1;
diff -r 2db50529223e -r f7b43e5c42b9
patches/linux-2.6.16.13/xenoprof-generic.patch
--- a/patches/linux-2.6.16.13/xenoprof-generic.patch Tue Jul 25 09:51:50
2006 -0600
+++ b/patches/linux-2.6.16.13/xenoprof-generic.patch Tue Jul 25 12:19:05
2006 -0600
@@ -1,6 +1,6 @@ diff -pru ../pristine-linux-2.6.16.13/dr
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c
./drivers/oprofile/buffer_sync.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.c 2006-05-03
05:38:44.000000000 +0800
-+++ ./drivers/oprofile/buffer_sync.c 2006-06-27 12:14:53.000000000 +0800
+diff -Naur orig/drivers/oprofile/buffer_sync.c
new/drivers/oprofile/buffer_sync.c
+--- orig/drivers/oprofile/buffer_sync.c 2006-05-02 14:38:44.000000000
-0700
++++ new/drivers/oprofile/buffer_sync.c 2006-07-06 18:19:05.000000000 -0700
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -12,7 +12,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
* This is the core of the buffer management. Each
* CPU buffer is processed and entered into the
* global event buffer. Such processing is necessary
-@@ -275,15 +279,30 @@ static void add_cpu_switch(int i)
+@@ -275,15 +279,31 @@
last_cookie = INVALID_COOKIE;
}
@@ -34,22 +34,23 @@ diff -pru ../pristine-linux-2.6.16.13/dr
+ case CPU_MODE_XEN:
+ add_event_entry(XEN_ENTER_SWITCH_CODE);
+ break;
-+ case CPU_MODE_PASSIVE_START:
-+ add_event_entry(PASSIVE_START_CODE);
-+ break;
-+ case CPU_MODE_PASSIVE_STOP:
-+ add_event_entry(PASSIVE_STOP_CODE);
-+ break;
+ default:
+ break;
+ }
}
-
+
++static void add_domain_switch(unsigned long domain_id)
++{
++ add_event_entry(ESCAPE_CODE);
++ add_event_entry(DOMAIN_SWITCH_CODE);
++ add_event_entry(domain_id);
++}
++
static void
add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
{
-@@ -348,9 +367,9 @@ static int add_us_sample(struct mm_struc
+@@ -348,9 +368,9 @@
* for later lookup from userspace.
*/
static int
@@ -61,7 +62,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
add_sample_entry(s->eip, s->event);
return 1;
} else if (mm) {
-@@ -496,10 +515,11 @@ void sync_buffer(int cpu)
+@@ -496,10 +516,11 @@
struct mm_struct *mm = NULL;
struct task_struct * new;
unsigned long cookie = 0;
@@ -70,34 +71,35 @@ diff -pru ../pristine-linux-2.6.16.13/dr
unsigned int i;
sync_buffer_state state = sb_buffer_start;
unsigned long available;
-+ int domain_switch = NO_DOMAIN_SWITCH;
++ int domain_switch = 0;
down(&buffer_sem);
-@@ -513,12 +533,19 @@ void sync_buffer(int cpu)
+@@ -512,16 +533,18 @@
+ for (i = 0; i < available; ++i) {
struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
- if (is_code(s->eip)) {
+- if (is_code(s->eip)) {
- if (s->event <= CPU_IS_KERNEL) {
-+ if (s->event < CPU_TRACE_BEGIN) {
- /* kernel/userspace switch */
+- /* kernel/userspace switch */
- in_kernel = s->event;
++ if (is_code(s->eip) && !domain_switch) {
++ if (s->event <= CPU_MODE_XEN) {
++ /* xen/kernel/userspace switch */
+ cpu_mode = s->event;
if (state == sb_buffer_start)
state = sb_sample_start;
- add_kernel_ctx_switch(s->event);
-+
-+ if (s->event == CPU_MODE_PASSIVE_START)
-+ domain_switch =
DOMAIN_SWITCH_START_EVENT1;
-+ else if (s->event == CPU_MODE_PASSIVE_STOP)
-+ domain_switch =
DOMAIN_SWITCH_STOP_EVENT1;
-+
-+ if (domain_switch != DOMAIN_SWITCH_START_EVENT2)
-+ add_cpu_mode_switch(s->event);
++ add_cpu_mode_switch(s->event);
} else if (s->event == CPU_TRACE_BEGIN) {
state = sb_bt_start;
add_trace_begin();
-@@ -535,11 +562,20 @@ void sync_buffer(int cpu)
++ } else if (s->event == CPU_DOMAIN_SWITCH) {
++ domain_switch = 1;
+ } else {
+ struct mm_struct * oldmm = mm;
+
+@@ -535,11 +558,16 @@
add_user_ctx_switch(new, cookie);
}
} else {
@@ -106,13 +108,9 @@ diff -pru ../pristine-linux-2.6.16.13/dr
- if (state == sb_bt_start) {
- state = sb_bt_ignore;
-
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
-+ if (domain_switch == DOMAIN_SWITCH_START_EVENT1) {
-+ add_event_entry(s->event);
-+ domain_switch = DOMAIN_SWITCH_START_EVENT2;
-+ } else if (domain_switch == DOMAIN_SWITCH_START_EVENT1)
{
-+ add_sample_entry(s->eip, s->event);
-+ } else if (domain_switch == DOMAIN_SWITCH_STOP_EVENT1) {
-+ domain_switch = NO_DOMAIN_SWITCH;
++ if (domain_switch) {
++ add_domain_switch(s->eip);
++ domain_switch = 0;
+ } else {
+ if (state >= sb_bt_start &&
+ !add_sample(mm, s, cpu_mode)) {
@@ -123,24 +121,9 @@ diff -pru ../pristine-linux-2.6.16.13/dr
}
}
}
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h
./drivers/oprofile/buffer_sync.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/buffer_sync.h 2006-05-03
05:38:44.000000000 +0800
-+++ ./drivers/oprofile/buffer_sync.h 2006-06-27 12:12:09.000000000 +0800
-@@ -9,6 +9,11 @@
-
- #ifndef OPROFILE_BUFFER_SYNC_H
- #define OPROFILE_BUFFER_SYNC_H
-+
-+#define NO_DOMAIN_SWITCH -1
-+#define DOMAIN_SWITCH_START_EVENT1 0
-+#define DOMAIN_SWITCH_START_EVENT2 1
-+#define DOMAIN_SWITCH_STOP_EVENT1 2
-
- /* add the necessary profiling hooks */
- int sync_start(void);
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c
./drivers/oprofile/cpu_buffer.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.c 2006-05-03
05:38:44.000000000 +0800
-+++ ./drivers/oprofile/cpu_buffer.c 2006-06-19 22:43:53.000000000 +0800
+diff -Naur orig/drivers/oprofile/cpu_buffer.c new/drivers/oprofile/cpu_buffer.c
+--- orig/drivers/oprofile/cpu_buffer.c 2006-05-02 14:38:44.000000000 -0700
++++ new/drivers/oprofile/cpu_buffer.c 2006-07-06 18:19:05.000000000 -0700
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@xxxxxxxxxxxxxxxxx>
@@ -152,7 +135,16 @@ diff -pru ../pristine-linux-2.6.16.13/dr
* Each CPU has a local buffer that stores PC value/event
* pairs. We also log context switches when we notice them.
* Eventually each CPU's buffer is processed into the global
-@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void)
+@@ -34,6 +38,8 @@
+ #define DEFAULT_TIMER_EXPIRE (HZ / 10)
+ static int work_enabled;
+
++static int32_t current_domain = COORDINATOR_DOMAIN;
++
+ void free_cpu_buffers(void)
+ {
+ int i;
+@@ -58,7 +64,7 @@
goto fail;
b->last_task = NULL;
@@ -161,7 +153,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
b->tracing = 0;
b->buffer_size = buffer_size;
b->tail_pos = 0;
-@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp
+@@ -114,7 +120,7 @@
* collected will populate the buffer with proper
* values to initialize the buffer
*/
@@ -170,7 +162,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
cpu_buf->last_task = NULL;
}
-@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu
+@@ -164,13 +170,13 @@
* because of the head/tail separation of the writer and reader
* of the CPU buffer.
*
@@ -188,7 +180,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
{
struct task_struct * task;
-@@ -181,16 +185,14 @@ static int log_sample(struct oprofile_cp
+@@ -181,18 +187,18 @@
return 0;
}
@@ -207,12 +199,43 @@ diff -pru ../pristine-linux-2.6.16.13/dr
-
+
/* notice a task switch */
- if (cpu_buf->last_task != task) {
+- if (cpu_buf->last_task != task) {
++ /* if not processing other domain samples */
++ if ((cpu_buf->last_task != task) &&
++ (current_domain == COORDINATOR_DOMAIN)) {
cpu_buf->last_task = task;
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h
./drivers/oprofile/cpu_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/cpu_buffer.h 2006-05-03
05:38:44.000000000 +0800
-+++ ./drivers/oprofile/cpu_buffer.h 2006-06-27 10:38:08.000000000 +0800
-@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
+ add_code(cpu_buf, (unsigned long)task);
+ }
+@@ -269,6 +275,25 @@
+ add_sample(cpu_buf, pc, 0);
+ }
+
++int oprofile_add_domain_switch(int32_t domain_id)
++{
++ struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()];
++
++ /* should have space for switching into and out of domain
++ (2 slots each) plus one sample and one cpu mode switch */
++ if (((nr_available_slots(cpu_buf) < 6) &&
++ (domain_id != COORDINATOR_DOMAIN)) ||
++ (nr_available_slots(cpu_buf) < 2))
++ return 0;
++
++ add_code(cpu_buf, CPU_DOMAIN_SWITCH);
++ add_sample(cpu_buf, domain_id, 0);
++
++ current_domain = domain_id;
++
++ return 1;
++}
++
+ /*
+ * This serves to avoid cpu buffer overflow, and makes sure
+ * the task mortuary progresses
+diff -Naur orig/drivers/oprofile/cpu_buffer.h new/drivers/oprofile/cpu_buffer.h
+--- orig/drivers/oprofile/cpu_buffer.h 2006-05-02 14:38:44.000000000 -0700
++++ new/drivers/oprofile/cpu_buffer.h 2006-07-06 18:19:05.000000000 -0700
+@@ -36,7 +36,7 @@
volatile unsigned long tail_pos;
unsigned long buffer_size;
struct task_struct * last_task;
@@ -221,7 +244,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
int tracing;
struct op_sample * buffer;
unsigned long sample_received;
-@@ -51,7 +51,13 @@ extern struct oprofile_cpu_buffer cpu_bu
+@@ -51,7 +51,10 @@
void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
/* transient events for the CPU buffer -> event buffer */
@@ -230,17 +253,14 @@ diff -pru ../pristine-linux-2.6.16.13/dr
+#define CPU_MODE_USER 0
+#define CPU_MODE_KERNEL 1
+#define CPU_MODE_XEN 2
-+#define CPU_MODE_PASSIVE_START 3
-+#define CPU_MODE_PASSIVE_STOP 4
-+#define CPU_TRACE_BEGIN 5
-+
-+#define IGNORED_PC 0
++#define CPU_TRACE_BEGIN 3
++#define CPU_DOMAIN_SWITCH 4
#endif /* OPROFILE_CPU_BUFFER_H */
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h
./drivers/oprofile/event_buffer.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/event_buffer.h
2006-05-03 05:38:44.000000000 +0800
-+++ ./drivers/oprofile/event_buffer.h 2006-06-19 22:43:53.000000000 +0800
-@@ -29,11 +29,14 @@ void wake_up_buffer_waiter(void);
+diff -Naur orig/drivers/oprofile/event_buffer.h
new/drivers/oprofile/event_buffer.h
+--- orig/drivers/oprofile/event_buffer.h 2006-05-02 14:38:44.000000000
-0700
++++ new/drivers/oprofile/event_buffer.h 2006-07-06 18:19:05.000000000
-0700
+@@ -29,15 +29,20 @@
#define CPU_SWITCH_CODE 2
#define COOKIE_SWITCH_CODE 3
#define KERNEL_ENTER_SWITCH_CODE 4
@@ -251,14 +271,20 @@ diff -pru ../pristine-linux-2.6.16.13/dr
#define TRACE_BEGIN_CODE 8
#define TRACE_END_CODE 9
+#define XEN_ENTER_SWITCH_CODE 10
-+#define PASSIVE_START_CODE 11
-+#define PASSIVE_STOP_CODE 12
++#define DOMAIN_SWITCH_CODE 11
#define INVALID_COOKIE ~0UL
#define NO_COOKIE 0UL
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c
./drivers/oprofile/oprof.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.c 2006-05-03
05:38:44.000000000 +0800
-+++ ./drivers/oprofile/oprof.c 2006-06-19 23:45:17.000000000 +0800
+
++/* Constant used to refer to coordinator domain (Xen) */
++#define COORDINATOR_DOMAIN -1
++
+ /* add data to the event buffer */
+ void add_event_entry(unsigned long data);
+
+diff -Naur orig/drivers/oprofile/oprof.c new/drivers/oprofile/oprof.c
+--- orig/drivers/oprofile/oprof.c 2006-05-02 14:38:44.000000000 -0700
++++ new/drivers/oprofile/oprof.c 2006-07-06 18:19:05.000000000 -0700
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
@@ -279,7 +305,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
struct oprofile_operations oprofile_ops;
unsigned long oprofile_started;
-@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem);
+@@ -33,6 +37,32 @@
*/
static int timer = 0;
@@ -312,10 +338,10 @@ diff -pru ../pristine-linux-2.6.16.13/dr
int oprofile_setup(void)
{
int err;
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h
./drivers/oprofile/oprof.h
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprof.h 2006-05-03
05:38:44.000000000 +0800
-+++ ./drivers/oprofile/oprof.h 2006-06-19 23:42:36.000000000 +0800
-@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
+diff -Naur orig/drivers/oprofile/oprof.h new/drivers/oprofile/oprof.h
+--- orig/drivers/oprofile/oprof.h 2006-05-02 14:38:44.000000000 -0700
++++ new/drivers/oprofile/oprof.h 2006-07-06 18:19:05.000000000 -0700
+@@ -35,5 +35,8 @@
void oprofile_timer_init(struct oprofile_operations * ops);
int oprofile_set_backtrace(unsigned long depth);
@@ -324,9 +350,9 @@ diff -pru ../pristine-linux-2.6.16.13/dr
+int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
#endif /* OPROF_H */
-diff -pru ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c
./drivers/oprofile/oprofile_files.c
---- ../pristine-linux-2.6.16.13/drivers/oprofile/oprofile_files.c
2006-05-03 05:38:44.000000000 +0800
-+++ ./drivers/oprofile/oprofile_files.c 2006-06-19 23:29:07.000000000
+0800
+diff -Naur orig/drivers/oprofile/oprofile_files.c
new/drivers/oprofile/oprofile_files.c
+--- orig/drivers/oprofile/oprofile_files.c 2006-05-02 14:38:44.000000000
-0700
++++ new/drivers/oprofile/oprofile_files.c 2006-07-06 18:19:05.000000000
-0700
@@ -5,15 +5,21 @@
* @remark Read the file COPYING
*
@@ -350,7 +376,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
unsigned long fs_buffer_size = 131072;
unsigned long fs_cpu_buffer_size = 8192;
unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
-@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file *
+@@ -117,11 +123,202 @@
static struct file_operations dump_fops = {
.write = dump_write,
};
@@ -554,8 +580,9 @@ diff -pru ../pristine-linux-2.6.16.13/dr
oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
oprofilefs_create_ulong(sb, root, "buffer_watershed",
&fs_buffer_watershed);
---- ../pristine-linux-2.6.16.13/include/linux/oprofile.h 2006-05-03
05:38:44.000000000 +0800
-+++ ./include/linux/oprofile.h 2006-06-19 23:52:00.000000000 +0800
+diff -Naur orig/include/linux/oprofile.h new/include/linux/oprofile.h
+--- orig/include/linux/oprofile.h 2006-05-02 14:38:44.000000000 -0700
++++ new/include/linux/oprofile.h 2006-07-06 18:19:31.000000000 -0700
@@ -16,6 +16,8 @@
#include <linux/types.h>
#include <linux/spinlock.h>
@@ -565,7 +592,7 @@ diff -pru ../pristine-linux-2.6.16.13/dr
struct super_block;
struct dentry;
-@@ -27,6 +29,11 @@ struct oprofile_operations {
+@@ -27,6 +29,11 @@
/* create any necessary configuration files in the oprofile fs.
* Optional. */
int (*create_files)(struct super_block * sb, struct dentry * root);
@@ -577,3 +604,12 @@ diff -pru ../pristine-linux-2.6.16.13/dr
/* Do any necessary interrupt setup. Optional. */
int (*setup)(void);
/* Do any necessary interrupt shutdown. Optional. */
+@@ -68,6 +75,8 @@
+ /* add a backtrace entry, to be called from the ->backtrace callback */
+ void oprofile_add_trace(unsigned long eip);
+
++/* add a domain switch entry */
++int oprofile_add_domain_switch(int32_t domain_id);
+
+ /**
+ * Create a file of the given name as a child of the given root, with
diff -r 2db50529223e -r f7b43e5c42b9 tools/Makefile
--- a/tools/Makefile Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/Makefile Tue Jul 25 12:19:05 2006 -0600
@@ -7,7 +7,7 @@ SUBDIRS-y += misc
SUBDIRS-y += misc
SUBDIRS-y += examples
SUBDIRS-y += xentrace
-SUBDIRS-$(CONFIG_X86) += xcutils
+SUBDIRS-$(CONFIG_XCUTILS) += xcutils
SUBDIRS-y += firmware
SUBDIRS-y += security
SUBDIRS-y += console
@@ -16,6 +16,8 @@ SUBDIRS-$(VTPM_TOOLS) += vtpm_manager
SUBDIRS-$(VTPM_TOOLS) += vtpm_manager
SUBDIRS-$(VTPM_TOOLS) += vtpm
SUBDIRS-y += xenstat
+SUBDIRS-y += libaio
+SUBDIRS-y += blktap
# These don't cross-compile
ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
@@ -58,10 +60,13 @@ check_clean:
.PHONY: ioemu ioemuinstall ioemuclean
ifdef CONFIG_IOEMU
-ioemu ioemuinstall ioemuclean:
- [ -f ioemu/config-host.h ] || \
- (cd ioemu; sh ./configure --prefix=usr)
- $(MAKE) -C ioemu $(patsubst ioemu%,%,$@)
+export IOEMU_DIR ?= ioemu
+ioemu ioemuinstall:
+ [ -f $(IOEMU_DIR)/config-host.mak ] || \
+ (cd $(IOEMU_DIR) && sh configure --prefix=/usr)
+ $(MAKE) -C $(IOEMU_DIR) $(patsubst ioemu%,%,$@)
+ioemuclean:
+ $(MAKE) -C $(IOEMU_DIR) distclean
else
ioemu ioemuinstall ioemuclean:
endif
diff -r 2db50529223e -r f7b43e5c42b9 tools/examples/Makefile
--- a/tools/examples/Makefile Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/examples/Makefile Tue Jul 25 12:19:05 2006 -0600
@@ -26,7 +26,8 @@ XEN_SCRIPTS += network-nat vif-nat
XEN_SCRIPTS += network-nat vif-nat
XEN_SCRIPTS += block
XEN_SCRIPTS += block-enbd block-nbd
-XEN_SCRIPTS += vtpm vtpm-delete vtpm-addtodb
+XEN_SCRIPTS += blktap
+XEN_SCRIPTS += vtpm vtpm-delete
XEN_SCRIPTS += xen-hotplug-cleanup
XEN_SCRIPTS += external-device-migrate
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
diff -r 2db50529223e -r f7b43e5c42b9 tools/examples/README
--- a/tools/examples/README Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/examples/README Tue Jul 25 12:19:05 2006 -0600
@@ -25,7 +25,6 @@ vif-nat - xen virtual networ
vif-nat - xen virtual network start/stop script in NAT mode
vif-route - xen virtual network start/stop script in routed mode
vtpm - called by xen-backend.agent to bind/unbind vTPM devices
-vtpm-addtodb - script for adding a vTPM instance to the vTPM table
vtpm-common.sh - common code for vTPM handling
vtpm-delete - remove an entry from the vTPM table given the
domain's name
diff -r 2db50529223e -r f7b43e5c42b9 tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/examples/vtpm-common.sh Tue Jul 25 12:19:05 2006 -0600
@@ -24,12 +24,9 @@ VTPMDB="/etc/xen/vtpm.db"
#In the vtpm-impl file some commands should be defined:
# vtpm_create, vtpm_setup, vtpm_start, etc. (see below)
-#This should be indicated by setting VTPM_IMPL_DEFINED.
if [ -r "$dir/vtpm-impl" ]; then
. "$dir/vtpm-impl"
-fi
-
-if [ -z "$VTPM_IMPL_DEFINED" ]; then
+else
function vtpm_create () {
true
}
@@ -245,6 +242,12 @@ function vtpm_create_instance () {
claim_lock vtpmdb
instance=$(vtpmdb_find_instance $domname)
+
+ if [ "$instance" == "0" -a "$reason" != "create" ]; then
+ release_lock vtpmdb
+ return
+ fi
+
if [ "$instance" == "0" ]; then
#Try to give the preferred instance to the domain
instance=$(xenstore_read "$XENBUS_PATH"/pref_instance)
@@ -317,7 +320,7 @@ function vtpm_delete_instance () {
# "-1" : the given machine name is invalid
# "0" : this is not an address of this machine
# "1" : this is an address local to this machine
-function isLocalAddress() {
+function vtpm_isLocalAddress() {
local addr res
addr=$(ping $1 -c 1 | \
gawk '{ print substr($3,2,length($3)-2); exit }')
@@ -347,7 +350,7 @@ function isLocalAddress() {
# 2nd: name of the domain to migrate
# 3rd: the migration step to perform
function vtpm_migration_step() {
- local res=$(isLocalAddress $1)
+ local res=$(vtpm_isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate $1 $2 $3
fi
@@ -361,8 +364,39 @@ function vtpm_migration_step() {
# 3rd: the last successful migration step that was done
function vtpm_recover() {
local res
- res=$(isLocalAddress $1)
+ res=$(vtpm_isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate_recover $1 $2 $3
fi
}
+
+
+#Determine the domain id given a domain's name.
+#1st parameter: name of the domain
+#return value: domain id or -1 if domain id could not be determined
+function vtpm_domid_from_name () {
+ local id name ids
+ ids=$(xenstore-list /local/domain)
+ for id in $ids; do
+ name=$(xenstore-read /local/domain/$id/name)
+ if [ "$name" == "$1" ]; then
+ echo "$id"
+ return
+ fi
+ done
+ echo "-1"
+}
+
+
+#Add a virtual TPM instance number and its associated domain name
+#to the VTPMDB file and activate usage of this virtual TPM instance
+#by writing the instance number into the xenstore
+#1st parm: name of virtual machine
+#2nd parm: instance of assoicate virtual TPM
+function vtpm_add_and_activate() {
+ local domid=$(vtpm_domid_from_name $1)
+ if [ "$domid" != "-1" ]; then
+ vtpmdb_add_instance $1 $2
+ xenstore-write backend/vtpm/$domid/0/instance $2
+ fi
+}
diff -r 2db50529223e -r f7b43e5c42b9 tools/examples/vtpm-impl
--- a/tools/examples/vtpm-impl Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/examples/vtpm-impl Tue Jul 25 12:19:05 2006 -0600
@@ -32,8 +32,6 @@
# OF THE POSSIBILITY OF SUCH DAMAGE.
# ===================================================================
-VTPM_IMPL_DEFINED=1
-
# | SRC | TAG | CMD SIZE | ORD
| type| mode
TPM_CMD_OPEN=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x01
TPM_CMD_RESM=\\x00\\x00\\x00\\x00\\x01\\xc1\\x00\\x00\\x00\\x10\\x01\\x00\\x00\\x01\\x01\\x02
@@ -44,6 +42,8 @@ TPM_SUCCESS=00000000
TX_VTPM_MANAGER=/var/vtpm/fifos/from_console.fifo
RX_VTPM_MANAGER=/var/vtpm/fifos/to_console.fifo
+
+VTPM_MIG=/usr/bin/vtpm_migrator
# -------------------- Helpers for binary streams -----------
@@ -67,11 +67,17 @@ function vtpm_manager_cmd() {
local inst=$2;
local inst_bin=$(hex32_to_bin $inst);
+ claim_lock vtpm_mgr
+
#send cmd to vtpm_manager
printf "$cmd$inst_bin" > $TX_VTPM_MANAGER
#recv response
+ set +e
local resp_hex=`dd skip=10 bs=1 count=4 if=$RX_VTPM_MANAGER 2> /dev/null |
xxd -ps`
+ set -e
+
+ release_lock vtpm_mgr
#return whether the command was successful
if [ $resp_hex != $TPM_SUCCESS ]; then
@@ -126,11 +132,55 @@ function vtpm_delete() {
fi
}
+# Perform a migration step. This function differentiates between migration
+# to the local host or to a remote machine.
+# Parameters:
+# 1st: destination host to migrate to
+# 2nd: name of the domain to migrate
+# 3rd: the migration step to perform
function vtpm_migrate() {
- echo "Error: vTPM migration accross machines not implemented."
+ local instance res
+
+ instance=$(vtpmdb_find_instance $2)
+ if [ "$instance" == "" ]; then
+ log err "VTPM Migratoin failed. Unable to translation of domain name"
+ echo "Error: VTPM Migration failed while looking up instance number"
+ fi
+
+ case "$3" in
+ 0)
+ #Incicate migration supported
+ echo "0"
+ ;;
+
+ 1)
+ # Get Public Key from Destination
+ # Call vtpm_manager's migration part 1
+ claim_lock vtpm_mgr
+ $VTPM_MIG $1 $2 $instance $3
+ release_lock vtpm_mgr
+ ;;
+
+ 2)
+ # Call manager's migration step 2 and send result to destination
+ # If successful remove from db
+ claim_lock vtpm_mgr
+ $VTPM_MIG $1 $2 $instance $3
+ release_lock vtpm_mgr
+ ;;
+
+ 3)
+ if `ps x | grep "$VTPM_MIG $1"`; then
+ log err "VTPM Migration failed to complete."
+ echo "Error: VTPM Migration failed to complete."
+ fi
+ ;;
+ esac
+
}
+
function vtpm_migrate_recover() {
- true
+ echo "Error: Recovery not supported yet"
}
diff -r 2db50529223e -r f7b43e5c42b9 tools/examples/xen-backend.agent
--- a/tools/examples/xen-backend.agent Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/examples/xen-backend.agent Tue Jul 25 12:19:05 2006 -0600
@@ -7,6 +7,9 @@ claim_lock xenbus_hotplug_global
claim_lock xenbus_hotplug_global
case "$XENBUS_TYPE" in
+ tap)
+ /etc/xen/scripts/blktap "$ACTION"
+ ;;
vbd)
/etc/xen/scripts/block "$ACTION"
;;
diff -r 2db50529223e -r f7b43e5c42b9 tools/examples/xen-backend.rules
--- a/tools/examples/xen-backend.rules Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/examples/xen-backend.rules Tue Jul 25 12:19:05 2006 -0600
@@ -1,3 +1,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vbd*"
+SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap
$env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block
$env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm
$env{ACTION}"
SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script}
online"
diff -r 2db50529223e -r f7b43e5c42b9 tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/examples/xmexample.hvm Tue Jul 25 12:19:05 2006 -0600
@@ -54,7 +54,7 @@ name = "ExampleHVMDomain"
# Optionally define mac and/or bridge for the network interfaces.
# Random MACs are assigned if not given.
-#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
# type=ioemu specify the NIC is an ioemu device not netfront
vif = [ 'type=ioemu, bridge=xenbr0' ]
@@ -130,8 +130,13 @@ vnc=1
vnc=1
#----------------------------------------------------------------------------
-# enable spawning vncviewer(only valid when vnc=1), default = 1
-vncviewer=1
+# set VNC display number, default = domid
+#vncdisplay=1
+
+#----------------------------------------------------------------------------
+# enable spawning vncviewer for domain's console
+# (only valid when vnc=1), default = 0
+#vncconsole=0
#----------------------------------------------------------------------------
# no graphics, use serial port
@@ -146,10 +151,6 @@ stdvga=0
# then xm console or minicom can connect
serial='pty'
-#----------------------------------------------------------------------------
-# enable ne2000, default = 0(use pcnet)
-ne2000=0
-
#-----------------------------------------------------------------------------
# enable audio support
diff -r 2db50529223e -r f7b43e5c42b9 tools/firmware/vmxassist/vmxassist.ld
--- a/tools/firmware/vmxassist/vmxassist.ld Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/firmware/vmxassist/vmxassist.ld Tue Jul 25 12:19:05 2006 -0600
@@ -11,8 +11,7 @@ SECTIONS
_btext = .;
*(.text)
*(.rodata)
- *(.rodata.str1.1)
- *(.rodata.str1.4)
+ *(.rodata.*)
_etext = .;
}
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/Changelog
--- a/tools/ioemu/Changelog Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/Changelog Tue Jul 25 12:19:05 2006 -0600
@@ -1,3 +1,84 @@ version 0.6.1:
+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)
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/Makefile
--- a/tools/ioemu/Makefile Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/Makefile Tue Jul 25 12:19:05 2006 -0600
@@ -3,89 +3,112 @@ include $(XEN_ROOT)/tools/Rules.mk
-include config-host.mak
-CFLAGS+=-g -fno-strict-aliasing
+CFLAGS+=-Wall -O2 -g -fno-strict-aliasing -I.
ifdef CONFIG_DARWIN
CFLAGS+= -mdynamic-no-pic
-endif
-ifdef CONFIG_WIN32
-CFLAGS+=-fpack-struct
endif
LDFLAGS=-g
LIBS=
DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-TOOLS=qemu-img
+TOOLS=qemu-img$(EXESUF)
ifdef CONFIG_STATIC
LDFLAGS+=-static
endif
-#DOCS=qemu-doc.html qemu-tech.html qemu.1
+ifdef BUILD_DOCS
+DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1
+else
+DOCS=
+endif
-.PHONY: all
-all: $(DOCS) HEADERS
+all: $(DOCS)
for d in $(TARGET_DIRS); do \
$(MAKE) -C $$d $@ || exit 1 ; \
done
-qemu-img: qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c
block-cloop.c
+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 $@ $^
-.PHONY: clean
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 qemu.pod *~ */*~
- #$(MAKE) -C tests clean
+ rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS *.pod *~ */*~
+ $(MAKE) -C tests clean
for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
+ [ -d $$d ] && $(MAKE) -C $$d $@ || exit 0 ; \
done
- rm -f config-host.mak config-host.h
- rm -f keysym_adapter_sdl.h keysym_adapter_vnc.h
-.PHONY: distclean
distclean: clean
- rm -f config-host.mak config-host.h
- rm -f keysym_adapter_sdl.h keysym_adapter_vnc.h
+ rm -f config-host.mak config-host.h $(DOCS)
for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
+ 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
-.PHONY: install
-install: all
- mkdir -p "$(bindir)"
- mkdir -p "$(DESTDIR)/$(datadir)"
- mkdir -p "$(DESTDIR)/$(datadir)/keymaps"
- install -m 644 $(addprefix keymaps/,$(KEYMAPS))
"$(DESTDIR)/$(datadir)/keymaps"
+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
-.PHONY: test speed test2
test speed test2: all
$(MAKE) -C tests $@
-.PHONY: TAGS
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
- ./texi2pod.pl $< qemu.pod
+ 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)
-.PHONY: tar
tar:
rm -rf /tmp/$(FILE)
cp -r . /tmp/$(FILE)
@@ -93,36 +116,34 @@ tar:
rm -rf /tmp/$(FILE)
# generate a binary distribution
-.PHONY: tarbin
tarbin:
- ( cd $(DESTDIR) ; tar zcvf ~/qemu-$(VERSION)-i386.tar.gz \
- $(DESTDIR)/$(bindir)/qemu $(DESTDIR)/$(bindir)/qemu-fast \
- $(DESTDIR)/$(bindir)/qemu-system-ppc \
- $(DESTDIR)/$(bindir)/qemu-i386 \
- $(DESTDIR)/$(bindir)/qemu-arm \
- $(DESTDIR)/$(bindir)/qemu-sparc \
- $(DESTDIR)/$(bindir)/qemu-ppc \
- $(DESTDIR)/$(mandir)/man1/qemu.1 $(DESTDIR)/$(mandir)/man1/qemu-mkcow.1
)
+ ( 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
-
-.PHONY: HEADERS
-HEADERS:
-
-ifdef CONFIG_SDL
-HEADERS: keysym_adapter_sdl.h
-endif
-
-ifdef CONFIG_VNC
-HEADERS: keysym_adapter_vnc.h
-endif
-
-keysym_adapter_sdl.h: Makefile create_keysym_header.sh
- sh create_keysym_header.sh sdl "$(SDL_CFLAGS)"
-
-keysym_adapter_vnc.h: Makefile create_keysym_header.sh
- sh create_keysym_header.sh vnc "$(VNC_CFLAGS)"
-
-
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/README
--- a/tools/ioemu/README Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/README Tue Jul 25 12:19:05 2006 -0600
@@ -1,61 +1,3 @@ The QEMU x86 emulator
-The QEMU x86 emulator
----------------------
-
-INSTALLATION
-------------
-
-Type
-
- ./configure
- make
-
-to build qemu, qemu-CPU and libqemu.a (CPU is the name of the various
-supported target CPUs).
-
-Type
-
- make install
-
-to install QEMU in /usr/local
-
-Tested tool versions
---------------------
-
-In order to compile QEMU succesfully, it is very important that you
-have the right tools. The most important one is gcc. I cannot guaranty
-that QEMU works if you do not use a tested gcc version. Look at
-'configure' and 'Makefile' if you want to make a different gcc
-version work.
-
-host gcc binutils glibc linux distribution
-----------------------------------------------------------------------
-x86 2.95.2 2.13.2 2.1.3 2.4.18
- 3.2 2.13.2 2.1.3 2.4.18
- 2.96 2.11.93.0.2 2.2.5 2.4.18 Red Hat 7.3
- 3.2.2 2.13.90.0.18 2.3.2 2.4.20 Red Hat 9
-
-PowerPC 3.3 [4] 2.13.90.0.18 2.3.1 2.4.20briq
- 3.2
-
-Alpha 3.3 [1] 2.14.90.0.4 2.2.5 2.2.20 [2] Debian 3.0
-
-Sparc32 2.95.4 2.12.90.0.1 2.2.5 2.4.18 Debian 3.0
-
-ARM 2.95.4 2.12.90.0.1 2.2.5 2.4.9 [3] Debian 3.0
-
-[1] On Alpha, QEMU needs the gcc 'visibility' attribute only available
- for gcc version >= 3.3.
-[2] Linux >= 2.4.20 is necessary for precise exception support
- (untested).
-[3] 2.4.9-ac10-rmk2-np1-cerf2
-
-[4] gcc 2.95.x generates invalid code when using too many register
-variables. You must use gcc 3.x on PowerPC.
-
-Documentation
--------------
-
Read the documentation in qemu-doc.html.
-
Fabrice Bellard.
\ No newline at end of file
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/TODO
--- a/tools/ioemu/TODO Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/TODO Tue Jul 25 12:19:05 2006 -0600
@@ -1,20 +1,19 @@ short term:
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
-- Solaris display error with Cirrus VGA
- (http://lists.gnu.org/archive/html/qemu-devel/2004-10/msg00390.html).
- Precise VGA timings for old games/demos (malc patch)
- merge PIC spurious interrupt patch
-- merge VNC keyboard patch
- merge Solaris patch
-- merge ARM patches + self modifying code patch (Paul Brook)
-- warning for OS/2: must not use 128 MB memory
+- 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
-- test sysenter/sysexit and fxsr for L4 pistachio 686
- 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.
@@ -33,34 +32,30 @@ short term:
- 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)
-- SMP support
ppc specific:
------------
- TLB invalidate not needed if msr_pr changes
-- endianness bugs in do_load_fpscr and do_store_fpscr
- SPR_ENCODE() not useful
- enable shift optimizations ?
-lower priority:
---------------
-- more friendly BIOS (logo)
-- int15 ah=86: use better timing
-- HDD geometry in CMOS (not used except for very old DOS programs)
-- suppress shift_mem ops
-- fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret)
-- sysenter/sysexit emulation
-- optimize FPU operations (evaluate x87 stack pointer statically)
+linux-user specific:
+-------------------
- add IPC syscalls
-- use -msoft-float on ARM
-- use kernel traps for unaligned accesses on ARM ?
- handle rare page fault cases (in particular if page fault in helpers or
in syscall emulation code).
-- fix thread stack freeing (use kernel 2.5.x CLONE_CHILD_CLEARTID)
- 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.
-- use gcc as a backend to generate better code (easy to do by using
- op-i386.c operations as local inline functions).
-- add SSE2/MMX operations
+- 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 2db50529223e -r f7b43e5c42b9 tools/ioemu/VERSION
--- a/tools/ioemu/VERSION Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/VERSION Tue Jul 25 12:19:05 2006 -0600
@@ -1,1 +1,1 @@ 0.6.1
-0.6.1
\ No newline at end of file
+0.8.1
\ No newline at end of file
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/audio.c
--- a/tools/ioemu/audio/audio.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/audio.c Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
* QEMU Audio subsystem
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
+ *
+ * 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
@@ -21,34 +21,95 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include <assert.h>
#include "vl.h"
-#define USE_WAV_AUDIO
-
-#include "audio/audio_int.h"
-
-#define dolog(...) AUD_log ("audio", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
+#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
-#define ldebug(...)
-#endif
-
-#define QC_AUDIO_DRV "QEMU_AUDIO_DRV"
-#define QC_VOICES "QEMU_VOICES"
-#define QC_FIXED_FORMAT "QEMU_FIXED_FORMAT"
-#define QC_FIXED_FREQ "QEMU_FIXED_FREQ"
-
-static HWVoice *hw_voices;
-
-AudioState audio_state = {
- 1, /* use fixed settings */
- 44100, /* fixed frequency */
- 2, /* fixed channels */
- AUD_FMT_S16, /* fixed format */
- 1, /* number of hw voices */
- -1 /* voice size */
+ UINT_MAX,
+ UINT_MAX
+#endif
};
/* http://www.df.lth.se/~john_e/gems/gem002d.html */
@@ -68,74 +129,419 @@ inline uint32_t lsbindex (uint32_t u)
return popcount ((u&-u)-1);
}
-int audio_get_conf_int (const char *key, int defval)
-{
- int val = defval;
+#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;
-}
-
-const char *audio_get_conf_str (const char *key, const char *defval)
+ 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)
+ if (!val) {
+ *defaultp = 1;
return defval;
- else
+ }
+ 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;
- fprintf (stderr, "%s: ", cap);
+
va_start (ap, fmt);
- vfprintf (stderr, fmt, ap);
+ AUD_vlog (cap, fmt, ap);
va_end (ap);
}
-/*
- * Soft Voice
- */
-void pcm_sw_free_resources (SWVoice *sw)
-{
- if (sw->buf) qemu_free (sw->buf);
- if (sw->rate) st_rate_stop (sw->rate);
- sw->buf = NULL;
- sw->rate = NULL;
-}
-
-int pcm_sw_alloc_resources (SWVoice *sw)
-{
- sw->buf = qemu_mallocz (sw->hw->samples * sizeof (st_sample_t));
- if (!sw->buf)
+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;
-
- sw->rate = st_rate_start (sw->freq, sw->hw->freq);
- if (!sw->rate) {
- qemu_free (sw->buf);
- sw->buf = NULL;
- return -1;
}
return 0;
}
-void pcm_sw_fini (SWVoice *sw)
-{
- pcm_sw_free_resources (sw);
-}
-
-int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt)
+static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as)
{
int bits = 8, sign = 0;
- switch (fmt) {
+ switch (as->fmt) {
case AUD_FMT_S8:
sign = 1;
case AUD_FMT_U8:
@@ -147,626 +553,428 @@ int pcm_sw_init (SWVoice *sw, HWVoice *h
bits = 16;
break;
}
-
- sw->hw = hw;
- sw->freq = freq;
- sw->fmt = fmt;
- sw->nchannels = nchannels;
- sw->shift = (nchannels == 2) + (bits == 16);
- sw->align = (1 << sw->shift) - 1;
- sw->left = 0;
- sw->pos = 0;
- sw->wpos = 0;
- sw->live = 0;
- sw->ratio = (sw->hw->freq * ((int64_t) INT_MAX)) / sw->freq;
- sw->bytes_per_second = sw->freq << sw->shift;
- sw->conv = mixeng_conv[nchannels == 2][sign][bits == 16];
-
- pcm_sw_free_resources (sw);
- return pcm_sw_alloc_resources (sw);
-}
-
-/* Hard voice */
-void pcm_hw_free_resources (HWVoice *hw)
-{
- if (hw->mix_buf)
- qemu_free (hw->mix_buf);
- hw->mix_buf = NULL;
-}
-
-int pcm_hw_alloc_resources (HWVoice *hw)
-{
- hw->mix_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
- if (!hw->mix_buf)
- return -1;
- return 0;
-}
-
-void pcm_hw_fini (HWVoice *hw)
-{
- if (hw->active) {
- ldebug ("pcm_hw_fini: %d %d %d\n", hw->freq, hw->nchannels, hw->fmt);
- pcm_hw_free_resources (hw);
- hw->pcm_ops->fini (hw);
- memset (hw, 0, audio_state.drv->voice_size);
- }
-}
-
-void pcm_hw_gc (HWVoice *hw)
-{
- if (hw->nb_voices)
+ 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;
-
- pcm_hw_fini (hw);
-}
-
-int pcm_hw_get_live (HWVoice *hw)
-{
- int i, alive = 0, live = hw->samples;
-
- for (i = 0; i < hw->nb_voices; i++) {
- if (hw->pvoice[i]->live) {
- live = audio_MIN (hw->pvoice[i]->live, live);
- alive += 1;
- }
- }
-
- if (alive)
+ }
+
+ 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;
- else
- return -1;
-}
-
-int pcm_hw_get_live2 (HWVoice *hw, int *nb_active)
-{
- int i, alive = 0, live = hw->samples;
-
- *nb_active = 0;
- for (i = 0; i < hw->nb_voices; i++) {
- if (hw->pvoice[i]->live) {
- if (hw->pvoice[i]->live < live) {
- *nb_active = hw->pvoice[i]->active != 0;
- live = hw->pvoice[i]->live;
- }
- alive += 1;
- }
- }
-
- if (alive)
- return live;
- else
- return -1;
-}
-
-void pcm_hw_dec_live (HWVoice *hw, int decr)
-{
- int i;
-
- for (i = 0; i < hw->nb_voices; i++) {
- if (hw->pvoice[i]->live) {
- hw->pvoice[i]->live -= decr;
- }
- }
-}
-
-void pcm_hw_clear (HWVoice *hw, void *buf, int len)
-{
- if (!len)
- return;
-
- switch (hw->fmt) {
- case AUD_FMT_S16:
- case AUD_FMT_S8:
- memset (buf, 0x00, len << hw->shift);
- break;
-
- case AUD_FMT_U8:
- memset (buf, 0x80, len << hw->shift);
- break;
-
- case AUD_FMT_U16:
- {
- unsigned int i;
- uint16_t *p = buf;
- int shift = hw->nchannels - 1;
-
- for (i = 0; i < len << shift; i++) {
- p[i] = INT16_MAX;
- }
- }
- break;
- }
-}
-
-int pcm_hw_write (SWVoice *sw, void *buf, int size)
+ }
+}
+
+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;
- if (!sw)
+ int ret = 0, pos = 0, total = 0;
+
+ if (!sw) {
return size;
+ }
hwsamples = sw->hw->samples;
- samples = size >> sw->shift;
-
- if (!sw->live) {
- sw->wpos = sw->hw->rpos;
- }
- wpos = sw->wpos;
- live = sw->live;
+
+ 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 = (dead * ((int64_t) INT_MAX)) / sw->ratio;
+ swlim = ((int64_t) dead << 32) / sw->ratio;
swlim = audio_MIN (swlim, samples);
-
- ldebug ("size=%d live=%d dead=%d swlim=%d wpos=%d\n",
- size, live, dead, swlim, wpos);
- if (swlim)
- sw->conv (sw->buf, buf, swlim);
+ 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) {
- /* dolog ("swlim=%d\n", swlim); */
break;
}
isamp = swlim;
osamp = blck;
- st_rate_flow (sw->rate, sw->buf + pos, sw->hw->mix_buf + wpos, &isamp,
&osamp);
+ 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;
- }
-
- sw->wpos = wpos;
- sw->live = live;
- return ret << sw->shift;
-}
-
-int pcm_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- int sign = 0, bits = 8;
-
- pcm_hw_fini (hw);
- ldebug ("pcm_hw_init: %d %d %d\n", freq, nchannels, fmt);
- if (hw->pcm_ops->init (hw, freq, nchannels, fmt)) {
- memset (hw, 0, audio_state.drv->voice_size);
- return -1;
- }
-
- switch (hw->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;
- }
-
- hw->nb_voices = 0;
- hw->active = 1;
- hw->shift = (hw->nchannels == 2) + (bits == 16);
- hw->bytes_per_second = hw->freq << hw->shift;
- hw->align = (1 << hw->shift) - 1;
- hw->samples = hw->bufsize >> hw->shift;
- hw->clip = mixeng_clip[hw->nchannels == 2][sign][bits == 16];
- if (pcm_hw_alloc_resources (hw)) {
- pcm_hw_fini (hw);
- return -1;
- }
- return 0;
-}
-
-static int dist (void *hw)
-{
- if (hw) {
- return (((uint8_t *) hw - (uint8_t *) hw_voices)
- / audio_state.voice_size) + 1;
- }
- else {
- return 0;
- }
-}
-
-#define ADVANCE(hw) hw ? advance (hw, audio_state.voice_size) : hw_voices
-
-HWVoice *pcm_hw_find_any (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_any_active (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- if (hw->active)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_any_active_enabled (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- if (hw->active && hw->enabled)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_any_passive (HWVoice *hw)
-{
- int i = dist (hw);
- for (; i < audio_state.nb_hw_voices; i++) {
- hw = ADVANCE (hw);
- if (!hw->active)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_find_specific (HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt)
-{
- while ((hw = pcm_hw_find_any_active (hw))) {
- if (hw->freq == freq &&
- hw->nchannels == nchannels &&
- hw->fmt == fmt)
- return hw;
- }
- return NULL;
-}
-
-HWVoice *pcm_hw_add (int freq, int nchannels, audfmt_e fmt)
-{
- HWVoice *hw;
-
- if (audio_state.fixed_format) {
- freq = audio_state.fixed_freq;
- nchannels = audio_state.fixed_channels;
- fmt = audio_state.fixed_fmt;
- }
-
- hw = pcm_hw_find_specific (NULL, freq, nchannels, fmt);
-
- if (hw)
- return hw;
-
- hw = pcm_hw_find_any_passive (NULL);
- if (hw) {
- hw->pcm_ops = audio_state.drv->pcm_ops;
- if (!hw->pcm_ops)
- return NULL;
-
- if (pcm_hw_init (hw, freq, nchannels, fmt)) {
- pcm_hw_gc (hw);
- return NULL;
- }
- else
- return hw;
- }
-
- return pcm_hw_find_any (NULL);
-}
-
-int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw)
-{
- SWVoice **pvoice = qemu_mallocz ((hw->nb_voices + 1) * sizeof (sw));
- if (!pvoice)
- return -1;
-
- memcpy (pvoice, hw->pvoice, hw->nb_voices * sizeof (sw));
- qemu_free (hw->pvoice);
- hw->pvoice = pvoice;
- hw->pvoice[hw->nb_voices++] = sw;
- return 0;
-}
-
-int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw)
-{
- int i, j;
- if (hw->nb_voices > 1) {
- SWVoice **pvoice = qemu_mallocz ((hw->nb_voices - 1) * sizeof (sw));
-
- if (!pvoice) {
- dolog ("Can not maintain consistent state (not enough memory)\n");
- return -1;
- }
-
- for (i = 0, j = 0; i < hw->nb_voices; i++) {
- if (j >= hw->nb_voices - 1) {
- dolog ("Can not maintain consistent state "
- "(invariant violated)\n");
- return -1;
- }
- if (hw->pvoice[i] != sw)
- pvoice[j++] = hw->pvoice[i];
- }
- qemu_free (hw->pvoice);
- hw->pvoice = pvoice;
- hw->nb_voices -= 1;
- }
- else {
- qemu_free (hw->pvoice);
- hw->pvoice = NULL;
- hw->nb_voices = 0;
- }
- return 0;
-}
-
-SWVoice *pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt)
-{
- SWVoice *sw;
- HWVoice *hw;
-
- sw = qemu_mallocz (sizeof (*sw));
- if (!sw)
- goto err1;
-
- hw = pcm_hw_add (freq, nchannels, fmt);
- if (!hw)
- goto err2;
-
- if (pcm_hw_add_sw (hw, sw))
- goto err3;
-
- if (pcm_sw_init (sw, hw, freq, nchannels, fmt))
- goto err4;
-
- return sw;
-
-err4:
- pcm_hw_del_sw (hw, sw);
-err3:
- pcm_hw_gc (hw);
-err2:
- qemu_free (sw);
-err1:
- return NULL;
-}
-
-SWVoice *AUD_open (SWVoice *sw, const char *name,
- int freq, int nchannels, audfmt_e fmt)
-{
- if (!audio_state.drv) {
- return NULL;
- }
-
- if (sw && freq == sw->freq && sw->nchannels == nchannels && sw->fmt ==
fmt) {
- return sw;
- }
-
- if (sw) {
- ldebug ("Different format %s %d %d %d\n",
- name,
- sw->freq == freq,
- sw->nchannels == nchannels,
- sw->fmt == fmt);
- }
-
- if (nchannels != 1 && nchannels != 2) {
- dolog ("Bogus channel count %d for voice %s\n", nchannels, name);
- return NULL;
- }
-
- if (!audio_state.fixed_format && sw) {
- pcm_sw_fini (sw);
- pcm_hw_del_sw (sw->hw, sw);
- pcm_hw_gc (sw->hw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- qemu_free (sw);
- sw = NULL;
- }
-
- if (sw) {
- HWVoice *hw = sw->hw;
- if (!hw) {
- dolog ("Internal logic error voice %s has no hardware store\n",
- name);
- return sw;
- }
-
- if (pcm_sw_init (sw, hw, freq, nchannels, fmt)) {
- pcm_sw_fini (sw);
- pcm_hw_del_sw (hw, sw);
- pcm_hw_gc (hw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- qemu_free (sw);
- return NULL;
- }
- }
- else {
- sw = pcm_create_voice_pair (freq, nchannels, fmt);
- if (!sw) {
- dolog ("Failed to create voice %s\n", name);
- return NULL;
- }
- }
-
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- sw->name = qemu_strdup (name);
- return sw;
-}
-
-void AUD_close (SWVoice *sw)
-{
- if (!sw)
- return;
-
- pcm_sw_fini (sw);
- pcm_hw_del_sw (sw->hw, sw);
- pcm_hw_gc (sw->hw);
- if (sw->name) {
- qemu_free (sw->name);
- sw->name = NULL;
- }
- qemu_free (sw);
-}
-
-int AUD_write (SWVoice *sw, void *buf, int size)
+ 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->hw->enabled)
- dolog ("Writing to disabled voice %s\n", sw->name);
+ 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;
}
-void AUD_run (void)
-{
- HWVoice *hw = NULL;
-
- while ((hw = pcm_hw_find_any_active_enabled (hw))) {
- int i;
- if (hw->pending_disable && pcm_hw_get_live (hw) <= 0) {
- hw->enabled = 0;
- hw->pcm_ops->ctl (hw, VOICE_DISABLE);
- for (i = 0; i < hw->nb_voices; i++) {
- hw->pvoice[i]->live = 0;
- /* hw->pvoice[i]->old_ticks = 0; */
- }
- continue;
- }
-
- hw->pcm_ops->run (hw);
- assert (hw->rpos < hw->samples);
- for (i = 0; i < hw->nb_voices; i++) {
- SWVoice *sw = hw->pvoice[i];
- if (!sw->active && !sw->live && sw->old_ticks) {
- int64_t delta = qemu_get_clock (vm_clock) - sw->old_ticks;
- if (delta > audio_state.ticks_threshold) {
- ldebug ("resetting old_ticks for %s\n", sw->name);
- sw->old_ticks = 0;
- }
- }
- }
- }
-}
-
-int AUD_get_free (SWVoice *sw)
-{
- int free;
-
- if (!sw)
- return 4096;
-
- free = ((sw->hw->samples - sw->live) << sw->hw->shift) * sw->ratio
- / INT_MAX;
-
- free &= ~sw->hw->align;
- if (!free) return 0;
-
- return free;
-}
-
-int AUD_get_buffer_size (SWVoice *sw)
-{
- return sw->hw->bufsize;
-}
-
-void AUD_adjust (SWVoice *sw, int bytes)
-{
- if (!sw)
+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;
- sw->old_ticks += (ticks_per_sec * (int64_t) bytes) / sw->bytes_per_second;
-}
-
-void AUD_reset (SWVoice *sw)
-{
- sw->active = 0;
- sw->old_ticks = 0;
-}
-
-int AUD_calc_elapsed (SWVoice *sw)
-{
- int64_t now, delta, bytes;
- int dead, swlim;
-
- if (!sw)
- return 0;
-
- now = qemu_get_clock (vm_clock);
- delta = now - sw->old_ticks;
- bytes = (delta * sw->bytes_per_second) / ticks_per_sec;
- if (delta < 0) {
- dolog ("whoops delta(<0)=%"PRId64"\n", delta);
- return 0;
- }
-
- dead = sw->hw->samples - sw->live;
- swlim = ((dead * (int64_t) INT_MAX) / sw->ratio);
-
- if (bytes > swlim) {
- return swlim;
- }
- else {
- return bytes;
- }
-}
-
-void AUD_enable (SWVoice *sw, int on)
-{
- int i;
- HWVoice *hw;
-
- if (!sw)
- return;
+ }
hw = sw->hw;
- if (on) {
- if (!sw->live)
- sw->wpos = sw->hw->rpos;
- if (!sw->old_ticks) {
- sw->old_ticks = qemu_get_clock (vm_clock);
- }
- }
-
if (sw->active != on) {
+ SWVoiceOut *temp_sw;
+
if (on) {
+ int total;
+
hw->pending_disable = 0;
if (!hw->enabled) {
hw->enabled = 1;
- for (i = 0; i < hw->nb_voices; i++) {
- ldebug ("resetting voice\n");
- sw = hw->pvoice[i];
- sw->old_ticks = qemu_get_clock (vm_clock);
+ 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->pcm_ops->ctl (hw, VOICE_ENABLE);
- }
+
+ 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 && !hw->pending_disable) {
+ if (hw->enabled) {
int nb_active = 0;
- for (i = 0; i < hw->nb_voices; i++) {
- nb_active += hw->pvoice[i]->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->pending_disable = 1;
+ hw->enabled = 0;
+ hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);
}
}
}
@@ -774,137 +982,500 @@ void AUD_enable (SWVoice *sw, int on)
}
}
-static struct audio_output_driver *drvtab[] = {
-#ifdef CONFIG_OSS
- &oss_output_driver,
-#endif
-#ifdef CONFIG_FMOD
- &fmod_output_driver,
-#endif
-#ifdef CONFIG_SDL
- &sdl_output_driver,
-#endif
- &no_output_driver,
-#ifdef USE_WAV_AUDIO
- &wav_output_driver,
-#endif
+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 int voice_init (struct audio_output_driver *drv)
-{
- audio_state.opaque = drv->init ();
- if (audio_state.opaque) {
- if (audio_state.nb_hw_voices > drv->max_voices) {
- dolog ("`%s' does not support %d multiple hardware channels\n"
- "Resetting to %d\n",
- drv->name, audio_state.nb_hw_voices, drv->max_voices);
- audio_state.nb_hw_voices = drv->max_voices;
- }
- hw_voices = qemu_mallocz (audio_state.nb_hw_voices * drv->voice_size);
- if (hw_voices) {
- audio_state.drv = drv;
- return 1;
+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 {
- dolog ("Not enough memory for %d `%s' voices (each %d bytes)\n",
- audio_state.nb_hw_voices, drv->name, drv->voice_size);
- drv->fini (audio_state.opaque);
- return 0;
- }
+ 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\n", drv->name);
- return 0;
- }
-}
-
-static void audio_vm_stop_handler (void *opaque, int reason)
-{
- HWVoice *hw = NULL;
-
- while ((hw = pcm_hw_find_any (hw))) {
- if (!hw->pcm_ops)
- continue;
-
- hw->pcm_ops->ctl (hw, reason ? VOICE_ENABLE : VOICE_DISABLE);
+ 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)
{
- HWVoice *hw = NULL;
-
- while ((hw = pcm_hw_find_any (hw))) {
- if (!hw->pcm_ops)
- continue;
-
- hw->pcm_ops->ctl (hw, VOICE_DISABLE);
- hw->pcm_ops->fini (hw);
- }
- audio_state.drv->fini (audio_state.opaque);
+ 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)
{
- if (version_id != 1)
+ (void) f;
+ (void) opaque;
+
+ if (version_id != 1) {
return -EINVAL;
+ }
return 0;
}
-void AUD_init (void)
-{
- int i;
+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;
-
- audio_state.fixed_format =
- !!audio_get_conf_int (QC_FIXED_FORMAT, audio_state.fixed_format);
- audio_state.fixed_freq =
- audio_get_conf_int (QC_FIXED_FREQ, audio_state.fixed_freq);
- audio_state.nb_hw_voices =
- audio_get_conf_int (QC_VOICES, audio_state.nb_hw_voices);
-
- if (audio_state.nb_hw_voices <= 0) {
- dolog ("Bogus number of voices %d, resetting to 1\n",
- audio_state.nb_hw_voices);
- }
-
- drvname = audio_get_conf_str (QC_AUDIO_DRV, NULL);
+ 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 = voice_init (drvtab[i]);
+ done = !audio_driver_init (s, drvtab[i]);
found = 1;
break;
}
}
+
if (!found) {
dolog ("Unknown audio driver `%s'\n", drvname);
- }
- }
-
- qemu_add_vm_stop_handler (audio_vm_stop_handler, NULL);
- atexit (audio_atexit);
+ 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 = voice_init (drvtab[i]);
- }
- }
-
- audio_state.ticks_threshold = ticks_per_sec / 50;
- audio_state.freq_threshold = 100;
-
- register_savevm ("audio", 0, 1, audio_save, audio_load, NULL);
+ if (drvtab[i]->can_be_default) {
+ done = !audio_driver_init (s, drvtab[i]);
+ }
+ }
+ }
+
if (!done) {
- dolog ("Can not initialize audio subsystem\n");
- voice_init (&no_output_driver);
- }
-}
+ 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 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/audio.h
--- a/tools/ioemu/audio/audio.h Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/audio.h Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
* QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
+ *
+ * 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
@@ -24,31 +24,85 @@
#ifndef QEMU_AUDIO_H
#define QEMU_AUDIO_H
-#include "mixeng.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
+ AUD_FMT_U8,
+ AUD_FMT_S8,
+ AUD_FMT_U16,
+ AUD_FMT_S16
} audfmt_e;
-typedef struct SWVoice SWVoice;
+typedef struct {
+ int freq;
+ int nchannels;
+ audfmt_e fmt;
+} audsettings_t;
-SWVoice * AUD_open (SWVoice *sw, const char *name, int freq,
- int nchannels, audfmt_e fmt);
-void AUD_init (void);
-void AUD_log (const char *cap, const char *fmt, ...)
- __attribute__ ((__format__ (__printf__, 2, 3)));;
-void AUD_close (SWVoice *sw);
-int AUD_write (SWVoice *sw, void *pcm_buf, int size);
-void AUD_adjust (SWVoice *sw, int leftover);
-void AUD_reset (SWVoice *sw);
-int AUD_get_free (SWVoice *sw);
-int AUD_get_buffer_size (SWVoice *sw);
-void AUD_run (void);
-void AUD_enable (SWVoice *sw, int on);
-int AUD_calc_elapsed (SWVoice *sw);
+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)
{
@@ -59,7 +113,21 @@ uint32_t popcount (uint32_t u);
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 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/audio_int.h
--- a/tools/ioemu/audio/audio_int.h Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/audio_int.h Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
* QEMU Audio subsystem header
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
+ *
+ * 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
@@ -24,141 +24,245 @@
#ifndef QEMU_AUDIO_INT_H
#define QEMU_AUDIO_INT_H
-#include "vl.h"
-
-struct pcm_ops;
-
-typedef struct HWVoice {
- int active;
+#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;
- int freq;
+ struct audio_pcm_info info;
f_sample *clip;
- audfmt_e fmt;
- int nchannels;
-
- int align;
- int shift;
int rpos;
- int bufsize;
-
- int bytes_per_second;
+ uint64_t ts_helper;
+
st_sample_t *mix_buf;
int samples;
- int64_t old_ticks;
- int nb_voices;
- struct SWVoice **pvoice;
- struct pcm_ops *pcm_ops;
-} HWVoice;
-
-extern struct pcm_ops no_pcm_ops;
-extern struct audio_output_driver no_output_driver;
-
-extern struct pcm_ops oss_pcm_ops;
-extern struct audio_output_driver oss_output_driver;
-
-extern struct pcm_ops sdl_pcm_ops;
-extern struct audio_output_driver sdl_output_driver;
-
-extern struct pcm_ops wav_pcm_ops;
-extern struct audio_output_driver wav_output_driver;
-
-extern struct pcm_ops fmod_pcm_ops;
-extern struct audio_output_driver fmod_output_driver;
-
-struct audio_output_driver {
- const char *name;
- void *(*init) (void);
- void (*fini) (void *);
- struct pcm_ops *pcm_ops;
- int can_be_default;
- int max_voices;
- int voice_size;
-};
-
-typedef struct AudioState {
- int fixed_format;
- int fixed_freq;
- int fixed_channels;
- int fixed_fmt;
- int nb_hw_voices;
- int voice_size;
- int64_t ticks_threshold;
- int freq_threshold;
- void *opaque;
- struct audio_output_driver *drv;
-} AudioState;
-extern AudioState audio_state;
-
-struct SWVoice {
- int freq;
- audfmt_e fmt;
- int nchannels;
-
- int shift;
- int align;
+ 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 left;
- int pos;
- int bytes_per_second;
+ 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 wpos;
- int live;
+ int total_hw_samples_mixed;
int active;
- int64_t old_ticks;
- HWVoice *hw;
+ int empty;
+ HWVoiceOut *hw;
char *name;
-};
-
-struct pcm_ops {
- int (*init) (HWVoice *hw, int freq, int nchannels, audfmt_e fmt);
- void (*fini) (HWVoice *hw);
- void (*run) (HWVoice *hw);
- int (*write) (SWVoice *sw, void *buf, int size);
- int (*ctl) (HWVoice *hw, int cmd, ...);
-};
-
-void pcm_sw_free_resources (SWVoice *sw);
-int pcm_sw_alloc_resources (SWVoice *sw);
-void pcm_sw_fini (SWVoice *sw);
-int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt);
-
-void pcm_hw_clear (HWVoice *hw, void *buf, int len);
-HWVoice * pcm_hw_find_any (HWVoice *hw);
-HWVoice * pcm_hw_find_any_active (HWVoice *hw);
-HWVoice * pcm_hw_find_any_passive (HWVoice *hw);
-HWVoice * pcm_hw_find_specific (HWVoice *hw, int freq,
- int nchannels, audfmt_e fmt);
-HWVoice * pcm_hw_add (int freq, int nchannels, audfmt_e fmt);
-int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw);
-int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw);
-SWVoice * pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt);
-
-void pcm_hw_free_resources (HWVoice *hw);
-int pcm_hw_alloc_resources (HWVoice *hw);
-void pcm_hw_fini (HWVoice *hw);
-void pcm_hw_gc (HWVoice *hw);
-int pcm_hw_get_live (HWVoice *hw);
-int pcm_hw_get_live2 (HWVoice *hw, int *nb_active);
-void pcm_hw_dec_live (HWVoice *hw, int decr);
-int pcm_hw_write (SWVoice *sw, void *buf, int len);
-
-int audio_get_conf_int (const char *key, int defval);
-const char *audio_get_conf_str (const char *key, const char *defval);
-
-struct audio_output_driver;
+ 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 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/mixeng.c
--- a/tools/ioemu/audio/mixeng.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/mixeng.c Tue Jul 25 12:19:05 2006 -0600
@@ -1,7 +1,7 @@
/*
* QEMU Mixing engine
*
- * Copyright (c) 2004 Vassili Karpov (malc)
+ * Copyright (c) 2004-2005 Vassili Karpov (malc)
* Copyright (c) 1998 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -23,87 +23,174 @@
* THE SOFTWARE.
*/
#include "vl.h"
-//#define DEBUG_FP
-#include "audio/mixeng.h"
-
+
+#define AUDIO_CAP "mixeng"
+#include "audio_int.h"
+
+#define NOVOL
+
+/* 8 bit */
+#define ENDIAN_CONVERSION natural
+#define ENDIAN_CONVERT(v) (v)
+
+/* Signed 8 bit */
#define IN_T int8_t
-#define IN_MIN CHAR_MIN
-#define IN_MAX CHAR_MAX
+#define IN_MIN SCHAR_MIN
+#define IN_MAX SCHAR_MAX
#define SIGNED
+#define SHIFT 8
#include "mixeng_template.h"
#undef SIGNED
#undef IN_MAX
#undef IN_MIN
#undef IN_T
-
+#undef SHIFT
+
+/* Unsigned 8 bit */
#define IN_T uint8_t
#define IN_MIN 0
#define IN_MAX UCHAR_MAX
-#include "mixeng_template.h"
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-
+#define SHIFT 8
+#include "mixeng_template.h"
+#undef IN_MAX
+#undef IN_MIN
+#undef IN_T
+#undef SHIFT
+
+#undef ENDIAN_CONVERT
+#undef ENDIAN_CONVERSION
+
+/* Signed 16 bit */
#define IN_T int16_t
#define IN_MIN SHRT_MIN
#define IN_MAX SHRT_MAX
#define SIGNED
-#include "mixeng_template.h"
+#define SHIFT 16
+#define ENDIAN_CONVERSION natural
+#define ENDIAN_CONVERT(v) (v)
+#include "mixeng_template.h"
+#undef ENDIAN_CONVERT
+#undef ENDIAN_CONVERSION
+#define ENDIAN_CONVERSION swap
+#define ENDIAN_CONVERT(v) bswap16 (v)
+#include "mixeng_template.h"
+#undef ENDIAN_CONVERT
+#undef ENDIAN_CONVERSION
#undef SIGNED
#undef IN_MAX
#undef IN_MIN
#undef IN_T
+#undef SHIFT
#define IN_T uint16_t
#define IN_MIN 0
#define IN_MAX USHRT_MAX
-#include "mixeng_template.h"
-#undef IN_MAX
-#undef IN_MIN
-#undef IN_T
-
-t_sample *mixeng_conv[2][2][2] = {
- {
- {
- conv_uint8_t_to_mono,
- conv_uint16_t_to_mono
- },
- {
- conv_int8_t_to_mono,
- conv_int16_t_to_mono
+#define SHIFT 16
+#define ENDIAN_CONVERSION natural
+#define ENDIAN_CONVERT(v) (v)
+#include "mixeng_template.h"
+#undef ENDIAN_CONVERT
+#undef ENDIAN_CONVERSION
+#define ENDIAN_CONVERSION swap
+#define ENDIAN_CONVERT(v) bswap16 (v)
+#include "mixeng_template.h"
+#undef ENDIAN_CONVERT
+#undef ENDIAN_CONVERSION
+#undef IN_MAX
+#undef IN_MIN
+#undef IN_T
+#undef SHIFT
+
+t_sample *mixeng_conv[2][2][2][2] = {
+ {
+ {
+ {
+ conv_natural_uint8_t_to_mono,
+ conv_natural_uint16_t_to_mono
+ },
+ {
+ conv_natural_uint8_t_to_mono,
+ conv_swap_uint16_t_to_mono
+ }
+ },
+ {
+ {
+ conv_natural_int8_t_to_mono,
+ conv_natural_int16_t_to_mono
+ },
+ {
+ conv_natural_int8_t_to_mono,
+ conv_swap_int16_t_to_mono
+ }
}
},
{
{
- conv_uint8_t_to_stereo,
- conv_uint16_t_to_stereo
- },
- {
- conv_int8_t_to_stereo,
- conv_int16_t_to_stereo
- }
- }
-};
-
-f_sample *mixeng_clip[2][2][2] = {
- {
- {
- clip_uint8_t_from_mono,
- clip_uint16_t_from_mono
- },
- {
- clip_int8_t_from_mono,
- clip_int16_t_from_mono
+ {
+ conv_natural_uint8_t_to_stereo,
+ conv_natural_uint16_t_to_stereo
+ },
+ {
+ conv_natural_uint8_t_to_stereo,
+ conv_swap_uint16_t_to_stereo
+ }
+ },
+ {
+ {
+ conv_natural_int8_t_to_stereo,
+ conv_natural_int16_t_to_stereo
+ },
+ {
+ conv_natural_int8_t_to_stereo,
+ conv_swap_int16_t_to_stereo
+ }
+ }
+ }
+};
+
+f_sample *mixeng_clip[2][2][2][2] = {
+ {
+ {
+ {
+ clip_natural_uint8_t_from_mono,
+ clip_natural_uint16_t_from_mono
+ },
+ {
+ clip_natural_uint8_t_from_mono,
+ clip_swap_uint16_t_from_mono
+ }
+ },
+ {
+ {
+ clip_natural_int8_t_from_mono,
+ clip_natural_int16_t_from_mono
+ },
+ {
+ clip_natural_int8_t_from_mono,
+ clip_swap_int16_t_from_mono
+ }
}
},
{
{
- clip_uint8_t_from_stereo,
- clip_uint16_t_from_stereo
- },
- {
- clip_int8_t_from_stereo,
- clip_int16_t_from_stereo
+ {
+ clip_natural_uint8_t_from_stereo,
+ clip_natural_uint16_t_from_stereo
+ },
+ {
+ clip_natural_uint8_t_from_stereo,
+ clip_swap_uint16_t_from_stereo
+ }
+ },
+ {
+ {
+ clip_natural_int8_t_from_stereo,
+ clip_natural_int16_t_from_stereo
+ },
+ {
+ clip_natural_int8_t_from_stereo,
+ clip_swap_int16_t_from_stereo
+ }
}
}
};
@@ -116,9 +203,9 @@ f_sample *mixeng_clip[2][2][2] = {
* Contributors with a more efficient algorithm.]
*
* This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
+ * any purpose. This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
*/
/*
@@ -141,36 +228,29 @@ f_sample *mixeng_clip[2][2][2] = {
*/
/* Private data */
-typedef struct ratestuff {
+struct rate {
uint64_t opos;
uint64_t opos_inc;
uint32_t ipos; /* position in the input stream (integer) */
st_sample_t ilast; /* last sample in the input stream */
-} *rate_t;
+};
/*
* Prepare processing.
*/
void *st_rate_start (int inrate, int outrate)
{
- rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff));
+ struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
if (!rate) {
- exit (EXIT_FAILURE);
- }
-
- if (inrate == outrate) {
- // exit (EXIT_FAILURE);
- }
-
- if (inrate >= 65535 || outrate >= 65535) {
- // exit (EXIT_FAILURE);
+ dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
+ return NULL;
}
rate->opos = 0;
/* increment */
- rate->opos_inc = (inrate * ((int64_t) UINT_MAX)) / outrate;
+ rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
rate->ipos = 0;
rate->ilast.l = 0;
@@ -178,78 +258,20 @@ void *st_rate_start (int inrate, int out
return rate;
}
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
- int *isamp, int *osamp)
-{
- rate_t rate = (rate_t) opaque;
- st_sample_t *istart, *iend;
- st_sample_t *ostart, *oend;
- st_sample_t ilast, icur, out;
- int64_t t;
-
- ilast = rate->ilast;
-
- istart = ibuf;
- iend = ibuf + *isamp;
-
- ostart = obuf;
- oend = obuf + *osamp;
-
- if (rate->opos_inc == 1ULL << 32) {
- int i, n = *isamp > *osamp ? *osamp : *isamp;
- for (i = 0; i < n; i++) {
- obuf[i].l += ibuf[i].r;
- obuf[i].r += ibuf[i].r;
- }
- *isamp = n;
- *osamp = n;
- return;
- }
-
- while (obuf < oend) {
-
- /* Safety catch to make sure we have input samples. */
- if (ibuf >= iend)
- break;
-
- /* read as many input samples so that ipos > opos */
-
- while (rate->ipos <= (rate->opos >> 32)) {
- ilast = *ibuf++;
- rate->ipos++;
- /* See if we finished the input buffer yet */
- if (ibuf >= iend) goto the_end;
- }
-
- icur = *ibuf;
-
- /* interpolate */
- t = rate->opos & 0xffffffff;
- out.l = (ilast.l * (INT_MAX - t) + icur.l * t) / INT_MAX;
- out.r = (ilast.r * (INT_MAX - t) + icur.r * t) / INT_MAX;
-
- /* output sample & increment position */
-#if 0
- *obuf++ = out;
-#else
- obuf->l += out.l;
- obuf->r += out.r;
- obuf += 1;
-#endif
- rate->opos += rate->opos_inc;
- }
-
-the_end:
- *isamp = ibuf - istart;
- *osamp = obuf - ostart;
- rate->ilast = ilast;
-}
+#define NAME st_rate_flow_mix
+#define OP(a, b) a += b
+#include "rate_template.h"
+
+#define NAME st_rate_flow
+#define OP(a, b) a = b
+#include "rate_template.h"
void st_rate_stop (void *opaque)
{
qemu_free (opaque);
}
+
+void mixeng_clear (st_sample_t *buf, int len)
+{
+ memset (buf, 0, len * sizeof (st_sample_t));
+}
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/mixeng.h
--- a/tools/ioemu/audio/mixeng.h Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/mixeng.h Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
* QEMU Mixing engine header
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
+ *
+ * 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
@@ -24,16 +24,28 @@
#ifndef QEMU_MIXENG_H
#define QEMU_MIXENG_H
-typedef void (t_sample) (void *dst, const void *src, int samples);
-typedef void (f_sample) (void *dst, const void *src, int samples);
+#ifdef FLOAT_MIXENG
+typedef float real_t;
+typedef struct { int mute; real_t r; real_t l; } volume_t;
+typedef struct { real_t l; real_t r; } st_sample_t;
+#else
+typedef struct { int mute; int64_t r; int64_t l; } volume_t;
typedef struct { int64_t l; int64_t r; } st_sample_t;
+#endif
-extern t_sample *mixeng_conv[2][2][2];
-extern f_sample *mixeng_clip[2][2][2];
+typedef void (t_sample) (st_sample_t *dst, const void *src,
+ int samples, volume_t *vol);
+typedef void (f_sample) (void *dst, const st_sample_t *src, int samples);
+
+extern t_sample *mixeng_conv[2][2][2][2];
+extern f_sample *mixeng_clip[2][2][2][2];
void *st_rate_start (int inrate, int outrate);
void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
int *isamp, int *osamp);
+void st_rate_flow_mix (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
+ int *isamp, int *osamp);
void st_rate_stop (void *opaque);
+void mixeng_clear (st_sample_t *buf, int len);
#endif /* mixeng.h */
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/mixeng_template.h
--- a/tools/ioemu/audio/mixeng_template.h Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/mixeng_template.h Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
* QEMU Mixing engine
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
+ *
+ * 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
@@ -27,85 +27,151 @@
* dec++'ified by Dscho
*/
-#ifdef SIGNED
-#define HALFT IN_MAX
-#define HALF IN_MAX
-#else
-#define HALFT ((IN_MAX)>>1)
-#define HALF HALFT
+#ifndef SIGNED
+#define HALF (IN_MAX >> 1)
#endif
-static int64_t inline glue(conv_,IN_T) (IN_T v)
+#ifdef NOVOL
+#define VOL(a, b) a
+#else
+#ifdef FLOAT_MIXENG
+#define VOL(a, b) ((a) * (b))
+#else
+#define VOL(a, b) ((a) * (b)) >> 32
+#endif
+#endif
+
+#define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
+
+#ifdef FLOAT_MIXENG
+static real_t inline glue (conv_, ET) (IN_T v)
{
+ IN_T nv = ENDIAN_CONVERT (v);
+
+#ifdef RECIPROCAL
#ifdef SIGNED
- return (INT_MAX*(int64_t)v)/HALF;
+ return nv * (1.f / (real_t) (IN_MAX - IN_MIN));
#else
- return (INT_MAX*((int64_t)v-HALFT))/HALF;
+ return (nv - HALF) * (1.f / (real_t) IN_MAX);
+#endif
+#else /* !RECIPROCAL */
+#ifdef SIGNED
+ return nv / (real_t) (IN_MAX - IN_MIN);
+#else
+ return (nv - HALF) / (real_t) IN_MAX;
+#endif
#endif
}
-static IN_T inline glue(clip_,IN_T) (int64_t v)
+static IN_T inline glue (clip_, ET) (real_t v)
{
- if (v >= INT_MAX)
+ if (v >= 0.5) {
return IN_MAX;
- else if (v < -INT_MAX)
+ }
+ else if (v < -0.5) {
return IN_MIN;
+ }
#ifdef SIGNED
- return (IN_T) (v*HALF/INT_MAX);
+ return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
#else
- return (IN_T) (v+INT_MAX/2)*HALF/INT_MAX;
+ return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
#endif
}
-static void glue(glue(conv_,IN_T),_to_stereo) (void *dst, const void *src,
- int samples)
+#else /* !FLOAT_MIXENG */
+
+static inline int64_t glue (conv_, ET) (IN_T v)
{
- st_sample_t *out = (st_sample_t *) dst;
+ IN_T nv = ENDIAN_CONVERT (v);
+#ifdef SIGNED
+ return ((int64_t) nv) << (32 - SHIFT);
+#else
+ return ((int64_t) nv - HALF) << (32 - SHIFT);
+#endif
+}
+
+static inline IN_T glue (clip_, ET) (int64_t v)
+{
+ if (v >= 0x7f000000) {
+ return IN_MAX;
+ }
+ else if (v < -2147483648LL) {
+ return IN_MIN;
+ }
+
+#ifdef SIGNED
+ return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
+#else
+ return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
+#endif
+}
+#endif
+
+static void glue (glue (conv_, ET), _to_stereo)
+ (st_sample_t *dst, const void *src, int samples, volume_t *vol)
+{
+ st_sample_t *out = dst;
IN_T *in = (IN_T *) src;
+#ifndef NOVOL
+ if (vol->mute) {
+ mixeng_clear (dst, samples);
+ return;
+ }
+#else
+ (void) vol;
+#endif
while (samples--) {
- out->l = glue(conv_,IN_T) (*in++);
- out->r = glue(conv_,IN_T) (*in++);
+ out->l = VOL (glue (conv_, ET) (*in++), vol->l);
+ out->r = VOL (glue (conv_, ET) (*in++), vol->r);
out += 1;
}
}
-static void glue(glue(conv_,IN_T),_to_mono) (void *dst, const void *src,
- int samples)
+static void glue (glue (conv_, ET), _to_mono)
+ (st_sample_t *dst, const void *src, int samples, volume_t *vol)
{
- st_sample_t *out = (st_sample_t *) dst;
+ st_sample_t *out = dst;
IN_T *in = (IN_T *) src;
+#ifndef NOVOL
+ if (vol->mute) {
+ mixeng_clear (dst, samples);
+ return;
+ }
+#else
+ (void) vol;
+#endif
while (samples--) {
- out->l = glue(conv_,IN_T) (in[0]);
+ out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
out->r = out->l;
out += 1;
in += 1;
}
}
-static void glue(glue(clip_,IN_T),_from_stereo) (void *dst, const void *src,
- int samples)
+static void glue (glue (clip_, ET), _from_stereo)
+ (void *dst, const st_sample_t *src, int samples)
{
- st_sample_t *in = (st_sample_t *) src;
+ const st_sample_t *in = src;
IN_T *out = (IN_T *) dst;
while (samples--) {
- *out++ = glue(clip_,IN_T) (in->l);
- *out++ = glue(clip_,IN_T) (in->r);
+ *out++ = glue (clip_, ET) (in->l);
+ *out++ = glue (clip_, ET) (in->r);
in += 1;
}
}
-static void glue(glue(clip_,IN_T),_from_mono) (void *dst, const void *src,
- int samples)
+static void glue (glue (clip_, ET), _from_mono)
+ (void *dst, const st_sample_t *src, int samples)
{
- st_sample_t *in = (st_sample_t *) src;
+ const st_sample_t *in = src;
IN_T *out = (IN_T *) dst;
while (samples--) {
- *out++ = glue(clip_,IN_T) (in->l + in->r);
+ *out++ = glue (clip_, ET) (in->l + in->r);
in += 1;
}
}
+#undef ET
#undef HALF
-#undef HALFT
-
+#undef VOL
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/noaudio.c
--- a/tools/ioemu/audio/noaudio.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/noaudio.c Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
- * QEMU NULL audio output driver
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
+ * QEMU Timer based audio emulation
+ *
+ * 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
@@ -23,77 +23,108 @@
*/
#include "vl.h"
-#include "audio/audio_int.h"
+#define AUDIO_CAP "noaudio"
+#include "audio_int.h"
-typedef struct NoVoice {
- HWVoice hw;
+typedef struct NoVoiceOut {
+ HWVoiceOut hw;
int64_t old_ticks;
-} NoVoice;
+} NoVoiceOut;
-#define dolog(...) AUD_log ("noaudio", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
+typedef struct NoVoiceIn {
+ HWVoiceIn hw;
+ int64_t old_ticks;
+} NoVoiceIn;
-static void no_hw_run (HWVoice *hw)
+static int no_run_out (HWVoiceOut *hw)
{
- NoVoice *no = (NoVoice *) hw;
- int rpos, live, decr, samples;
- st_sample_t *src;
+ NoVoiceOut *no = (NoVoiceOut *) hw;
+ int live, decr, samples;
int64_t now = qemu_get_clock (vm_clock);
int64_t ticks = now - no->old_ticks;
- int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec;
+ int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
- if (bytes > INT_MAX)
- samples = INT_MAX >> hw->shift;
- else
- samples = bytes >> hw->shift;
+ if (bytes > INT_MAX) {
+ samples = INT_MAX >> hw->info.shift;
+ }
+ else {
+ samples = bytes >> hw->info.shift;
+ }
- live = pcm_hw_get_live (hw);
- if (live <= 0)
- return;
+ live = audio_pcm_hw_get_live_out (&no->hw);
+ if (!live) {
+ return 0;
+ }
no->old_ticks = now;
decr = audio_MIN (live, samples);
- samples = decr;
- rpos = hw->rpos;
- while (samples) {
- int left_till_end_samples = hw->samples - rpos;
- int convert_samples = audio_MIN (samples, left_till_end_samples);
-
- src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
- memset (src, 0, convert_samples * sizeof (st_sample_t));
-
- rpos = (rpos + convert_samples) % hw->samples;
- samples -= convert_samples;
- }
-
- pcm_hw_dec_live (hw, decr);
- hw->rpos = rpos;
+ hw->rpos = (hw->rpos + decr) % hw->samples;
+ return decr;
}
-static int no_hw_write (SWVoice *sw, void *buf, int len)
+static int no_write (SWVoiceOut *sw, void *buf, int len)
{
- return pcm_hw_write (sw, buf, len);
+ return audio_pcm_sw_write (sw, buf, len);
}
-static int no_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
+static int no_init_out (HWVoiceOut *hw, audsettings_t *as)
{
- hw->freq = freq;
- hw->nchannels = nchannels;
- hw->fmt = fmt;
- hw->bufsize = 4096;
+ audio_pcm_init_info (&hw->info, as, 0);
+ hw->samples = 1024;
return 0;
}
-static void no_hw_fini (HWVoice *hw)
+static void no_fini_out (HWVoiceOut *hw)
{
(void) hw;
}
-static int no_hw_ctl (HWVoice *hw, int cmd, ...)
+static int no_ctl_out (HWVoiceOut *hw, int cmd, ...)
+{
+ (void) hw;
+ (void) cmd;
+ return 0;
+}
+
+static int no_init_in (HWVoiceIn *hw, audsettings_t *as)
+{
+ audio_pcm_init_info (&hw->info, as, 0);
+ hw->samples = 1024;
+ return 0;
+}
+
+static void no_fini_in (HWVoiceIn *hw)
+{
+ (void) hw;
+}
+
+static int no_run_in (HWVoiceIn *hw)
+{
+ NoVoiceIn *no = (NoVoiceIn *) hw;
+ int64_t now = qemu_get_clock (vm_clock);
+ int64_t ticks = now - no->old_ticks;
+ int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
+ int live = audio_pcm_hw_get_live_in (hw);
+ int dead = hw->samples - live;
+ int samples;
+
+ bytes = audio_MIN (bytes, INT_MAX);
+ samples = bytes >> hw->info.shift;
+ samples = audio_MIN (samples, dead);
+
+ return samples;
+}
+
+static int no_read (SWVoiceIn *sw, void *buf, int size)
+{
+ int samples = size >> sw->info.shift;
+ int total = sw->hw->total_samples_captured - sw->total_hw_samples_acquired;
+ int to_clear = audio_MIN (samples, total);
+ audio_pcm_info_clear_buf (&sw->info, buf, to_clear);
+ return to_clear;
+}
+
+static int no_ctl_in (HWVoiceIn *hw, int cmd, ...)
{
(void) hw;
(void) cmd;
@@ -107,22 +138,33 @@ static void *no_audio_init (void)
static void no_audio_fini (void *opaque)
{
+ (void) opaque;
}
-struct pcm_ops no_pcm_ops = {
- no_hw_init,
- no_hw_fini,
- no_hw_run,
- no_hw_write,
- no_hw_ctl
+static struct audio_pcm_ops no_pcm_ops = {
+ no_init_out,
+ no_fini_out,
+ no_run_out,
+ no_write,
+ no_ctl_out,
+
+ no_init_in,
+ no_fini_in,
+ no_run_in,
+ no_read,
+ no_ctl_in
};
-struct audio_output_driver no_output_driver = {
- "none",
- no_audio_init,
- no_audio_fini,
- &no_pcm_ops,
- 1,
- 1,
- sizeof (NoVoice)
+struct audio_driver no_audio_driver = {
+ INIT_FIELD (name = ) "none",
+ INIT_FIELD (descr = ) "Timer based audio emulation",
+ INIT_FIELD (options = ) NULL,
+ INIT_FIELD (init = ) no_audio_init,
+ INIT_FIELD (fini = ) no_audio_fini,
+ INIT_FIELD (pcm_ops = ) &no_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 (NoVoiceOut),
+ INIT_FIELD (voice_size_in = ) sizeof (NoVoiceIn)
};
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/ossaudio.c
--- a/tools/ioemu/audio/ossaudio.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/ossaudio.c Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
- * QEMU OSS audio output driver
- *
- * Copyright (c) 2003-2004 Vassili Karpov (malc)
- *
+ * QEMU OSS audio driver
+ *
+ * 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
@@ -25,45 +25,42 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
-#include <assert.h>
#include "vl.h"
-#include "audio/audio_int.h"
-
-typedef struct OSSVoice {
- HWVoice hw;
+#define AUDIO_CAP "oss"
+#include "audio_int.h"
+
+typedef struct OSSVoiceOut {
+ HWVoiceOut hw;
void *pcm_buf;
int fd;
int nfrags;
int fragsize;
int mmapped;
int old_optr;
-} OSSVoice;
-
-#define dolog(...) AUD_log ("oss", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
-#define QC_OSS_NFRAGS "QEMU_OSS_NFRAGS"
-#define QC_OSS_MMAP "QEMU_OSS_MMAP"
-#define QC_OSS_DEV "QEMU_OSS_DEV"
-
-#define errstr() strerror (errno)
+} OSSVoiceOut;
+
+typedef struct OSSVoiceIn {
+ HWVoiceIn hw;
+ void *pcm_buf;
+ int fd;
+ int nfrags;
+ int fragsize;
+ int old_optr;
+} OSSVoiceIn;
static struct {
int try_mmap;
int nfrags;
int fragsize;
- const char *dspname;
+ const char *devpath_out;
+ const char *devpath_in;
} conf = {
.try_mmap = 0,
.nfrags = 4,
.fragsize = 4096,
- .dspname = "/dev/dsp"
+ .devpath_out = "/dev/dsp",
+ .devpath_in = "/dev/dsp"
};
struct oss_params {
@@ -74,65 +71,141 @@ struct oss_params {
int fragsize;
};
-static int oss_hw_write (SWVoice *sw, void *buf, int len)
-{
- return pcm_hw_write (sw, buf, len);
-}
-
-static int AUD_to_ossfmt (audfmt_e fmt)
+static void GCC_FMT_ATTR (2, 3) oss_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", strerror (err));
+}
+
+static void GCC_FMT_ATTR (3, 4) oss_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", strerror (err));
+}
+
+static void oss_anal_close (int *fdp)
+{
+ int err = close (*fdp);
+ if (err) {
+ oss_logerr (errno, "Failed to close file(fd=%d)\n", *fdp);
+ }
+ *fdp = -1;
+}
+
+static int oss_write (SWVoiceOut *sw, void *buf, int len)
+{
+ return audio_pcm_sw_write (sw, buf, len);
+}
+
+static int aud_to_ossfmt (audfmt_e fmt)
{
switch (fmt) {
- case AUD_FMT_S8: return AFMT_S8;
- case AUD_FMT_U8: return AFMT_U8;
- case AUD_FMT_S16: return AFMT_S16_LE;
- case AUD_FMT_U16: return AFMT_U16_LE;
+ case AUD_FMT_S8:
+ return AFMT_S8;
+
+ case AUD_FMT_U8:
+ return AFMT_U8;
+
+ case AUD_FMT_S16:
+ return AFMT_S16_LE;
+
+ case AUD_FMT_U16:
+ return AFMT_U16_LE;
+
default:
- dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
- exit (EXIT_FAILURE);
- }
-}
-
-static int oss_to_audfmt (int fmt)
-{
- switch (fmt) {
- case AFMT_S8: return AUD_FMT_S8;
- case AFMT_U8: return AUD_FMT_U8;
- case AFMT_S16_LE: return AUD_FMT_S16;
- case AFMT_U16_LE: return AUD_FMT_U16;
+ dolog ("Internal logic error: Bad audio format %d\n", fmt);
+#ifdef DEBUG_AUDIO
+ abort ();
+#endif
+ return AFMT_U8;
+ }
+}
+
+static int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness)
+{
+ switch (ossfmt) {
+ case AFMT_S8:
+ *endianness =0;
+ *fmt = AUD_FMT_S8;
+ break;
+
+ case AFMT_U8:
+ *endianness = 0;
+ *fmt = AUD_FMT_U8;
+ break;
+
+ case AFMT_S16_LE:
+ *endianness = 0;
+ *fmt = AUD_FMT_S16;
+ break;
+
+ case AFMT_U16_LE:
+ *endianness = 0;
+ *fmt = AUD_FMT_U16;
+ break;
+
+ case AFMT_S16_BE:
+ *endianness = 1;
+ *fmt = AUD_FMT_S16;
+ break;
+
+ case AFMT_U16_BE:
+ *endianness = 1;
+ *fmt = AUD_FMT_U16;
+ break;
+
default:
- dolog ("Internal logic error: Unrecognized OSS audio format %d\n"
- "Aborting\n",
- fmt);
- exit (EXIT_FAILURE);
- }
-}
-
-#ifdef DEBUG_PCM
-static void oss_dump_pcm_info (struct oss_params *req, struct oss_params *obt)
+ dolog ("Unrecognized audio format %d\n", ossfmt);
+ return -1;
+ }
+
+ return 0;
+}
+
+#if defined DEBUG_MISMATCHES || defined DEBUG
+static void oss_dump_info (struct oss_params *req, struct oss_params *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 ("channels | %10d | %10d\n",
+ req->nchannels, obt->nchannels);
dolog ("frequency | %10d | %10d\n", req->freq, obt->freq);
dolog ("nfrags | %10d | %10d\n", req->nfrags, obt->nfrags);
- dolog ("fragsize | %10d | %10d\n", req->fragsize, obt->fragsize);
+ dolog ("fragsize | %10d | %10d\n",
+ req->fragsize, obt->fragsize);
}
#endif
-static int oss_open (struct oss_params *req, struct oss_params *obt, int *pfd)
+static int oss_open (int in, struct oss_params *req,
+ struct oss_params *obt, int *pfd)
{
int fd;
int mmmmssss;
audio_buf_info abinfo;
int fmt, freq, nchannels;
- const char *dspname = conf.dspname;
-
- fd = open (dspname, O_RDWR | O_NONBLOCK);
+ const char *dspname = in ? conf.devpath_in : conf.devpath_out;
+ const char *typ = in ? "ADC" : "DAC";
+
+ fd = open (dspname, (in ? O_RDONLY : O_WRONLY) | O_NONBLOCK);
if (-1 == fd) {
- dolog ("Could not initialize audio hardware. Failed to open `%s':\n"
- "Reason:%s\n",
- dspname,
- errstr ());
+ oss_logerr2 (errno, typ, "Failed to open `%s'\n", dspname);
return -1;
}
@@ -141,52 +214,35 @@ static int oss_open (struct oss_params *
fmt = req->fmt;
if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set sample size\n"
- "Reason: %s\n",
- errstr ());
+ oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt);
goto err;
}
if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set number of channels\n"
- "Reason: %s\n",
- errstr ());
+ oss_logerr2 (errno, typ, "Failed to set number of channels %d\n",
+ req->nchannels);
goto err;
}
if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set frequency\n"
- "Reason: %s\n",
- errstr ());
+ oss_logerr2 (errno, typ, "Failed to set frequency %d\n", req->freq);
goto err;
}
if (ioctl (fd, SNDCTL_DSP_NONBLOCK)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set non-blocking mode\n"
- "Reason: %s\n",
- errstr ());
+ oss_logerr2 (errno, typ, "Failed to set non-blocking mode\n");
goto err;
}
mmmmssss = (req->nfrags << 16) | lsbindex (req->fragsize);
if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to set buffer length (%d, %d)\n"
- "Reason:%s\n",
- conf.nfrags, conf.fragsize,
- errstr ());
+ oss_logerr2 (errno, typ, "Failed to set buffer length (%d, %d)\n",
+ req->nfrags, req->fragsize);
goto err;
}
- if (ioctl (fd, SNDCTL_DSP_GETOSPACE, &abinfo)) {
- dolog ("Could not initialize audio hardware\n"
- "Failed to get buffer length\n"
- "Reason:%s\n",
- errstr ());
+ if (ioctl (fd, in ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo))
{
+ oss_logerr2 (errno, typ, "Failed to get buffer length\n");
goto err;
}
@@ -197,75 +253,87 @@ static int oss_open (struct oss_params *
obt->fragsize = abinfo.fragsize;
*pfd = fd;
+#ifdef DEBUG_MISMATCHES
if ((req->fmt != obt->fmt) ||
(req->nchannels != obt->nchannels) ||
(req->freq != obt->freq) ||
(req->fragsize != obt->fragsize) ||
(req->nfrags != obt->nfrags)) {
-#ifdef DEBUG_PCM
dolog ("Audio parameters mismatch\n");
- oss_dump_pcm_info (req, obt);
+ oss_dump_info (req, obt);
+ }
#endif
- }
-
-#ifdef DEBUG_PCM
- oss_dump_pcm_info (req, obt);
+
+#ifdef DEBUG
+ oss_dump_info (req, obt);
#endif
return 0;
-err:
- close (fd);
+ err:
+ oss_anal_close (&fd);
return -1;
}
-static void oss_hw_run (HWVoice *hw)
-{
- OSSVoice *oss = (OSSVoice *) hw;
+static int oss_run_out (HWVoiceOut *hw)
+{
+ OSSVoiceOut *oss = (OSSVoiceOut *) hw;
int err, rpos, live, decr;
int samples;
uint8_t *dst;
st_sample_t *src;
struct audio_buf_info abinfo;
struct count_info cntinfo;
-
- live = pcm_hw_get_live (hw);
- if (live <= 0)
- return;
+ int bufsize;
+
+ live = audio_pcm_hw_get_live_out (hw);
+ if (!live) {
+ return 0;
+ }
+
+ bufsize = hw->samples << hw->info.shift;
if (oss->mmapped) {
int bytes;
err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
if (err < 0) {
- dolog ("SNDCTL_DSP_GETOPTR failed\nReason: %s\n", errstr ());
- return;
+ oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
+ return 0;
}
if (cntinfo.ptr == oss->old_optr) {
- if (abs (hw->samples - live) < 64)
- dolog ("overrun\n");
- return;
+ if (abs (hw->samples - live) < 64) {
+ dolog ("warning: Overrun\n");
+ }
+ return 0;
}
if (cntinfo.ptr > oss->old_optr) {
bytes = cntinfo.ptr - oss->old_optr;
}
else {
- bytes = hw->bufsize + cntinfo.ptr - oss->old_optr;
- }
-
- decr = audio_MIN (bytes >> hw->shift, live);
+ bytes = bufsize + cntinfo.ptr - oss->old_optr;
+ }
+
+ decr = audio_MIN (bytes >> hw->info.shift, live);
}
else {
err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
if (err < 0) {
- dolog ("SNDCTL_DSP_GETOSPACE failed\nReason: %s\n", errstr ());
- return;
- }
-
- decr = audio_MIN (abinfo.bytes >> hw->shift, live);
- if (decr <= 0)
- return;
+ oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n");
+ return 0;
+ }
+
+ if (abinfo.bytes < 0 || abinfo.bytes > bufsize) {
+ ldebug ("warning: Invalid available size, size=%d bufsize=%d\n",
+ abinfo.bytes, bufsize);
+ return 0;
+ }
+
+ decr = audio_MIN (abinfo.bytes >> hw->info.shift, live);
+ if (!decr) {
+ return 0;
+ }
}
samples = decr;
@@ -274,33 +342,41 @@ static void oss_hw_run (HWVoice *hw)
int left_till_end_samples = hw->samples - rpos;
int convert_samples = audio_MIN (samples, left_till_end_samples);
- src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
- dst = advance (oss->pcm_buf, rpos << hw->shift);
+ src = hw->mix_buf + rpos;
+ dst = advance (oss->pcm_buf, rpos << hw->info.shift);
hw->clip (dst, src, convert_samples);
if (!oss->mmapped) {
int written;
- written = write (oss->fd, dst, convert_samples << hw->shift);
+ written = write (oss->fd, dst, convert_samples << hw->info.shift);
/* XXX: follow errno recommendations ? */
if (written == -1) {
- dolog ("Failed to write audio\nReason: %s\n", errstr ());
+ oss_logerr (
+ errno,
+ "Failed to write %d bytes of audio data from %p\n",
+ convert_samples << hw->info.shift,
+ dst
+ );
continue;
}
- if (written != convert_samples << hw->shift) {
- int wsamples = written >> hw->shift;
- int wbytes = wsamples << hw->shift;
+ if (written != convert_samples << hw->info.shift) {
+ int wsamples = written >> hw->info.shift;
+ int wbytes = wsamples << hw->info.shift;
if (wbytes != written) {
- dolog ("Unaligned write %d, %d\n", wbytes, written);
+ dolog ("warning: Misaligned write %d (requested %d), "
+ "alignment %d\n",
+ wbytes, written, hw->info.align + 1);
}
- memset (src, 0, wbytes);
- decr -= samples;
+ mixeng_clear (src, wsamples);
+ decr -= wsamples;
rpos = (rpos + wsamples) % hw->samples;
break;
}
}
- memset (src, 0, convert_samples * sizeof (st_sample_t));
+
+ mixeng_clear (src, convert_samples);
rpos = (rpos + convert_samples) % hw->samples;
samples -= convert_samples;
@@ -309,28 +385,24 @@ static void oss_hw_run (HWVoice *hw)
oss->old_optr = cntinfo.ptr;
}
- pcm_hw_dec_live (hw, decr);
hw->rpos = rpos;
-}
-
-static void oss_hw_fini (HWVoice *hw)
+ return decr;
+}
+
+static void oss_fini_out (HWVoiceOut *hw)
{
int err;
- OSSVoice *oss = (OSSVoice *) hw;
-
- ldebug ("oss_hw_fini\n");
- err = close (oss->fd);
- if (err) {
- dolog ("Failed to close OSS descriptor\nReason: %s\n", errstr ());
- }
- oss->fd = -1;
+ OSSVoiceOut *oss = (OSSVoiceOut *) hw;
+
+ ldebug ("oss_fini\n");
+ oss_anal_close (&oss->fd);
if (oss->pcm_buf) {
if (oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->bufsize);
+ err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
if (err) {
- dolog ("Failed to unmap OSS buffer\nReason: %s\n",
- errstr ());
+ oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",
+ oss->pcm_buf, hw->samples << hw->info.shift);
}
}
else {
@@ -340,48 +412,79 @@ static void oss_hw_fini (HWVoice *hw)
}
}
-static int oss_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- OSSVoice *oss = (OSSVoice *) hw;
+static int oss_init_out (HWVoiceOut *hw, audsettings_t *as)
+{
+ OSSVoiceOut *oss = (OSSVoiceOut *) hw;
struct oss_params req, obt;
-
- assert (!oss->fd);
- req.fmt = AUD_to_ossfmt (fmt);
- req.freq = freq;
- req.nchannels = nchannels;
+ int endianness;
+ int err;
+ int fd;
+ audfmt_e effective_fmt;
+ audsettings_t obt_as;
+
+ oss->fd = -1;
+
+ req.fmt = aud_to_ossfmt (as->fmt);
+ req.freq = as->freq;
+ req.nchannels = as->nchannels;
req.fragsize = conf.fragsize;
req.nfrags = conf.nfrags;
- if (oss_open (&req, &obt, &oss->fd))
+ if (oss_open (0, &req, &obt, &fd)) {
return -1;
-
- hw->freq = obt.freq;
- hw->fmt = oss_to_audfmt (obt.fmt);
- hw->nchannels = obt.nchannels;
-
+ }
+
+ err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
+ if (err) {
+ oss_anal_close (&fd);
+ 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)
+ );
oss->nfrags = obt.nfrags;
oss->fragsize = obt.fragsize;
- hw->bufsize = obt.nfrags * obt.fragsize;
+
+ if (obt.nfrags * obt.fragsize & hw->info.align) {
+ dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",
+ obt.nfrags * obt.fragsize, hw->info.align + 1);
+ }
+
+ hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
oss->mmapped = 0;
if (conf.try_mmap) {
- oss->pcm_buf = mmap (0, hw->bufsize, PROT_READ | PROT_WRITE,
- MAP_SHARED, oss->fd, 0);
+ oss->pcm_buf = mmap (
+ 0,
+ hw->samples << hw->info.shift,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ fd,
+ 0
+ );
if (oss->pcm_buf == MAP_FAILED) {
- dolog ("Failed to mmap OSS device\nReason: %s\n",
- errstr ());
+ oss_logerr (errno, "Failed to map %d bytes of DAC\n",
+ hw->samples << hw->info.shift);
} else {
int err;
int trig = 0;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
- errstr ());
+ if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
+ oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
}
else {
trig = PCM_ENABLE_OUTPUT;
- if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- "Reason: %s\n", errstr ());
+ if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
+ oss_logerr (
+ errno,
+ "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
+ );
}
else {
oss->mmapped = 1;
@@ -389,43 +492,55 @@ static int oss_hw_init (HWVoice *hw, int
}
if (!oss->mmapped) {
- err = munmap (oss->pcm_buf, hw->bufsize);
+ err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);
if (err) {
- dolog ("Failed to unmap OSS device\nReason: %s\n",
- errstr ());
+ oss_logerr (errno, "Failed to unmap buffer %p size %d\n",
+ oss->pcm_buf, hw->samples << hw->info.shift);
}
}
}
}
if (!oss->mmapped) {
- oss->pcm_buf = qemu_mallocz (hw->bufsize);
+ oss->pcm_buf = audio_calloc (
+ AUDIO_FUNC,
+ hw->samples,
+ 1 << hw->info.shift
+ );
if (!oss->pcm_buf) {
- close (oss->fd);
- oss->fd = -1;
+ dolog (
+ "Could not allocate DAC buffer (%d samples, each %d bytes)\n",
+ hw->samples,
+ 1 << hw->info.shift
+ );
+ oss_anal_close (&fd);
return -1;
}
}
+ oss->fd = fd;
return 0;
}
-static int oss_hw_ctl (HWVoice *hw, int cmd, ...)
+static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
int trig;
- OSSVoice *oss = (OSSVoice *) hw;
-
- if (!oss->mmapped)
+ OSSVoiceOut *oss = (OSSVoiceOut *) hw;
+
+ if (!oss->mmapped) {
return 0;
+ }
switch (cmd) {
case VOICE_ENABLE:
ldebug ("enabling voice\n");
- pcm_hw_clear (hw, oss->pcm_buf, hw->samples);
+ audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);
trig = PCM_ENABLE_OUTPUT;
if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
- "Reason: %s\n", errstr ());
+ oss_logerr (
+ errno,
+ "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
+ );
return -1;
}
break;
@@ -434,8 +549,7 @@ static int oss_hw_ctl (HWVoice *hw, int
ldebug ("disabling voice\n");
trig = 0;
if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
- dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
- errstr ());
+ oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
return -1;
}
break;
@@ -443,33 +557,206 @@ static int oss_hw_ctl (HWVoice *hw, int
return 0;
}
+static int oss_init_in (HWVoiceIn *hw, audsettings_t *as)
+{
+ OSSVoiceIn *oss = (OSSVoiceIn *) hw;
+ struct oss_params req, obt;
+ int endianness;
+ int err;
+ int fd;
+ audfmt_e effective_fmt;
+ audsettings_t obt_as;
+
+ oss->fd = -1;
+
+ req.fmt = aud_to_ossfmt (as->fmt);
+ req.freq = as->freq;
+ req.nchannels = as->nchannels;
+ req.fragsize = conf.fragsize;
+ req.nfrags = conf.nfrags;
+ if (oss_open (1, &req, &obt, &fd)) {
+ return -1;
+ }
+
+ err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
+ if (err) {
+ oss_anal_close (&fd);
+ 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)
+ );
+ oss->nfrags = obt.nfrags;
+ oss->fragsize = obt.fragsize;
+
+ if (obt.nfrags * obt.fragsize & hw->info.align) {
+ dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n",
+ obt.nfrags * obt.fragsize, hw->info.align + 1);
+ }
+
+ hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;
+ oss->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
+ if (!oss->pcm_buf) {
+ dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",
+ hw->samples, 1 << hw->info.shift);
+ oss_anal_close (&fd);
+ return -1;
+ }
+
+ oss->fd = fd;
+ return 0;
+}
+
+static void oss_fini_in (HWVoiceIn *hw)
+{
+ OSSVoiceIn *oss = (OSSVoiceIn *) hw;
+
+ oss_anal_close (&oss->fd);
+
+ if (oss->pcm_buf) {
+ qemu_free (oss->pcm_buf);
+ oss->pcm_buf = NULL;
+ }
+}
+
+static int oss_run_in (HWVoiceIn *hw)
+{
+ OSSVoiceIn *oss = (OSSVoiceIn *) hw;
+ int hwshift = hw->info.shift;
+ int i;
+ int live = audio_pcm_hw_get_live_in (hw);
+ int dead = hw->samples - live;
+ size_t read_samples = 0;
+ struct {
+ int add;
+ int len;
+ } bufs[2] = {
+ { hw->wpos, 0 },
+ { 0, 0 }
+ };
+
+ if (!dead) {
+ return 0;
+ }
+
+ if (hw->wpos + dead > hw->samples) {
+ bufs[0].len = (hw->samples - hw->wpos) << hwshift;
+ bufs[1].len = (dead - (hw->samples - hw->wpos)) << hwshift;
+ }
+ else {
+ bufs[0].len = dead << hwshift;
+ }
+
+
+ for (i = 0; i < 2; ++i) {
+ ssize_t nread;
+
+ if (bufs[i].len) {
+ void *p = advance (oss->pcm_buf, bufs[i].add << hwshift);
+ nread = read (oss->fd, p, bufs[i].len);
+
+ if (nread > 0) {
+ if (nread & hw->info.align) {
+ dolog ("warning: Misaligned read %zd (requested %d), "
+ "alignment %d\n", nread, bufs[i].add << hwshift,
+ hw->info.align + 1);
+ }
+ read_samples += nread >> hwshift;
+ hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift,
+ &nominal_volume);
+ }
+
+ if (bufs[i].len - nread) {
+ if (nread == -1) {
+ switch (errno) {
+ case EINTR:
+ case EAGAIN:
+ break;
+ default:
+ oss_logerr (
+ errno,
+ "Failed to read %d bytes of audio (to %p)\n",
+ bufs[i].len, p
+ );
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ hw->wpos = (hw->wpos + read_samples) % hw->samples;
+ return read_samples;
+}
+
+static int oss_read (SWVoiceIn *sw, void *buf, int size)
+{
+ return audio_pcm_sw_read (sw, buf, size);
+}
+
+static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...)
+{
+ (void) hw;
+ (void) cmd;
+ return 0;
+}
+
static void *oss_audio_init (void)
{
- conf.fragsize = audio_get_conf_int (QC_OSS_FRAGSIZE, conf.fragsize);
- conf.nfrags = audio_get_conf_int (QC_OSS_NFRAGS, conf.nfrags);
- conf.try_mmap = audio_get_conf_int (QC_OSS_MMAP, conf.try_mmap);
- conf.dspname = audio_get_conf_str (QC_OSS_DEV, conf.dspname);
return &conf;
}
static void oss_audio_fini (void *opaque)
{
-}
-
-struct pcm_ops oss_pcm_ops = {
- oss_hw_init,
- oss_hw_fini,
- oss_hw_run,
- oss_hw_write,
- oss_hw_ctl
+ (void) opaque;
+}
+
+static struct audio_option oss_options[] = {
+ {"FRAGSIZE", AUD_OPT_INT, &conf.fragsize,
+ "Fragment size in bytes", NULL, 0},
+ {"NFRAGS", AUD_OPT_INT, &conf.nfrags,
+ "Number of fragments", NULL, 0},
+ {"MMAP", AUD_OPT_BOOL, &conf.try_mmap,
+ "Try using memory mapped access", NULL, 0},
+ {"DAC_DEV", AUD_OPT_STR, &conf.devpath_out,
+ "Path to DAC device", NULL, 0},
+ {"ADC_DEV", AUD_OPT_STR, &conf.devpath_in,
+ "Path to ADC device", NULL, 0},
+ {NULL, 0, NULL, NULL, NULL, 0}
};
-struct audio_output_driver oss_output_driver = {
- "oss",
- oss_audio_init,
- oss_audio_fini,
- &oss_pcm_ops,
- 1,
- INT_MAX,
- sizeof (OSSVoice)
+static struct audio_pcm_ops oss_pcm_ops = {
+ oss_init_out,
+ oss_fini_out,
+ oss_run_out,
+ oss_write,
+ oss_ctl_out,
+
+ oss_init_in,
+ oss_fini_in,
+ oss_run_in,
+ oss_read,
+ oss_ctl_in
};
+
+struct audio_driver oss_audio_driver = {
+ INIT_FIELD (name = ) "oss",
+ INIT_FIELD (descr = ) "OSS http://www.opensound.com",
+ INIT_FIELD (options = ) oss_options,
+ INIT_FIELD (init = ) oss_audio_init,
+ INIT_FIELD (fini = ) oss_audio_fini,
+ INIT_FIELD (pcm_ops = ) &oss_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 (OSSVoiceOut),
+ INIT_FIELD (voice_size_in = ) sizeof (OSSVoiceIn)
+};
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/sdlaudio.c
--- a/tools/ioemu/audio/sdlaudio.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/sdlaudio.c Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
- * QEMU SDL audio output driver
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
+ * QEMU SDL 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
@@ -25,22 +25,15 @@
#include <SDL_thread.h>
#include "vl.h"
-#include "audio/audio_int.h"
-
-typedef struct SDLVoice {
- HWVoice hw;
-} SDLVoice;
-
-#define dolog(...) AUD_log ("sdl", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
-
-#define QC_SDL_SAMPLES "QEMU_SDL_SAMPLES"
-
-#define errstr() SDL_GetError ()
+#define AUDIO_CAP "sdl"
+#include "audio_int.h"
+
+typedef struct SDLVoiceOut {
+ HWVoiceOut hw;
+ int live;
+ int rpos;
+ int decr;
+} SDLVoiceOut;
static struct {
int nb_samples;
@@ -56,91 +49,129 @@ struct SDLAudioState {
} glob_sdl;
typedef struct SDLAudioState SDLAudioState;
-static void sdl_hw_run (HWVoice *hw)
-{
- (void) hw;
-}
-
-static int sdl_lock (SDLAudioState *s)
+static void GCC_FMT_ATTR (1, 2) sdl_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", SDL_GetError ());
+}
+
+static int sdl_lock (SDLAudioState *s, const char *forfn)
{
if (SDL_LockMutex (s->mutex)) {
- dolog ("SDL_LockMutex failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock (SDLAudioState *s)
+ sdl_logerr ("SDL_LockMutex for %s failed\n", forfn);
+ return -1;
+ }
+ return 0;
+}
+
+static int sdl_unlock (SDLAudioState *s, const char *forfn)
{
if (SDL_UnlockMutex (s->mutex)) {
- dolog ("SDL_UnlockMutex failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_post (SDLAudioState *s)
+ sdl_logerr ("SDL_UnlockMutex for %s failed\n", forfn);
+ return -1;
+ }
+ return 0;
+}
+
+static int sdl_post (SDLAudioState *s, const char *forfn)
{
if (SDL_SemPost (s->sem)) {
- dolog ("SDL_SemPost failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_wait (SDLAudioState *s)
+ sdl_logerr ("SDL_SemPost for %s failed\n", forfn);
+ return -1;
+ }
+ return 0;
+}
+
+static int sdl_wait (SDLAudioState *s, const char *forfn)
{
if (SDL_SemWait (s->sem)) {
- dolog ("SDL_SemWait failed\nReason: %s\n", errstr ());
- return -1;
- }
- return 0;
-}
-
-static int sdl_unlock_and_post (SDLAudioState *s)
-{
- if (sdl_unlock (s))
- return -1;
-
- return sdl_post (s);
-}
-
-static int sdl_hw_write (SWVoice *sw, void *buf, int len)
-{
- int ret;
- SDLAudioState *s = &glob_sdl;
- sdl_lock (s);
- ret = pcm_hw_write (sw, buf, len);
- sdl_unlock_and_post (s);
- return ret;
-}
-
-static int AUD_to_sdlfmt (audfmt_e fmt, int *shift)
-{
- *shift = 0;
+ sdl_logerr ("SDL_SemWait for %s failed\n", forfn);
+ return -1;
+ }
+ return 0;
+}
+
+static int sdl_unlock_and_post (SDLAudioState *s, const char *forfn)
+{
+ if (sdl_unlock (s, forfn)) {
+ return -1;
+ }
+
+ return sdl_post (s, forfn);
+}
+
+static int aud_to_sdlfmt (audfmt_e fmt, int *shift)
+{
switch (fmt) {
- case AUD_FMT_S8: return AUDIO_S8;
- case AUD_FMT_U8: return AUDIO_U8;
- case AUD_FMT_S16: *shift = 1; return AUDIO_S16LSB;
- case AUD_FMT_U16: *shift = 1; return AUDIO_U16LSB;
+ case AUD_FMT_S8:
+ *shift = 0;
+ return AUDIO_S8;
+
+ case AUD_FMT_U8:
+ *shift = 0;
+ return AUDIO_U8;
+
+ case AUD_FMT_S16:
+ *shift = 1;
+ return AUDIO_S16LSB;
+
+ case AUD_FMT_U16:
+ *shift = 1;
+ return AUDIO_U16LSB;
+
default:
- dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
- exit (EXIT_FAILURE);
- }
-}
-
-static int sdl_to_audfmt (int fmt)
-{
- switch (fmt) {
- case AUDIO_S8: return AUD_FMT_S8;
- case AUDIO_U8: return AUD_FMT_U8;
- case AUDIO_S16LSB: return AUD_FMT_S16;
- case AUDIO_U16LSB: return AUD_FMT_U16;
+ dolog ("Internal logic error: Bad audio format %d\n", fmt);
+#ifdef DEBUG_AUDIO
+ abort ();
+#endif
+ return AUDIO_U8;
+ }
+}
+
+static int sdl_to_audfmt (int sdlfmt, audfmt_e *fmt, int *endianess)
+{
+ switch (sdlfmt) {
+ case AUDIO_S8:
+ *endianess = 0;
+ *fmt = AUD_FMT_S8;
+ break;
+
+ case AUDIO_U8:
+ *endianess = 0;
+ *fmt = AUD_FMT_U8;
+ break;
+
+ case AUDIO_S16LSB:
+ *endianess = 0;
+ *fmt = AUD_FMT_S16;
+ break;
+
+ case AUDIO_U16LSB:
+ *endianess = 0;
+ *fmt = AUD_FMT_U16;
+ break;
+
+ case AUDIO_S16MSB:
+ *endianess = 1;
+ *fmt = AUD_FMT_S16;
+ break;
+
+ case AUDIO_U16MSB:
+ *endianess = 1;
+ *fmt = AUD_FMT_U16;
+ break;
+
default:
- dolog ("Internal logic error: Unrecognized SDL audio format %d\n"
- "Aborting\n", fmt);
- exit (EXIT_FAILURE);
- }
+ dolog ("Unrecognized SDL audio format %d\n", sdlfmt);
+ return -1;
+ }
+
+ return 0;
}
static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
@@ -149,7 +180,7 @@ static int sdl_open (SDL_AudioSpec *req,
status = SDL_OpenAudio (req, obt);
if (status) {
- dolog ("SDL_OpenAudio failed\nReason: %s\n", errstr ());
+ sdl_logerr ("SDL_OpenAudio failed\n");
}
return status;
}
@@ -157,9 +188,9 @@ static void sdl_close (SDLAudioState *s)
static void sdl_close (SDLAudioState *s)
{
if (s->initialized) {
- sdl_lock (s);
+ sdl_lock (s, "sdl_close");
s->exit = 1;
- sdl_unlock_and_post (s);
+ sdl_unlock_and_post (s, "sdl_close");
SDL_PauseAudio (1);
SDL_CloseAudio ();
s->initialized = 0;
@@ -168,31 +199,40 @@ static void sdl_close (SDLAudioState *s)
static void sdl_callback (void *opaque, Uint8 *buf, int len)
{
- SDLVoice *sdl = opaque;
+ SDLVoiceOut *sdl = opaque;
SDLAudioState *s = &glob_sdl;
- HWVoice *hw = &sdl->hw;
- int samples = len >> hw->shift;
+ HWVoiceOut *hw = &sdl->hw;
+ int samples = len >> hw->info.shift;
if (s->exit) {
return;
}
while (samples) {
- int to_mix, live, decr;
+ int to_mix, decr;
/* dolog ("in callback samples=%d\n", samples); */
- sdl_wait (s);
+ sdl_wait (s, "sdl_callback");
if (s->exit) {
return;
}
- sdl_lock (s);
- live = pcm_hw_get_live (hw);
- if (live <= 0)
+ if (sdl_lock (s, "sdl_callback")) {
+ return;
+ }
+
+ if (audio_bug (AUDIO_FUNC, sdl->live < 0 || sdl->live > hw->samples)) {
+ dolog ("sdl->live=%d hw->samples=%d\n",
+ sdl->live, hw->samples);
+ return;
+ }
+
+ if (!sdl->live) {
goto again;
+ }
/* dolog ("in callback live=%d\n", live); */
- to_mix = audio_MIN (samples, live);
+ to_mix = audio_MIN (samples, sdl->live);
decr = to_mix;
while (to_mix) {
int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
@@ -200,58 +240,109 @@ static void sdl_callback (void *opaque,
/* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
hw->clip (buf, src, chunk);
- memset (src, 0, chunk * sizeof (st_sample_t));
- hw->rpos = (hw->rpos + chunk) % hw->samples;
+ mixeng_clear (src, chunk);
+ sdl->rpos = (sdl->rpos + chunk) % hw->samples;
to_mix -= chunk;
- buf += chunk << hw->shift;
+ buf += chunk << hw->info.shift;
}
samples -= decr;
- pcm_hw_dec_live (hw, decr);
+ sdl->live -= decr;
+ sdl->decr += decr;
again:
- sdl_unlock (s);
+ if (sdl_unlock (s, "sdl_callback")) {
+ return;
+ }
}
/* dolog ("done len=%d\n", len); */
}
-static void sdl_hw_fini (HWVoice *hw)
-{
- ldebug ("sdl_hw_fini %d fixed=%d\n",
- glob_sdl.initialized, audio_conf.fixed_format);
+static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
+{
+ return audio_pcm_sw_write (sw, buf, len);
+}
+
+static int sdl_run_out (HWVoiceOut *hw)
+{
+ int decr, live;
+ SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
+ SDLAudioState *s = &glob_sdl;
+
+ if (sdl_lock (s, "sdl_callback")) {
+ return 0;
+ }
+
+ live = audio_pcm_hw_get_live_out (hw);
+
+ if (sdl->decr > live) {
+ ldebug ("sdl->decr %d live %d sdl->live %d\n",
+ sdl->decr,
+ live,
+ sdl->live);
+ }
+
+ decr = audio_MIN (sdl->decr, live);
+ sdl->decr -= decr;
+
+ sdl->live = live - decr;
+ hw->rpos = sdl->rpos;
+
+ if (sdl->live > 0) {
+ sdl_unlock_and_post (s, "sdl_callback");
+ }
+ else {
+ sdl_unlock (s, "sdl_callback");
+ }
+ return decr;
+}
+
+static void sdl_fini_out (HWVoiceOut *hw)
+{
+ (void) hw;
+
sdl_close (&glob_sdl);
}
-static int sdl_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- SDLVoice *sdl = (SDLVoice *) hw;
+static int sdl_init_out (HWVoiceOut *hw, audsettings_t *as)
+{
+ SDLVoiceOut *sdl = (SDLVoiceOut *) hw;
SDLAudioState *s = &glob_sdl;
SDL_AudioSpec req, obt;
int shift;
-
- ldebug ("sdl_hw_init %d freq=%d fixed=%d\n",
- s->initialized, freq, audio_conf.fixed_format);
-
- if (nchannels != 2) {
- dolog ("Bogus channel count %d\n", nchannels);
- return -1;
- }
-
- req.freq = freq;
- req.format = AUD_to_sdlfmt (fmt, &shift);
- req.channels = nchannels;
+ int endianess;
+ int err;
+ audfmt_e effective_fmt;
+ audsettings_t obt_as;
+
+ shift <<= as->nchannels == 2;
+
+ req.freq = as->freq;
+ req.format = aud_to_sdlfmt (as->fmt, &shift);
+ req.channels = as->nchannels;
req.samples = conf.nb_samples;
- shift <<= nchannels == 2;
-
req.callback = sdl_callback;
req.userdata = sdl;
- if (sdl_open (&req, &obt))
- return -1;
-
- hw->freq = obt.freq;
- hw->fmt = sdl_to_audfmt (obt.format);
- hw->nchannels = obt.channels;
- hw->bufsize = obt.samples << shift;
+ if (sdl_open (&req, &obt)) {
+ return -1;
+ }
+
+ err = sdl_to_audfmt (obt.format, &effective_fmt, &endianess);
+ if (err) {
+ sdl_close (s);
+ return -1;
+ }
+
+ obt_as.freq = obt.freq;
+ obt_as.nchannels = obt.channels;
+ obt_as.fmt = effective_fmt;
+
+ audio_pcm_init_info (
+ &hw->info,
+ &obt_as,
+ audio_need_to_swap_endian (endianess)
+ );
+ hw->samples = obt.samples;
s->initialized = 1;
s->exit = 0;
@@ -259,7 +350,7 @@ static int sdl_hw_init (HWVoice *hw, int
return 0;
}
-static int sdl_hw_ctl (HWVoice *hw, int cmd, ...)
+static int sdl_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
(void) hw;
@@ -278,24 +369,22 @@ static void *sdl_audio_init (void)
static void *sdl_audio_init (void)
{
SDLAudioState *s = &glob_sdl;
- conf.nb_samples = audio_get_conf_int (QC_SDL_SAMPLES, conf.nb_samples);
if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
- dolog ("SDL failed to initialize audio subsystem\nReason: %s\n",
- errstr ());
+ sdl_logerr ("SDL failed to initialize audio subsystem\n");
return NULL;
}
s->mutex = SDL_CreateMutex ();
if (!s->mutex) {
- dolog ("Failed to create SDL mutex\nReason: %s\n", errstr ());
+ sdl_logerr ("Failed to create SDL mutex\n");
SDL_QuitSubSystem (SDL_INIT_AUDIO);
return NULL;
}
s->sem = SDL_CreateSemaphore (0);
if (!s->sem) {
- dolog ("Failed to create SDL semaphore\nReason: %s\n", errstr ());
+ sdl_logerr ("Failed to create SDL semaphore\n");
SDL_DestroyMutex (s->mutex);
SDL_QuitSubSystem (SDL_INIT_AUDIO);
return NULL;
@@ -313,20 +402,36 @@ static void sdl_audio_fini (void *opaque
SDL_QuitSubSystem (SDL_INIT_AUDIO);
}
-struct pcm_ops sdl_pcm_ops = {
- sdl_hw_init,
- sdl_hw_fini,
- sdl_hw_run,
- sdl_hw_write,
- sdl_hw_ctl
+static struct audio_option sdl_options[] = {
+ {"SAMPLES", AUD_OPT_INT, &conf.nb_samples,
+ "Size of SDL buffer in samples", NULL, 0},
+ {NULL, 0, NULL, NULL, NULL, 0}
};
-struct audio_output_driver sdl_output_driver = {
- "sdl",
- sdl_audio_init,
- sdl_audio_fini,
- &sdl_pcm_ops,
- 1,
- 1,
- sizeof (SDLVoice)
+static struct audio_pcm_ops sdl_pcm_ops = {
+ sdl_init_out,
+ sdl_fini_out,
+ sdl_run_out,
+ sdl_write_out,
+ sdl_ctl_out,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
};
+
+struct audio_driver sdl_audio_driver = {
+ INIT_FIELD (name = ) "sdl",
+ INIT_FIELD (descr = ) "SDL http://www.libsdl.org",
+ INIT_FIELD (options = ) sdl_options,
+ INIT_FIELD (init = ) sdl_audio_init,
+ INIT_FIELD (fini = ) sdl_audio_fini,
+ INIT_FIELD (pcm_ops = ) &sdl_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 (SDLVoiceOut),
+ INIT_FIELD (voice_size_in = ) 0
+};
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/audio/wavaudio.c
--- a/tools/ioemu/audio/wavaudio.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/audio/wavaudio.c Tue Jul 25 12:19:05 2006 -0600
@@ -1,8 +1,8 @@
/*
- * QEMU WAV audio output driver
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
+ * QEMU WAV 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
@@ -23,47 +23,50 @@
*/
#include "vl.h"
-#include "audio/audio_int.h"
-
-typedef struct WAVVoice {
- HWVoice hw;
+#define AUDIO_CAP "wav"
+#include "audio_int.h"
+
+typedef struct WAVVoiceOut {
+ HWVoiceOut hw;
QEMUFile *f;
int64_t old_ticks;
void *pcm_buf;
int total_samples;
-} WAVVoice;
-
-#define dolog(...) AUD_log ("wav", __VA_ARGS__)
-#ifdef DEBUG
-#define ldebug(...) dolog (__VA_ARGS__)
-#else
-#define ldebug(...)
-#endif
+} WAVVoiceOut;
static struct {
+ audsettings_t settings;
const char *wav_path;
} conf = {
- .wav_path = "qemu.wav"
-};
-
-static void wav_hw_run (HWVoice *hw)
-{
- WAVVoice *wav = (WAVVoice *) hw;
+ {
+ 44100,
+ 2,
+ AUD_FMT_S16
+ },
+ "qemu.wav"
+};
+
+static int wav_run_out (HWVoiceOut *hw)
+{
+ WAVVoiceOut *wav = (WAVVoiceOut *) hw;
int rpos, live, decr, samples;
uint8_t *dst;
st_sample_t *src;
int64_t now = qemu_get_clock (vm_clock);
int64_t ticks = now - wav->old_ticks;
- int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec;
-
- if (bytes > INT_MAX)
- samples = INT_MAX >> hw->shift;
- else
- samples = bytes >> hw->shift;
-
- live = pcm_hw_get_live (hw);
- if (live <= 0)
- return;
+ int64_t bytes = (ticks * hw->info.bytes_per_second) / ticks_per_sec;
+
+ if (bytes > INT_MAX) {
+ samples = INT_MAX >> hw->info.shift;
+ }
+ else {
+ samples = bytes >> hw->info.shift;
+ }
+
+ live = audio_pcm_hw_get_live_out (hw);
+ if (!live) {
+ return 0;
+ }
wav->old_ticks = now;
decr = audio_MIN (live, samples);
@@ -73,25 +76,25 @@ static void wav_hw_run (HWVoice *hw)
int left_till_end_samples = hw->samples - rpos;
int convert_samples = audio_MIN (samples, left_till_end_samples);
- src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
- dst = advance (wav->pcm_buf, rpos << hw->shift);
+ src = hw->mix_buf + rpos;
+ dst = advance (wav->pcm_buf, rpos << hw->info.shift);
hw->clip (dst, src, convert_samples);
- qemu_put_buffer (wav->f, dst, convert_samples << hw->shift);
- memset (src, 0, convert_samples * sizeof (st_sample_t));
+ qemu_put_buffer (wav->f, dst, convert_samples << hw->info.shift);
+ mixeng_clear (src, convert_samples);
rpos = (rpos + convert_samples) % hw->samples;
samples -= convert_samples;
wav->total_samples += convert_samples;
}
- pcm_hw_dec_live (hw, decr);
hw->rpos = rpos;
-}
-
-static int wav_hw_write (SWVoice *sw, void *buf, int len)
-{
- return pcm_hw_write (sw, buf, len);
+ return decr;
+}
+
+static int wav_write_out (SWVoiceOut *sw, void *buf, int len)
+{
+ return audio_pcm_sw_write (sw, buf, len);
}
/* VICE code: Store number as little endian. */
@@ -104,20 +107,25 @@ static void le_store (uint8_t *buf, uint
}
}
-static int wav_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
-{
- WAVVoice *wav = (WAVVoice *) hw;
- int bits16 = 0, stereo = audio_state.fixed_channels == 2;
+static int wav_init_out (HWVoiceOut *hw, audsettings_t *as)
+{
+ WAVVoiceOut *wav = (WAVVoiceOut *) hw;
+ int bits16 = 0, stereo = 0;
uint8_t hdr[] = {
0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
};
-
- switch (audio_state.fixed_fmt) {
+ audsettings_t wav_as = conf.settings;
+
+ (void) as;
+
+ stereo = wav_as.nchannels == 2;
+ switch (wav_as.fmt) {
case AUD_FMT_S8:
case AUD_FMT_U8:
+ bits16 = 0;
break;
case AUD_FMT_S16:
@@ -127,22 +135,25 @@ static int wav_hw_init (HWVoice *hw, int
}
hdr[34] = bits16 ? 0x10 : 0x08;
- hw->freq = 44100;
- hw->nchannels = stereo ? 2 : 1;
- hw->fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
- hw->bufsize = 4096;
- wav->pcm_buf = qemu_mallocz (hw->bufsize);
- if (!wav->pcm_buf)
+
+ audio_pcm_init_info (&hw->info, &wav_as, audio_need_to_swap_endian (0));
+
+ hw->samples = 1024;
+ wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);
+ if (!wav->pcm_buf) {
+ dolog ("Could not allocate buffer (%d bytes)\n",
+ hw->samples << hw->info.shift);
return -1;
-
- le_store (hdr + 22, hw->nchannels, 2);
- le_store (hdr + 24, hw->freq, 4);
- le_store (hdr + 28, hw->freq << (bits16 + stereo), 4);
+ }
+
+ le_store (hdr + 22, hw->info.nchannels, 2);
+ le_store (hdr + 24, hw->info.freq, 4);
+ le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4);
le_store (hdr + 32, 1 << (bits16 + stereo), 2);
wav->f = fopen (conf.wav_path, "wb");
if (!wav->f) {
- dolog ("failed to open wave file `%s'\nReason: %s\n",
+ dolog ("Failed to open wave file `%s'\nReason: %s\n",
conf.wav_path, strerror (errno));
qemu_free (wav->pcm_buf);
wav->pcm_buf = NULL;
@@ -153,17 +164,17 @@ static int wav_hw_init (HWVoice *hw, int
return 0;
}
-static void wav_hw_fini (HWVoice *hw)
-{
- WAVVoice *wav = (WAVVoice *) hw;
- int stereo = hw->nchannels == 2;
+static void wav_fini_out (HWVoiceOut *hw)
+{
+ WAVVoiceOut *wav = (WAVVoiceOut *) hw;
uint8_t rlen[4];
uint8_t dlen[4];
- uint32_t rifflen = (wav->total_samples << stereo) + 36;
- uint32_t datalen = wav->total_samples << stereo;
-
- if (!wav->f || !hw->active)
+ uint32_t datalen = wav->total_samples << hw->info.shift;
+ uint32_t rifflen = datalen + 36;
+
+ if (!wav->f) {
return;
+ }
le_store (rlen, rifflen, 4);
le_store (dlen, datalen, 4);
@@ -181,7 +192,7 @@ static void wav_hw_fini (HWVoice *hw)
wav->pcm_buf = NULL;
}
-static int wav_hw_ctl (HWVoice *hw, int cmd, ...)
+static int wav_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
(void) hw;
(void) cmd;
@@ -195,23 +206,50 @@ static void *wav_audio_init (void)
static void wav_audio_fini (void *opaque)
{
+ (void) opaque;
ldebug ("wav_fini");
}
-struct pcm_ops wav_pcm_ops = {
- wav_hw_init,
- wav_hw_fini,
- wav_hw_run,
- wav_hw_write,
- wav_hw_ctl
-};
-
-struct audio_output_driver wav_output_driver = {
- "wav",
- wav_audio_init,
- wav_audio_fini,
- &wav_pcm_ops,
- 1,
- 1,
- sizeof (WAVVoice)
-};
+struct audio_option wav_options[] = {
+ {"FREQUENCY", AUD_OPT_INT, &conf.settings.freq,
+ "Frequency", NULL, 0},
+
+ {"FORMAT", AUD_OPT_FMT, &conf.settings.fmt,
+ "Format", NULL, 0},
+
+ {"DAC_FIXED_CHANNELS", AUD_OPT_INT, &conf.settings.nchannels,
+ "Number of channels (1 - mono, 2 - stereo)", NULL, 0},
+
+ {"PATH", AUD_OPT_STR, &conf.wav_path,
+ "Path to wave file", NULL, 0},
+ {NULL, 0, NULL, NULL, NULL, 0}
+};
+
+struct audio_pcm_ops wav_pcm_ops = {
+ wav_init_out,
+ wav_fini_out,
+ wav_run_out,
+ wav_write_out,
+ wav_ctl_out,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+struct audio_driver wav_audio_driver = {
+ INIT_FIELD (name = ) "wav",
+ INIT_FIELD (descr = )
+ "WAV renderer http://wikipedia.org/wiki/WAV",
+ INIT_FIELD (options = ) wav_options,
+ INIT_FIELD (init = ) wav_audio_init,
+ INIT_FIELD (fini = ) wav_audio_fini,
+ INIT_FIELD (pcm_ops = ) &wav_pcm_ops,
+ INIT_FIELD (can_be_default = ) 0,
+ INIT_FIELD (max_voices_out = ) 1,
+ INIT_FIELD (max_voices_in = ) 0,
+ INIT_FIELD (voice_size_out = ) sizeof (WAVVoiceOut),
+ INIT_FIELD (voice_size_in = ) 0
+};
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/block-cloop.c
--- a/tools/ioemu/block-cloop.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/block-cloop.c Tue Jul 25 12:19:05 2006 -0600
@@ -1,5 +1,5 @@
/*
- * QEMU System Emulator block driver
+ * QEMU Block driver for CLOOP images
*
* Copyright (c) 2004 Johannes E. Schindelin
*
@@ -32,8 +32,8 @@ typedef struct BDRVCloopState {
uint64_t* offsets;
uint32_t sectors_per_block;
uint32_t current_block;
- char* compressed_block;
- char* uncompressed_block;
+ uint8_t *compressed_block;
+ uint8_t *uncompressed_block;
z_stream zstream;
} BDRVCloopState;
@@ -89,9 +89,9 @@ cloop_close:
}
/* initialize zlib engine */
- if(!(s->compressed_block=(char*)malloc(max_compressed_block_size+1)))
+ if(!(s->compressed_block = malloc(max_compressed_block_size+1)))
goto cloop_close;
- if(!(s->uncompressed_block=(char*)malloc(s->block_size)))
+ if(!(s->uncompressed_block = malloc(s->block_size)))
goto cloop_close;
if(inflateInit(&s->zstream) != Z_OK)
goto cloop_close;
@@ -149,6 +149,8 @@ static void cloop_close(BlockDriverState
{
BDRVCloopState *s = bs->opaque;
close(s->fd);
+ if(s->n_blocks>0)
+ free(s->offsets);
free(s->compressed_block);
free(s->uncompressed_block);
inflateEnd(&s->zstream);
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/block-cow.c
--- a/tools/ioemu/block-cow.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/block-cow.c Tue Jul 25 12:19:05 2006 -0600
@@ -54,7 +54,8 @@ static int cow_probe(const uint8_t *buf,
{
const struct cow_header_v2 *cow_header = (const void *)buf;
- if (be32_to_cpu(cow_header->magic) == COW_MAGIC &&
+ if (buf_size >= sizeof(struct cow_header_v2) &&
+ be32_to_cpu(cow_header->magic) == COW_MAGIC &&
be32_to_cpu(cow_header->version) == COW_VERSION)
return 100;
else
@@ -124,7 +125,7 @@ static int cow_open(BlockDriverState *bs
return -1;
}
-static inline void set_bit(uint8_t *bitmap, int64_t bitnum)
+static inline void cow_set_bit(uint8_t *bitmap, int64_t bitnum)
{
bitmap[bitnum / 8] |= (1 << (bitnum%8));
}
@@ -198,7 +199,7 @@ static int cow_write(BlockDriverState *b
if (ret != nb_sectors * 512)
return -1;
for (i = 0; i < nb_sectors; i++)
- set_bit(s->cow_bitmap, sector_num + i);
+ cow_set_bit(s->cow_bitmap, sector_num + i);
return 0;
}
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/block-qcow.c
--- a/tools/ioemu/block-qcow.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/block-qcow.c Tue Jul 25 12:19:05 2006 -0600
@@ -80,8 +80,9 @@ static int qcow_probe(const uint8_t *buf
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
const QCowHeader *cow_header = (const void *)buf;
-
- if (be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
+
+ if (buf_size >= sizeof(QCowHeader) &&
+ be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
be32_to_cpu(cow_header->version) == QCOW_VERSION)
return 100;
else
@@ -551,15 +552,28 @@ static int qcow_create(const char *filen
header_size = sizeof(header);
backing_filename_len = 0;
if (backing_file) {
- realpath(backing_file, backing_filename);
- if (stat(backing_filename, &st) != 0) {
- return -1;
- }
+ if (strcmp(backing_file, "fat:")) {
+ const char *p;
+ /* XXX: this is a hack: we do not attempt to check for URL
+ like syntax */
+ p = strchr(backing_file, ':');
+ if (p && (p - backing_file) >= 2) {
+ /* URL like but exclude "c:" like filenames */
+ pstrcpy(backing_filename, sizeof(backing_filename),
+ backing_file);
+ } else {
+ realpath(backing_file, backing_filename);
+ if (stat(backing_filename, &st) != 0) {
+ return -1;
+ }
+ }
+ header.backing_file_offset = cpu_to_be64(header_size);
+ backing_filename_len = strlen(backing_filename);
+ header.backing_file_size = cpu_to_be32(backing_filename_len);
+ header_size += backing_filename_len;
+ } else
+ backing_file = NULL;
header.mtime = cpu_to_be32(st.st_mtime);
- header.backing_file_offset = cpu_to_be64(header_size);
- backing_filename_len = strlen(backing_filename);
- header.backing_file_size = cpu_to_be32(backing_filename_len);
- header_size += backing_filename_len;
header.cluster_bits = 9; /* 512 byte cluster to avoid copying
unmodifyed sectors */
header.l2_bits = 12; /* 32 KB L2 tables */
@@ -589,6 +603,24 @@ static int qcow_create(const char *filen
write(fd, &tmp, sizeof(tmp));
}
close(fd);
+ return 0;
+}
+
+int qcow_make_empty(BlockDriverState *bs)
+{
+ BDRVQcowState *s = bs->opaque;
+ uint32_t l1_length = s->l1_size * sizeof(uint64_t);
+
+ memset(s->l1_table, 0, l1_length);
+ lseek(s->fd, s->l1_table_offset, SEEK_SET);
+ if (write(s->fd, s->l1_table, l1_length) < 0)
+ return -1;
+ ftruncate(s->fd, s->l1_table_offset + l1_length);
+
+ memset(s->l2_cache, 0, s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
+ memset(s->l2_cache_offsets, 0, L2_CACHE_SIZE * sizeof(uint64_t));
+ memset(s->l2_cache_counts, 0, L2_CACHE_SIZE * sizeof(uint32_t));
+
return 0;
}
@@ -672,6 +704,7 @@ BlockDriver bdrv_qcow = {
qcow_create,
qcow_is_allocated,
qcow_set_key,
+ qcow_make_empty
};
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/block-vmdk.c
--- a/tools/ioemu/block-vmdk.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/block-vmdk.c Tue Jul 25 12:19:05 2006 -0600
@@ -2,6 +2,7 @@
* Block driver for the VMDK format
*
* Copyright (c) 2004 Fabrice Bellard
+ * Copyright (c) 2005 Filip Navara
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
deal
@@ -24,9 +25,6 @@
#include "vl.h"
#include "block_int.h"
-/* XXX: this code is untested */
-/* XXX: add write support */
-
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
@@ -56,14 +54,16 @@ typedef struct {
int64_t grain_offset;
char filler[1];
char check_bytes[4];
-} VMDK4Header;
+} __attribute__((packed)) VMDK4Header;
#define L2_CACHE_SIZE 16
typedef struct BDRVVmdkState {
int fd;
int64_t l1_table_offset;
+ int64_t l1_backup_table_offset;
uint32_t *l1_table;
+ uint32_t *l1_backup_table;
unsigned int l1_size;
uint32_t l1_entry_sectors;
@@ -96,9 +96,13 @@ static int vmdk_open(BlockDriverState *b
uint32_t magic;
int l1_size;
- fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return -1;
+ fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+ if (fd < 0) {
+ fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+ if (fd < 0)
+ return -1;
+ bs->read_only = 1;
+ }
if (read(fd, &magic, sizeof(magic)) != sizeof(magic))
goto fail;
magic = be32_to_cpu(magic);
@@ -111,22 +115,24 @@ static int vmdk_open(BlockDriverState *b
s->l2_size = 1 << 9;
s->l1_size = 1 << 6;
bs->total_sectors = le32_to_cpu(header.disk_sectors);
- s->l1_table_offset = le32_to_cpu(header.l1dir_offset) * 512;
+ s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;
+ s->l1_backup_table_offset = 0;
s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
} else if (magic == VMDK4_MAGIC) {
VMDK4Header header;
if (read(fd, &header, sizeof(header)) != sizeof(header))
goto fail;
- bs->total_sectors = le32_to_cpu(header.capacity);
- s->cluster_sectors = le32_to_cpu(header.granularity);
+ bs->total_sectors = le64_to_cpu(header.capacity);
+ s->cluster_sectors = le64_to_cpu(header.granularity);
s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
if (s->l1_entry_sectors <= 0)
goto fail;
s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
/ s->l1_entry_sectors;
- s->l1_table_offset = le64_to_cpu(header.rgd_offset) * 512;
+ s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
+ s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
} else {
goto fail;
}
@@ -143,14 +149,26 @@ static int vmdk_open(BlockDriverState *b
le32_to_cpus(&s->l1_table[i]);
}
+ if (s->l1_backup_table_offset) {
+ s->l1_backup_table = qemu_malloc(l1_size);
+ if (!s->l1_backup_table)
+ goto fail;
+ if (lseek(fd, s->l1_backup_table_offset, SEEK_SET) == -1)
+ goto fail;
+ if (read(fd, s->l1_backup_table, l1_size) != l1_size)
+ goto fail;
+ for(i = 0; i < s->l1_size; i++) {
+ le32_to_cpus(&s->l1_backup_table[i]);
+ }
+ }
+
s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
if (!s->l2_cache)
goto fail;
s->fd = fd;
- /* XXX: currently only read only */
- bs->read_only = 1;
return 0;
fail:
+ qemu_free(s->l1_backup_table);
qemu_free(s->l1_table);
qemu_free(s->l2_cache);
close(fd);
@@ -158,12 +176,12 @@ static int vmdk_open(BlockDriverState *b
}
static uint64_t get_cluster_offset(BlockDriverState *bs,
- uint64_t offset)
+ uint64_t offset, int allocate)
{
BDRVVmdkState *s = bs->opaque;
unsigned int l1_index, l2_offset, l2_index;
int min_index, i, j;
- uint32_t min_count, *l2_table;
+ uint32_t min_count, *l2_table, tmp;
uint64_t cluster_offset;
l1_index = (offset >> 9) / s->l1_entry_sectors;
@@ -172,7 +190,6 @@ static uint64_t get_cluster_offset(Block
l2_offset = s->l1_table[l1_index];
if (!l2_offset)
return 0;
-
for(i = 0; i < L2_CACHE_SIZE; i++) {
if (l2_offset == s->l2_cache_offsets[i]) {
/* increment the hit count */
@@ -204,6 +221,26 @@ static uint64_t get_cluster_offset(Block
found:
l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
cluster_offset = le32_to_cpu(l2_table[l2_index]);
+ if (!cluster_offset) {
+ if (!allocate)
+ return 0;
+ cluster_offset = lseek(s->fd, 0, SEEK_END);
+ ftruncate(s->fd, cluster_offset + (s->cluster_sectors << 9));
+ cluster_offset >>= 9;
+ /* update L2 table */
+ tmp = cpu_to_le32(cluster_offset);
+ l2_table[l2_index] = tmp;
+ lseek(s->fd, ((int64_t)l2_offset * 512) + (l2_index * sizeof(tmp)),
SEEK_SET);
+ if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+ return 0;
+ /* update backup L2 table */
+ if (s->l1_backup_table_offset != 0) {
+ l2_offset = s->l1_backup_table[l1_index];
+ lseek(s->fd, ((int64_t)l2_offset * 512) + (l2_index *
sizeof(tmp)), SEEK_SET);
+ if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+ return 0;
+ }
+ }
cluster_offset <<= 9;
return cluster_offset;
}
@@ -215,7 +252,7 @@ static int vmdk_is_allocated(BlockDriver
int index_in_cluster, n;
uint64_t cluster_offset;
- cluster_offset = get_cluster_offset(bs, sector_num << 9);
+ cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);
index_in_cluster = sector_num % s->cluster_sectors;
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
@@ -232,7 +269,7 @@ static int vmdk_read(BlockDriverState *b
uint64_t cluster_offset;
while (nb_sectors > 0) {
- cluster_offset = get_cluster_offset(bs, sector_num << 9);
+ cluster_offset = get_cluster_offset(bs, sector_num << 9, 0);
index_in_cluster = sector_num % s->cluster_sectors;
n = s->cluster_sectors - index_in_cluster;
if (n > nb_sectors)
@@ -255,7 +292,130 @@ static int vmdk_write(BlockDriverState *
static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
{
- return -1;
+ BDRVVmdkState *s = bs->opaque;
+ int ret, index_in_cluster, n;
+ uint64_t cluster_offset;
+
+ while (nb_sectors > 0) {
+ index_in_cluster = sector_num & (s->cluster_sectors - 1);
+ n = s->cluster_sectors - index_in_cluster;
+ if (n > nb_sectors)
+ n = nb_sectors;
+ cluster_offset = get_cluster_offset(bs, sector_num << 9, 1);
+ if (!cluster_offset)
+ return -1;
+ lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
+ ret = write(s->fd, buf, n * 512);
+ if (ret != n * 512)
+ return -1;
+ nb_sectors -= n;
+ sector_num += n;
+ buf += n * 512;
+ }
+ return 0;
+}
+
+static int vmdk_create(const char *filename, int64_t total_size,
+ const char *backing_file, int flags)
+{
+ int fd, i;
+ VMDK4Header header;
+ uint32_t tmp, magic, grains, gd_size, gt_size, gt_count;
+ char *desc_template =
+ "# Disk DescriptorFile\n"
+ "version=1\n"
+ "CID=%x\n"
+ "parentCID=ffffffff\n"
+ "createType=\"monolithicSparse\"\n"
+ "\n"
+ "# Extent description\n"
+ "RW %lu SPARSE \"%s\"\n"
+ "\n"
+ "# The Disk Data Base \n"
+ "#DDB\n"
+ "\n"
+ "ddb.virtualHWVersion = \"3\"\n"
+ "ddb.geometry.cylinders = \"%lu\"\n"
+ "ddb.geometry.heads = \"16\"\n"
+ "ddb.geometry.sectors = \"63\"\n"
+ "ddb.adapterType = \"ide\"\n";
+ char desc[1024];
+ const char *real_filename, *temp_str;
+
+ /* XXX: add support for backing file */
+
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
+ 0644);
+ if (fd < 0)
+ return -1;
+ magic = cpu_to_be32(VMDK4_MAGIC);
+ memset(&header, 0, sizeof(header));
+ header.version = cpu_to_le32(1);
+ header.flags = cpu_to_le32(3); /* ?? */
+ header.capacity = cpu_to_le64(total_size);
+ header.granularity = cpu_to_le64(128);
+ header.num_gtes_per_gte = cpu_to_le32(512);
+
+ grains = (total_size + header.granularity - 1) / header.granularity;
+ gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
+ gt_count = (grains + header.num_gtes_per_gte - 1) /
header.num_gtes_per_gte;
+ gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
+
+ header.desc_offset = 1;
+ header.desc_size = 20;
+ header.rgd_offset = header.desc_offset + header.desc_size;
+ header.gd_offset = header.rgd_offset + gd_size + (gt_size * gt_count);
+ header.grain_offset =
+ ((header.gd_offset + gd_size + (gt_size * gt_count) +
+ header.granularity - 1) / header.granularity) *
+ header.granularity;
+
+ header.desc_offset = cpu_to_le64(header.desc_offset);
+ header.desc_size = cpu_to_le64(header.desc_size);
+ header.rgd_offset = cpu_to_le64(header.rgd_offset);
+ header.gd_offset = cpu_to_le64(header.gd_offset);
+ header.grain_offset = cpu_to_le64(header.grain_offset);
+
+ header.check_bytes[0] = 0xa;
+ header.check_bytes[1] = 0x20;
+ header.check_bytes[2] = 0xd;
+ header.check_bytes[3] = 0xa;
+
+ /* write all the data */
+ write(fd, &magic, sizeof(magic));
+ write(fd, &header, sizeof(header));
+
+ ftruncate(fd, header.grain_offset << 9);
+
+ /* write grain directory */
+ lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
+ for (i = 0, tmp = header.rgd_offset + gd_size;
+ i < gt_count; i++, tmp += gt_size)
+ write(fd, &tmp, sizeof(tmp));
+
+ /* write backup grain directory */
+ lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
+ for (i = 0, tmp = header.gd_offset + gd_size;
+ i < gt_count; i++, tmp += gt_size)
+ write(fd, &tmp, sizeof(tmp));
+
+ /* compose the descriptor */
+ real_filename = filename;
+ if ((temp_str = strrchr(real_filename, '\\')) != NULL)
+ real_filename = temp_str + 1;
+ if ((temp_str = strrchr(real_filename, '/')) != NULL)
+ real_filename = temp_str + 1;
+ if ((temp_str = strrchr(real_filename, ':')) != NULL)
+ real_filename = temp_str + 1;
+ sprintf(desc, desc_template, time(NULL), (unsigned long)total_size,
+ real_filename, total_size / (63 * 16));
+
+ /* write the descriptor */
+ lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
+ write(fd, desc, strlen(desc));
+
+ close(fd);
+ return 0;
}
static void vmdk_close(BlockDriverState *bs)
@@ -274,6 +434,6 @@ BlockDriver bdrv_vmdk = {
vmdk_read,
vmdk_write,
vmdk_close,
- NULL, /* no create yet */
+ vmdk_create,
vmdk_is_allocated,
};
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/block.c
--- a/tools/ioemu/block.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/block.c Tue Jul 25 12:19:05 2006 -0600
@@ -24,8 +24,90 @@
#include "vl.h"
#include "block_int.h"
+#ifdef _BSD
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/queue.h>
+#include <sys/disk.h>
+#endif
+
+#ifdef CONFIG_COCOA
+#include <paths.h>
+#include <sys/param.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOBSD.h>
+#include <IOKit/storage/IOMediaBSDClient.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/storage/IOCDMedia.h>
+//#include <IOKit/storage/IOCDTypes.h>
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#ifdef __sun__
+#include <sys/dkio.h>
+#endif
+
static BlockDriverState *bdrv_first;
static BlockDriver *first_drv;
+
+#ifdef CONFIG_COCOA
+static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
+static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath,
CFIndex maxPathSize );
+
+kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
+{
+ kern_return_t kernResult;
+ mach_port_t masterPort;
+ CFMutableDictionaryRef classesToMatch;
+
+ kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
+ if ( KERN_SUCCESS != kernResult ) {
+ printf( "IOMasterPort returned %d\n", kernResult );
+ }
+
+ classesToMatch = IOServiceMatching( kIOCDMediaClass );
+ if ( classesToMatch == NULL ) {
+ printf( "IOServiceMatching returned a NULL dictionary.\n" );
+ } else {
+ CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ),
kCFBooleanTrue );
+ }
+ kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch,
mediaIterator );
+ if ( KERN_SUCCESS != kernResult )
+ {
+ printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
+ }
+
+ return kernResult;
+}
+
+kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex
maxPathSize )
+{
+ io_object_t nextMedia;
+ kern_return_t kernResult = KERN_FAILURE;
+ *bsdPath = '\0';
+ nextMedia = IOIteratorNext( mediaIterator );
+ if ( nextMedia )
+ {
+ CFTypeRef bsdPathAsCFString;
+ bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR(
kIOBSDNameKey ), kCFAllocatorDefault, 0 );
+ if ( bsdPathAsCFString ) {
+ size_t devPathLength;
+ strcpy( bsdPath, _PATH_DEV );
+ strcat( bsdPath, "r" );
+ devPathLength = strlen( bsdPath );
+ if ( CFStringGetCString( bsdPathAsCFString, bsdPath +
devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
+ kernResult = KERN_SUCCESS;
+ }
+ CFRelease( bsdPathAsCFString );
+ }
+ IOObjectRelease( nextMedia );
+ }
+
+ return kernResult;
+}
+
+#endif
void bdrv_register(BlockDriver *bdrv)
{
@@ -71,21 +153,68 @@ int bdrv_create(BlockDriver *drv,
return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
}
+#ifdef _WIN32
+void get_tmp_filename(char *filename, int size)
+{
+ char* p = strrchr(filename, '/');
+
+ if (p == NULL)
+ return;
+
+ /* XXX: find a better function */
+ tmpnam(p);
+ *p = '/';
+}
+#else
+void get_tmp_filename(char *filename, int size)
+{
+ int fd;
+ /* XXX: race condition possible */
+ pstrcpy(filename, size, "/tmp/vl.XXXXXX");
+ fd = mkstemp(filename);
+ close(fd);
+}
+#endif
+
+/* XXX: force raw format if block or character device ? It would
+ simplify the BSD case */
static BlockDriver *find_image_format(const char *filename)
{
int fd, ret, score, score_max;
BlockDriver *drv1, *drv;
- uint8_t buf[1024];
+ uint8_t *buf;
+ size_t bufsize = 1024;
fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return NULL;
- ret = read(fd, buf, sizeof(buf));
- if (ret < 0) {
+ if (fd < 0) {
+ buf = NULL;
+ ret = 0;
+ } else {
+#ifdef DIOCGSECTORSIZE
+ {
+ unsigned int sectorsize = 512;
+ if (!ioctl(fd, DIOCGSECTORSIZE, §orsize) &&
+ sectorsize > bufsize)
+ bufsize = sectorsize;
+ }
+#endif
+#ifdef CONFIG_COCOA
+ u_int32_t blockSize = 512;
+ if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize >
bufsize) {
+ bufsize = blockSize;
+ }
+#endif
+ buf = qemu_malloc(bufsize);
+ if (!buf)
+ return NULL;
+ ret = read(fd, buf, bufsize);
+ if (ret < 0) {
+ close(fd);
+ qemu_free(buf);
+ return NULL;
+ }
close(fd);
- return NULL;
- }
- close(fd);
+ }
drv = NULL;
score_max = 0;
@@ -96,11 +225,38 @@ static BlockDriver *find_image_format(co
drv = drv1;
}
}
+ qemu_free(buf);
return drv;
}
int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
{
+#ifdef CONFIG_COCOA
+ if ( strncmp( filename, "/dev/cdrom", 10 ) == 0 ) {
+ kern_return_t kernResult;
+ io_iterator_t mediaIterator;
+ char bsdPath[ MAXPATHLEN ];
+ int fd;
+
+ kernResult = FindEjectableCDMedia( &mediaIterator );
+ kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
+
+ if ( bsdPath[ 0 ] != '\0' ) {
+ strcat(bsdPath,"s0");
+ /* some CDs don't have a partition 0 */
+ fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
+ if (fd < 0) {
+ bsdPath[strlen(bsdPath)-1] = '1';
+ } else {
+ close(fd);
+ }
+ filename = bsdPath;
+ }
+
+ if ( mediaIterator )
+ IOObjectRelease( mediaIterator );
+ }
+#endif
return bdrv_open2(bs, filename, snapshot, NULL);
}
@@ -108,11 +264,41 @@ int bdrv_open2(BlockDriverState *bs, con
BlockDriver *drv)
{
int ret;
+ char tmp_filename[1024];
bs->read_only = 0;
bs->is_temporary = 0;
bs->encrypted = 0;
-
+
+ if (snapshot) {
+ BlockDriverState *bs1;
+ int64_t total_size;
+
+ /* if snapshot, we create a temporary backing file and open it
+ instead of opening 'filename' directly */
+
+ /* if there is a backing file, use it */
+ bs1 = bdrv_new("");
+ if (!bs1) {
+ return -1;
+ }
+ if (bdrv_open(bs1, filename, 0) < 0) {
+ bdrv_delete(bs1);
+ return -1;
+ }
+ total_size = bs1->total_sectors;
+ bdrv_delete(bs1);
+
+ get_tmp_filename(tmp_filename, sizeof(tmp_filename));
+ /* XXX: use cow for linux as it is more efficient ? */
+ if (bdrv_create(&bdrv_qcow, tmp_filename,
+ total_size, filename, 0) < 0) {
+ return -1;
+ }
+ filename = tmp_filename;
+ bs->is_temporary = 1;
+ }
+
pstrcpy(bs->filename, sizeof(bs->filename), filename);
if (!drv) {
drv = find_image_format(filename);
@@ -218,6 +404,10 @@ int bdrv_commit(BlockDriverState *bs)
i += n;
}
}
+
+ if (bs->drv->bdrv_make_empty)
+ return bs->drv->bdrv_make_empty(bs);
+
return 0;
}
@@ -268,6 +458,9 @@ int bdrv_write(BlockDriverState *bs, int
return -1;
if (bs->read_only)
return -1;
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(bs->boot_sector_data, buf, 512);
+ }
return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors);
}
@@ -301,6 +494,11 @@ void bdrv_set_type_hint(BlockDriverState
type == BDRV_TYPE_FLOPPY));
}
+void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
+{
+ bs->translation = translation;
+}
+
void bdrv_get_geometry_hint(BlockDriverState *bs,
int *pcyls, int *pheads, int *psecs)
{
@@ -312,6 +510,11 @@ int bdrv_get_type_hint(BlockDriverState
int bdrv_get_type_hint(BlockDriverState *bs)
{
return bs->type;
+}
+
+int bdrv_get_translation_hint(BlockDriverState *bs)
+{
+ return bs->translation;
}
int bdrv_is_removable(BlockDriverState *bs)
@@ -449,7 +652,6 @@ void bdrv_info(void)
}
}
-
/**************************************************************/
/* RAW block driver */
@@ -467,6 +669,13 @@ static int raw_open(BlockDriverState *bs
BDRVRawState *s = bs->opaque;
int fd;
int64_t size;
+#ifdef _BSD
+ struct stat sb;
+#endif
+#ifdef __sun__
+ struct dk_minfo minfo;
+ int rv;
+#endif
fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
if (fd < 0) {
@@ -475,7 +684,38 @@ static int raw_open(BlockDriverState *bs
return -1;
bs->read_only = 1;
}
- size = lseek(fd, 0, SEEK_END);
+#ifdef _BSD
+ if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
+#ifdef DIOCGMEDIASIZE
+ if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
+#endif
+#ifdef CONFIG_COCOA
+ size = LONG_LONG_MAX;
+#else
+ size = lseek(fd, 0LL, SEEK_END);
+#endif
+ } else
+#endif
+#ifdef __sun__
+ /*
+ * use the DKIOCGMEDIAINFO ioctl to read the size.
+ */
+ rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
+ if ( rv != -1 ) {
+ size = minfo.dki_lbsize * minfo.dki_capacity;
+ } else /* there are reports that lseek on some devices
+ fails, but irc discussion said that contingency
+ on contingency was overkill */
+#endif
+ {
+ size = lseek(fd, 0, SEEK_END);
+ }
+#ifdef _WIN32
+ /* On Windows hosts it can happen that we're unable to get file size
+ for CD-ROM raw device (it's inherent limitation of the CDFS driver). */
+ if (size == -1)
+ size = LONG_LONG_MAX;
+#endif
bs->total_sectors = size / 512;
s->fd = fd;
return 0;
@@ -544,6 +784,14 @@ void bdrv_init(void)
void bdrv_init(void)
{
bdrv_register(&bdrv_raw);
+#ifndef _WIN32
+ bdrv_register(&bdrv_cow);
+#endif
bdrv_register(&bdrv_qcow);
+ bdrv_register(&bdrv_vmdk);
bdrv_register(&bdrv_cloop);
-}
+ bdrv_register(&bdrv_dmg);
+ bdrv_register(&bdrv_bochs);
+ bdrv_register(&bdrv_vpc);
+ bdrv_register(&bdrv_vvfat);
+}
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/block_int.h
--- a/tools/ioemu/block_int.h Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/block_int.h Tue Jul 25 12:19:05 2006 -0600
@@ -39,6 +39,7 @@ struct BlockDriver {
int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum);
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
+ int (*bdrv_make_empty)(BlockDriverState *bs);
struct BlockDriver *next;
};
@@ -68,10 +69,12 @@ struct BlockDriverState {
/* NOTE: the following infos are only hints for real hardware
drivers. They are not used by the block driver */
- int cyls, heads, secs;
+ int cyls, heads, secs, translation;
int type;
char device_name[32];
BlockDriverState *next;
};
+void get_tmp_filename(char *filename, int size);
+
#endif /* BLOCK_INT_H */
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/configure
--- a/tools/ioemu/configure Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/configure Tue Jul 25 12:19:05 2006 -0600
@@ -25,14 +25,18 @@ host_cc="gcc"
host_cc="gcc"
ar="ar"
make="make"
+install="install"
strip="strip"
cpu=`uname -m`
-target_list="target-i386-dm"
+target_list=""
case "$cpu" in
i386|i486|i586|i686|i86pc|BePC)
cpu="i386"
;;
- armv4l)
+ armv*b)
+ cpu="armv4b"
+ ;;
+ armv*l)
cpu="armv4l"
;;
alpha)
@@ -47,7 +51,7 @@ case "$cpu" in
s390)
cpu="s390"
;;
- sparc)
+ sparc|sun4[muv])
cpu="sparc"
;;
sparc64)
@@ -60,7 +64,7 @@ case "$cpu" in
cpu="m68k"
;;
x86_64|amd64)
- cpu="amd64"
+ cpu="x86_64"
libdir="lib64"
;;
*)
@@ -75,19 +79,40 @@ slirp="no"
slirp="no"
adlib="no"
oss="no"
+dsound="no"
+coreaudio="no"
+alsa="no"
fmod="no"
fmod_lib=""
fmod_inc=""
+bsd="no"
+linux="no"
+kqemu="no"
+profiler="no"
+kernel_path=""
+cocoa="no"
+check_gfx="yes"
+check_gcc="no"
+softmmu="yes"
+user="no"
+build_docs="no"
# OS specific
targetos=`uname -s`
case $targetos in
+CYGWIN*)
+mingw32="yes"
+CFLAGS="-O2 -mno-cygwin"
+;;
MINGW32*)
mingw32="yes"
;;
FreeBSD)
bsd="yes"
oss="yes"
+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+ kqemu="yes"
+fi
;;
NetBSD)
bsd="yes"
@@ -101,52 +126,73 @@ bsd="yes"
bsd="yes"
darwin="yes"
;;
-*)
+SunOS)
+solaris="yes"
+;;
+*)
oss="yes"
+linux="yes"
+user="yes"
+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+ kqemu="yes"
+fi
;;
esac
if [ "$bsd" = "yes" ] ; then
- if [ ! "$darwin" = "yes" ] ; then
+ if [ "$darwin" != "yes" ] ; then
make="gmake"
fi
- target_list="i386-softmmu ppc-softmmu sparc-softmmu"
+fi
+
+if [ "$solaris" = "yes" ] ; then
+ make="gmake"
+ install="ginstall"
+ solarisrev=`uname -r | cut -f2 -d.`
fi
# find source path
-# XXX: we assume an absolute path is given when launching configure,
-# except in './configure' case.
-source_path=${0%configure}
-source_path=${source_path%/}
-source_path_used="yes"
-if test -z "$source_path" -o "$source_path" = "." ; then
+source_path=`dirname "$0"`
+if [ -z "$source_path" ]; then
source_path=`pwd`
+else
+ source_path=`cd "$source_path"; pwd`
+fi
+if test "$source_path" = `pwd` ; then
source_path_used="no"
+else
+ source_path_used="yes"
fi
for opt do
+ optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
case "$opt" in
- --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
- ;;
- --interp-prefix=*) interp_prefix=`echo $opt | cut -d '=' -f 2`
- ;;
- --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
- ;;
- --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
- ;;
- --cc=*) cc=`echo $opt | cut -d '=' -f 2`
- ;;
- --make=*) make=`echo $opt | cut -d '=' -f 2`
- ;;
- --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
- ;;
- --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
- ;;
- --extra-libs=*) extralibs=${opt#--extra-libs=}
- ;;
- --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
- ;;
- --target-list=*) target_list=${opt#--target-list=}
+ --help|-h) show_help=yes
+ ;;
+ --prefix=*) prefix="$optarg"
+ ;;
+ --interp-prefix=*) interp_prefix="$optarg"
+ ;;
+ --source-path=*) source_path="$optarg"
+ source_path_used="yes"
+ ;;
+ --cross-prefix=*) cross_prefix="$optarg"
+ ;;
+ --cc=*) cc="$optarg"
+ ;;
+ --host-cc=*) host_cc="$optarg"
+ ;;
+ --make=*) make="$optarg"
+ ;;
+ --install=*) install="$optarg"
+ ;;
+ --extra-cflags=*) CFLAGS="$optarg"
+ ;;
+ --extra-ldflags=*) LDFLAGS="$optarg"
+ ;;
+ --cpu=*) cpu="$optarg"
+ ;;
+ --target-list=*) target_list="$optarg"
;;
--enable-gprof) gprof="yes"
;;
@@ -154,20 +200,44 @@ for opt do
;;
--disable-sdl) sdl="no"
;;
+ --enable-coreaudio) coreaudio="yes"
+ ;;
+ --enable-alsa) alsa="yes"
+ ;;
+ --enable-dsound) dsound="yes"
+ ;;
--enable-fmod) fmod="yes"
;;
- --fmod-lib=*) fmod_lib=${opt#--fmod-lib=}
- ;;
- --fmod-inc=*) fmod_inc=${opt#--fmod-inc=}
- ;;
- --disable-vnc) vnc="no"
+ --fmod-lib=*) fmod_lib="$optarg"
+ ;;
+ --fmod-inc=*) fmod_inc="$optarg"
;;
--enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
- ;;
+ ;;
--disable-slirp) slirp="no"
- ;;
+ ;;
--enable-adlib) adlib="yes"
- ;;
+ ;;
+ --disable-kqemu) kqemu="no"
+ ;;
+ --enable-profiler) profiler="yes"
+ ;;
+ --kernel-path=*) kernel_path="$optarg"
+ ;;
+ --enable-cocoa) cocoa="yes" ; coreaudio="yes" ; sdl="no"
+ ;;
+ --disable-gfx-check) check_gfx="no"
+ ;;
+ --disable-gcc-check) check_gcc="no"
+ ;;
+ --disable-system) softmmu="no"
+ ;;
+ --enable-system) softmmu="yes"
+ ;;
+ --disable-user) user="no"
+ ;;
+ --enable-user) user="yes"
+ ;;
esac
done
@@ -176,16 +246,130 @@ if test -z "$CFLAGS"; then
CFLAGS="-O2"
fi
+if test x"$show_help" = x"yes" ; then
+cat << EOF
+
+Usage: configure [options]
+Options: [defaults in brackets after descriptions]
+
+EOF
+echo "Standard options:"
+echo " --help print this message"
+echo " --prefix=PREFIX install in PREFIX [$prefix]"
+echo " --interp-prefix=PREFIX where to find shared libraries, etc."
+echo " use %M for cpu name [$interp_prefix]"
+echo " --target-list=LIST set target list [$target_list]"
+echo ""
+echo "kqemu kernel acceleration support:"
+echo " --disable-kqemu disable kqemu support"
+echo " --kernel-path=PATH set the kernel path (configure probes it)"
+echo ""
+echo "Advanced options (experts only):"
+echo " --source-path=PATH path of source code [$source_path]"
+echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
+echo " --cc=CC use C compiler CC [$cc]"
+echo " --host-cc=CC use C compiler CC [$host_cc] for dyngen etc."
+echo " --make=MAKE use specified make [$make]"
+echo " --install=INSTALL use specified install [$install]"
+echo " --static enable static build [$static]"
+echo " --enable-cocoa enable COCOA (Mac OS X only)"
+echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
+echo " --enable-adlib enable Adlib emulation"
+echo " --enable-coreaudio enable Coreaudio audio driver"
+echo " --enable-alsa enable ALSA audio driver"
+echo " --enable-fmod enable FMOD audio driver"
+echo " --enabled-dsound enable DirectSound audio driver"
+echo " --enable-system enable all system emulation targets"
+echo " --disable-system disable all system emulation targets"
+echo " --enable-user enable all linux usermode emulation targets"
+echo " --disable-user disable all linux usermode emulation targets"
+echo " --fmod-lib path to FMOD library"
+echo " --fmod-inc path to FMOD includes"
+echo ""
+echo "NOTE: The object files are build at the place where configure is
launched"
+exit 1
+fi
+
cc="${cross_prefix}${cc}"
ar="${cross_prefix}${ar}"
strip="${cross_prefix}${strip}"
+if [ ! -x "`which $cc`" ] ; then
+ echo "Compiler $cc could not be found"
+ exit
+fi
+
if test "$mingw32" = "yes" ; then
- target_list="i386-softmmu ppc-softmmu sparc-softmmu"
+ linux="no"
EXESUF=".exe"
gdbstub="no"
oss="no"
-fi
+ if [ "$cpu" = "i386" ] ; then
+ kqemu="yes"
+ fi
+fi
+
+#
+# Solaris specific configure tool chain decisions
+#
+if test "$solaris" = "yes" ; then
+ #
+ # gcc for solaris 10/fcs in /usr/sfw/bin doesn't compile qemu correctly
+ # override the check with --disable-gcc-check
+ #
+ if test "$solarisrev" -eq 10 -a "$check_gcc" = "yes" ; then
+ solgcc=`which $cc`
+ if test "$solgcc" = "/usr/sfw/bin/gcc" ; then
+ echo "Solaris 10/FCS gcc in /usr/sfw/bin will not compiled qemu
correctly."
+ echo "please get gcc-3.4.3 or later, from www.blastwave.org using
pkg-get -i gcc3"
+ echo "or get the latest patch from SunSolve for gcc"
+ exit 1
+ fi
+ fi
+ solinst=`which $install 2> /dev/null | /usr/bin/grep -v "no $install in"`
+ if test -z "$solinst" ; then
+ echo "Solaris install program not found. Use --install=/usr/ucb/install or"
+ echo "install fileutils from www.blastwave.org using pkg-get -i fileutils"
+ echo "to get ginstall which is used by default (which lives in
/opt/csw/bin)"
+ exit 1
+ fi
+ if test "$solinst" = "/usr/sbin/install" ; then
+ echo "Error: Solaris /usr/sbin/install is not an appropriate install
program."
+ echo "try ginstall from the GNU fileutils available from www.blastwave.org"
+ echo "using pkg-get -i fileutils, or use --install=/usr/ucb/install"
+ exit 1
+ fi
+ sol_ar=`which ar 2> /dev/null | /usr/bin/grep -v "no ar in"`
+ if test -z "$sol_ar" ; then
+ echo "Error: No path includes ar"
+ if test -f /usr/ccs/bin/ar ; then
+ echo "Add /usr/ccs/bin to your path and rerun configure"
+ fi
+ exit 1
+ fi
+fi
+
+
+if test -z "$target_list" ; then
+# these targets are portable
+ if [ "$softmmu" = "yes" ] ; then
+ target_list="i386-softmmu ppc-softmmu sparc-softmmu x86_64-softmmu
mips-softmmu mipsel-softmmu arm-softmmu"
+ fi
+# the following are Linux specific
+ if [ "$user" = "yes" ] ; then
+ target_list="i386-user arm-user armeb-user sparc-user ppc-user
mips-user mipsel-user $target_list"
+ fi
+# the i386-dm target
+ target_list="i386-dm"
+else
+ target_list=`echo "$target_list" | sed -e 's/,/ /g'`
+fi
+if test -z "$target_list" ; then
+ echo "No targets enabled"
+ exit 1
+fi
+
+kqemu="no"
if test -z "$cross_prefix" ; then
@@ -194,8 +378,8 @@ cat > $TMPC << EOF
cat > $TMPC << EOF
#include <inttypes.h>
int main(int argc, char ** argv){
- volatile uint32_t i=0x01234567;
- return (*((uint8_t*)(&i))) == 0x67;
+ volatile uint32_t i=0x01234567;
+ return (*((uint8_t*)(&i))) == 0x67;
}
EOF
@@ -208,10 +392,16 @@ else
else
# if cross compiling, cannot launch a program, so make a static guess
-if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" -o "$cpu" =
"sparc" -o "$cpu" = "sparc64" -o "$cpu" = "m68k"; then
+if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" -o "$cpu" =
"sparc" -o "$cpu" = "sparc64" -o "$cpu" = "m68k" -o "$cpu" = "armv4b"; then
bigendian="yes"
fi
+fi
+
+# host long bits test
+hostlongbits="32"
+if test "$cpu" = "sparc64" -o "$cpu" = "ia64" -o "$cpu" = "x86_64" -o "$cpu" =
"alpha"; then
+ hostlongbits="64"
fi
# check gcc options support
@@ -225,40 +415,21 @@ if $cc -fno-reorder-blocks -fno-optimize
have_gcc3_options="yes"
fi
-##########################################
-# VNC probe
-
-if test -z "$vnc"; then
-
-if libvncserver-config --version > /dev/null 2>&1; then
- vnc=yes
-else
- vnc=no
-fi
-
-fi
-
-if test "$vnc" = "yes" ; then
-
-# check for eager event handling
-cat > $TMPC <<EOF
-#include "rfb/rfb.h"
-int main(void) {
- rfbScreenInfoPtr screen;
-
- screen->handleEventsEagerly = 1;
-}
+# Check for gcc4, error if pre-gcc4
+if test "$check_gcc" = "yes" ; then
+ cat > $TMPC <<EOF
+#if __GNUC__ < 4
+#error gcc3
+#endif
+int main(){return 0;}
EOF
-
-if $cc `libvncserver-config --cflags` -o $TMPO $TMPC 2> /dev/null ; then
- have_eager_events="yes"
-else
- echo "!!"
- echo "!! Slow VNC mouse, LibVNCServer doesn't support eager events"
- echo "!!"
- have_eager_events="no"
-fi
-
+ if $cc -o $TMPO $TMPC 2>/dev/null ; then
+ echo "ERROR: \"$cc\" looks like gcc 4.x"
+ echo "QEMU is known to have problems when compiled with gcc 4.x"
+ echo "It is recommended that you use gcc 3.x to build QEMU"
+ echo "To use this compiler anyway, configure with --disable-gcc-check"
+ exit 1;
+ fi
fi
##########################################
@@ -312,45 +483,15 @@ fi # cross compilation
fi # cross compilation
fi # -z $sdl
-if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
-cat << EOF
-
-Usage: configure [options]
-Options: [defaults in brackets after descriptions]
-
-EOF
-echo "Standard options:"
-echo " --help print this message"
-echo " --prefix=PREFIX install in PREFIX [$prefix]"
-echo " --interp-prefix=PREFIX where to find shared libraries, etc."
-echo " use %M for cpu name [$interp_prefix]"
-echo " --target-list=LIST set target list [$target_list]"
-echo " --disable-vnc disable vnc support (else configure checks"
-echo " for libvncserver-config in your PATH)"
-echo ""
-echo "Advanced options (experts only):"
-echo " --source-path=PATH path of source code [$source_path]"
-echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
-echo " --cc=CC use C compiler CC [$cc]"
-echo " --make=MAKE use specified make [$make]"
-echo " --static enable static build [$static]"
-echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
-echo " --enable-fmod enable FMOD audio output driver"
-echo " --fmod-lib path to FMOD library"
-echo " --fmod-inc path to FMOD includes"
-echo ""
-echo "NOTE: The object files are build at the place where configure is
launched"
-exit 1
-fi
-
-#installroot=$source_path/../../dist/install
-installroot=
+# Check if tools are available to build documentation.
+if [ -x "`which texi2html`" ] && [ -x "`which pod2man`" ]; then
+ build_docs="yes"
+fi
if test "$mingw32" = "yes" ; then
if test -z "$prefix" ; then
prefix="/c/Program Files/Qemu"
fi
-
mandir="$prefix"
datadir="$prefix"
docdir="$prefix"
@@ -358,13 +499,13 @@ configdir=""
configdir=""
else
if test -z "$prefix" ; then
- prefix="usr/local"
-fi
-mandir="$installroot/$prefix/share/man"
-datadir="$installroot/$prefix/share/xen/qemu"
-docdir="$installroot/$prefix/share/doc/qemu"
-bindir="$installroot/$prefix/bin"
-configdir="$installroot/etc/xen"
+ prefix="/usr/local"
+fi
+mandir="$prefix/share/man"
+datadir="$prefix/share/xen/qemu"
+docdir="$prefix/share/doc/qemu"
+bindir="$prefix/$libdir/xen/bin"
+configdir="/etc/xen"
fi
echo "Install prefix $prefix"
@@ -372,39 +513,60 @@ echo "binary directory $bindir"
echo "binary directory $bindir"
if test "$mingw32" = "no" ; then
echo "Manual directory $mandir"
+echo "ELF interp prefix $interp_prefix"
fi
echo "Source path $source_path"
echo "C compiler $cc"
+echo "Host C compiler $host_cc"
echo "make $make"
+echo "install $install"
echo "host CPU $cpu"
echo "host big endian $bigendian"
echo "target list $target_list"
echo "gprof enabled $gprof"
+echo "profiler $profiler"
echo "static build $static"
-echo "VNC support $vnc"
+if test "$darwin" = "yes" ; then
+ echo "Cocoa support $cocoa"
+fi
echo "SDL support $sdl"
-echo "SDL static link $sdl_static"
+if test "$sdl" != "no" ; then
+ echo "SDL static link $sdl_static"
+fi
echo "mingw32 support $mingw32"
echo "Adlib support $adlib"
-echo -n "FMOD support $fmod"
-if test $fmod = "yes"; then
- echo -n " (lib='$fmod_lib' include='$fmod_inc')"
-fi
-echo ""
+echo "CoreAudio support $coreaudio"
+echo "ALSA support $alsa"
+echo "DSound support $dsound"
+if test "$fmod" = "yes"; then
+ if test -z $fmod_lib || test -z $fmod_inc; then
+ echo
+ echo "Error: You must specify path to FMOD library and headers"
+ echo "Example: --fmod-inc=/path/include/fmod
--fmod-lib=/path/lib/libfmod-3.74.so"
+ echo
+ exit 1
+ fi
+ fmod_support=" (lib='$fmod_lib' include='$fmod_inc')"
+else
+ fmod_support=""
+fi
+echo "FMOD support $fmod $fmod_support"
+echo "kqemu support $kqemu"
+echo "Documentation $build_docs"
if test $sdl_too_old = "yes"; then
-echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL
support"
-fi
-if test "$sdl_static" = "no"; then
- echo "WARNING: cannot compile statically with SDL - qemu-fast won't have a
graphical output"
-fi
-
+echo "-> Your SDL version is too old - please upgrade to have SDL support"
+fi
+#if test "$sdl_static" = "no"; then
+# echo "WARNING: cannot compile statically with SDL - qemu-fast won't have a
graphical output"
+#fi
config_mak="config-host.mak"
config_h="config-host.h"
#echo "Creating $config_mak and $config_h"
echo "# Automatically generated by configure - do not modify" > $config_mak
+echo "# Configured with: $0 $@" >> $config_mak
echo "/* Automatically generated by configure - do not modify */" > $config_h
echo "prefix=$prefix" >> $config_mak
@@ -415,22 +577,63 @@ echo "configdir=$configdir" >> $config_m
echo "configdir=$configdir" >> $config_mak
echo "LIBDIR=$libdir" >> $config_mak
echo "#define CONFIG_QEMU_SHAREDIR \"$datadir\"" >> $config_h
-#echo "MAKE=$make" >> $config_mak
-#echo "CC=$cc" >> $config_mak
-#if test "$have_gcc3_options" = "yes" ; then
-# echo "HAVE_GCC3_OPTIONS=yes" >> $config_mak
-#fi
-#echo "HOST_CC=$host_cc" >> $config_mak
-#echo "AR=$ar" >> $config_mak
-#echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
-#echo "CFLAGS=$CFLAGS" >> $config_mak
-#echo "LDFLAGS=$LDFLAGS" >> $config_mak
-#echo "EXESUF=$EXESUF" >> $config_mak
-
+echo "MAKE=$make" >> $config_mak
+echo "INSTALL=$install" >> $config_mak
+echo "CC=$cc" >> $config_mak
+if test "$have_gcc3_options" = "yes" ; then
+ echo "HAVE_GCC3_OPTIONS=yes" >> $config_mak
+fi
+echo "HOST_CC=$host_cc" >> $config_mak
+echo "AR=$ar" >> $config_mak
+echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
+echo "CFLAGS=$CFLAGS" >> $config_mak
+echo "LDFLAGS=$LDFLAGS" >> $config_mak
+echo "EXESUF=$EXESUF" >> $config_mak
+if test "$cpu" = "i386" ; then
+ echo "ARCH=i386" >> $config_mak
+ echo "#define HOST_I386 1" >> $config_h
+elif test "$cpu" = "x86_64" ; then
+ echo "ARCH=x86_64" >> $config_mak
+ echo "#define HOST_X86_64 1" >> $config_h
+elif test "$cpu" = "armv4b" ; then
+ echo "ARCH=arm" >> $config_mak
+ echo "#define HOST_ARM 1" >> $config_h
+elif test "$cpu" = "armv4l" ; then
+ echo "ARCH=arm" >> $config_mak
+ echo "#define HOST_ARM 1" >> $config_h
+elif test "$cpu" = "powerpc" ; then
+ echo "ARCH=ppc" >> $config_mak
+ echo "#define HOST_PPC 1" >> $config_h
+elif test "$cpu" = "mips" ; then
+ echo "ARCH=mips" >> $config_mak
+ echo "#define HOST_MIPS 1" >> $config_h
+elif test "$cpu" = "s390" ; then
+ echo "ARCH=s390" >> $config_mak
+ echo "#define HOST_S390 1" >> $config_h
+elif test "$cpu" = "alpha" ; then
+ echo "ARCH=alpha" >> $config_mak
+ echo "#define HOST_ALPHA 1" >> $config_h
+elif test "$cpu" = "sparc" ; then
+ echo "ARCH=sparc" >> $config_mak
+ echo "#define HOST_SPARC 1" >> $config_h
+elif test "$cpu" = "sparc64" ; then
+ echo "ARCH=sparc64" >> $config_mak
+ echo "#define HOST_SPARC64 1" >> $config_h
+elif test "$cpu" = "ia64" ; then
+ echo "ARCH=ia64" >> $config_mak
+ echo "#define HOST_IA64 1" >> $config_h
+elif test "$cpu" = "m68k" ; then
+ echo "ARCH=m68k" >> $config_mak
+ echo "#define HOST_M68K 1" >> $config_h
+else
+ echo "Unsupported CPU"
+ exit 1
+fi
if test "$bigendian" = "yes" ; then
echo "WORDS_BIGENDIAN=yes" >> $config_mak
echo "#define WORDS_BIGENDIAN 1" >> $config_h
fi
+echo "#define HOST_LONG_BITS $hostlongbits" >> $config_h
if test "$mingw32" = "yes" ; then
echo "CONFIG_WIN32=yes" >> $config_mak
echo "#define CONFIG_WIN32 1" >> $config_h
@@ -441,6 +644,10 @@ if test "$darwin" = "yes" ; then
echo "CONFIG_DARWIN=yes" >> $config_mak
echo "#define CONFIG_DARWIN 1" >> $config_h
fi
+if test "$solaris" = "yes" ; then
+ echo "CONFIG_SOLARIS=yes" >> $config_mak
+ echo "#define HOST_SOLARIS $solarisrev" >> $config_h
+fi
if test "$gdbstub" = "yes" ; then
echo "CONFIG_GDBSTUB=yes" >> $config_mak
echo "#define CONFIG_GDBSTUB 1" >> $config_h
@@ -453,6 +660,9 @@ if test "$static" = "yes" ; then
echo "CONFIG_STATIC=yes" >> $config_mak
echo "#define CONFIG_STATIC 1" >> $config_h
fi
+if test $profiler = "yes" ; then
+ echo "#define CONFIG_PROFILER 1" >> $config_h
+fi
if test "$slirp" = "yes" ; then
echo "CONFIG_SLIRP=yes" >> $config_mak
echo "#define CONFIG_SLIRP 1" >> $config_h
@@ -464,6 +674,18 @@ if test "$oss" = "yes" ; then
if test "$oss" = "yes" ; then
echo "CONFIG_OSS=yes" >> $config_mak
echo "#define CONFIG_OSS 1" >> $config_h
+fi
+if test "$coreaudio" = "yes" ; then
+ echo "CONFIG_COREAUDIO=yes" >> $config_mak
+ echo "#define CONFIG_COREAUDIO 1" >> $config_h
+fi
+if test "$alsa" = "yes" ; then
+ echo "CONFIG_ALSA=yes" >> $config_mak
+ echo "#define CONFIG_ALSA 1" >> $config_h
+fi
+if test "$dsound" = "yes" ; then
+ echo "CONFIG_DSOUND=yes" >> $config_mak
+ echo "#define CONFIG_DSOUND 1" >> $config_h
fi
if test "$fmod" = "yes" ; then
echo "CONFIG_FMOD=yes" >> $config_mak
@@ -471,15 +693,18 @@ if test "$fmod" = "yes" ; then
echo "CONFIG_FMOD_INC=$fmod_inc" >> $config_mak
echo "#define CONFIG_FMOD 1" >> $config_h
fi
-echo -n "VERSION=" >>$config_mak
-head $source_path/VERSION >>$config_mak
-echo "" >>$config_mak
-echo -n "#define QEMU_VERSION \"" >> $config_h
-head $source_path/VERSION >> $config_h
-echo "\"" >> $config_h
+qemu_version=`head $source_path/VERSION`
+echo "VERSION=$qemu_version" >>$config_mak
+echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h
echo "SRC_PATH=$source_path" >> $config_mak
+if [ "$source_path_used" = "yes" ]; then
+ echo "VPATH=$source_path" >> $config_mak
+fi
echo "TARGET_DIRS=$target_list" >> $config_mak
+if [ "$build_docs" = "yes" ] ; then
+ echo "BUILD_DOCS=yes" >> $config_mak
+fi
# XXX: suppress that
if [ "$bsd" = "yes" ] ; then
@@ -488,30 +713,18 @@ if [ "$bsd" = "yes" ] ; then
echo "#define _BSD 1" >> $config_h
fi
-if test "$vnc" = "yes"; then
- echo "CONFIG_VNC=yes" >> $config_mak
- vnc_cflags=`libvncserver-config --cflags`
- if [ -z $vnc_cflags ]; then
- vnc_cflags="/usr/include"
- fi
- echo "VNC_CFLAGS=$vnc_cflags" >> $config_mak
- if test "$have_eager_events" = "yes" ; then
- echo "#define VNC_EAGER_EVENTS 1" >> $config_h
- fi
-fi
-
-if test "$sdl" = "yes"; then
- echo "CONFIG_SDL=yes" >> $config_mak
- echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
-fi
-
-for target in $target_list; do
-
+for target in $target_list; do
target_dir="$target"
config_mak=$target_dir/config.mak
config_h=$target_dir/config.h
-target_cpu=`echo $target | cut -d '-' -f 2`
+target_cpu=`echo $target | cut -d '-' -f 1`
+target_bigendian="no"
+[ "$target_cpu" = "armeb" ] && target_bigendian=yes
+[ "$target_cpu" = "sparc" ] && target_bigendian=yes
+[ "$target_cpu" = "sparc64" ] && target_bigendian=yes
[ "$target_cpu" = "ppc" ] && target_bigendian=yes
+[ "$target_cpu" = "ppc64" ] && target_bigendian=yes
+[ "$target_cpu" = "mips" ] && target_bigendian=yes
target_softmmu="no"
if expr $target : '.*-softmmu' > /dev/null ; then
target_softmmu="yes"
@@ -522,17 +735,32 @@ if expr $target : '.*-user' > /dev/null
if expr $target : '.*-user' > /dev/null ; then
target_user_only="yes"
fi
+
+if test "$target_user_only" = "no" -a "$check_gfx" = "yes" \
+ -a "$sdl" = "no" -a "$cocoa" = "no" ; then
+ echo "ERROR: QEMU requires SDL or Cocoa for graphical output"
+ echo "To build QEMU without graphical output configure with
--disable-gfx-check"
+ echo "Note that this will disable all output from the virtual graphics
card."
+ exit 1;
+fi
+
#echo "Creating $config_mak, $config_h and $target_dir/Makefile"
mkdir -p $target_dir
-if test "$target" = "arm-user" ; then
+mkdir -p $target_dir/fpu
+if test "$target" = "arm-user" -o "$target" = "armeb-user" ; then
mkdir -p $target_dir/nwfpe
fi
if test "$target_user_only" = "no" ; then
mkdir -p $target_dir/slirp
fi
-#ln -sf $source_path/Makefile.target $target_dir/Makefile
+#
+# don't use ln -sf as not all "ln -sf" over write the file/link
+#
+rm -f $target_dir/Makefile
+ln -s ../Makefile.target $target_dir/Makefile
+
echo "# Automatically generated by configure - do not modify" > $config_mak
echo "/* Automatically generated by configure - do not modify */" > $config_h
@@ -541,13 +769,64 @@ echo "include ../config-host.mak" >> $co
echo "include ../config-host.mak" >> $config_mak
echo "#include \"../config-host.h\"" >> $config_h
-echo "TARGET_ARCH=i386" >> $config_mak
-echo "#define TARGET_ARCH \"i386\"" >> $config_h
-echo "#define TARGET_I386 1" >> $config_h
-
interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
+target_sub=
+if expr $target : '.*-dm' > /dev/null ; then
+ target_sub=-dm
+fi
+echo "TARGET_SUB=${target_sub}" >> $config_mak
+
+if test "$target_cpu" = "i386" ; then
+ echo "TARGET_ARCH=i386" >> $config_mak
+ echo "#define TARGET_ARCH \"i386\"" >> $config_h
+ echo "#define TARGET_I386 1" >> $config_h
+ if test $kqemu = "yes" -a "$target_softmmu" = "yes" -a $cpu = "i386" ; then
+ echo "#define USE_KQEMU 1" >> $config_h
+ fi
+elif test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" ; then
+ echo "TARGET_ARCH=arm" >> $config_mak
+ echo "#define TARGET_ARCH \"arm\"" >> $config_h
+ echo "#define TARGET_ARM 1" >> $config_h
+elif test "$target_cpu" = "sparc" ; then
+ echo "TARGET_ARCH=sparc" >> $config_mak
+ echo "#define TARGET_ARCH \"sparc\"" >> $config_h
+ echo "#define TARGET_SPARC 1" >> $config_h
+elif test "$target_cpu" = "sparc64" ; then
+ echo "TARGET_ARCH=sparc64" >> $config_mak
+ echo "#define TARGET_ARCH \"sparc64\"" >> $config_h
+ echo "#define TARGET_SPARC 1" >> $config_h
+ echo "#define TARGET_SPARC64 1" >> $config_h
+elif test "$target_cpu" = "ppc" ; then
+ echo "TARGET_ARCH=ppc" >> $config_mak
+ echo "#define TARGET_ARCH \"ppc\"" >> $config_h
+ echo "#define TARGET_PPC 1" >> $config_h
+elif test "$target_cpu" = "ppc64" ; then
+ echo "TARGET_ARCH=ppc64" >> $config_mak
+ echo "#define TARGET_ARCH \"ppc64\"" >> $config_h
+ echo "#define TARGET_PPC 1" >> $config_h
+ echo "#define TARGET_PPC64 1" >> $config_h
+elif test "$target_cpu" = "x86_64" ; then
+ echo "TARGET_ARCH=x86_64" >> $config_mak
+ echo "#define TARGET_ARCH \"x86_64\"" >> $config_h
+ echo "#define TARGET_I386 1" >> $config_h
+ echo "#define TARGET_X86_64 1" >> $config_h
+ if test $kqemu = "yes" -a "$target_softmmu" = "yes" -a $cpu = "x86_64" ;
then
+ echo "#define USE_KQEMU 1" >> $config_h
+ fi
+elif test "$target_cpu" = "mips" -o "$target_cpu" = "mipsel" ; then
+ echo "TARGET_ARCH=mips" >> $config_mak
+ echo "#define TARGET_ARCH \"mips\"" >> $config_h
+ echo "#define TARGET_MIPS 1" >> $config_h
+elif test "$target_cpu" = "sh4" ; then
+ echo "TARGET_ARCH=sh4" >> $config_mak
+ echo "#define TARGET_ARCH \"sh4\"" >> $config_h
+ echo "#define TARGET_SH4 1" >> $config_h
+else
+ echo "Unsupported target CPU"
+ exit 1
+fi
if test "$target_bigendian" = "yes" ; then
echo "TARGET_WORDS_BIGENDIAN=yes" >> $config_mak
echo "#define TARGET_WORDS_BIGENDIAN 1" >> $config_h
@@ -561,18 +840,17 @@ if test "$target_user_only" = "yes" ; th
echo "#define CONFIG_USER_ONLY 1" >> $config_h
fi
+if expr $target : '.*-dm' > /dev/null ; then
+ echo "#define CONFIG_DM 1" >> $config_h
+fi
+
+if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" ; then
+ echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
+ echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
+fi
+# sdl defines
+
if test "$target_user_only" = "no"; then
- if test "$vnc" = "yes"; then
- echo "#define CONFIG_VNC 1" >> $config_h
- echo "CONFIG_VNC=yes" >> $config_mak
- echo "VNC_CFLAGS=`libvncserver-config --cflags`" >> $config_mak
- echo "VNC_LIBS=`libvncserver-config --libs`" >> $config_mak
- fi
-fi
-
-# sdl defines
-
-if test "$sdl" = "yes" -a "$target_user_only" = "no"; then
if test "$target_softmmu" = "no" -o "$static" = "yes"; then
sdl1=$sdl_static
else
@@ -586,12 +864,17 @@ if test "$sdl" = "yes" -a "$target_user_
else
echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak
fi
- echo -n "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
if [ "${aa}" = "yes" ] ; then
- echo -n " `aalib-config --cflags`" >> $config_mak ;
+ echo "SDL_CFLAGS=`$sdl_config --cflags` `aalib-config --cflags`"
>> $config_mak
+ else
+ echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
fi
- echo "" >> $config_mak
- fi
+ fi
+fi
+
+if test "$cocoa" = "yes" ; then
+ echo "#define CONFIG_COCOA 1" >> $config_h
+ echo "CONFIG_COCOA=yes" >> $config_mak
fi
done # for target in $targets
@@ -603,8 +886,10 @@ if test "$source_path_used" = "yes" ; th
for dir in $DIRS ; do
mkdir -p $dir
done
+ # remove the link and recreate it, as not all "ln -sf" overwrite the link
for f in $FILES ; do
- ln -sf $source_path/$f $f
+ rm -f $f
+ ln -s $source_path/$f $f
done
fi
diff -r 2db50529223e -r f7b43e5c42b9 tools/ioemu/console.c
--- a/tools/ioemu/console.c Tue Jul 25 09:51:50 2006 -0600
+++ b/tools/ioemu/console.c Tue Jul 25 12:19:05 2006 -0600
@@ -23,16 +23,26 @@
*/
#include "vl.h"
+//#define DEBUG_CONSOLE
#define DEFAULT_BACKSCROLL 512
#define MAX_CONSOLES 12
#define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define RGB(r, g, b) RGBA(r, g, b, 0xff)
+typedef struct TextAttributes {
+ uint8_t fgcol:4;
+ uint8_t bgcol:4;
+ uint8_t bold:1;
+ uint8_t uline:1;
+ uint8_t blink:1;
+ uint8_t invers:1;
+ uint8_t unvisible:1;
+} TextAttributes;
+
typedef struct TextCell {
uint8_t ch;
- uint8_t bgcol:4;
- uint8_t fgcol:4;
+ TextAttributes t_attrib;
} TextCell;
#define MAX_ESC_PARAMS 3
@@ -43,19 +53,27 @@ enum TTYState {
TTY_STATE_CSI,
};
+/* ??? This is mis-named.
+ It is used for both text and graphical consoles. */
struct TextConsole {
int text_console; /* true if text console */
DisplayState *ds;
+ /* Graphic console state. */
+ vga_hw_update_ptr hw_update;
+ vga_hw_invalidate_ptr hw_invalidate;
+ vga_hw_screen_dump_ptr hw_screen_dump;
+ void *hw;
+
int g_width, g_height;
int width;
int height;
int total_height;
int backscroll_height;
- int fgcol;
- int bgcol;
int x, y;
int y_displayed;
int y_base;
+ TextAttributes t_attrib_default; /* default text attributes */
+ TextAttributes t_attrib; /* currently active text attributes */
TextCell *cells;
enum TTYState state;
@@ -70,6 +88,26 @@ static TextConsole *active_console;
static TextConsole *active_console;
static TextConsole *consoles[MAX_CONSOLES];
static int nb_consoles = 0;
+
+void vga_hw_update(void)
+{
+ if (active_console->hw_update)
+ active_console->hw_update(active_console->hw);
+}
+
+void vga_hw_invalidate(void)
+{
+ if (active_console->hw_invalidate)
+ active_console->hw_invalidate(active_console->hw);
+}
+
+void vga_hw_screen_dump(const char *filename)
+{
+ /* There is currently no was of specifying which screen we want to dump,
+ so always dump the dirst one. */
+ if (consoles[0]->hw_screen_dump)
+ consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
+}
/* convert a RGBA color to a color index usable in graphic primitives */
static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
@@ -221,17 +259,40 @@ static const uint32_t dmask4[4] = {
PAT(0xffffffff),
};
-static uint32_t color_table[8];
-
-static const uint32_t color_table_rgb[8] = {
- RGB(0x00, 0x00, 0x00),
- RGB(0xff, 0x00, 0x00),
- RGB(0x00, 0xff, 0x00),
- RGB(0xff, 0xff, 0x00),
- RGB(0x00, 0x00, 0xff),
- RGB(0xff, 0x00, 0xff),
- RGB(0x00, 0xff, 0xff),
- RGB(0xff, 0xff, 0xff),
+static uint32_t color_table[2][8];
+
+enum color_names {
+ COLOR_BLACK = 0,
+ COLOR_RED = 1,
+ COLOR_GREEN = 2,
+ COLOR_YELLOW = 3,
+ COLOR_BLUE = 4,
+ COLOR_MAGENTA = 5,
+ COLOR_CYAN = 6,
+ COLOR_WHITE = 7
+};
+
+static const uint32_t color_table_rgb[2][8] = {
+ { /* dark */
+ RGB(0x00, 0x00, 0x00), /* black */
+ RGB(0xaa, 0x00, 0x00), /* red */
+ RGB(0x00, 0xaa, 0x00), /* green */
+ RGB(0xaa, 0xaa, 0x00), /* yellow */
+ RGB(0x00, 0x00, 0xaa), /* blue */
+ RGB(0xaa, 0x00, 0xaa), /* magenta */
+ RGB(0x00, 0xaa, 0xaa), /* cyan */
+ RGB(0xaa, 0xaa, 0xaa), /* white */
+ },
+ { /* bright */
+ RGB(0x00, 0x00, 0x00), /* black */
+ RGB(0xff, 0x00, 0x00), /* red */
+ RGB(0x00, 0xff, 0x00), /* green */
+ RGB(0xff, 0xff, 0x00), /* yellow */
+ RGB(0x00, 0x00, 0xff), /* blue */
+ RGB(0xff, 0x00, 0xff), /* magenta */
+ RGB(0x00, 0xff, 0xff), /* cyan */
+ RGB(0xff, 0xff, 0xff), /* white */
+ }
};
static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
@@ -251,14 +312,60 @@ static inline unsigned int col_expand(Di
return col;
}
+#ifdef DEBUG_CONSOLE
+static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
+{
+ if (t_attrib->bold) {
+ printf("b");
+ } else {
+ printf(" ");
+ }
+ if (t_attrib->uline) {
+ printf("u");
+ } else {
+ printf(" ");
+ }
+ if (t_attrib->blink) {
+ printf("l");
+ } else {
+ printf(" ");
+ }
+ if (t_attrib->invers) {
+ printf("i");
+ } else {
+ printf(" ");
+ }
+ if (t_attrib->unvisible) {
+ printf("n");
+ } else {
+ printf(" ");
+ }
+
+ printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol,
ch, ch);
+}
+#endif
static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
- unsigned int fgcol, unsigned int bgcol)
+ TextAttributes *t_attrib)
{
uint8_t *d;
const uint8_t *font_ptr;
unsigned int font_data, linesize, xorcol, bpp;
int i;
+ unsigned int fgcol, bgcol;
+
+#ifdef DEBUG_CONSOLE
+ printf("x: %2i y: %2i", x, y);
+ console_print_text_attributes(t_attrib, ch);
+#endif
+
+ if (t_attrib->invers) {
+ bgcol = color_table[t_attrib->bold][t_attrib->fgcol];
+ fgcol = color_table[t_attrib->bold][t_attrib->bgcol];
+ } else {
+ fgcol = color_table[t_attrib->bold][t_attrib->fgcol];
+ bgcol = color_table[t_attrib->bold][t_attrib->bgcol];
+ }
bpp = (ds->depth + 7) >> 3;
d = ds->data +
@@ -270,6 +377,10 @@ static void vga_putcharxy(DisplayState *
case 8:
for(i = 0; i < FONT_HEIGHT; i++) {
font_data = *font_ptr++;
+ if (t_attrib->uline
+ && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
+ font_data = 0xFFFF;
+ }
((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^
bgcol;
d += linesize;
@@ -279,6 +390,10 @@ static void vga_putcharxy(DisplayState *
case 15:
for(i = 0; i < FONT_HEIGHT; i++) {
font_data = *font_ptr++;
+ if (t_attrib->uline
+ && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
+ font_data = 0xFFFF;
+ }
((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^
bgcol;
((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^
bgcol;
@@ -289,6 +404,9 @@ static void vga_putcharxy(DisplayState *
case 32:
for(i = 0; i < FONT_HEIGHT; i++) {
font_data = *font_ptr++;
+ if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i ==
FONT_HEIGHT - 3))) {
+ font_data = 0xFFFF;
+ }
((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
@@ -327,8 +445,7 @@ static void text_console_resize(TextCons
}
for(x = w1; x < s->width; x++) {
c->ch = ' ';
- c->fgcol = 7;
- c->bgcol = 0;
+ c->t_attrib = s->t_attrib_default;
c++;
}
}
@@ -349,7 +466,7 @@ static void update_xy(TextConsole *s, in
if (y2 < s->height) {
c = &s->cells[y1 * s->width + x];
vga_putcharxy(s->ds, x, y2, c->ch,
- color_table[c->fgcol], color_table[c->bgcol]);
+ &(c->t_attrib));
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|